From 3fe6ad6c39834350d74145de855fbffdde02ace4 Mon Sep 17 00:00:00 2001 From: Peter Ma Date: Mon, 24 Aug 2009 14:13:29 -0700 Subject: avr32: re-instate MCI WP/CD pin assignments for ATNGW100 The MRMT1 patch mistakenly reverted commit fe272b5bd13d3522f9d1ed35425f1c7af4d8343f. This new patch is intended to correct this, so that both daughtercards should be able to assign GPIO PC25 and PE0 to the MCI driver. Signed-off-by: Peter Ma Signed-off-by: Haavard Skinnemoen diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c index bc299fb..5b022aa 100644 --- a/arch/avr32/boards/atngw100/setup.c +++ b/arch/avr32/boards/atngw100/setup.c @@ -56,13 +56,8 @@ static struct spi_board_info spi0_board_info[] __initdata = { static struct mci_platform_data __initdata mci0_data = { .slot[0] = { .bus_width = 4, -#if defined(CONFIG_BOARD_ATNGW100_EVKLCD10X) || defined(CONFIG_BOARD_ATNGW100_MRMT1) - .detect_pin = GPIO_PIN_NONE, - .wp_pin = GPIO_PIN_NONE, -#else .detect_pin = GPIO_PIN_PC(25), .wp_pin = GPIO_PIN_PE(0), -#endif }, }; -- cgit v0.10.2 From 0708420370db7350b75cbf64b1eb80ad1b2a89df Mon Sep 17 00:00:00 2001 From: Peter Ma Date: Thu, 27 Aug 2009 00:31:47 -0700 Subject: avr32: function for independently setting up SPI slaves at32ap_spi_setup_slaves() is exposed to allow the addition of SPI slaves to a SPI bus that has already been registered. This is especially useful for add-on cards, which have their own board setup function. at32ap_spi_add_device() has been slightly re-organized, but should be transparent to existing users. So to add a SPI slave, after a SPI bus has already been registered: /* Configure the list of slaves on SPI controller "id" */ at32_spi_setup_slaves(id,spi_board_info,ARRAY_SIZE(spi_board_info)); /* Register the list of slaves */ spi_register_board_info(spi_board_info,ARRAY_SIZE(spi_board_info)); Signed-off-by: Peter Ma [haavard.skinnemoen@atmel.com: trivial whitespace fix] Signed-off-by: Haavard Skinnemoen diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index eb9d4dc..a47592e 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c @@ -1181,19 +1181,32 @@ static struct resource atmel_spi1_resource[] = { DEFINE_DEV(atmel_spi, 1); DEV_CLK(spi_clk, atmel_spi1, pba, 1); -static void __init -at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, - unsigned int n, const u8 *pins) +void __init +at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, unsigned int n) { + /* + * Manage the chipselects as GPIOs, normally using the same pins + * the SPI controller expects; but boards can use other pins. + */ + static u8 __initdata spi_pins[][4] = { + { GPIO_PIN_PA(3), GPIO_PIN_PA(4), + GPIO_PIN_PA(5), GPIO_PIN_PA(20) }, + { GPIO_PIN_PB(2), GPIO_PIN_PB(3), + GPIO_PIN_PB(4), GPIO_PIN_PA(27) }, + }; unsigned int pin, mode; + /* There are only 2 SPI controllers */ + if (bus_num > 1) + return; + for (; n; n--, b++) { b->bus_num = bus_num; if (b->chip_select >= 4) continue; pin = (unsigned)b->controller_data; if (!pin) { - pin = pins[b->chip_select]; + pin = spi_pins[bus_num][b->chip_select]; b->controller_data = (void *)pin; } mode = AT32_GPIOF_OUTPUT; @@ -1206,16 +1219,6 @@ at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, struct platform_device *__init at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n) { - /* - * Manage the chipselects as GPIOs, normally using the same pins - * the SPI controller expects; but boards can use other pins. - */ - static u8 __initdata spi0_pins[] = - { GPIO_PIN_PA(3), GPIO_PIN_PA(4), - GPIO_PIN_PA(5), GPIO_PIN_PA(20), }; - static u8 __initdata spi1_pins[] = - { GPIO_PIN_PB(2), GPIO_PIN_PB(3), - GPIO_PIN_PB(4), GPIO_PIN_PA(27), }; struct platform_device *pdev; u32 pin_mask; @@ -1228,7 +1231,7 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n) select_peripheral(PIOA, (1 << 0), PERIPH_A, AT32_GPIOF_PULLUP); select_peripheral(PIOA, pin_mask, PERIPH_A, 0); - at32_spi_setup_slaves(0, b, n, spi0_pins); + at32_spi_setup_slaves(0, b, n); break; case 1: @@ -1239,7 +1242,7 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n) select_peripheral(PIOB, (1 << 0), PERIPH_B, AT32_GPIOF_PULLUP); select_peripheral(PIOB, pin_mask, PERIPH_B, 0); - at32_spi_setup_slaves(1, b, n, spi1_pins); + at32_spi_setup_slaves(1, b, n); break; default: diff --git a/arch/avr32/mach-at32ap/include/mach/board.h b/arch/avr32/mach-at32ap/include/mach/board.h index ddedb47..c7f25bb 100644 --- a/arch/avr32/mach-at32ap/include/mach/board.h +++ b/arch/avr32/mach-at32ap/include/mach/board.h @@ -49,6 +49,7 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data); struct spi_board_info; struct platform_device * at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n); +void at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, unsigned int n); struct atmel_lcdfb_info; struct platform_device * -- cgit v0.10.2 From d55651168a20078a94597a297d5cdfd807bf07b6 Mon Sep 17 00:00:00 2001 From: Peter Ma Date: Thu, 27 Aug 2009 00:56:43 -0700 Subject: avr32: MRMT: correct setup of SPI slaves For MRMT1/2 add-on card to Atmel ATNGW100. This patch implements the SPI slave setup method created by patch: <> Signed-off-by: Peter Ma Signed-off-by: Haavard Skinnemoen diff --git a/arch/avr32/boards/atngw100/mrmt.c b/arch/avr32/boards/atngw100/mrmt.c index bf78e51..7919be3 100644 --- a/arch/avr32/boards/atngw100/mrmt.c +++ b/arch/avr32/boards/atngw100/mrmt.c @@ -302,6 +302,7 @@ static int __init mrmt1_init(void) at32_select_periph( GPIO_PIOB_BASE, 1 << (PB_EXTINT_BASE+TS_IRQ), GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH); set_irq_type( AT32_EXTINT(TS_IRQ), IRQ_TYPE_EDGE_FALLING ); + at32_spi_setup_slaves(0,spi01_board_info,ARRAY_SIZE(spi01_board_info)); spi_register_board_info(spi01_board_info,ARRAY_SIZE(spi01_board_info)); #endif -- cgit v0.10.2 From ea60658a08f8f3511a70587b27f12cd7e0ac5ae3 Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Thu, 24 Sep 2009 15:46:22 -0400 Subject: mtd: m25p80: disable SST software protection bits by default The SST SPI flashes is like Atmel SPI flashes in that the software protection bits are set by default at power up, so clear them at init time. Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger Signed-off-by: David Woodhouse diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 379c316..933267a 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -775,11 +775,12 @@ static int __devinit m25p_probe(struct spi_device *spi) dev_set_drvdata(&spi->dev, flash); /* - * Atmel serial flash tend to power up - * with the software protection bits set + * Atmel and SST serial flash tend to power + * up with the software protection bits set */ - if (info->jedec_id >> 16 == 0x1f) { + if (info->jedec_id >> 16 == 0x1f || + info->jedec_id >> 16 == 0xbf) { write_enable(flash); write_sr(flash, 0); } -- cgit v0.10.2 From c62d81bcfe82526cc3da10cf4fc63faad368bc60 Mon Sep 17 00:00:00 2001 From: Alessandro Rubini Date: Sun, 20 Sep 2009 23:28:04 +0200 Subject: mtd: use bbm.h in nand.h This consolidates common code in nand.h and bbm.h. The comments and data structures were the same, this keeps the comment from nand.h as it fits 80 columns, while the one in bbm.h did not. Signed-off-by: Alessandro Rubini Signed-off-by: David Woodhouse diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h index fff8c53..9c3757c 100644 --- a/include/linux/mtd/bbm.h +++ b/include/linux/mtd/bbm.h @@ -19,22 +19,21 @@ /** * struct nand_bbt_descr - bad block table descriptor - * @options: options for this descriptor - * @pages: the page(s) where we find the bbt, used with - * option BBT_ABSPAGE when bbt is searched, - * then we store the found bbts pages here. - * Its an array and supports up to 8 chips now - * @offs: offset of the pattern in the oob area of the page - * @veroffs: offset of the bbt version counter in the oob area of the page - * @version: version read from the bbt page during scan - * @len: length of the pattern, if 0 no pattern check is performed - * @maxblocks: maximum number of blocks to search for a bbt. This - * number of blocks is reserved at the end of the device - * where the tables are written. - * @reserved_block_code: if non-0, this pattern denotes a reserved - * (rather than bad) block in the stored bbt - * @pattern: pattern to identify bad block table or factory marked - * good / bad blocks, can be NULL, if len = 0 + * @options: options for this descriptor + * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE + * when bbt is searched, then we store the found bbts pages here. + * Its an array and supports up to 8 chips now + * @offs: offset of the pattern in the oob area of the page + * @veroffs: offset of the bbt version counter in the oob are of the page + * @version: version read from the bbt page during scan + * @len: length of the pattern, if 0 no pattern check is performed + * @maxblocks: maximum number of blocks to search for a bbt. This number of + * blocks is reserved at the end of the device where the tables are + * written. + * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than + * bad) block in the stored bbt + * @pattern: pattern to identify bad block table or factory marked good / + * bad blocks, can be NULL, if len = 0 * * Descriptor for the bad block table marker and the descriptor for the * pattern which identifies good and bad blocks. The assumption is made @@ -90,7 +89,9 @@ struct nand_bbt_descr { /* * Constants for oob configuration */ -#define ONENAND_BADBLOCK_POS 0 +#define NAND_SMALL_BADBLOCK_POS 5 +#define NAND_LARGE_BADBLOCK_POS 0 +#define ONENAND_BADBLOCK_POS 0 /* * Bad block scanning errors diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 7a232a9..d87ada5 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -21,6 +21,7 @@ #include #include #include +#include struct mtd_info; /* Scan and identify a NAND device */ @@ -470,75 +471,6 @@ struct nand_manufacturers { extern struct nand_flash_dev nand_flash_ids[]; extern struct nand_manufacturers nand_manuf_ids[]; -/** - * struct nand_bbt_descr - bad block table descriptor - * @options: options for this descriptor - * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE - * when bbt is searched, then we store the found bbts pages here. - * Its an array and supports up to 8 chips now - * @offs: offset of the pattern in the oob area of the page - * @veroffs: offset of the bbt version counter in the oob are of the page - * @version: version read from the bbt page during scan - * @len: length of the pattern, if 0 no pattern check is performed - * @maxblocks: maximum number of blocks to search for a bbt. This number of - * blocks is reserved at the end of the device where the tables are - * written. - * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than - * bad) block in the stored bbt - * @pattern: pattern to identify bad block table or factory marked good / - * bad blocks, can be NULL, if len = 0 - * - * Descriptor for the bad block table marker and the descriptor for the - * pattern which identifies good and bad blocks. The assumption is made - * that the pattern and the version count are always located in the oob area - * of the first block. - */ -struct nand_bbt_descr { - int options; - int pages[NAND_MAX_CHIPS]; - int offs; - int veroffs; - uint8_t version[NAND_MAX_CHIPS]; - int len; - int maxblocks; - int reserved_block_code; - uint8_t *pattern; -}; - -/* Options for the bad block table descriptors */ - -/* The number of bits used per block in the bbt on the device */ -#define NAND_BBT_NRBITS_MSK 0x0000000F -#define NAND_BBT_1BIT 0x00000001 -#define NAND_BBT_2BIT 0x00000002 -#define NAND_BBT_4BIT 0x00000004 -#define NAND_BBT_8BIT 0x00000008 -/* The bad block table is in the last good block of the device */ -#define NAND_BBT_LASTBLOCK 0x00000010 -/* The bbt is at the given page, else we must scan for the bbt */ -#define NAND_BBT_ABSPAGE 0x00000020 -/* The bbt is at the given page, else we must scan for the bbt */ -#define NAND_BBT_SEARCH 0x00000040 -/* bbt is stored per chip on multichip devices */ -#define NAND_BBT_PERCHIP 0x00000080 -/* bbt has a version counter at offset veroffs */ -#define NAND_BBT_VERSION 0x00000100 -/* Create a bbt if none axists */ -#define NAND_BBT_CREATE 0x00000200 -/* Search good / bad pattern through all pages of a block */ -#define NAND_BBT_SCANALLPAGES 0x00000400 -/* Scan block empty during good / bad block scan */ -#define NAND_BBT_SCANEMPTY 0x00000800 -/* Write bbt if neccecary */ -#define NAND_BBT_WRITE 0x00001000 -/* Read and write back block contents when writing bbt */ -#define NAND_BBT_SAVECONTENT 0x00002000 -/* Search good / bad pattern on the first and the second page */ -#define NAND_BBT_SCAN2NDPAGE 0x00004000 - -/* The maximum number of blocks to scan for a bbt */ -#define NAND_BBT_SCAN_MAXBLOCKS 4 - extern int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd); extern int nand_update_bbt(struct mtd_info *mtd, loff_t offs); extern int nand_default_bbt(struct mtd_info *mtd); @@ -548,12 +480,6 @@ extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, uint8_t * buf); -/* -* Constants for oob configuration -*/ -#define NAND_SMALL_BADBLOCK_POS 5 -#define NAND_LARGE_BADBLOCK_POS 0 - /** * struct platform_nand_chip - chip level device structure * @nr_chips: max. number of chips to scan for -- cgit v0.10.2 From 30631cb82d5c6c662d5ec682beaa834c1f9f0987 Mon Sep 17 00:00:00 2001 From: Alessandro Rubini Date: Sun, 20 Sep 2009 23:28:14 +0200 Subject: mtd: unify status enum from three headers nand.h, onenand.h and flashchip.h defined enumeration types for chip status using the same symbolic names. This prevented a board file to include more than one of them. In particular, no nand and onenand platform devices could live in the same file. This patch augments flashchip.h with a few status values in order to cover all cases, so nand.h and onenand.h can use flstate_t without declaring their own status enum. Signed-off-by: Alessandro Rubini Signed-off-by: David Woodhouse diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h index d4f38c5..f350a48 100644 --- a/include/linux/mtd/flashchip.h +++ b/include/linux/mtd/flashchip.h @@ -38,6 +38,13 @@ typedef enum { FL_XIP_WHILE_ERASING, FL_XIP_WHILE_WRITING, FL_SHUTDOWN, + /* These 2 come from nand_state_t, which has been unified here */ + FL_READING, + FL_CACHEDPRG, + /* These 2 come from onenand_state_t, which has been unified here */ + FL_RESETING, + FL_OTPING, + FL_UNKNOWN } flstate_t; diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index d87ada5..2476078 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -21,6 +21,7 @@ #include #include #include +#include #include struct mtd_info; @@ -203,20 +204,6 @@ typedef enum { #define NAND_CI_CHIPNR_MSK 0x03 #define NAND_CI_CELLTYPE_MSK 0x0C -/* - * nand_state_t - chip states - * Enumeration for NAND flash chip state - */ -typedef enum { - FL_READY, - FL_READING, - FL_WRITING, - FL_ERASING, - FL_SYNCING, - FL_CACHEDPRG, - FL_PM_SUSPENDED, -} nand_state_t; - /* Keep gcc happy */ struct nand_chip; @@ -403,7 +390,7 @@ struct nand_chip { uint8_t cellinfo; int badblockpos; - nand_state_t state; + flstate_t state; uint8_t *oob_poi; struct nand_hw_control *controller; diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index 4e49f33..f57e29e 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -25,22 +26,6 @@ extern int onenand_scan(struct mtd_info *mtd, int max_chips); /* Free resources held by the OneNAND device */ extern void onenand_release(struct mtd_info *mtd); -/* - * onenand_state_t - chip states - * Enumeration for OneNAND flash chip state - */ -typedef enum { - FL_READY, - FL_READING, - FL_WRITING, - FL_ERASING, - FL_SYNCING, - FL_LOCKING, - FL_RESETING, - FL_OTPING, - FL_PM_SUSPENDED, -} onenand_state_t; - /** * struct onenand_bufferram - OneNAND BufferRAM Data * @blockpage: block & page address in BufferRAM @@ -137,7 +122,7 @@ struct onenand_chip { spinlock_t chip_lock; wait_queue_head_t wq; - onenand_state_t state; + flstate_t state; unsigned char *page_buf; unsigned char *oob_buf; -- cgit v0.10.2 From c1558b55c55620f54f0f78cb8295947a2a3f6de2 Mon Sep 17 00:00:00 2001 From: Alessandro Rubini Date: Sun, 20 Sep 2009 23:28:24 +0200 Subject: ARM Nomadik: use new OneNand name and pdata This enables the onenand with the new platform device name. Moreover, it fixes a related typo that doesn't deserve a separate patch. Signed-off-by: Alessandro Rubini Acked-by: Andrea Gallo Signed-off-by: David Woodhouse diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index 6bfd537..781b915 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -142,7 +143,7 @@ static struct mtd_partition nhk8815_onenand_partitions[] = { } }; -static struct flash_platform_data nhk8815_onenand_data = { +static struct onenand_platform_data nhk8815_onenand_data = { .parts = nhk8815_onenand_partitions, .nr_parts = ARRAY_SIZE(nhk8815_onenand_partitions), }; @@ -156,7 +157,7 @@ static struct resource nhk8815_onenand_resource[] = { }; static struct platform_device nhk8815_onenand_device = { - .name = "onenand", + .name = "onenand-flash", .id = -1, .dev = { .platform_data = &nhk8815_onenand_data, @@ -167,10 +168,10 @@ static struct platform_device nhk8815_onenand_device = { static void __init nhk8815_onenand_init(void) { -#ifdef CONFIG_ONENAND +#ifdef CONFIG_MTD_ONENAND /* Set up SMCS0 for OneNand */ - writel(0x000030db, FSMC_BCR0); - writel(0x02100551, FSMC_BTR0); + writel(0x000030db, FSMC_BCR(0)); + writel(0x02100551, FSMC_BTR(0)); #endif } -- cgit v0.10.2 From 794d579ae17a7ec8028e4844096059c19431a96c Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 27 Sep 2009 23:51:04 +0100 Subject: mtd: Fix warning in sa1100-flash.c drivers/mtd/maps/sa1100-flash.c: In function 'sa1100_probe_subdev': drivers/mtd/maps/sa1100-flash.c:214: warning: format '%d' expects type 'int', but argument 3 has type 'uint64_t' Signed-off-by: Russell King Signed-off-by: David Woodhouse diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index fdb97f3..d7a4757 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -209,8 +209,8 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *r } subdev->mtd->owner = THIS_MODULE; - printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %dMiB, " - "%d-bit\n", phys, subdev->mtd->size >> 20, + printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %uMiB, %d-bit\n", + phys, (unsigned)(subdev->mtd->size >> 20), subdev->map.bankwidth * 8); return 0; -- cgit v0.10.2 From 03d6a74b5f85ff46f20e1382982b7f4860f5fec6 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Tue, 22 Sep 2009 11:09:12 -0400 Subject: nfsd: fix Documentation typo Caught by Benny, thanks! Signed-off-by: J. Bruce Fields diff --git a/Documentation/filesystems/nfs41-server.txt b/Documentation/filesystems/nfs41-server.txt index 5920fe2..1f95e77 100644 --- a/Documentation/filesystems/nfs41-server.txt +++ b/Documentation/filesystems/nfs41-server.txt @@ -41,7 +41,7 @@ interoperability problems with future clients. Known issues: conformant with the spec (for example, we don't use kerberos on the backchannel correctly). - no trunking support: no clients currently take advantage of - trunking, but this is a mandatory failure, and its use is + trunking, but this is a mandatory feature, and its use is recommended to clients in a number of places. (E.g. to ensure timely renewal in case an existing connection's retry timeouts have gotten too long; see section 8.3 of the draft.) -- cgit v0.10.2 From fed83811269d0f559d2da9139e12c5e5d9874d5c Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Sat, 26 Sep 2009 16:53:01 -0400 Subject: nfsd4: cross mountpoints when looking up parents 3c394ddaa7ea4205f933fd9b481166b2669368a9 "nfsd4: nfsv4 clients should cross mountpoints" forgot to handle lookups of parents directories. Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index a293f02..b8ed58b 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -169,7 +169,7 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, dentry = dget(dparent); else if (dparent != exp->ex_path.dentry) dentry = dget_parent(dparent); - else if (!EX_NOHIDE(exp)) + else if (!EX_NOHIDE(exp) && !nfsd_v4client(rqstp)) dentry = dget(dparent); /* .. == . just like at / */ else { /* checking mountpoint crossing is very different when stepping up */ -- cgit v0.10.2 From 289ede453e5a621de19c61e630302b1845cc1d59 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Sat, 26 Sep 2009 20:32:24 -0400 Subject: nfsd: minor nfsd_lookup cleanup Break out some of nfsd_lookup_dentry into helper functions. Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index b8ed58b..6385739 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -141,6 +141,40 @@ out: return err; } +static void follow_to_parent(struct path *path) +{ + struct dentry *dp; + + while (path->dentry == path->mnt->mnt_root && follow_up(path)) + ; + dp = dget_parent(path->dentry); + dput(path->dentry); + path->dentry = dp; +} + +static int nfsd_lookup_parent(struct svc_rqst *rqstp, struct dentry *dparent, struct svc_export **exp, struct dentry **dentryp) +{ + struct svc_export *exp2; + struct path path = {.mnt = mntget((*exp)->ex_path.mnt), + .dentry = dget(dparent)}; + + follow_to_parent(&path); + + exp2 = rqst_exp_parent(rqstp, &path); + if (PTR_ERR(exp2) == -ENOENT) { + *dentryp = dget(dparent); + } else if (IS_ERR(exp2)) { + path_put(&path); + return PTR_ERR(exp2); + } else { + *dentryp = dget(path.dentry); + exp_put(*exp); + *exp = exp2; + } + path_put(&path); + return 0; +} + __be32 nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, unsigned int len, @@ -173,31 +207,9 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, dentry = dget(dparent); /* .. == . just like at / */ else { /* checking mountpoint crossing is very different when stepping up */ - struct svc_export *exp2 = NULL; - struct dentry *dp; - struct path path = {.mnt = mntget(exp->ex_path.mnt), - .dentry = dget(dparent)}; - - while (path.dentry == path.mnt->mnt_root && - follow_up(&path)) - ; - dp = dget_parent(path.dentry); - dput(path.dentry); - path.dentry = dp; - - exp2 = rqst_exp_parent(rqstp, &path); - if (PTR_ERR(exp2) == -ENOENT) { - dentry = dget(dparent); - } else if (IS_ERR(exp2)) { - host_err = PTR_ERR(exp2); - path_put(&path); + host_err = nfsd_lookup_parent(rqstp, dparent, &exp, &dentry); + if (host_err) goto out_nfserr; - } else { - dentry = dget(path.dentry); - exp_put(exp); - exp = exp2; - } - path_put(&path); } } else { fh_lock(fhp); -- cgit v0.10.2 From f39bde24b275ddc45df1ed835725b609e178c7a0 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Sun, 27 Sep 2009 14:41:43 -0400 Subject: nfsd4: fix error return when pseudoroot missing We really shouldn't hit this case at all, and forthcoming kernel and nfs-utils changes should eliminate this case; if it does happen, consider it a bug rather than reporting an error that doesn't really make sense for the operation (since there's no reason for a server to be accepting v4 traffic yet have no root filehandle). Also move some exp_pseudoroot code into a helper function while we're here. Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index c1c9e03..b73baba 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -1320,6 +1320,23 @@ rqst_exp_parent(struct svc_rqst *rqstp, struct path *path) return exp; } +static struct svc_export *find_fsidzero_export(struct svc_rqst *rqstp) +{ + struct svc_export *exp; + u32 fsidv[2]; + + mk_fsid(FSID_NUM, fsidv, 0, 0, 0, NULL); + + exp = rqst_exp_find(rqstp, FSID_NUM, fsidv); + /* + * We shouldn't have accepting an nfsv4 request at all if we + * don't have a pseudoexport!: + */ + if (IS_ERR(exp) && PTR_ERR(exp) == -ENOENT) + exp = ERR_PTR(-ESERVERFAULT); + return exp; +} + /* * Called when we need the filehandle for the root of the pseudofs, * for a given NFSv4 client. The root is defined to be the @@ -1330,11 +1347,8 @@ exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp) { struct svc_export *exp; __be32 rv; - u32 fsidv[2]; - - mk_fsid(FSID_NUM, fsidv, 0, 0, 0, NULL); - exp = rqst_exp_find(rqstp, FSID_NUM, fsidv); + exp = find_fsidzero_export(rqstp); if (IS_ERR(exp)) return nfserrno(PTR_ERR(exp)); rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL); diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index 0eb9c82..c5393d1 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -758,6 +758,7 @@ nfserrno (int errno) { nfserr_io, -ETXTBSY }, { nfserr_notsupp, -EOPNOTSUPP }, { nfserr_toosmall, -ETOOSMALL }, + { nfserr_serverfault, -ESERVERFAULT }, }; int i; -- cgit v0.10.2 From ddc04fd4d5163aee9ebdb38a56c365b602e2b7b7 Mon Sep 17 00:00:00 2001 From: Andy Adamson Date: Wed, 23 Sep 2009 21:32:21 -0400 Subject: nfsd41: use sv_max_mesg for forechannel max sizes ca_maxresponsesize and ca_maxrequest size include the RPC header. sv_max_mesg is sv_max_payolad plus a page for overhead and is used in svc_init_buffer to allocate server buffer space for both the request and reply. Note that this means we can service an RPC compound that requires ca_maxrequestsize (MAXWRITE) or ca_max_responsesize (MAXREAD) but that we do not support an RPC compound that requires both ca_maxrequestsize and ca_maxresponsesize. Signed-off-by: Andy Adamson [bfields@citi.umich.edu: more documentation updates] Signed-off-by: J. Bruce Fields diff --git a/Documentation/filesystems/nfs41-server.txt b/Documentation/filesystems/nfs41-server.txt index 1f95e77..1bd0d0c 100644 --- a/Documentation/filesystems/nfs41-server.txt +++ b/Documentation/filesystems/nfs41-server.txt @@ -213,3 +213,10 @@ The following cases aren't supported yet: DESTROY_CLIENTID, DESTROY_SESSION, EXCHANGE_ID. * DESTROY_SESSION MUST be the final operation in the COMPOUND request. +Nonstandard compound limitations: +* No support for a sessions fore channel RPC compound that requires both a + ca_maxrequestsize request and a ca_maxresponsesize reply, so we may + fail to live up to the promise we made in CREATE_SESSION fore channel + negotiation. +* No more than one IO operation (read, write, readdir) allowed per + compound. diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2153f9bd..fcb9817 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -477,13 +477,14 @@ static int set_forechannel_drc_size(struct nfsd4_channel_attrs *fchan) /* * fchan holds the client values on input, and the server values on output + * sv_max_mesg is the maximum payload plus one page for overhead. */ static int init_forechannel_attrs(struct svc_rqst *rqstp, struct nfsd4_channel_attrs *session_fchan, struct nfsd4_channel_attrs *fchan) { int status = 0; - __u32 maxcount = svc_max_payload(rqstp); + __u32 maxcount = nfsd_serv->sv_max_mesg; /* headerpadsz set to zero in encode routine */ -- cgit v0.10.2 From 5cd0be8ec946ee3901e7f651a795225c6badff8f Mon Sep 17 00:00:00 2001 From: Hemant Pedanekar Date: Thu, 1 Oct 2009 19:55:06 +0530 Subject: mtd: nand: davinci: fix to use mask_ale from pdata Correct typo to use mask_ale from platform data when set to non-zero. Signed-off-by: Hemant Pedanekar Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index f13f5b9..68cc924 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -599,7 +599,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev) info->mask_chipsel = pdata->mask_chipsel; /* use nandboot-capable ALE/CLE masks by default */ - info->mask_ale = pdata->mask_cle ? : MASK_ALE; + info->mask_ale = pdata->mask_ale ? : MASK_ALE; info->mask_cle = pdata->mask_cle ? : MASK_CLE; /* Set address of hardware control function */ -- cgit v0.10.2 From 297758f8fc4e92b1915d2f5f2f84cedfe8941e5a Mon Sep 17 00:00:00 2001 From: Amul Kumar Saha Date: Fri, 2 Oct 2009 16:59:11 +0530 Subject: mtd: Standardising prints in onenand_base.c This patch resolves all the prints present in onenand_base.c Primarily, it replaces the hard-coded function names in the prints, and makes use of __func__. Signed-off-by: Amul Kumar Saha Signed-off-by: David Woodhouse diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index ff66e43..8935e63 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -500,25 +500,28 @@ static int onenand_wait(struct mtd_info *mtd, int state) int ecc = onenand_read_ecc(this); if (ecc) { if (ecc & ONENAND_ECC_2BIT_ALL) { - printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc); + printk(KERN_ERR "%s: ECC error = 0x%04x\n", + __func__, ecc); mtd->ecc_stats.failed++; return -EBADMSG; } else if (ecc & ONENAND_ECC_1BIT_ALL) { - printk(KERN_DEBUG "onenand_wait: correctable ECC error = 0x%04x\n", ecc); + printk(KERN_DEBUG "%s: correctable ECC error = 0x%04x\n", + __func__, ecc); mtd->ecc_stats.corrected++; } } } else if (state == FL_READING) { - printk(KERN_ERR "onenand_wait: read timeout! ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt); + printk(KERN_ERR "%s: read timeout! ctrl=0x%04x intr=0x%04x\n", + __func__, ctrl, interrupt); return -EIO; } /* If there's controller error, it's a real error */ if (ctrl & ONENAND_CTRL_ERROR) { - printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", - ctrl); + printk(KERN_ERR "%s: controller error = 0x%04x\n", + __func__, ctrl); if (ctrl & ONENAND_CTRL_LOCK) - printk(KERN_ERR "onenand_wait: it's locked error.\n"); + printk(KERN_ERR "%s: it's locked error.\n", __func__); return -EIO; } @@ -1015,7 +1018,8 @@ static int onenand_recover_lsb(struct mtd_info *mtd, loff_t addr, int status) /* We are attempting to reread, so decrement stats.failed * which was incremented by onenand_wait due to read failure */ - printk(KERN_INFO "onenand_recover_lsb: Attempting to recover from uncorrectable read\n"); + printk(KERN_INFO "%s: Attempting to recover from uncorrectable read\n", + __func__); mtd->ecc_stats.failed--; /* Issue the LSB page recovery command */ @@ -1046,7 +1050,8 @@ static int onenand_mlc_read_ops_nolock(struct mtd_info *mtd, loff_t from, int ret = 0; int writesize = this->writesize; - DEBUG(MTD_DEBUG_LEVEL3, "onenand_mlc_read_ops_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); + DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %i\n", + (unsigned int) from, (int) len); if (ops->mode == MTD_OOB_AUTO) oobsize = this->ecclayout->oobavail; @@ -1057,7 +1062,8 @@ static int onenand_mlc_read_ops_nolock(struct mtd_info *mtd, loff_t from, /* Do not allow reads past end of device */ if (from + len > mtd->size) { - printk(KERN_ERR "onenand_mlc_read_ops_nolock: Attempt read beyond end of device\n"); + printk(KERN_ERR "%s: Attempt read beyond end of device\n", + __func__); ops->retlen = 0; ops->oobretlen = 0; return -EINVAL; @@ -1146,7 +1152,8 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from, int ret = 0, boundary = 0; int writesize = this->writesize; - DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ops_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); + DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %i\n", + __func__, (unsigned int) from, (int) len); if (ops->mode == MTD_OOB_AUTO) oobsize = this->ecclayout->oobavail; @@ -1157,7 +1164,8 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from, /* Do not allow reads past end of device */ if ((from + len) > mtd->size) { - printk(KERN_ERR "onenand_read_ops_nolock: Attempt read beyond end of device\n"); + printk(KERN_ERR "%s: Attempt read beyond end of device\n", + __func__); ops->retlen = 0; ops->oobretlen = 0; return -EINVAL; @@ -1275,7 +1283,8 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from, from += ops->ooboffs; - DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); + DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %i\n", + __func__, (unsigned int) from, (int) len); /* Initialize return length value */ ops->oobretlen = 0; @@ -1288,7 +1297,8 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from, column = from & (mtd->oobsize - 1); if (unlikely(column >= oobsize)) { - printk(KERN_ERR "onenand_read_oob_nolock: Attempted to start read outside oob\n"); + printk(KERN_ERR "%s: Attempted to start read outside oob\n", + __func__); return -EINVAL; } @@ -1296,7 +1306,8 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from, if (unlikely(from >= mtd->size || column + len > ((mtd->size >> this->page_shift) - (from >> this->page_shift)) * oobsize)) { - printk(KERN_ERR "onenand_read_oob_nolock: Attempted to read beyond end of device\n"); + printk(KERN_ERR "%s: Attempted to read beyond end of device\n", + __func__); return -EINVAL; } @@ -1319,7 +1330,8 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from, ret = onenand_recover_lsb(mtd, from, ret); if (ret && ret != -EBADMSG) { - printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret); + printk(KERN_ERR "%s: read failed = 0x%x\n", + __func__, ret); break; } @@ -1450,20 +1462,21 @@ static int onenand_bbt_wait(struct mtd_info *mtd, int state) if (interrupt & ONENAND_INT_READ) { int ecc = onenand_read_ecc(this); if (ecc & ONENAND_ECC_2BIT_ALL) { - printk(KERN_INFO "onenand_bbt_wait: ecc error = 0x%04x" - ", controller error 0x%04x\n", ecc, ctrl); + printk(KERN_WARNING "%s: ecc error = 0x%04x, " + "controller error 0x%04x\n", + __func__, ecc, ctrl); return ONENAND_BBT_READ_ECC_ERROR; } } else { - printk(KERN_ERR "onenand_bbt_wait: read timeout!" - "ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt); + printk(KERN_ERR "%s: read timeout! ctrl=0x%04x intr=0x%04x\n", + __func__, ctrl, interrupt); return ONENAND_BBT_READ_FATAL_ERROR; } /* Initial bad block case: 0x2400 or 0x0400 */ if (ctrl & ONENAND_CTRL_ERROR) { - printk(KERN_DEBUG "onenand_bbt_wait: " - "controller error = 0x%04x\n", ctrl); + printk(KERN_DEBUG "%s: controller error = 0x%04x\n", + __func__, ctrl); return ONENAND_BBT_READ_ERROR; } @@ -1487,14 +1500,16 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, size_t len = ops->ooblen; u_char *buf = ops->oobbuf; - DEBUG(MTD_DEBUG_LEVEL3, "onenand_bbt_read_oob: from = 0x%08x, len = %zi\n", (unsigned int) from, len); + DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %zi\n", + __func__, (unsigned int) from, len); /* Initialize return value */ ops->oobretlen = 0; /* Do not allow reads past end of device */ if (unlikely((from + len) > mtd->size)) { - printk(KERN_ERR "onenand_bbt_read_oob: Attempt read beyond end of device\n"); + printk(KERN_ERR "%s: Attempt read beyond end of device\n", + __func__); return ONENAND_BBT_READ_FATAL_ERROR; } @@ -1661,21 +1676,23 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len, /* Wait for any existing operation to clear */ onenand_panic_wait(mtd); - DEBUG(MTD_DEBUG_LEVEL3, "onenand_panic_write: to = 0x%08x, len = %i\n", - (unsigned int) to, (int) len); + DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n", + __func__, (unsigned int) to, (int) len); /* Initialize retlen, in case of early exit */ *retlen = 0; /* Do not allow writes past end of device */ if (unlikely((to + len) > mtd->size)) { - printk(KERN_ERR "onenand_panic_write: Attempt write to past end of device\n"); + printk(KERN_ERR "%s: Attempt write to past end of device\n", + __func__); return -EINVAL; } /* Reject writes, which are not page aligned */ if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) { - printk(KERN_ERR "onenand_panic_write: Attempt to write not page aligned data\n"); + printk(KERN_ERR "%s: Attempt to write not page aligned data\n", + __func__); return -EINVAL; } @@ -1711,7 +1728,7 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len, } if (ret) { - printk(KERN_ERR "onenand_panic_write: write failed %d\n", ret); + printk(KERN_ERR "%s: write failed %d\n", __func__, ret); break; } @@ -1792,7 +1809,8 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to, u_char *oobbuf; int ret = 0; - DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ops_nolock: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); + DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n", + __func__, (unsigned int) to, (int) len); /* Initialize retlen, in case of early exit */ ops->retlen = 0; @@ -1800,13 +1818,15 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to, /* Do not allow writes past end of device */ if (unlikely((to + len) > mtd->size)) { - printk(KERN_ERR "onenand_write_ops_nolock: Attempt write to past end of device\n"); + printk(KERN_ERR "%s: Attempt write to past end of device\n", + __func__); return -EINVAL; } /* Reject writes, which are not page aligned */ if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) { - printk(KERN_ERR "onenand_write_ops_nolock: Attempt to write not page aligned data\n"); + printk(KERN_ERR "%s: Attempt to write not page aligned data\n", + __func__); return -EINVAL; } @@ -1879,7 +1899,8 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to, onenand_update_bufferram(mtd, prev, !ret && !prev_subpage); if (ret) { written -= prevlen; - printk(KERN_ERR "onenand_write_ops_nolock: write failed %d\n", ret); + printk(KERN_ERR "%s: write failed %d\n", + __func__, ret); break; } @@ -1887,7 +1908,8 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to, /* Only check verify write turn on */ ret = onenand_verify(mtd, buf - len, to - len, len); if (ret) - printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret); + printk(KERN_ERR "%s: verify failed %d\n", + __func__, ret); break; } @@ -1905,14 +1927,16 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to, /* In partial page write we don't update bufferram */ onenand_update_bufferram(mtd, to, !ret && !subpage); if (ret) { - printk(KERN_ERR "onenand_write_ops_nolock: write failed %d\n", ret); + printk(KERN_ERR "%s: write failed %d\n", + __func__, ret); break; } /* Only check verify write turn on */ ret = onenand_verify(mtd, buf, to, thislen); if (ret) { - printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret); + printk(KERN_ERR "%s: verify failed %d\n", + __func__, ret); break; } @@ -1968,7 +1992,8 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to, to += ops->ooboffs; - DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob_nolock: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); + DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n", + __func__, (unsigned int) to, (int) len); /* Initialize retlen, in case of early exit */ ops->oobretlen = 0; @@ -1981,14 +2006,15 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to, column = to & (mtd->oobsize - 1); if (unlikely(column >= oobsize)) { - printk(KERN_ERR "onenand_write_oob_nolock: Attempted to start write outside oob\n"); + printk(KERN_ERR "%s: Attempted to start write outside oob\n", + __func__); return -EINVAL; } /* For compatibility with NAND: Do not allow write past end of page */ if (unlikely(column + len > oobsize)) { - printk(KERN_ERR "onenand_write_oob_nolock: " - "Attempt to write past end of page\n"); + printk(KERN_ERR "%s: Attempt to write past end of page\n", + __func__); return -EINVAL; } @@ -1996,7 +2022,8 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to, if (unlikely(to >= mtd->size || column + len > ((mtd->size >> this->page_shift) - (to >> this->page_shift)) * oobsize)) { - printk(KERN_ERR "onenand_write_oob_nolock: Attempted to write past end of device\n"); + printk(KERN_ERR "%s: Attempted to write past end of device\n" + __func__); return -EINVAL; } @@ -2038,13 +2065,14 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to, ret = this->wait(mtd, FL_WRITING); if (ret) { - printk(KERN_ERR "onenand_write_oob_nolock: write failed %d\n", ret); + printk(KERN_ERR "%s: write failed %d\n", __func__, ret); break; } ret = onenand_verify_oob(mtd, oobbuf, to); if (ret) { - printk(KERN_ERR "onenand_write_oob_nolock: verify failed %d\n", ret); + printk(KERN_ERR "%s: verify failed %d\n", + __func__, ret); break; } @@ -2161,7 +2189,7 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) /* Do not allow erase past end of device */ if (unlikely((len + addr) > mtd->size)) { - printk(KERN_ERR "onenand_erase: Erase past end of device\n"); + printk(KERN_ERR "%s: Erase past end of device\n", __func__); return -EINVAL; } @@ -2177,7 +2205,7 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) * Erase region's start offset is always block start address. */ if (unlikely((addr - region->offset) & (block_size - 1))) { - printk(KERN_ERR "onenand_erase: Unaligned address\n"); + printk(KERN_ERR "%s: Unaligned address\n", __func__); return -EINVAL; } } else { @@ -2185,14 +2213,14 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) /* Start address must align on block boundary */ if (unlikely(addr & (block_size - 1))) { - printk(KERN_ERR "onenand_erase: Unaligned address\n"); + printk(KERN_ERR "%s: Unaligned address\n", __func__); return -EINVAL; } } /* Length must align on block boundary */ if (unlikely(len & (block_size - 1))) { - printk(KERN_ERR "onenand_erase: Length not block aligned\n"); + printk(KERN_ERR "%s: Length not block aligned\n", __func__); return -EINVAL; } @@ -2209,7 +2237,9 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) /* Check if we have a bad block, we do not erase bad blocks */ if (onenand_block_isbad_nolock(mtd, addr, 0)) { - printk (KERN_WARNING "onenand_erase: attempt to erase a bad block at addr 0x%012llx\n", (unsigned long long) addr); + printk(KERN_WARNING "%s: attempt to erase a bad block " + "at addr 0x%012llx\n", + __func__, (unsigned long long) addr); instr->state = MTD_ERASE_FAILED; goto erase_exit; } @@ -2221,8 +2251,8 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) ret = this->wait(mtd, FL_ERASING); /* Check, if it is write protected */ if (ret) { - printk(KERN_ERR "onenand_erase: Failed erase, block %d\n", - onenand_block(this, addr)); + printk(KERN_ERR "%s: Failed erase, block %d\n", + __func__, onenand_block(this, addr)); instr->state = MTD_ERASE_FAILED; instr->fail_addr = addr; goto erase_exit; @@ -2241,7 +2271,8 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) if (len & (block_size - 1)) { /* FIXME: This should be handled at MTD partitioning level. */ - printk(KERN_ERR "onenand_erase: Unaligned address\n"); + printk(KERN_ERR "%s: Unaligned address\n", + __func__); goto erase_exit; } } @@ -2272,7 +2303,7 @@ erase_exit: */ static void onenand_sync(struct mtd_info *mtd) { - DEBUG(MTD_DEBUG_LEVEL3, "onenand_sync: called\n"); + DEBUG(MTD_DEBUG_LEVEL3, "%s: called\n", __func__); /* Grab the lock and see if the device is available */ onenand_get_device(mtd, FL_SYNCING); @@ -2406,7 +2437,8 @@ static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int /* Check lock status */ status = this->read_word(this->base + ONENAND_REG_WP_STATUS); if (!(status & wp_status_mask)) - printk(KERN_ERR "wp status = 0x%x\n", status); + printk(KERN_ERR "%s: wp status = 0x%x\n", + __func__, status); return 0; } @@ -2435,7 +2467,8 @@ static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int /* Check lock status */ status = this->read_word(this->base + ONENAND_REG_WP_STATUS); if (!(status & wp_status_mask)) - printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status); + printk(KERN_ERR "%s: block = %d, wp status = 0x%x\n", + __func__, block, status); } return 0; @@ -2502,7 +2535,8 @@ static int onenand_check_lock_status(struct onenand_chip *this) /* Check lock status */ status = this->read_word(this->base + ONENAND_REG_WP_STATUS); if (!(status & ONENAND_WP_US)) { - printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status); + printk(KERN_ERR "%s: block = %d, wp status = 0x%x\n", + __func__, block, status); return 0; } } @@ -3172,7 +3206,8 @@ static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int break; if (i != mtd->oobsize) { - printk(KERN_WARNING "Block %d not erased.\n", block); + printk(KERN_WARNING "%s: Block %d not erased.\n", + __func__, block); return 1; } } @@ -3204,8 +3239,8 @@ int flexonenand_set_boundary(struct mtd_info *mtd, int die, blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0; if (boundary >= blksperdie) { - printk(KERN_ERR "flexonenand_set_boundary: Invalid boundary value. " - "Boundary not changed.\n"); + printk(KERN_ERR "%s: Invalid boundary value. " + "Boundary not changed.\n", __func__); return -EINVAL; } @@ -3214,7 +3249,8 @@ int flexonenand_set_boundary(struct mtd_info *mtd, int die, new = boundary + (die * this->density_mask); ret = flexonenand_check_blocks_erased(mtd, min(old, new) + 1, max(old, new)); if (ret) { - printk(KERN_ERR "flexonenand_set_boundary: Please erase blocks before boundary change\n"); + printk(KERN_ERR "%s: Please erase blocks " + "before boundary change\n", __func__); return ret; } @@ -3227,12 +3263,12 @@ int flexonenand_set_boundary(struct mtd_info *mtd, int die, thisboundary = this->read_word(this->base + ONENAND_DATARAM); if ((thisboundary >> FLEXONENAND_PI_UNLOCK_SHIFT) != 3) { - printk(KERN_ERR "flexonenand_set_boundary: boundary locked\n"); + printk(KERN_ERR "%s: boundary locked\n", __func__); ret = 1; goto out; } - printk(KERN_INFO "flexonenand_set_boundary: Changing die %d boundary: %d%s\n", + printk(KERN_INFO "Changing die %d boundary: %d%s\n", die, boundary, lock ? "(Locked)" : "(Unlocked)"); addr = die ? this->diesize[0] : 0; @@ -3243,7 +3279,8 @@ int flexonenand_set_boundary(struct mtd_info *mtd, int die, this->command(mtd, ONENAND_CMD_ERASE, addr, 0); ret = this->wait(mtd, FL_ERASING); if (ret) { - printk(KERN_ERR "flexonenand_set_boundary: Failed PI erase for Die %d\n", die); + printk(KERN_ERR "%s: flexonenand_set_boundary: " + "Failed PI erase for Die %d\n", __func__, die); goto out; } @@ -3251,7 +3288,8 @@ int flexonenand_set_boundary(struct mtd_info *mtd, int die, this->command(mtd, ONENAND_CMD_PROG, addr, 0); ret = this->wait(mtd, FL_WRITING); if (ret) { - printk(KERN_ERR "flexonenand_set_boundary: Failed PI write for Die %d\n", die); + printk(KERN_ERR "%s: Failed PI write for Die %d\n", + __func__, die); goto out; } @@ -3408,8 +3446,8 @@ static void onenand_resume(struct mtd_info *mtd) if (this->state == FL_PM_SUSPENDED) onenand_release_device(mtd); else - printk(KERN_ERR "resume() called for the chip which is not" - "in suspended state\n"); + printk(KERN_ERR "%s: resume() called for the chip which is not " + "in suspended state\n", __func__); } /** @@ -3464,7 +3502,8 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) if (!this->page_buf) { this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL); if (!this->page_buf) { - printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n"); + printk(KERN_ERR "%s: Can't allocate page_buf\n", + __func__); return -ENOMEM; } this->options |= ONENAND_PAGEBUF_ALLOC; @@ -3472,7 +3511,8 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) if (!this->oob_buf) { this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL); if (!this->oob_buf) { - printk(KERN_ERR "onenand_scan(): Can't allocate oob_buf\n"); + printk(KERN_ERR "%s: Can't allocate oob_buf\n", + __func__); if (this->options & ONENAND_PAGEBUF_ALLOC) { this->options &= ~ONENAND_PAGEBUF_ALLOC; kfree(this->page_buf); @@ -3505,8 +3545,8 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) break; default: - printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n", - mtd->oobsize); + printk(KERN_WARNING "%s: No OOB scheme defined for oobsize %d\n", + __func__, mtd->oobsize); mtd->subpage_sft = 0; /* To prevent kernel oops */ this->ecclayout = &onenand_oob_32; -- cgit v0.10.2 From ee34b32d8c2950f66038c8975747ef9aec855289 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Fri, 2 Oct 2009 11:01:21 -0700 Subject: dmar: support for parsing Remapping Hardware Static Affinity structure Add support for parsing Remapping Hardware Static Affinity (RHSA) structure. This enables identifying the association between remapping hardware units and the corresponding proximity domain. This enables to allocate transalation structures closer to the remapping hardware unit. Signed-off-by: Suresh Siddha Signed-off-by: David Woodhouse diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 22b02c6..5779565 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -348,6 +348,26 @@ found: } #endif +static int __init +dmar_parse_one_rhsa(struct acpi_dmar_header *header) +{ + struct acpi_dmar_rhsa *rhsa; + struct dmar_drhd_unit *drhd; + + rhsa = (struct acpi_dmar_rhsa *)header; + for_each_drhd_unit(drhd) + if (drhd->reg_base_addr == rhsa->base_address) { + int node = acpi_map_pxm_to_node(rhsa->proximity_domain); + + if (!node_online(node)) + node = -1; + drhd->iommu->node = node; + return 0; + } + + return -ENODEV; +} + static void __init dmar_table_print_dmar_entry(struct acpi_dmar_header *header) { @@ -467,7 +487,7 @@ parse_dmar_table(void) #endif break; case ACPI_DMAR_HARDWARE_AFFINITY: - /* We don't do anything with RHSA (yet?) */ + ret = dmar_parse_one_rhsa(entry_header); break; default: printk(KERN_WARNING PREFIX @@ -677,6 +697,8 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) iommu->agaw = agaw; iommu->msagaw = msagaw; + iommu->node = -1; + /* the registers might be more than one page */ map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), cap_max_fault_reg_offset(iommu->cap)); diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 4f0a72a..9310c69 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -332,6 +332,7 @@ struct intel_iommu { #ifdef CONFIG_INTR_REMAP struct ir_table *ir_table; /* Interrupt remapping info */ #endif + int node; }; static inline void __iommu_flush_cache( -- cgit v0.10.2 From 751cafe3aeceb9ff887c97237f6daaf596c9e547 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Fri, 2 Oct 2009 11:01:22 -0700 Subject: dmar: Allocate queued invalidation structure using numa locality info Allocate queued invalidation descriptor structures using numa locality info. Signed-off-by: Suresh Siddha Signed-off-by: David Woodhouse diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 5779565..63aa529 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -1040,6 +1040,7 @@ static void __dmar_enable_qi(struct intel_iommu *iommu) int dmar_enable_qi(struct intel_iommu *iommu) { struct q_inval *qi; + struct page *desc_page; if (!ecap_qis(iommu->ecap)) return -ENOENT; @@ -1056,13 +1057,16 @@ int dmar_enable_qi(struct intel_iommu *iommu) qi = iommu->qi; - qi->desc = (void *)(get_zeroed_page(GFP_ATOMIC)); - if (!qi->desc) { + + desc_page = alloc_pages_node(iommu->node, GFP_ATOMIC | __GFP_ZERO, 0); + if (!desc_page) { kfree(qi); iommu->qi = 0; return -ENOMEM; } + qi->desc = page_address(desc_page); + qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_ATOMIC); if (!qi->desc_status) { free_page((unsigned long) qi->desc); -- cgit v0.10.2 From 824cd75bf30cfc52c4b468f3cabf6932fd012654 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Fri, 2 Oct 2009 11:01:23 -0700 Subject: intr_remap: Allocate intr-remapping table using numa locality info Allocate intr-remapping table using numa locality info. On platforms having remapping hardware units span different nodes, this enables optimized intr-remapping table entry access by remapping hardware. Signed-off-by: Suresh Siddha Signed-off-by: David Woodhouse diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index 0ed78a7..fccf0e2 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c @@ -548,7 +548,8 @@ static int setup_intr_remapping(struct intel_iommu *iommu, int mode) if (!iommu->ir_table) return -ENOMEM; - pages = alloc_pages(GFP_ATOMIC | __GFP_ZERO, INTR_REMAP_PAGE_ORDER); + pages = alloc_pages_node(iommu->node, GFP_ATOMIC | __GFP_ZERO, + INTR_REMAP_PAGE_ORDER); if (!pages) { printk(KERN_ERR "failed to allocate pages of order %d\n", -- cgit v0.10.2 From 4c923d4714821cf32ff115bb9c91867dff711972 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Fri, 2 Oct 2009 11:01:24 -0700 Subject: iommu: Allocate dma-remapping structures using numa locality info Allocate dma-remapping structures using numa locality info. On platforms having remapping hardware units span different nodes, this enables optimized dma-remapping transalation structures access by remapping hardware. Signed-off-by: Suresh Siddha Signed-off-by: David Woodhouse diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index b1e97e6..c831136 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -277,6 +277,7 @@ static int hw_pass_through = 1; struct dmar_domain { int id; /* domain id */ + int nid; /* node id */ unsigned long iommu_bmp; /* bitmap of iommus this domain uses*/ struct list_head devices; /* all devices' list */ @@ -400,15 +401,18 @@ static inline void *iommu_kmem_cache_alloc(struct kmem_cache *cachep) } -static inline void *alloc_pgtable_page(void) +static inline void *alloc_pgtable_page(int node) { unsigned int flags; - void *vaddr; + struct page *page; + void *vaddr = NULL; /* trying to avoid low memory issues */ flags = current->flags & PF_MEMALLOC; current->flags |= PF_MEMALLOC; - vaddr = (void *)get_zeroed_page(GFP_ATOMIC); + page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0); + if (page) + vaddr = page_address(page); current->flags &= (~PF_MEMALLOC | flags); return vaddr; } @@ -589,7 +593,8 @@ static struct context_entry * device_to_context_entry(struct intel_iommu *iommu, root = &iommu->root_entry[bus]; context = get_context_addr_from_root(root); if (!context) { - context = (struct context_entry *)alloc_pgtable_page(); + context = (struct context_entry *) + alloc_pgtable_page(iommu->node); if (!context) { spin_unlock_irqrestore(&iommu->lock, flags); return NULL; @@ -732,7 +737,7 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, if (!dma_pte_present(pte)) { uint64_t pteval; - tmp_page = alloc_pgtable_page(); + tmp_page = alloc_pgtable_page(domain->nid); if (!tmp_page) return NULL; @@ -868,7 +873,7 @@ static int iommu_alloc_root_entry(struct intel_iommu *iommu) struct root_entry *root; unsigned long flags; - root = (struct root_entry *)alloc_pgtable_page(); + root = (struct root_entry *)alloc_pgtable_page(iommu->node); if (!root) return -ENOMEM; @@ -1263,6 +1268,7 @@ static struct dmar_domain *alloc_domain(void) if (!domain) return NULL; + domain->nid = -1; memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); domain->flags = 0; @@ -1420,9 +1426,10 @@ static int domain_init(struct dmar_domain *domain, int guest_width) domain->iommu_snooping = 0; domain->iommu_count = 1; + domain->nid = iommu->node; /* always allocate the top pgd */ - domain->pgd = (struct dma_pte *)alloc_pgtable_page(); + domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid); if (!domain->pgd) return -ENOMEM; __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE); @@ -1577,6 +1584,8 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment, spin_lock_irqsave(&domain->iommu_lock, flags); if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) { domain->iommu_count++; + if (domain->iommu_count == 1) + domain->nid = iommu->node; domain_update_iommu_cap(domain); } spin_unlock_irqrestore(&domain->iommu_lock, flags); @@ -3416,6 +3425,7 @@ static struct dmar_domain *iommu_alloc_vm_domain(void) return NULL; domain->id = vm_domid++; + domain->nid = -1; memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE; @@ -3442,9 +3452,10 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width) domain->iommu_coherency = 0; domain->iommu_snooping = 0; domain->max_addr = 0; + domain->nid = -1; /* always allocate the top pgd */ - domain->pgd = (struct dma_pte *)alloc_pgtable_page(); + domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid); if (!domain->pgd) return -ENOMEM; domain_flush_cache(domain, domain->pgd, PAGE_SIZE); -- cgit v0.10.2 From 8032747e7680a31cdde293421af62d2e1904c528 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 5 Oct 2009 08:30:04 +0100 Subject: mtd: make onenand_base.c compile again Signed-off-by: David Woodhouse diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 8935e63..6e250f3 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1051,7 +1051,7 @@ static int onenand_mlc_read_ops_nolock(struct mtd_info *mtd, loff_t from, int writesize = this->writesize; DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %i\n", - (unsigned int) from, (int) len); + __func__, (unsigned int) from, (int) len); if (ops->mode == MTD_OOB_AUTO) oobsize = this->ecclayout->oobavail; @@ -2022,8 +2022,8 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to, if (unlikely(to >= mtd->size || column + len > ((mtd->size >> this->page_shift) - (to >> this->page_shift)) * oobsize)) { - printk(KERN_ERR "%s: Attempted to write past end of device\n" - __func__); + printk(KERN_ERR "%s: Attempted to write past end of device\n", + __func__); return -EINVAL; } -- cgit v0.10.2 From 209205801caf24ba0d54cc607800ee20c7d5132a Mon Sep 17 00:00:00 2001 From: Nelson Elhage Date: Wed, 16 Sep 2009 12:40:47 -0400 Subject: avr32: clean up linker script using standard macros. As a side effect, this patch changes the .init.ramfs data to be PAGE_SIZE-aligned, instead of 32-byte aligned. Also, the init data is moved into its own output sections rather than the .init output section. There should be no other changes to the resulting vmlinux as a result of this patch. Signed-off-by: Nelson Elhage Signed-off-by: Tim Abbott Cc: Haavard Skinnemoen Signed-off-by: Haavard Skinnemoen diff --git a/arch/avr32/kernel/vmlinux.lds.S b/arch/avr32/kernel/vmlinux.lds.S index c4b5665..9cd2bd9 100644 --- a/arch/avr32/kernel/vmlinux.lds.S +++ b/arch/avr32/kernel/vmlinux.lds.S @@ -39,30 +39,10 @@ SECTIONS __tagtable_begin = .; *(.taglist.init) __tagtable_end = .; - INIT_DATA - . = ALIGN(16); - __setup_start = .; - *(.init.setup) - __setup_end = .; - . = ALIGN(4); - __initcall_start = .; - INITCALLS - __initcall_end = .; - __con_initcall_start = .; - *(.con_initcall.init) - __con_initcall_end = .; - __security_initcall_start = .; - *(.security_initcall.init) - __security_initcall_end = .; -#ifdef CONFIG_BLK_DEV_INITRD - . = ALIGN(32); - __initramfs_start = .; - *(.init.ramfs) - __initramfs_end = .; -#endif - . = ALIGN(PAGE_SIZE); - __init_end = .; } + INIT_DATA_SECTION(16) + . = ALIGN(PAGE_SIZE); + __init_end = .; .text : AT(ADDR(.text) - LOAD_OFFSET) { _evba = .; @@ -78,34 +58,16 @@ SECTIONS _etext = .; } = 0xd703d703 - . = ALIGN(4); - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { - __start___ex_table = .; - *(__ex_table) - __stop___ex_table = .; - } - + EXCEPTION_TABLE(4) RODATA - . = ALIGN(THREAD_SIZE); - .data : AT(ADDR(.data) - LOAD_OFFSET) { _data = .; _sdata = .; - /* - * First, the init task union, aligned to an 8K boundary. - */ - *(.data.init_task) - /* Then, the page-aligned data */ - . = ALIGN(PAGE_SIZE); - *(.data.page_aligned) - - /* Then, the cacheline aligned data */ - . = ALIGN(L1_CACHE_BYTES); - *(.data.cacheline_aligned) - - /* And the rest... */ + INIT_TASK_DATA(THREAD_SIZE) + PAGE_ALIGNED_DATA(PAGE_SIZE); + CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) *(.data.rel*) DATA_DATA CONSTRUCTORS @@ -113,16 +75,8 @@ SECTIONS _edata = .; } - - . = ALIGN(8); - .bss : AT(ADDR(.bss) - LOAD_OFFSET) { - __bss_start = .; - *(.bss) - *(COMMON) - . = ALIGN(8); - __bss_stop = .; - _end = .; - } + BSS_SECTION(0, 8, 8) + _end = .; DWARF_DEBUG -- cgit v0.10.2 From 5416bf33f92a4104dbcd6062bf377c8421ca3cfd Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Mon, 6 Jul 2009 12:15:12 +0200 Subject: avr32: add two new at91 to cpu.h definition Somme common drivers will need those at91 cpu_is_xxx() definitions. As at91sam9g10 and at91sam9g45 are on the way to linus' tree, here is the patch that adds those chips to cpu.h in AVR32 architecture. Signed-off-by: Nicolas Ferre Signed-off-by: Haavard Skinnemoen diff --git a/arch/avr32/mach-at32ap/include/mach/cpu.h b/arch/avr32/mach-at32ap/include/mach/cpu.h index 44d0bfa..c253e9b 100644 --- a/arch/avr32/mach-at32ap/include/mach/cpu.h +++ b/arch/avr32/mach-at32ap/include/mach/cpu.h @@ -31,5 +31,7 @@ #define cpu_is_at91sam9263() (0) #define cpu_is_at91sam9rl() (0) #define cpu_is_at91cap9() (0) +#define cpu_is_at91sam9g10() (0) +#define cpu_is_at91sam9g45() (0) #endif /* __ASM_ARCH_CPU_H */ -- cgit v0.10.2 From aa697079ee66315c4b9747a5eb3e48487fb1b8be Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 7 Oct 2009 12:18:00 +0100 Subject: dmar: Fix build failure without NUMA, warn on bogus RHSA tables and don't abort Signed-off-by: David Woodhouse diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 63aa529..0d064d1 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -348,6 +348,7 @@ found: } #endif +#ifdef CONFIG_ACPI_NUMA static int __init dmar_parse_one_rhsa(struct acpi_dmar_header *header) { @@ -355,18 +356,26 @@ dmar_parse_one_rhsa(struct acpi_dmar_header *header) struct dmar_drhd_unit *drhd; rhsa = (struct acpi_dmar_rhsa *)header; - for_each_drhd_unit(drhd) + for_each_drhd_unit(drhd) { if (drhd->reg_base_addr == rhsa->base_address) { int node = acpi_map_pxm_to_node(rhsa->proximity_domain); if (!node_online(node)) node = -1; drhd->iommu->node = node; - return 0; + return 0; + } } + WARN(1, "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + drhd->reg_base_addr, + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); - return -ENODEV; + return 0; } +#endif static void __init dmar_table_print_dmar_entry(struct acpi_dmar_header *header) @@ -487,7 +496,9 @@ parse_dmar_table(void) #endif break; case ACPI_DMAR_HARDWARE_AFFINITY: +#ifdef CONFIG_ACPI_NUMA ret = dmar_parse_one_rhsa(entry_header); +#endif break; default: printk(KERN_WARNING PREFIX -- cgit v0.10.2 From e4af3bf6334341435740fce9ff236ba814686b99 Mon Sep 17 00:00:00 2001 From: Claudio Scordino Date: Wed, 7 Oct 2009 14:27:07 +0200 Subject: mtd: atmel_nand: unused variable removed Unused variable "eccpos" removed from atmel_nand driver. Signed-off-by: Claudio Scordino Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index f8e9975..4f62d20 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -192,7 +192,6 @@ static int atmel_nand_calculate(struct mtd_info *mtd, { struct nand_chip *nand_chip = mtd->priv; struct atmel_nand_host *host = nand_chip->priv; - uint32_t *eccpos = nand_chip->ecc.layout->eccpos; unsigned int ecc_value; /* get the first 2 ECC bytes */ -- cgit v0.10.2 From 82613b0da622efbd24cb7b23eb349966802310f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 1 Oct 2009 10:28:21 +0200 Subject: mtd: move mxcnd_remove to .exit.text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function mxcnd_remove is used only wrapped by __exit_p so define it using __exit. Signed-off-by: Uwe Kleine-König Acked-by: Sam Ravnborg Cc: Sascha Hauer Cc: Vladimir Barinov Cc: Vladimir Barinov Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 65b26d5..ef3e199 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -1052,7 +1052,7 @@ eclk: return err; } -static int __devexit mxcnd_remove(struct platform_device *pdev) +static int __exit mxcnd_remove(struct platform_device *pdev) { struct mxc_nand_host *host = platform_get_drvdata(pdev); -- cgit v0.10.2 From 5a134239e707b23c65948f41f40b828d40e440af Mon Sep 17 00:00:00 2001 From: Dmitry Artamonow Date: Fri, 9 Oct 2009 12:18:49 +0400 Subject: mtd: maps/sa1100: fix section mismatch Commit f0b1e589 changed sa1100_mtd_probe from __init to __devinit, but missed to correct sa1100_setup_mtd definition accordingly, which causes following warning: WARNING: vmlinux.o(.devinit.text+0xf4): Section mismatch in reference from the function sa1100_mtd_probe() to the function .init.text:sa1100_setup_mtd() The function __devinit sa1100_mtd_probe() references a function __init sa1100_setup_mtd(). If sa1100_setup_mtd is only used by sa1100_mtd_probe then annotate sa1100_setup_mtd with a matching annotation. Signed-off-by: Dmitry Artamonow Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index d7a4757..f3af87e 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -248,7 +248,7 @@ static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *pla plat->exit(); } -static struct sa_info *__init +static struct sa_info *__devinit sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) { struct sa_info *info; -- cgit v0.10.2 From f54d6336372b97d3624d1c5c179b2dd062472bd1 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 9 Oct 2009 18:43:52 +0900 Subject: mtd: cleanup mtd_oobtest - Remove unnecessary memset for bbt All entries will be initialized at a few lines below - Remove unnecessary initialization for mtd->erasesize - Use write_whole_device() Signed-off-by: Akinobu Mita Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c index 5553cd4..5813920 100644 --- a/drivers/mtd/tests/mtd_oobtest.c +++ b/drivers/mtd/tests/mtd_oobtest.c @@ -343,7 +343,6 @@ static int scan_for_bad_eraseblocks(void) printk(PRINT_PREF "error: cannot allocate memory\n"); return -ENOMEM; } - memset(bbt, 0 , ebcnt); printk(PRINT_PREF "scanning for bad eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { @@ -392,7 +391,6 @@ static int __init mtd_oobtest_init(void) mtd->writesize, ebcnt, pgcnt, mtd->oobsize); err = -ENOMEM; - mtd->erasesize = mtd->erasesize; readbuf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!readbuf) { printk(PRINT_PREF "error: cannot allocate memory\n"); @@ -476,18 +474,10 @@ static int __init mtd_oobtest_init(void) use_len_max = mtd->ecclayout->oobavail; vary_offset = 1; simple_srand(5); - printk(PRINT_PREF "writing OOBs of whole device\n"); - for (i = 0; i < ebcnt; ++i) { - if (bbt[i]) - continue; - err = write_eraseblock(i); - if (err) - goto out; - if (i % 256 == 0) - printk(PRINT_PREF "written up to eraseblock %u\n", i); - cond_resched(); - } - printk(PRINT_PREF "written %u eraseblocks\n", i); + + err = write_whole_device(); + if (err) + goto out; /* Check all eraseblocks */ use_offset = 0; -- cgit v0.10.2 From d4702669b0b64b8fa7c91123639ec20d9592ee43 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 7 Oct 2009 17:08:08 -0400 Subject: mtd: fix memory leak in mtd_dataflash Fix a potential memory leak in mtd_dataflash driver. The private data that is allocated when registering a DataFlash device with the MTD subsystem is not released if an error occurs when add_mtd_partitions() or add_mtd_device() is called. Fix this by adding an error path. The memory is already released during a remove. Also, add a dev_set_drvdata(&spi->dev, NULL) before the kfree() so that the spi device does not reference invalid data. Signed-off-by: H Hartley Sweeten Cc: David Brownell Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 93e3627..1981740 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -636,6 +636,7 @@ add_dataflash_otp(struct spi_device *spi, char *name, struct mtd_info *device; struct flash_platform_data *pdata = spi->dev.platform_data; char *otp_tag = ""; + int err = 0; priv = kzalloc(sizeof *priv, GFP_KERNEL); if (!priv) @@ -693,13 +694,23 @@ add_dataflash_otp(struct spi_device *spi, char *name, if (nr_parts > 0) { priv->partitioned = 1; - return add_mtd_partitions(device, parts, nr_parts); + err = add_mtd_partitions(device, parts, nr_parts); + goto out; } } else if (pdata && pdata->nr_parts) dev_warn(&spi->dev, "ignoring %d default partitions on %s\n", pdata->nr_parts, device->name); - return add_mtd_device(device) == 1 ? -ENODEV : 0; + if (add_mtd_device(device) == 1) + err = -ENODEV; + +out: + if (!err) + return 0; + + dev_set_drvdata(&spi->dev, NULL); + kfree(priv); + return err; } static inline int __devinit @@ -932,8 +943,10 @@ static int __devexit dataflash_remove(struct spi_device *spi) status = del_mtd_partitions(&flash->mtd); else status = del_mtd_device(&flash->mtd); - if (status == 0) + if (status == 0) { + dev_set_drvdata(&spi->dev, NULL); kfree(flash); + } return status; } -- cgit v0.10.2 From 9729b260ea5ef4b2c5de0643a7b764b408e275b1 Mon Sep 17 00:00:00 2001 From: Dmitry Artamonow Date: Tue, 13 Oct 2009 15:34:54 +0400 Subject: mtd: maps: remove obsolete ipaq-flash driver This driver seems to be obsolete and broken for a long time. It depends on CONFIG_IPAQ_HANDHELD that simply doesn't exists anywhere in kernel. Also, it seems that none of machines it claims to support have any use of it: SA11xx-based iPAQs (h3100/h3600) use sa1100-flash iPAQ h5000 uses physmap-flash Jornada 720 uses sa1100-flash Jornada 560 and iPAQ h1910 are not in mainline Signed-off-by: Dmitry Artamonow Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 0fc67a2..c7e97cf 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -361,12 +361,6 @@ config MTD_SA1100 the SA1100 and SA1110, including the Assabet and the Compaq iPAQ. If you have such a board, say 'Y'. -config MTD_IPAQ - tristate "CFI Flash device mapped on Compaq/HP iPAQ" - depends on IPAQ_HANDHELD && MTD_CFI - help - This provides a driver for the on-board flash of the iPAQ. - config MTD_DC21285 tristate "CFI Flash device mapped on DC21285 Footbridge" depends on MTD_CFI && ARCH_FOOTBRIDGE && MTD_COMPLEX_MAPPINGS diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 1d5cf86..34f3cdd 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -29,7 +29,6 @@ obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o obj-$(CONFIG_MTD_TQM8XXL) += tqm8xxl.o obj-$(CONFIG_MTD_SA1100) += sa1100-flash.o -obj-$(CONFIG_MTD_IPAQ) += ipaq-flash.o obj-$(CONFIG_MTD_SBC_GXX) += sbc_gxx.o obj-$(CONFIG_MTD_SC520CDP) += sc520cdp.o obj-$(CONFIG_MTD_NETSC520) += netsc520.o diff --git a/drivers/mtd/maps/ipaq-flash.c b/drivers/mtd/maps/ipaq-flash.c deleted file mode 100644 index 76708e7..0000000 --- a/drivers/mtd/maps/ipaq-flash.c +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Flash memory access on iPAQ Handhelds (either SA1100 or PXA250 based) - * - * (C) 2000 Nicolas Pitre - * (C) 2002 Hewlett-Packard Company - * (C) 2003 Christian Pellegrin , : concatenation of multiple flashes - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#ifdef CONFIG_MTD_CONCAT -#include -#endif - -#include -#include -#include - - -#ifndef CONFIG_IPAQ_HANDHELD -#error This is for iPAQ Handhelds only -#endif -#ifdef CONFIG_SA1100_JORNADA56X - -static void jornada56x_set_vpp(struct map_info *map, int vpp) -{ - if (vpp) - GPSR = GPIO_GPIO26; - else - GPCR = GPIO_GPIO26; - GPDR |= GPIO_GPIO26; -} - -#endif - -#ifdef CONFIG_SA1100_JORNADA720 - -static void jornada720_set_vpp(struct map_info *map, int vpp) -{ - if (vpp) - PPSR |= 0x80; - else - PPSR &= ~0x80; - PPDR |= 0x80; -} - -#endif - -#define MAX_IPAQ_CS 2 /* Number of CS we are going to test */ - -#define IPAQ_MAP_INIT(X) \ - { \ - name: "IPAQ flash " X, \ - } - - -static struct map_info ipaq_map[MAX_IPAQ_CS] = { - IPAQ_MAP_INIT("bank 1"), - IPAQ_MAP_INIT("bank 2") -}; - -static struct mtd_info *my_sub_mtd[MAX_IPAQ_CS] = { - NULL, - NULL -}; - -/* - * Here are partition information for all known IPAQ-based devices. - * See include/linux/mtd/partitions.h for definition of the mtd_partition - * structure. - * - * The *_max_flash_size is the maximum possible mapped flash size which - * is not necessarily the actual flash size. It must be no more than - * the value specified in the "struct map_desc *_io_desc" mapping - * definition for the corresponding machine. - * - * Please keep these in alphabetical order, and formatted as per existing - * entries. Thanks. - */ - -#ifdef CONFIG_IPAQ_HANDHELD -static unsigned long h3xxx_max_flash_size = 0x04000000; -static struct mtd_partition h3xxx_partitions[] = { - { - name: "H3XXX boot firmware", -#ifndef CONFIG_LAB - size: 0x00040000, -#else - size: 0x00080000, -#endif - offset: 0, -#ifndef CONFIG_LAB - mask_flags: MTD_WRITEABLE, /* force read-only */ -#endif - }, - { - name: "H3XXX root jffs2", -#ifndef CONFIG_LAB - size: 0x2000000 - 2*0x40000, /* Warning, this is fixed later */ - offset: 0x00040000, -#else - size: 0x2000000 - 0x40000 - 0x80000, /* Warning, this is fixed later */ - offset: 0x00080000, -#endif - }, - { - name: "asset", - size: 0x40000, - offset: 0x2000000 - 0x40000, /* Warning, this is fixed later */ - mask_flags: MTD_WRITEABLE, /* force read-only */ - } -}; - -#ifndef CONFIG_MTD_CONCAT -static struct mtd_partition h3xxx_partitions_bank2[] = { - /* this is used only on 2 CS machines when concat is not present */ - { - name: "second H3XXX root jffs2", - size: 0x1000000 - 0x40000, /* Warning, this is fixed later */ - offset: 0x00000000, - }, - { - name: "second asset", - size: 0x40000, - offset: 0x1000000 - 0x40000, /* Warning, this is fixed later */ - mask_flags: MTD_WRITEABLE, /* force read-only */ - } -}; -#endif - -static DEFINE_SPINLOCK(ipaq_vpp_lock); - -static void h3xxx_set_vpp(struct map_info *map, int vpp) -{ - static int nest = 0; - - spin_lock(&ipaq_vpp_lock); - if (vpp) - nest++; - else - nest--; - if (nest) - assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, 1); - else - assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, 0); - spin_unlock(&ipaq_vpp_lock); -} - -#endif - -#if defined(CONFIG_SA1100_JORNADA56X) || defined(CONFIG_SA1100_JORNADA720) -static unsigned long jornada_max_flash_size = 0x02000000; -static struct mtd_partition jornada_partitions[] = { - { - name: "Jornada boot firmware", - size: 0x00040000, - offset: 0, - mask_flags: MTD_WRITEABLE, /* force read-only */ - }, { - name: "Jornada root jffs2", - size: MTDPART_SIZ_FULL, - offset: 0x00040000, - } -}; -#endif - - -static struct mtd_partition *parsed_parts; -static struct mtd_info *mymtd; - -static unsigned long cs_phys[] = { -#ifdef CONFIG_ARCH_SA1100 - SA1100_CS0_PHYS, - SA1100_CS1_PHYS, - SA1100_CS2_PHYS, - SA1100_CS3_PHYS, - SA1100_CS4_PHYS, - SA1100_CS5_PHYS, -#else - PXA_CS0_PHYS, - PXA_CS1_PHYS, - PXA_CS2_PHYS, - PXA_CS3_PHYS, - PXA_CS4_PHYS, - PXA_CS5_PHYS, -#endif -}; - -static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; - -static int __init h1900_special_case(void); - -static int __init ipaq_mtd_init(void) -{ - struct mtd_partition *parts = NULL; - int nb_parts = 0; - int parsed_nr_parts = 0; - const char *part_type; - int i; /* used when we have >1 flash chips */ - unsigned long tot_flashsize = 0; /* used when we have >1 flash chips */ - - /* Default flash bankwidth */ - // ipaq_map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4; - - if (machine_is_h1900()) - { - /* For our intents, the h1900 is not a real iPAQ, so we special-case it. */ - return h1900_special_case(); - } - - if (machine_is_h3100() || machine_is_h1900()) - for(i=0; isize); - - /* do we really need this debugging? --joshua 20030703 */ - // printk("my_sub_mtd[%d]=%p\n", i, my_sub_mtd[i]); - my_sub_mtd[i]->owner = THIS_MODULE; - tot_flashsize += my_sub_mtd[i]->size; - } -#ifdef CONFIG_MTD_CONCAT - /* fix the asset location */ -# ifdef CONFIG_LAB - h3xxx_partitions[1].size = tot_flashsize - 0x40000 - 0x80000 /* extra big boot block */; -# else - h3xxx_partitions[1].size = tot_flashsize - 2 * 0x40000; -# endif - h3xxx_partitions[2].offset = tot_flashsize - 0x40000; - /* and concat the devices */ - mymtd = mtd_concat_create(&my_sub_mtd[0], i, - "ipaq"); - if (!mymtd) { - printk("Cannot create iPAQ concat device\n"); - return -ENXIO; - } -#else - mymtd = my_sub_mtd[0]; - - /* - *In the very near future, command line partition parsing - * will use the device name as 'mtd-id' instead of a value - * passed to the parse_cmdline_partitions() routine. Since - * the bootldr says 'ipaq', make sure it continues to work. - */ - mymtd->name = "ipaq"; - - if ((machine_is_h3600())) { -# ifdef CONFIG_LAB - h3xxx_partitions[1].size = my_sub_mtd[0]->size - 0x80000; -# else - h3xxx_partitions[1].size = my_sub_mtd[0]->size - 0x40000; -# endif - nb_parts = 2; - } else { -# ifdef CONFIG_LAB - h3xxx_partitions[1].size = my_sub_mtd[0]->size - 0x40000 - 0x80000; /* extra big boot block */ -# else - h3xxx_partitions[1].size = my_sub_mtd[0]->size - 2*0x40000; -# endif - h3xxx_partitions[2].offset = my_sub_mtd[0]->size - 0x40000; - } - - if (my_sub_mtd[1]) { -# ifdef CONFIG_LAB - h3xxx_partitions_bank2[0].size = my_sub_mtd[1]->size - 0x80000; -# else - h3xxx_partitions_bank2[0].size = my_sub_mtd[1]->size - 0x40000; -# endif - h3xxx_partitions_bank2[1].offset = my_sub_mtd[1]->size - 0x40000; - } -#endif - } - else { - /* - * Now let's probe for the actual flash. Do it here since - * specific machine settings might have been set above. - */ - printk(KERN_NOTICE "IPAQ flash: probing %d-bit flash bus, window=%lx\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt); - mymtd = do_map_probe("cfi_probe", &ipaq_map[0]); - if (!mymtd) - return -ENXIO; - mymtd->owner = THIS_MODULE; - } - - - /* - * Dynamic partition selection stuff (might override the static ones) - */ - - i = parse_mtd_partitions(mymtd, part_probes, &parsed_parts, 0); - - if (i > 0) { - nb_parts = parsed_nr_parts = i; - parts = parsed_parts; - part_type = "dynamic"; - } - - if (!parts) { - printk(KERN_NOTICE "IPAQ flash: no partition info available, registering whole flash at once\n"); - add_mtd_device(mymtd); -#ifndef CONFIG_MTD_CONCAT - if (my_sub_mtd[1]) - add_mtd_device(my_sub_mtd[1]); -#endif - } else { - printk(KERN_NOTICE "Using %s partition definition\n", part_type); - add_mtd_partitions(mymtd, parts, nb_parts); -#ifndef CONFIG_MTD_CONCAT - if (my_sub_mtd[1]) - add_mtd_partitions(my_sub_mtd[1], h3xxx_partitions_bank2, ARRAY_SIZE(h3xxx_partitions_bank2)); -#endif - } - - return 0; -} - -static void __exit ipaq_mtd_cleanup(void) -{ - int i; - - if (mymtd) { - del_mtd_partitions(mymtd); -#ifndef CONFIG_MTD_CONCAT - if (my_sub_mtd[1]) - del_mtd_partitions(my_sub_mtd[1]); -#endif - map_destroy(mymtd); -#ifdef CONFIG_MTD_CONCAT - for(i=0; i Date: Sun, 18 Oct 2009 16:07:34 -0700 Subject: pcmcia: convert pcmciamtd driver to use new CIS helpers Convert the (broken) pcmciamtd driver to use the new CIS helpers. Signed-off-by: Dominik Brodowski Signed-off-by: David Woodhouse diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index d600c2d..52c07f2 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -354,101 +354,108 @@ static void pcmciamtd_release(struct pcmcia_device *link) } -static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name) +#ifdef CONFIG_MTD_DEBUG +static int pcmciamtd_cistpl_format(struct pcmcia_device *p_dev, + tuple_t *tuple, + void *priv_data) { - int rc; - tuple_t tuple; cisparse_t parse; - u_char buf[64]; - - tuple.Attributes = 0; - tuple.TupleData = (cisdata_t *)buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; - tuple.DesiredTuple = RETURN_FIRST_TUPLE; - - rc = pcmcia_get_first_tuple(link, &tuple); - while (rc == 0) { - rc = pcmcia_get_tuple_data(link, &tuple); - if (rc != 0) { - cs_error(link, GetTupleData, rc); - break; - } - rc = pcmcia_parse_tuple(&tuple, &parse); - if (rc != 0) { - cs_error(link, ParseTuple, rc); - break; - } - switch(tuple.TupleCode) { - case CISTPL_FORMAT: { - cistpl_format_t *t = &parse.format; - (void)t; /* Shut up, gcc */ - DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u", - t->type, t->edc, t->offset, t->length); - break; + if (!pcmcia_parse_tuple(tuple, &parse)) { + cistpl_format_t *t = &parse.format; + (void)t; /* Shut up, gcc */ + DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u", + t->type, t->edc, t->offset, t->length); + } + return -ENOSPC; +} - } +static int pcmciamtd_cistpl_jedec(struct pcmcia_device *p_dev, + tuple_t *tuple, + void *priv_data) +{ + cisparse_t parse; + int i; - case CISTPL_DEVICE: { - cistpl_device_t *t = &parse.device; - int i; - DEBUG(2, "Common memory:"); - dev->pcmcia_map.size = t->dev[0].size; - for(i = 0; i < t->ndev; i++) { - DEBUG(2, "Region %d, type = %u", i, t->dev[i].type); - DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp); - DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed); - DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size); - } - break; - } + if (!pcmcia_parse_tuple(tuple, &parse)) { + cistpl_jedec_t *t = &parse.jedec; + for (i = 0; i < t->nid; i++) + DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info); + } + return -ENOSPC; +} +#endif - case CISTPL_VERS_1: { - cistpl_vers_1_t *t = &parse.version_1; - int i; - if(t->ns) { - dev->mtd_name[0] = '\0'; - for(i = 0; i < t->ns; i++) { - if(i) - strcat(dev->mtd_name, " "); - strcat(dev->mtd_name, t->str+t->ofs[i]); - } - } - DEBUG(2, "Found name: %s", dev->mtd_name); - break; - } +static int pcmciamtd_cistpl_device(struct pcmcia_device *p_dev, + tuple_t *tuple, + void *priv_data) +{ + struct pcmciamtd_dev *dev = priv_data; + cisparse_t parse; + cistpl_device_t *t = &parse.device; + + if (pcmcia_parse_tuple(tuple, &parse)) + return -EINVAL; + + DEBUG(2, "Common memory:"); + dev->pcmcia_map.size = t->dev[0].size; + /* from here on: DEBUG only */ + for (i = 0; i < t->ndev; i++) { + DEBUG(2, "Region %d, type = %u", i, t->dev[i].type); + DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp); + DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed); + DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size); + } + return 0; +} - case CISTPL_JEDEC_C: { - cistpl_jedec_t *t = &parse.jedec; - int i; - for(i = 0; i < t->nid; i++) { - DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info); - } - break; - } +static int pcmciamtd_cistpl_geo(struct pcmcia_device *p_dev, + tuple_t *tuple, + void *priv_data) +{ + struct pcmciamtd_dev *dev = priv_data; + cisparse_t parse; + cistpl_device_geo_t *t = &parse.device_geo; + + if (pcmcia_parse_tuple(tuple, &parse)) + return -EINVAL; + + dev->pcmcia_map.bankwidth = t->geo[0].buswidth; + /* from here on: DEBUG only */ + for (i = 0; i < t->ngeo; i++) { + DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth); + DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block); + DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block); + DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block); + DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition); + DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave); + } + return 0; +} - case CISTPL_DEVICE_GEO: { - cistpl_device_geo_t *t = &parse.device_geo; - int i; - dev->pcmcia_map.bankwidth = t->geo[0].buswidth; - for(i = 0; i < t->ngeo; i++) { - DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth); - DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block); - DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block); - DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block); - DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition); - DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave); - } - break; - } - default: - DEBUG(2, "Unknown tuple code %d", tuple.TupleCode); - } +static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name) +{ + int i; - rc = pcmcia_get_next_tuple(link, &tuple); + if (p_dev->prod_id[0]) { + dev->mtd_name[0] = '\0'; + for (i = 0; i < 4; i++) { + if (i) + strcat(dev->mtd_name, " "); + if (p_dev->prod_id[i]) + strcat(dev->mtd_name, p_dev->prod_id[i]); + } + DEBUG(2, "Found name: %s", dev->mtd_name); } + +#ifdef CONFIG_MTD_DEBUG + pcmcia_loop_tuple(p_dev, CISTPL_FORMAT, pcmciamtd_cistpl_format, NULL); + pcmcia_loop_tuple(p_dev, CISTPL_JEDEC_C, pcmciamtd_cistpl_jedec, NULL); +#endif + pcmcia_loop_tuple(p_dev, CISTPL_DEVICE, pcmciamtd_cistpl_device, dev); + pcmcia_loop_tuple(p_dev, CISTPL_DEVICE_GEO, pcmciamtd_cistpl_geo, dev); + if(!dev->pcmcia_map.size) dev->pcmcia_map.size = MAX_PCMCIA_ADDR; -- cgit v0.10.2 From 2d098a725333990d265dfe4754d1b63032c35afb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 19 Oct 2009 19:45:29 -0400 Subject: mtd: plat_nand: request memory resource before doing ioremap Add a request_mem_region() before doing the ioremap(). Also, use the resource_size macro instead of doing the end - start + 1 calc by hand. Signed-off-by: H Hartley Sweeten Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index 4e16c6f..8d46731 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c @@ -34,7 +34,12 @@ static int __devinit plat_nand_probe(struct platform_device *pdev) { struct platform_nand_data *pdata = pdev->dev.platform_data; struct plat_nand_data *data; - int res = 0; + struct resource *res; + int err = 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENXIO; /* Allocate memory for the device structure (and zero it) */ data = kzalloc(sizeof(struct plat_nand_data), GFP_KERNEL); @@ -43,12 +48,18 @@ static int __devinit plat_nand_probe(struct platform_device *pdev) return -ENOMEM; } - data->io_base = ioremap(pdev->resource[0].start, - pdev->resource[0].end - pdev->resource[0].start + 1); + if (!request_mem_region(res->start, resource_size(res), + dev_name(&pdev->dev))) { + dev_err(&pdev->dev, "request_mem_region failed\n"); + err = -EBUSY; + goto out_free; + } + + data->io_base = ioremap(res->start, resource_size(res)); if (data->io_base == NULL) { dev_err(&pdev->dev, "ioremap failed\n"); - kfree(data); - return -EIO; + err = -EIO; + goto out_release_io; } data->chip.priv = &data; @@ -74,24 +85,24 @@ static int __devinit plat_nand_probe(struct platform_device *pdev) /* Handle any platform specific setup */ if (pdata->ctrl.probe) { - res = pdata->ctrl.probe(pdev); - if (res) + err = pdata->ctrl.probe(pdev); + if (err) goto out; } /* Scan to find existance of the device */ if (nand_scan(&data->mtd, 1)) { - res = -ENXIO; + err = -ENXIO; goto out; } #ifdef CONFIG_MTD_PARTITIONS if (pdata->chip.part_probe_types) { - res = parse_mtd_partitions(&data->mtd, + err = parse_mtd_partitions(&data->mtd, pdata->chip.part_probe_types, &data->parts, 0); - if (res > 0) { - add_mtd_partitions(&data->mtd, data->parts, res); + if (err > 0) { + add_mtd_partitions(&data->mtd, data->parts, err); return 0; } } @@ -99,14 +110,14 @@ static int __devinit plat_nand_probe(struct platform_device *pdev) pdata->chip.set_parts(data->mtd.size, &pdata->chip); if (pdata->chip.partitions) { data->parts = pdata->chip.partitions; - res = add_mtd_partitions(&data->mtd, data->parts, + err = add_mtd_partitions(&data->mtd, data->parts, pdata->chip.nr_partitions); } else #endif - res = add_mtd_device(&data->mtd); + err = add_mtd_device(&data->mtd); - if (!res) - return res; + if (!err) + return err; nand_release(&data->mtd); out: @@ -114,8 +125,11 @@ out: pdata->ctrl.remove(pdev); platform_set_drvdata(pdev, NULL); iounmap(data->io_base); +out_release_io: + release_mem_region(res->start, resource_size(res)); +out_free: kfree(data); - return res; + return err; } /* @@ -125,6 +139,9 @@ static int __devexit plat_nand_remove(struct platform_device *pdev) { struct plat_nand_data *data = platform_get_drvdata(pdev); struct platform_nand_data *pdata = pdev->dev.platform_data; + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); nand_release(&data->mtd); #ifdef CONFIG_MTD_PARTITIONS @@ -134,6 +151,7 @@ static int __devexit plat_nand_remove(struct platform_device *pdev) if (pdata->ctrl.remove) pdata->ctrl.remove(pdev); iounmap(data->io_base); + release_mem_region(res->start, resource_size(res)); kfree(data); return 0; -- cgit v0.10.2 From 4b56ffcacee937a85bf39e14872dd141e23ee85f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 19 Oct 2009 13:31:46 -0400 Subject: mtd: Fix kernel NULL pointer dereference in physmap.c During the probe for physmap platform flash devices there are a number error exit conditions that all do a goto err_out which then calls physmap_flash_remove(). In that function one of the cleanup steps is: #ifdef CONFIG_MTD_CONCAT if (info->cmtd != info->mtd[0]) mtd_concat_destroy(info->cmtd); #endif This test will succeed since info->cmtd == NULL and info->mtd[0] is valid. Fix this by exiting the remove function when info->cmtd == NULL. Also, cleanup the #ifdef CONFIG_MTD_PARTITIONS stuff by using mtd_has_partitions(). Signed-off-by: H Hartley Sweeten Signed-off-by: David Woodhouse diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 380648e..65f52d4 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c @@ -44,22 +44,23 @@ static int physmap_flash_remove(struct platform_device *dev) return 0; platform_set_drvdata(dev, NULL); + if (info->cmtd == NULL) + return 0; + physmap_data = dev->dev.platform_data; - if (info->cmtd) { -#ifdef CONFIG_MTD_PARTITIONS - if (info->nr_parts || physmap_data->nr_parts) + if (mtd_has_partitions()) { + if (info->nr_parts || physmap_data->nr_parts) { del_mtd_partitions(info->cmtd); - else + + if (info->nr_parts) + kfree(info->parts); + } else { del_mtd_device(info->cmtd); -#else + } + } else { del_mtd_device(info->cmtd); -#endif } -#ifdef CONFIG_MTD_PARTITIONS - if (info->nr_parts) - kfree(info->parts); -#endif #ifdef CONFIG_MTD_CONCAT if (info->cmtd != info->mtd[0]) @@ -169,22 +170,22 @@ static int physmap_flash_probe(struct platform_device *dev) if (err) goto err_out; -#ifdef CONFIG_MTD_PARTITIONS - err = parse_mtd_partitions(info->cmtd, part_probe_types, - &info->parts, 0); - if (err > 0) { - add_mtd_partitions(info->cmtd, info->parts, err); - info->nr_parts = err; - return 0; - } + if (mtd_has_partitions()) { + err = parse_mtd_partitions(info->cmtd, part_probe_types, + &info->parts, 0); + if (err > 0) { + add_mtd_partitions(info->cmtd, info->parts, err); + info->nr_parts = err; + return 0; + } - if (physmap_data->nr_parts) { - printk(KERN_NOTICE "Using physmap partition information\n"); - add_mtd_partitions(info->cmtd, physmap_data->parts, - physmap_data->nr_parts); - return 0; + if (physmap_data->nr_parts) { + printk(KERN_NOTICE "Using physmap partition information\n"); + add_mtd_partitions(info->cmtd, physmap_data->parts, + physmap_data->nr_parts); + return 0; + } } -#endif add_mtd_device(info->cmtd); return 0; -- cgit v0.10.2 From 266dead21675aeb89407b1213788cd924353d5e1 Mon Sep 17 00:00:00 2001 From: "Leo (Hao) Chen" Date: Fri, 9 Oct 2009 19:13:08 -0700 Subject: mtd: add bcmring nand driver Signed-off-by: Leo Hao Chen Signed-off-by: David Woodhouse diff --git a/arch/arm/mach-bcmring/arch.c b/arch/arm/mach-bcmring/arch.c index 0da693b..074dad6 100644 --- a/arch/arm/mach-bcmring/arch.c +++ b/arch/arm/mach-bcmring/arch.c @@ -76,9 +76,19 @@ static struct ctl_table bcmring_sysctl_reboot[] = { {} }; +static struct resource nand_resource[] = { + [0] = { + .start = MM_ADDR_IO_NAND, + .end = MM_ADDR_IO_NAND + 0x1000 - 1, + .flags = IORESOURCE_MEM, + }, +}; + static struct platform_device nand_device = { .name = "bcm-nand", .id = -1, + .resource = nand_resource, + .num_resources = ARRAY_SIZE(nand_resource), }; static struct platform_device *devices[] __initdata = { diff --git a/arch/arm/mach-bcmring/include/mach/reg_nand.h b/arch/arm/mach-bcmring/include/mach/reg_nand.h new file mode 100644 index 0000000..387376f --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/reg_nand.h @@ -0,0 +1,66 @@ +/***************************************************************************** +* Copyright 2001 - 2008 Broadcom Corporation. All rights reserved. +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed to you +* under the terms of the GNU General Public License version 2, available at +* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). +* +* Notwithstanding the above, under no circumstances may you combine this +* software in any way with any other Broadcom software provided under a +* license other than the GPL, without Broadcom's express prior written +* consent. +*****************************************************************************/ + +/* +* +***************************************************************************** +* +* REG_NAND.h +* +* PURPOSE: +* +* This file contains definitions for the nand registers: +* +* NOTES: +* +*****************************************************************************/ + +#if !defined(__ASM_ARCH_REG_NAND_H) +#define __ASM_ARCH_REG_NAND_H + +/* ---- Include Files ---------------------------------------------------- */ +#include +#include + +/* ---- Constants and Types ---------------------------------------------- */ + +#define HW_NAND_BASE MM_IO_BASE_NAND /* NAND Flash */ + +/* DMA accesses by the bootstrap need hard nonvirtual addresses */ +#define REG_NAND_CMD __REG16(HW_NAND_BASE + 0) +#define REG_NAND_ADDR __REG16(HW_NAND_BASE + 4) + +#define REG_NAND_PHYS_DATA16 (HW_NAND_BASE + 8) +#define REG_NAND_PHYS_DATA8 (HW_NAND_BASE + 8) +#define REG_NAND_DATA16 __REG16(REG_NAND_PHYS_DATA16) +#define REG_NAND_DATA8 __REG8(REG_NAND_PHYS_DATA8) + +/* use appropriate offset to make sure it start at the 1K boundary */ +#define REG_NAND_PHYS_DATA_DMA (HW_NAND_BASE + 0x400) +#define REG_NAND_DATA_DMA __REG32(REG_NAND_PHYS_DATA_DMA) + +/* Linux DMA requires physical address of the data register */ +#define REG_NAND_DATA16_PADDR HW_IO_VIRT_TO_PHYS(REG_NAND_PHYS_DATA16) +#define REG_NAND_DATA8_PADDR HW_IO_VIRT_TO_PHYS(REG_NAND_PHYS_DATA8) +#define REG_NAND_DATA_PADDR HW_IO_VIRT_TO_PHYS(REG_NAND_PHYS_DATA_DMA) + +#define NAND_BUS_16BIT() (0) +#define NAND_BUS_8BIT() (!NAND_BUS_16BIT()) + +/* Register offsets */ +#define REG_NAND_CMD_OFFSET (0) +#define REG_NAND_ADDR_OFFSET (4) +#define REG_NAND_DATA8_OFFSET (8) + +#endif diff --git a/arch/arm/mach-bcmring/include/mach/reg_umi.h b/arch/arm/mach-bcmring/include/mach/reg_umi.h new file mode 100644 index 0000000..06a3554 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/reg_umi.h @@ -0,0 +1,237 @@ +/***************************************************************************** +* Copyright 2005 - 2008 Broadcom Corporation. All rights reserved. +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed to you +* under the terms of the GNU General Public License version 2, available at +* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). +* +* Notwithstanding the above, under no circumstances may you combine this +* software in any way with any other Broadcom software provided under a +* license other than the GPL, without Broadcom's express prior written +* consent. +*****************************************************************************/ + +/* +* +***************************************************************************** +* +* REG_UMI.h +* +* PURPOSE: +* +* This file contains definitions for the nand registers: +* +* NOTES: +* +*****************************************************************************/ + +#if !defined(__ASM_ARCH_REG_UMI_H) +#define __ASM_ARCH_REG_UMI_H + +/* ---- Include Files ---------------------------------------------------- */ +#include +#include + +/* ---- Constants and Types ---------------------------------------------- */ + +/* Unified Memory Interface Ctrl Register */ +#define HW_UMI_BASE MM_IO_BASE_UMI + +/* Flash bank 0 timing and control register */ +#define REG_UMI_FLASH0_TCR __REG32(HW_UMI_BASE + 0x00) +/* Flash bank 1 timing and control register */ +#define REG_UMI_FLASH1_TCR __REG32(HW_UMI_BASE + 0x04) +/* Flash bank 2 timing and control register */ +#define REG_UMI_FLASH2_TCR __REG32(HW_UMI_BASE + 0x08) +/* MMD interface and control register */ +#define REG_UMI_MMD_ICR __REG32(HW_UMI_BASE + 0x0c) +/* NAND timing and control register */ +#define REG_UMI_NAND_TCR __REG32(HW_UMI_BASE + 0x18) +/* NAND ready/chip select register */ +#define REG_UMI_NAND_RCSR __REG32(HW_UMI_BASE + 0x1c) +/* NAND ECC control & status register */ +#define REG_UMI_NAND_ECC_CSR __REG32(HW_UMI_BASE + 0x20) +/* NAND ECC data register XXB2B1B0 */ +#define REG_UMI_NAND_ECC_DATA __REG32(HW_UMI_BASE + 0x24) +/* BCH ECC Parameter N */ +#define REG_UMI_BCH_N __REG32(HW_UMI_BASE + 0x40) +/* BCH ECC Parameter T */ +#define REG_UMI_BCH_K __REG32(HW_UMI_BASE + 0x44) +/* BCH ECC Parameter K */ +#define REG_UMI_BCH_T __REG32(HW_UMI_BASE + 0x48) +/* BCH ECC Contro Status */ +#define REG_UMI_BCH_CTRL_STATUS __REG32(HW_UMI_BASE + 0x4C) +/* BCH WR ECC 31:0 */ +#define REG_UMI_BCH_WR_ECC_0 __REG32(HW_UMI_BASE + 0x50) +/* BCH WR ECC 63:32 */ +#define REG_UMI_BCH_WR_ECC_1 __REG32(HW_UMI_BASE + 0x54) +/* BCH WR ECC 95:64 */ +#define REG_UMI_BCH_WR_ECC_2 __REG32(HW_UMI_BASE + 0x58) +/* BCH WR ECC 127:96 */ +#define REG_UMI_BCH_WR_ECC_3 __REG32(HW_UMI_BASE + 0x5c) +/* BCH WR ECC 155:128 */ +#define REG_UMI_BCH_WR_ECC_4 __REG32(HW_UMI_BASE + 0x60) +/* BCH Read Error Location 1,0 */ +#define REG_UMI_BCH_RD_ERR_LOC_1_0 __REG32(HW_UMI_BASE + 0x64) +/* BCH Read Error Location 3,2 */ +#define REG_UMI_BCH_RD_ERR_LOC_3_2 __REG32(HW_UMI_BASE + 0x68) +/* BCH Read Error Location 5,4 */ +#define REG_UMI_BCH_RD_ERR_LOC_5_4 __REG32(HW_UMI_BASE + 0x6c) +/* BCH Read Error Location 7,6 */ +#define REG_UMI_BCH_RD_ERR_LOC_7_6 __REG32(HW_UMI_BASE + 0x70) +/* BCH Read Error Location 9,8 */ +#define REG_UMI_BCH_RD_ERR_LOC_9_8 __REG32(HW_UMI_BASE + 0x74) +/* BCH Read Error Location 11,10 */ +#define REG_UMI_BCH_RD_ERR_LOC_B_A __REG32(HW_UMI_BASE + 0x78) + +/* REG_UMI_FLASH0/1/2_TCR, REG_UMI_SRAM0/1_TCR bits */ +/* Enable wait pin during burst write or read */ +#define REG_UMI_TCR_WAITEN 0x80000000 +/* Enable mem ctrlr to work iwth ext mem of lower freq than AHB clk */ +#define REG_UMI_TCR_LOWFREQ 0x40000000 +/* 1=synch write, 0=async write */ +#define REG_UMI_TCR_MEMTYPE_SYNCWRITE 0x20000000 +/* 1=synch read, 0=async read */ +#define REG_UMI_TCR_MEMTYPE_SYNCREAD 0x10000000 +/* 1=page mode read, 0=normal mode read */ +#define REG_UMI_TCR_MEMTYPE_PAGEREAD 0x08000000 +/* page size/burst size (wrap only) */ +#define REG_UMI_TCR_MEMTYPE_PGSZ_MASK 0x07000000 +/* 4 word */ +#define REG_UMI_TCR_MEMTYPE_PGSZ_4 0x00000000 +/* 8 word */ +#define REG_UMI_TCR_MEMTYPE_PGSZ_8 0x01000000 +/* 16 word */ +#define REG_UMI_TCR_MEMTYPE_PGSZ_16 0x02000000 +/* 32 word */ +#define REG_UMI_TCR_MEMTYPE_PGSZ_32 0x03000000 +/* 64 word */ +#define REG_UMI_TCR_MEMTYPE_PGSZ_64 0x04000000 +/* 128 word */ +#define REG_UMI_TCR_MEMTYPE_PGSZ_128 0x05000000 +/* 256 word */ +#define REG_UMI_TCR_MEMTYPE_PGSZ_256 0x06000000 +/* 512 word */ +#define REG_UMI_TCR_MEMTYPE_PGSZ_512 0x07000000 +/* Page read access cycle / Burst write latency (n+2 / n+1) */ +#define REG_UMI_TCR_TPRC_TWLC_MASK 0x00f80000 +/* Bus turnaround cycle (n) */ +#define REG_UMI_TCR_TBTA_MASK 0x00070000 +/* Write pulse width cycle (n+1) */ +#define REG_UMI_TCR_TWP_MASK 0x0000f800 +/* Write recovery cycle (n+1) */ +#define REG_UMI_TCR_TWR_MASK 0x00000600 +/* Write address setup cycle (n+1) */ +#define REG_UMI_TCR_TAS_MASK 0x00000180 +/* Output enable delay cycle (n) */ +#define REG_UMI_TCR_TOE_MASK 0x00000060 +/* Read access cycle / Burst read latency (n+2 / n+1) */ +#define REG_UMI_TCR_TRC_TLC_MASK 0x0000001f + +/* REG_UMI_MMD_ICR bits */ +/* Flash write protection pin control */ +#define REG_UMI_MMD_ICR_FLASH_WP 0x8000 +/* Extend hold time for sram0, sram1 csn (39 MHz operation) */ +#define REG_UMI_MMD_ICR_XHCS 0x4000 +/* Enable SDRAM 2 interface control */ +#define REG_UMI_MMD_ICR_SDRAM2EN 0x2000 +/* Enable merge of flash banks 0/1 to 512 MBit bank */ +#define REG_UMI_MMD_ICR_INST512 0x1000 +/* Enable merge of flash banks 1/2 to 512 MBit bank */ +#define REG_UMI_MMD_ICR_DATA512 0x0800 +/* Enable SDRAM interface control */ +#define REG_UMI_MMD_ICR_SDRAMEN 0x0400 +/* Polarity of busy state of Burst Wait Signal */ +#define REG_UMI_MMD_ICR_WAITPOL 0x0200 +/* Enable burst clock stopped when not accessing external burst flash/sram */ +#define REG_UMI_MMD_ICR_BCLKSTOP 0x0100 +/* Enable the peri1_csn to replace flash1_csn in 512 Mb flash mode */ +#define REG_UMI_MMD_ICR_PERI1EN 0x0080 +/* Enable the peri2_csn to replace sdram_csn */ +#define REG_UMI_MMD_ICR_PERI2EN 0x0040 +/* Enable the peri3_csn to replace sdram2_csn */ +#define REG_UMI_MMD_ICR_PERI3EN 0x0020 +/* Enable sram bank1 for H/W controlled MRS */ +#define REG_UMI_MMD_ICR_MRSB1 0x0010 +/* Enable sram bank0 for H/W controlled MRS */ +#define REG_UMI_MMD_ICR_MRSB0 0x0008 +/* Polarity for assert3ed state of H/W controlled MRS */ +#define REG_UMI_MMD_ICR_MRSPOL 0x0004 +/* 0: S/W controllable ZZ/MRS/CRE/P-Mode pin */ +/* 1: H/W controlled ZZ/MRS/CRE/P-Mode, same timing as CS */ +#define REG_UMI_MMD_ICR_MRSMODE 0x0002 +/* MRS state for S/W controlled mode */ +#define REG_UMI_MMD_ICR_MRSSTATE 0x0001 + +/* REG_UMI_NAND_TCR bits */ +/* Enable software to control CS */ +#define REG_UMI_NAND_TCR_CS_SWCTRL 0x80000000 +/* 16-bit nand wordsize if set */ +#define REG_UMI_NAND_TCR_WORD16 0x40000000 +/* Bus turnaround cycle (n) */ +#define REG_UMI_NAND_TCR_TBTA_MASK 0x00070000 +/* Write pulse width cycle (n+1) */ +#define REG_UMI_NAND_TCR_TWP_MASK 0x0000f800 +/* Write recovery cycle (n+1) */ +#define REG_UMI_NAND_TCR_TWR_MASK 0x00000600 +/* Write address setup cycle (n+1) */ +#define REG_UMI_NAND_TCR_TAS_MASK 0x00000180 +/* Output enable delay cycle (n) */ +#define REG_UMI_NAND_TCR_TOE_MASK 0x00000060 +/* Read access cycle (n+2) */ +#define REG_UMI_NAND_TCR_TRC_TLC_MASK 0x0000001f + +/* REG_UMI_NAND_RCSR bits */ +/* Status: Ready=1, Busy=0 */ +#define REG_UMI_NAND_RCSR_RDY 0x02 +/* Keep CS asserted during operation */ +#define REG_UMI_NAND_RCSR_CS_ASSERTED 0x01 + +/* REG_UMI_NAND_ECC_CSR bits */ +/* Interrupt status - read-only */ +#define REG_UMI_NAND_ECC_CSR_NANDINT 0x80000000 +/* Read: Status of ECC done, Write: clear ECC interrupt */ +#define REG_UMI_NAND_ECC_CSR_ECCINT_RAW 0x00800000 +/* Read: Status of R/B, Write: clear R/B interrupt */ +#define REG_UMI_NAND_ECC_CSR_RBINT_RAW 0x00400000 +/* 1 = Enable ECC Interrupt */ +#define REG_UMI_NAND_ECC_CSR_ECCINT_ENABLE 0x00008000 +/* 1 = Assert interrupt at rising edge of R/B_ */ +#define REG_UMI_NAND_ECC_CSR_RBINT_ENABLE 0x00004000 +/* Calculate ECC by 0=512 bytes, 1=256 bytes */ +#define REG_UMI_NAND_ECC_CSR_256BYTE 0x00000080 +/* Enable ECC in hardware */ +#define REG_UMI_NAND_ECC_CSR_ECC_ENABLE 0x00000001 + +/* REG_UMI_BCH_CTRL_STATUS bits */ +/* Shift to Indicate Number of correctable errors detected */ +#define REG_UMI_BCH_CTRL_STATUS_NB_CORR_ERROR_SHIFT 20 +/* Indicate Number of correctable errors detected */ +#define REG_UMI_BCH_CTRL_STATUS_NB_CORR_ERROR 0x00F00000 +/* Indicate Errors detected during read but uncorrectable */ +#define REG_UMI_BCH_CTRL_STATUS_UNCORR_ERR 0x00080000 +/* Indicate Errors detected during read and are correctable */ +#define REG_UMI_BCH_CTRL_STATUS_CORR_ERR 0x00040000 +/* Flag indicates BCH's ECC status of read process are valid */ +#define REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID 0x00020000 +/* Flag indicates BCH's ECC status of write process are valid */ +#define REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID 0x00010000 +/* Pause ECC calculation */ +#define REG_UMI_BCH_CTRL_STATUS_PAUSE_ECC_DEC 0x00000010 +/* Enable Interrupt */ +#define REG_UMI_BCH_CTRL_STATUS_INT_EN 0x00000004 +/* Enable ECC during read */ +#define REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN 0x00000002 +/* Enable ECC during write */ +#define REG_UMI_BCH_CTRL_STATUS_ECC_WR_EN 0x00000001 +/* Mask for location */ +#define REG_UMI_BCH_ERR_LOC_MASK 0x00001FFF +/* location within a byte */ +#define REG_UMI_BCH_ERR_LOC_BYTE 0x00000007 +/* location within a word */ +#define REG_UMI_BCH_ERR_LOC_WORD 0x00000018 +/* location within a page (512 byte) */ +#define REG_UMI_BCH_ERR_LOC_PAGE 0x00001FE0 +#define REG_UMI_BCH_ERR_LOC_ADDR(index) (__REG32(HW_UMI_BASE + 0x64 + (index / 2)*4) >> ((index % 2) * 16)) +#endif diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 2fda0b6..34598e9 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -203,6 +203,22 @@ config MTD_NAND_S3C2410_CLKSTOP when the is NAND chip selected or released, but will save approximately 5mA of power when there is nothing happening. +config MTD_NAND_BCM_UMI + tristate "NAND Flash support for BCM Reference Boards" + depends on ARCH_BCMRING && MTD_NAND + help + This enables the NAND flash controller on the BCM UMI block. + + No board specfic support is done by this driver, each board + must advertise a platform_device for the driver to attach. + +config MTD_NAND_BCM_UMI_HWCS + bool "BCM UMI NAND Hardware CS" + depends on MTD_NAND_BCM_UMI + help + Enable the use of the BCM UMI block's internal CS using NAND. + This should only be used if you know the external NAND CS can toggle. + config MTD_NAND_DISKONCHIP tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)" depends on EXPERIMENTAL diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 6950d3d..460a1f3 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -42,5 +42,6 @@ obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o obj-$(CONFIG_MTD_NAND_W90P910) += w90p910_nand.o obj-$(CONFIG_MTD_NAND_NOMADIK) += nomadik_nand.o +obj-$(CONFIG_MTD_NAND_BCM_UMI) += bcm_umi_nand.o nand_bcm_umi.o nand-objs := nand_base.o nand_bbt.o diff --git a/drivers/mtd/nand/bcm_umi_bch.c b/drivers/mtd/nand/bcm_umi_bch.c new file mode 100644 index 0000000..a930666 --- /dev/null +++ b/drivers/mtd/nand/bcm_umi_bch.c @@ -0,0 +1,213 @@ +/***************************************************************************** +* Copyright 2004 - 2009 Broadcom Corporation. All rights reserved. +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed to you +* under the terms of the GNU General Public License version 2, available at +* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). +* +* Notwithstanding the above, under no circumstances may you combine this +* software in any way with any other Broadcom software provided under a +* license other than the GPL, without Broadcom's express prior written +* consent. +*****************************************************************************/ + +/* ---- Include Files ---------------------------------------------------- */ +#include "nand_bcm_umi.h" + +/* ---- External Variable Declarations ----------------------------------- */ +/* ---- External Function Prototypes ------------------------------------- */ +/* ---- Public Variables ------------------------------------------------- */ +/* ---- Private Constants and Types -------------------------------------- */ + +/* ---- Private Function Prototypes -------------------------------------- */ +static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd, + struct nand_chip *chip, uint8_t *buf, int page); +static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd, + struct nand_chip *chip, const uint8_t *buf); + +/* ---- Private Variables ------------------------------------------------ */ + +/* +** nand_hw_eccoob +** New oob placement block for use with hardware ecc generation. +*/ +static struct nand_ecclayout nand_hw_eccoob_512 = { + /* Reserve 5 for BI indicator */ + .oobfree = { +#if (NAND_ECC_NUM_BYTES > 3) + {.offset = 0, .length = 2} +#else + {.offset = 0, .length = 5}, + {.offset = 6, .length = 7} +#endif + } +}; + +/* +** We treat the OOB for a 2K page as if it were 4 512 byte oobs, +** except the BI is at byte 0. +*/ +static struct nand_ecclayout nand_hw_eccoob_2048 = { + /* Reserve 0 as BI indicator */ + .oobfree = { +#if (NAND_ECC_NUM_BYTES > 10) + {.offset = 1, .length = 2}, +#elif (NAND_ECC_NUM_BYTES > 7) + {.offset = 1, .length = 5}, + {.offset = 16, .length = 6}, + {.offset = 32, .length = 6}, + {.offset = 48, .length = 6} +#else + {.offset = 1, .length = 8}, + {.offset = 16, .length = 9}, + {.offset = 32, .length = 9}, + {.offset = 48, .length = 9} +#endif + } +}; + +/* We treat the OOB for a 4K page as if it were 8 512 byte oobs, + * except the BI is at byte 0. */ +static struct nand_ecclayout nand_hw_eccoob_4096 = { + /* Reserve 0 as BI indicator */ + .oobfree = { +#if (NAND_ECC_NUM_BYTES > 10) + {.offset = 1, .length = 2}, + {.offset = 16, .length = 3}, + {.offset = 32, .length = 3}, + {.offset = 48, .length = 3}, + {.offset = 64, .length = 3}, + {.offset = 80, .length = 3}, + {.offset = 96, .length = 3}, + {.offset = 112, .length = 3} +#else + {.offset = 1, .length = 5}, + {.offset = 16, .length = 6}, + {.offset = 32, .length = 6}, + {.offset = 48, .length = 6}, + {.offset = 64, .length = 6}, + {.offset = 80, .length = 6}, + {.offset = 96, .length = 6}, + {.offset = 112, .length = 6} +#endif + } +}; + +/* ---- Private Functions ------------------------------------------------ */ +/* ==== Public Functions ================================================= */ + +/**************************************************************************** +* +* bcm_umi_bch_read_page_hwecc - hardware ecc based page read function +* @mtd: mtd info structure +* @chip: nand chip info structure +* @buf: buffer to store read data +* +***************************************************************************/ +static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd, + struct nand_chip *chip, uint8_t * buf, + int page) +{ + int sectorIdx = 0; + int eccsize = chip->ecc.size; + int eccsteps = chip->ecc.steps; + uint8_t *datap = buf; + uint8_t eccCalc[NAND_ECC_NUM_BYTES]; + int sectorOobSize = mtd->oobsize / eccsteps; + int stat; + + for (sectorIdx = 0; sectorIdx < eccsteps; + sectorIdx++, datap += eccsize) { + if (sectorIdx > 0) { + /* Seek to page location within sector */ + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, sectorIdx * eccsize, + -1); + } + + /* Enable hardware ECC before reading the buf */ + nand_bcm_umi_bch_enable_read_hwecc(); + + /* Read in data */ + bcm_umi_nand_read_buf(mtd, datap, eccsize); + + /* Pause hardware ECC after reading the buf */ + nand_bcm_umi_bch_pause_read_ecc_calc(); + + /* Read the OOB ECC */ + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, + mtd->writesize + sectorIdx * sectorOobSize, -1); + nand_bcm_umi_bch_read_oobEcc(mtd->writesize, eccCalc, + NAND_ECC_NUM_BYTES, + chip->oob_poi + + sectorIdx * sectorOobSize); + + /* Correct any ECC detected errors */ + stat = + nand_bcm_umi_bch_correct_page(datap, eccCalc, + NAND_ECC_NUM_BYTES); + + /* Update Stats */ + if (stat < 0) { +#if defined(NAND_BCM_UMI_DEBUG) + printk(KERN_WARNING "%s uncorr_err sectorIdx=%d\n", + __func__, sectorIdx); + printk(KERN_WARNING + "%s data %02x %02x %02x %02x " + "%02x %02x %02x %02x\n", + __func__, datap[0], datap[1], datap[2], datap[3], + datap[4], datap[5], datap[6], datap[7]); + printk(KERN_WARNING + "%s ecc %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x " + "%02x %02x %02x\n", + __func__, eccCalc[0], eccCalc[1], eccCalc[2], + eccCalc[3], eccCalc[4], eccCalc[5], eccCalc[6], + eccCalc[7], eccCalc[8], eccCalc[9], eccCalc[10], + eccCalc[11], eccCalc[12]); + BUG(); +#endif + mtd->ecc_stats.failed++; + } else { +#if defined(NAND_BCM_UMI_DEBUG) + if (stat > 0) { + printk(KERN_INFO + "%s %d correctable_errors detected\n", + __func__, stat); + } +#endif + mtd->ecc_stats.corrected += stat; + } + } + return 0; +} + +/**************************************************************************** +* +* bcm_umi_bch_write_page_hwecc - hardware ecc based page write function +* @mtd: mtd info structure +* @chip: nand chip info structure +* @buf: data buffer +* +***************************************************************************/ +static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd, + struct nand_chip *chip, const uint8_t *buf) +{ + int sectorIdx = 0; + int eccsize = chip->ecc.size; + int eccsteps = chip->ecc.steps; + const uint8_t *datap = buf; + uint8_t *oobp = chip->oob_poi; + int sectorOobSize = mtd->oobsize / eccsteps; + + for (sectorIdx = 0; sectorIdx < eccsteps; + sectorIdx++, datap += eccsize, oobp += sectorOobSize) { + /* Enable hardware ECC before writing the buf */ + nand_bcm_umi_bch_enable_write_hwecc(); + bcm_umi_nand_write_buf(mtd, datap, eccsize); + nand_bcm_umi_bch_write_oobEcc(mtd->writesize, oobp, + NAND_ECC_NUM_BYTES); + } + + bcm_umi_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize); +} diff --git a/drivers/mtd/nand/bcm_umi_nand.c b/drivers/mtd/nand/bcm_umi_nand.c new file mode 100644 index 0000000..087bcd7 --- /dev/null +++ b/drivers/mtd/nand/bcm_umi_nand.c @@ -0,0 +1,581 @@ +/***************************************************************************** +* Copyright 2004 - 2009 Broadcom Corporation. All rights reserved. +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed to you +* under the terms of the GNU General Public License version 2, available at +* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). +* +* Notwithstanding the above, under no circumstances may you combine this +* software in any way with any other Broadcom software provided under a +* license other than the GPL, without Broadcom's express prior written +* consent. +*****************************************************************************/ + +/* ---- Include Files ---------------------------------------------------- */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "nand_bcm_umi.h" + +#include + +#define USE_DMA 1 +#include +#include +#include + +/* ---- External Variable Declarations ----------------------------------- */ +/* ---- External Function Prototypes ------------------------------------- */ +/* ---- Public Variables ------------------------------------------------- */ +/* ---- Private Constants and Types -------------------------------------- */ +static const __devinitconst char gBanner[] = KERN_INFO \ + "BCM UMI MTD NAND Driver: 1.00\n"; + +#ifdef CONFIG_MTD_PARTITIONS +const char *part_probes[] = { "cmdlinepart", NULL }; +#endif + +#if NAND_ECC_BCH +static uint8_t scan_ff_pattern[] = { 0xff }; + +static struct nand_bbt_descr largepage_bbt = { + .options = 0, + .offs = 0, + .len = 1, + .pattern = scan_ff_pattern +}; +#endif + +/* +** Preallocate a buffer to avoid having to do this every dma operation. +** This is the size of the preallocated coherent DMA buffer. +*/ +#if USE_DMA +#define DMA_MIN_BUFLEN 512 +#define DMA_MAX_BUFLEN PAGE_SIZE +#define USE_DIRECT_IO(len) (((len) < DMA_MIN_BUFLEN) || \ + ((len) > DMA_MAX_BUFLEN)) + +/* + * The current NAND data space goes from 0x80001900 to 0x80001FFF, + * which is only 0x700 = 1792 bytes long. This is too small for 2K, 4K page + * size NAND flash. Need to break the DMA down to multiple 1Ks. + * + * Need to make sure REG_NAND_DATA_PADDR + DMA_MAX_LEN < 0x80002000 + */ +#define DMA_MAX_LEN 1024 + +#else /* !USE_DMA */ +#define DMA_MIN_BUFLEN 0 +#define DMA_MAX_BUFLEN 0 +#define USE_DIRECT_IO(len) 1 +#endif +/* ---- Private Function Prototypes -------------------------------------- */ +static void bcm_umi_nand_read_buf(struct mtd_info *mtd, u_char * buf, int len); +static void bcm_umi_nand_write_buf(struct mtd_info *mtd, const u_char * buf, + int len); + +/* ---- Private Variables ------------------------------------------------ */ +static struct mtd_info *board_mtd; +static void __iomem *bcm_umi_io_base; +static void *virtPtr; +static dma_addr_t physPtr; +static struct completion nand_comp; + +/* ---- Private Functions ------------------------------------------------ */ +#if NAND_ECC_BCH +#include "bcm_umi_bch.c" +#else +#include "bcm_umi_hamming.c" +#endif + +#if USE_DMA + +/* Handler called when the DMA finishes. */ +static void nand_dma_handler(DMA_Device_t dev, int reason, void *userData) +{ + complete(&nand_comp); +} + +static int nand_dma_init(void) +{ + int rc; + + rc = dma_set_device_handler(DMA_DEVICE_NAND_MEM_TO_MEM, + nand_dma_handler, NULL); + if (rc != 0) { + printk(KERN_ERR "dma_set_device_handler failed: %d\n", rc); + return rc; + } + + virtPtr = + dma_alloc_coherent(NULL, DMA_MAX_BUFLEN, &physPtr, GFP_KERNEL); + if (virtPtr == NULL) { + printk(KERN_ERR "NAND - Failed to allocate memory for DMA buffer\n"); + return -ENOMEM; + } + + return 0; +} + +static void nand_dma_term(void) +{ + if (virtPtr != NULL) + dma_free_coherent(NULL, DMA_MAX_BUFLEN, virtPtr, physPtr); +} + +static void nand_dma_read(void *buf, int len) +{ + int offset = 0; + int tmp_len = 0; + int len_left = len; + DMA_Handle_t hndl; + + if (virtPtr == NULL) + panic("nand_dma_read: virtPtr == NULL\n"); + + if ((void *)physPtr == NULL) + panic("nand_dma_read: physPtr == NULL\n"); + + hndl = dma_request_channel(DMA_DEVICE_NAND_MEM_TO_MEM); + if (hndl < 0) { + printk(KERN_ERR + "nand_dma_read: unable to allocate dma channel: %d\n", + (int)hndl); + panic("\n"); + } + + while (len_left > 0) { + if (len_left > DMA_MAX_LEN) { + tmp_len = DMA_MAX_LEN; + len_left -= DMA_MAX_LEN; + } else { + tmp_len = len_left; + len_left = 0; + } + + init_completion(&nand_comp); + dma_transfer_mem_to_mem(hndl, REG_NAND_DATA_PADDR, + physPtr + offset, tmp_len); + wait_for_completion(&nand_comp); + + offset += tmp_len; + } + + dma_free_channel(hndl); + + if (buf != NULL) + memcpy(buf, virtPtr, len); +} + +static void nand_dma_write(const void *buf, int len) +{ + int offset = 0; + int tmp_len = 0; + int len_left = len; + DMA_Handle_t hndl; + + if (buf == NULL) + panic("nand_dma_write: buf == NULL\n"); + + if (virtPtr == NULL) + panic("nand_dma_write: virtPtr == NULL\n"); + + if ((void *)physPtr == NULL) + panic("nand_dma_write: physPtr == NULL\n"); + + memcpy(virtPtr, buf, len); + + + hndl = dma_request_channel(DMA_DEVICE_NAND_MEM_TO_MEM); + if (hndl < 0) { + printk(KERN_ERR + "nand_dma_write: unable to allocate dma channel: %d\n", + (int)hndl); + panic("\n"); + } + + while (len_left > 0) { + if (len_left > DMA_MAX_LEN) { + tmp_len = DMA_MAX_LEN; + len_left -= DMA_MAX_LEN; + } else { + tmp_len = len_left; + len_left = 0; + } + + init_completion(&nand_comp); + dma_transfer_mem_to_mem(hndl, physPtr + offset, + REG_NAND_DATA_PADDR, tmp_len); + wait_for_completion(&nand_comp); + + offset += tmp_len; + } + + dma_free_channel(hndl); +} + +#endif + +static int nand_dev_ready(struct mtd_info *mtd) +{ + return nand_bcm_umi_dev_ready(); +} + +/**************************************************************************** +* +* bcm_umi_nand_inithw +* +* This routine does the necessary hardware (board-specific) +* initializations. This includes setting up the timings, etc. +* +***************************************************************************/ +int bcm_umi_nand_inithw(void) +{ + /* Configure nand timing parameters */ + REG_UMI_NAND_TCR &= ~0x7ffff; + REG_UMI_NAND_TCR |= HW_CFG_NAND_TCR; + +#if !defined(CONFIG_MTD_NAND_BCM_UMI_HWCS) + /* enable software control of CS */ + REG_UMI_NAND_TCR |= REG_UMI_NAND_TCR_CS_SWCTRL; +#endif + + /* keep NAND chip select asserted */ + REG_UMI_NAND_RCSR |= REG_UMI_NAND_RCSR_CS_ASSERTED; + + REG_UMI_NAND_TCR &= ~REG_UMI_NAND_TCR_WORD16; + /* enable writes to flash */ + REG_UMI_MMD_ICR |= REG_UMI_MMD_ICR_FLASH_WP; + + writel(NAND_CMD_RESET, bcm_umi_io_base + REG_NAND_CMD_OFFSET); + nand_bcm_umi_wait_till_ready(); + +#if NAND_ECC_BCH + nand_bcm_umi_bch_config_ecc(NAND_ECC_NUM_BYTES); +#endif + + return 0; +} + +/* Used to turn latch the proper register for access. */ +static void bcm_umi_nand_hwcontrol(struct mtd_info *mtd, int cmd, + unsigned int ctrl) +{ + /* send command to hardware */ + struct nand_chip *chip = mtd->priv; + if (ctrl & NAND_CTRL_CHANGE) { + if (ctrl & NAND_CLE) { + chip->IO_ADDR_W = bcm_umi_io_base + REG_NAND_CMD_OFFSET; + goto CMD; + } + if (ctrl & NAND_ALE) { + chip->IO_ADDR_W = + bcm_umi_io_base + REG_NAND_ADDR_OFFSET; + goto CMD; + } + chip->IO_ADDR_W = bcm_umi_io_base + REG_NAND_DATA8_OFFSET; + } + +CMD: + /* Send command to chip directly */ + if (cmd != NAND_CMD_NONE) + writeb(cmd, chip->IO_ADDR_W); +} + +static void bcm_umi_nand_write_buf(struct mtd_info *mtd, const u_char * buf, + int len) +{ + if (USE_DIRECT_IO(len)) { + /* Do it the old way if the buffer is small or too large. + * Probably quicker than starting and checking dma. */ + int i; + struct nand_chip *this = mtd->priv; + + for (i = 0; i < len; i++) + writeb(buf[i], this->IO_ADDR_W); + } +#if USE_DMA + else + nand_dma_write(buf, len); +#endif +} + +static void bcm_umi_nand_read_buf(struct mtd_info *mtd, u_char * buf, int len) +{ + if (USE_DIRECT_IO(len)) { + int i; + struct nand_chip *this = mtd->priv; + + for (i = 0; i < len; i++) + buf[i] = readb(this->IO_ADDR_R); + } +#if USE_DMA + else + nand_dma_read(buf, len); +#endif +} + +static uint8_t readbackbuf[NAND_MAX_PAGESIZE]; +static int bcm_umi_nand_verify_buf(struct mtd_info *mtd, const u_char * buf, + int len) +{ + /* + * Try to readback page with ECC correction. This is necessary + * for MLC parts which may have permanently stuck bits. + */ + struct nand_chip *chip = mtd->priv; + int ret = chip->ecc.read_page(mtd, chip, readbackbuf, 0); + if (ret < 0) + return -EFAULT; + else { + if (memcmp(readbackbuf, buf, len) == 0) + return 0; + + return -EFAULT; + } + return 0; +} + +static int __devinit bcm_umi_nand_probe(struct platform_device *pdev) +{ + struct nand_chip *this; + struct resource *r; + int err = 0; + + printk(gBanner); + + /* Allocate memory for MTD device structure and private data */ + board_mtd = + kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), + GFP_KERNEL); + if (!board_mtd) { + printk(KERN_WARNING + "Unable to allocate NAND MTD device structure.\n"); + return -ENOMEM; + } + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + if (!r) + return -ENXIO; + + /* map physical adress */ + bcm_umi_io_base = ioremap(r->start, r->end - r->start + 1); + + if (!bcm_umi_io_base) { + printk(KERN_ERR "ioremap to access BCM UMI NAND chip failed\n"); + kfree(board_mtd); + return -EIO; + } + + /* Get pointer to private data */ + this = (struct nand_chip *)(&board_mtd[1]); + + /* Initialize structures */ + memset((char *)board_mtd, 0, sizeof(struct mtd_info)); + memset((char *)this, 0, sizeof(struct nand_chip)); + + /* Link the private data with the MTD structure */ + board_mtd->priv = this; + + /* Initialize the NAND hardware. */ + if (bcm_umi_nand_inithw() < 0) { + printk(KERN_ERR "BCM UMI NAND chip could not be initialized\n"); + iounmap(bcm_umi_io_base); + kfree(board_mtd); + return -EIO; + } + + /* Set address of NAND IO lines */ + this->IO_ADDR_W = bcm_umi_io_base + REG_NAND_DATA8_OFFSET; + this->IO_ADDR_R = bcm_umi_io_base + REG_NAND_DATA8_OFFSET; + + /* Set command delay time, see datasheet for correct value */ + this->chip_delay = 0; + /* Assign the device ready function, if available */ + this->dev_ready = nand_dev_ready; + this->options = 0; + + this->write_buf = bcm_umi_nand_write_buf; + this->read_buf = bcm_umi_nand_read_buf; + this->verify_buf = bcm_umi_nand_verify_buf; + + this->cmd_ctrl = bcm_umi_nand_hwcontrol; + this->ecc.mode = NAND_ECC_HW; + this->ecc.size = 512; + this->ecc.bytes = NAND_ECC_NUM_BYTES; +#if NAND_ECC_BCH + this->ecc.read_page = bcm_umi_bch_read_page_hwecc; + this->ecc.write_page = bcm_umi_bch_write_page_hwecc; +#else + this->ecc.correct = nand_correct_data512; + this->ecc.calculate = bcm_umi_hamming_get_hw_ecc; + this->ecc.hwctl = bcm_umi_hamming_enable_hwecc; +#endif + +#if USE_DMA + err = nand_dma_init(); + if (err != 0) + return err; +#endif + + /* Figure out the size of the device that we have. + * We need to do this to figure out which ECC + * layout we'll be using. + */ + + err = nand_scan_ident(board_mtd, 1); + if (err) { + printk(KERN_ERR "nand_scan failed: %d\n", err); + iounmap(bcm_umi_io_base); + kfree(board_mtd); + return err; + } + + /* Now that we know the nand size, we can setup the ECC layout */ + + switch (board_mtd->writesize) { /* writesize is the pagesize */ + case 4096: + this->ecc.layout = &nand_hw_eccoob_4096; + break; + case 2048: + this->ecc.layout = &nand_hw_eccoob_2048; + break; + case 512: + this->ecc.layout = &nand_hw_eccoob_512; + break; + default: + { + printk(KERN_ERR "NAND - Unrecognized pagesize: %d\n", + board_mtd->writesize); + return -EINVAL; + } + } + +#if NAND_ECC_BCH + if (board_mtd->writesize > 512) { + if (this->options & NAND_USE_FLASH_BBT) + largepage_bbt.options = NAND_BBT_SCAN2NDPAGE; + this->badblock_pattern = &largepage_bbt; + } +#endif + + /* Now finish off the scan, now that ecc.layout has been initialized. */ + + err = nand_scan_tail(board_mtd); + if (err) { + printk(KERN_ERR "nand_scan failed: %d\n", err); + iounmap(bcm_umi_io_base); + kfree(board_mtd); + return err; + } + + /* Register the partitions */ + { + int nr_partitions; + struct mtd_partition *partition_info; + + board_mtd->name = "bcm_umi-nand"; + nr_partitions = + parse_mtd_partitions(board_mtd, part_probes, + &partition_info, 0); + + if (nr_partitions <= 0) { + printk(KERN_ERR "BCM UMI NAND: Too few partitions - %d\n", + nr_partitions); + iounmap(bcm_umi_io_base); + kfree(board_mtd); + return -EIO; + } + add_mtd_partitions(board_mtd, partition_info, nr_partitions); + } + + /* Return happy */ + return 0; +} + +static int bcm_umi_nand_remove(struct platform_device *pdev) +{ +#if USE_DMA + nand_dma_term(); +#endif + + /* Release resources, unregister device */ + nand_release(board_mtd); + + /* unmap physical adress */ + iounmap(bcm_umi_io_base); + + /* Free the MTD device structure */ + kfree(board_mtd); + + return 0; +} + +#ifdef CONFIG_PM +static int bcm_umi_nand_suspend(struct platform_device *pdev, + pm_message_t state) +{ + printk(KERN_ERR "MTD NAND suspend is being called\n"); + return 0; +} + +static int bcm_umi_nand_resume(struct platform_device *pdev) +{ + printk(KERN_ERR "MTD NAND resume is being called\n"); + return 0; +} +#else +#define bcm_umi_nand_suspend NULL +#define bcm_umi_nand_resume NULL +#endif + +static struct platform_driver nand_driver = { + .driver = { + .name = "bcm-nand", + .owner = THIS_MODULE, + }, + .probe = bcm_umi_nand_probe, + .remove = bcm_umi_nand_remove, + .suspend = bcm_umi_nand_suspend, + .resume = bcm_umi_nand_resume, +}; + +static int __init nand_init(void) +{ + return platform_driver_register(&nand_driver); +} + +static void __exit nand_exit(void) +{ + platform_driver_unregister(&nand_driver); +} + +module_init(nand_init); +module_exit(nand_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Broadcom"); +MODULE_DESCRIPTION("BCM UMI MTD NAND driver"); diff --git a/drivers/mtd/nand/nand_bcm_umi.c b/drivers/mtd/nand/nand_bcm_umi.c new file mode 100644 index 0000000..46a6bc9 --- /dev/null +++ b/drivers/mtd/nand/nand_bcm_umi.c @@ -0,0 +1,149 @@ +/***************************************************************************** +* Copyright 2004 - 2009 Broadcom Corporation. All rights reserved. +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed to you +* under the terms of the GNU General Public License version 2, available at +* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). +* +* Notwithstanding the above, under no circumstances may you combine this +* software in any way with any other Broadcom software provided under a +* license other than the GPL, without Broadcom's express prior written +* consent. +*****************************************************************************/ + +/* ---- Include Files ---------------------------------------------------- */ +#include +#include "nand_bcm_umi.h" +#ifdef BOOT0_BUILD +#include +#endif + +/* ---- External Variable Declarations ----------------------------------- */ +/* ---- External Function Prototypes ------------------------------------- */ +/* ---- Public Variables ------------------------------------------------- */ +/* ---- Private Constants and Types -------------------------------------- */ +/* ---- Private Function Prototypes -------------------------------------- */ +/* ---- Private Variables ------------------------------------------------ */ +/* ---- Private Functions ------------------------------------------------ */ + +#if NAND_ECC_BCH +/**************************************************************************** +* nand_bch_ecc_flip_bit - Routine to flip an errored bit +* +* PURPOSE: +* This is a helper routine that flips the bit (0 -> 1 or 1 -> 0) of the +* errored bit specified +* +* PARAMETERS: +* datap - Container that holds the 512 byte data +* errorLocation - Location of the bit that needs to be flipped +* +* RETURNS: +* None +****************************************************************************/ +static void nand_bcm_umi_bch_ecc_flip_bit(uint8_t *datap, int errorLocation) +{ + int locWithinAByte = (errorLocation & REG_UMI_BCH_ERR_LOC_BYTE) >> 0; + int locWithinAWord = (errorLocation & REG_UMI_BCH_ERR_LOC_WORD) >> 3; + int locWithinAPage = (errorLocation & REG_UMI_BCH_ERR_LOC_PAGE) >> 5; + + uint8_t errorByte = 0; + uint8_t byteMask = 1 << locWithinAByte; + + /* BCH uses big endian, need to change the location + * bits to little endian */ + locWithinAWord = 3 - locWithinAWord; + + errorByte = datap[locWithinAPage * sizeof(uint32_t) + locWithinAWord]; + +#ifdef BOOT0_BUILD + puthexs("\nECC Correct Offset: ", + locWithinAPage * sizeof(uint32_t) + locWithinAWord); + puthexs(" errorByte:", errorByte); + puthex8(" Bit: ", locWithinAByte); +#endif + + if (errorByte & byteMask) { + /* bit needs to be cleared */ + errorByte &= ~byteMask; + } else { + /* bit needs to be set */ + errorByte |= byteMask; + } + + /* write back the value with the fixed bit */ + datap[locWithinAPage * sizeof(uint32_t) + locWithinAWord] = errorByte; +} + +/**************************************************************************** +* nand_correct_page_bch - Routine to correct bit errors when reading NAND +* +* PURPOSE: +* This routine reads the BCH registers to determine if there are any bit +* errors during the read of the last 512 bytes of data + ECC bytes. If +* errors exists, the routine fixes it. +* +* PARAMETERS: +* datap - Container that holds the 512 byte data +* +* RETURNS: +* 0 or greater = Number of errors corrected +* (No errors are found or errors have been fixed) +* -1 = Error(s) cannot be fixed +****************************************************************************/ +int nand_bcm_umi_bch_correct_page(uint8_t *datap, uint8_t *readEccData, + int numEccBytes) +{ + int numErrors; + int errorLocation; + int idx; + uint32_t regValue; + + /* wait for read ECC to be valid */ + regValue = nand_bcm_umi_bch_poll_read_ecc_calc(); + + /* + * read the control status register to determine if there + * are error'ed bits + * see if errors are correctible + */ + if ((regValue & REG_UMI_BCH_CTRL_STATUS_UNCORR_ERR) > 0) { + int i; + + for (i = 0; i < numEccBytes; i++) { + if (readEccData[i] != 0xff) { + /* errors cannot be fixed, return -1 */ + return -1; + } + } + /* If ECC is unprogrammed then we can't correct, + * assume everything OK */ + return 0; + } + + if ((regValue & REG_UMI_BCH_CTRL_STATUS_CORR_ERR) == 0) { + /* no errors */ + return 0; + } + + /* + * Fix errored bits by doing the following: + * 1. Read the number of errors in the control and status register + * 2. Read the error location registers that corresponds to the number + * of errors reported + * 3. Invert the bit in the data + */ + numErrors = (regValue & REG_UMI_BCH_CTRL_STATUS_NB_CORR_ERROR) >> 20; + + for (idx = 0; idx < numErrors; idx++) { + errorLocation = + REG_UMI_BCH_ERR_LOC_ADDR(idx) & REG_UMI_BCH_ERR_LOC_MASK; + + /* Flip bit */ + nand_bcm_umi_bch_ecc_flip_bit(datap, errorLocation); + } + /* Errors corrected */ + return numErrors; +} +#endif diff --git a/drivers/mtd/nand/nand_bcm_umi.h b/drivers/mtd/nand/nand_bcm_umi.h new file mode 100644 index 0000000..7cec2cd --- /dev/null +++ b/drivers/mtd/nand/nand_bcm_umi.h @@ -0,0 +1,358 @@ +/***************************************************************************** +* Copyright 2003 - 2009 Broadcom Corporation. All rights reserved. +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed to you +* under the terms of the GNU General Public License version 2, available at +* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). +* +* Notwithstanding the above, under no circumstances may you combine this +* software in any way with any other Broadcom software provided under a +* license other than the GPL, without Broadcom's express prior written +* consent. +*****************************************************************************/ +#ifndef NAND_BCM_UMI_H +#define NAND_BCM_UMI_H + +/* ---- Include Files ---------------------------------------------------- */ +#include +#include +#include + +/* ---- Constants and Types ---------------------------------------------- */ +#if (CFG_GLOBAL_CHIP_FAMILY == CFG_GLOBAL_CHIP_FAMILY_BCMRING) +#define NAND_ECC_BCH (CFG_GLOBAL_CHIP_REV > 0xA0) +#else +#define NAND_ECC_BCH 0 +#endif + +#define CFG_GLOBAL_NAND_ECC_BCH_NUM_BYTES 13 + +#if NAND_ECC_BCH +#ifdef BOOT0_BUILD +#define NAND_ECC_NUM_BYTES 13 +#else +#define NAND_ECC_NUM_BYTES CFG_GLOBAL_NAND_ECC_BCH_NUM_BYTES +#endif +#else +#define NAND_ECC_NUM_BYTES 3 +#endif + +#define NAND_DATA_ACCESS_SIZE 512 + +/* ---- Variable Externs ------------------------------------------ */ +/* ---- Function Prototypes --------------------------------------- */ +int nand_bcm_umi_bch_correct_page(uint8_t *datap, uint8_t *readEccData, + int numEccBytes); + +/* Check in device is ready */ +static inline int nand_bcm_umi_dev_ready(void) +{ + return REG_UMI_NAND_RCSR & REG_UMI_NAND_RCSR_RDY; +} + +/* Wait until device is ready */ +static inline void nand_bcm_umi_wait_till_ready(void) +{ + while (nand_bcm_umi_dev_ready() == 0) + ; +} + +/* Enable Hamming ECC */ +static inline void nand_bcm_umi_hamming_enable_hwecc(void) +{ + /* disable and reset ECC, 512 byte page */ + REG_UMI_NAND_ECC_CSR &= ~(REG_UMI_NAND_ECC_CSR_ECC_ENABLE | + REG_UMI_NAND_ECC_CSR_256BYTE); + /* enable ECC */ + REG_UMI_NAND_ECC_CSR |= REG_UMI_NAND_ECC_CSR_ECC_ENABLE; +} + +#if NAND_ECC_BCH +/* BCH ECC specifics */ +#define ECC_BITS_PER_CORRECTABLE_BIT 13 + +/* Enable BCH Read ECC */ +static inline void nand_bcm_umi_bch_enable_read_hwecc(void) +{ + /* disable and reset ECC */ + REG_UMI_BCH_CTRL_STATUS = REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID; + /* Turn on ECC */ + REG_UMI_BCH_CTRL_STATUS = REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN; +} + +/* Enable BCH Write ECC */ +static inline void nand_bcm_umi_bch_enable_write_hwecc(void) +{ + /* disable and reset ECC */ + REG_UMI_BCH_CTRL_STATUS = REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID; + /* Turn on ECC */ + REG_UMI_BCH_CTRL_STATUS = REG_UMI_BCH_CTRL_STATUS_ECC_WR_EN; +} + +/* Config number of BCH ECC bytes */ +static inline void nand_bcm_umi_bch_config_ecc(uint8_t numEccBytes) +{ + uint32_t nValue; + uint32_t tValue; + uint32_t kValue; + uint32_t numBits = numEccBytes * 8; + + /* disable and reset ECC */ + REG_UMI_BCH_CTRL_STATUS = + REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID | + REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID; + + /* Every correctible bit requires 13 ECC bits */ + tValue = (uint32_t) (numBits / ECC_BITS_PER_CORRECTABLE_BIT); + + /* Total data in number of bits for generating and computing BCH ECC */ + nValue = (NAND_DATA_ACCESS_SIZE + numEccBytes) * 8; + + /* K parameter is used internally. K = N - (T * 13) */ + kValue = nValue - (tValue * ECC_BITS_PER_CORRECTABLE_BIT); + + /* Write the settings */ + REG_UMI_BCH_N = nValue; + REG_UMI_BCH_T = tValue; + REG_UMI_BCH_K = kValue; +} + +/* Pause during ECC read calculation to skip bytes in OOB */ +static inline void nand_bcm_umi_bch_pause_read_ecc_calc(void) +{ + REG_UMI_BCH_CTRL_STATUS = + REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN | + REG_UMI_BCH_CTRL_STATUS_PAUSE_ECC_DEC; +} + +/* Resume during ECC read calculation after skipping bytes in OOB */ +static inline void nand_bcm_umi_bch_resume_read_ecc_calc(void) +{ + REG_UMI_BCH_CTRL_STATUS = REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN; +} + +/* Poll read ECC calc to check when hardware completes */ +static inline uint32_t nand_bcm_umi_bch_poll_read_ecc_calc(void) +{ + uint32_t regVal; + + do { + /* wait for ECC to be valid */ + regVal = REG_UMI_BCH_CTRL_STATUS; + } while ((regVal & REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID) == 0); + + return regVal; +} + +/* Poll write ECC calc to check when hardware completes */ +static inline void nand_bcm_umi_bch_poll_write_ecc_calc(void) +{ + /* wait for ECC to be valid */ + while ((REG_UMI_BCH_CTRL_STATUS & REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID) + == 0) + ; +} + +/* Read the OOB and ECC, for kernel write OOB to a buffer */ +#if defined(__KERNEL__) && !defined(STANDALONE) +static inline void nand_bcm_umi_bch_read_oobEcc(uint32_t pageSize, + uint8_t *eccCalc, int numEccBytes, uint8_t *oobp) +#else +static inline void nand_bcm_umi_bch_read_oobEcc(uint32_t pageSize, + uint8_t *eccCalc, int numEccBytes) +#endif +{ + int eccPos = 0; + int numToRead = 16; /* There are 16 bytes per sector in the OOB */ + + /* ECC is already paused when this function is called */ + + if (pageSize == NAND_DATA_ACCESS_SIZE) { + while (numToRead > numEccBytes) { + /* skip free oob region */ +#if defined(__KERNEL__) && !defined(STANDALONE) + *oobp++ = REG_NAND_DATA8; +#else + REG_NAND_DATA8; +#endif + numToRead--; + } + + /* read ECC bytes before BI */ + nand_bcm_umi_bch_resume_read_ecc_calc(); + + while (numToRead > 11) { +#if defined(__KERNEL__) && !defined(STANDALONE) + *oobp = REG_NAND_DATA8; + eccCalc[eccPos++] = *oobp; + oobp++; +#else + eccCalc[eccPos++] = REG_NAND_DATA8; +#endif + } + + nand_bcm_umi_bch_pause_read_ecc_calc(); + + if (numToRead == 11) { + /* read BI */ +#if defined(__KERNEL__) && !defined(STANDALONE) + *oobp++ = REG_NAND_DATA8; +#else + REG_NAND_DATA8; +#endif + numToRead--; + } + + /* read ECC bytes */ + nand_bcm_umi_bch_resume_read_ecc_calc(); + while (numToRead) { +#if defined(__KERNEL__) && !defined(STANDALONE) + *oobp = REG_NAND_DATA8; + eccCalc[eccPos++] = *oobp; + oobp++; +#else + eccCalc[eccPos++] = REG_NAND_DATA8; +#endif + numToRead--; + } + } else { + /* skip BI */ +#if defined(__KERNEL__) && !defined(STANDALONE) + *oobp++ = REG_NAND_DATA8; +#else + REG_NAND_DATA8; +#endif + numToRead--; + + while (numToRead > numEccBytes) { + /* skip free oob region */ +#if defined(__KERNEL__) && !defined(STANDALONE) + *oobp++ = REG_NAND_DATA8; +#else + REG_NAND_DATA8; +#endif + numToRead--; + } + + /* read ECC bytes */ + nand_bcm_umi_bch_resume_read_ecc_calc(); + while (numToRead) { +#if defined(__KERNEL__) && !defined(STANDALONE) + *oobp = REG_NAND_DATA8; + eccCalc[eccPos++] = *oobp; + oobp++; +#else + eccCalc[eccPos++] = REG_NAND_DATA8; +#endif + numToRead--; + } + } +} + +/* Helper function to write ECC */ +static inline void NAND_BCM_UMI_ECC_WRITE(int numEccBytes, int eccBytePos, + uint8_t *oobp, uint8_t eccVal) +{ + if (eccBytePos <= numEccBytes) + *oobp = eccVal; +} + +/* Write OOB with ECC */ +static inline void nand_bcm_umi_bch_write_oobEcc(uint32_t pageSize, + uint8_t *oobp, int numEccBytes) +{ + uint32_t eccVal = 0xffffffff; + + /* wait for write ECC to be valid */ + nand_bcm_umi_bch_poll_write_ecc_calc(); + + /* + ** Get the hardware ecc from the 32-bit result registers. + ** Read after 512 byte accesses. Format B3B2B1B0 + ** where B3 = ecc3, etc. + */ + + if (pageSize == NAND_DATA_ACCESS_SIZE) { + /* Now fill in the ECC bytes */ + if (numEccBytes >= 13) + eccVal = REG_UMI_BCH_WR_ECC_3; + + /* Usually we skip CM in oob[0,1] */ + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 15, &oobp[0], + (eccVal >> 16) & 0xff); + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 14, &oobp[1], + (eccVal >> 8) & 0xff); + + /* Write ECC in oob[2,3,4] */ + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 13, &oobp[2], + eccVal & 0xff); /* ECC 12 */ + + if (numEccBytes >= 9) + eccVal = REG_UMI_BCH_WR_ECC_2; + + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 12, &oobp[3], + (eccVal >> 24) & 0xff); /* ECC11 */ + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 11, &oobp[4], + (eccVal >> 16) & 0xff); /* ECC10 */ + + /* Always Skip BI in oob[5] */ + } else { + /* Always Skip BI in oob[0] */ + + /* Now fill in the ECC bytes */ + if (numEccBytes >= 13) + eccVal = REG_UMI_BCH_WR_ECC_3; + + /* Usually skip CM in oob[1,2] */ + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 15, &oobp[1], + (eccVal >> 16) & 0xff); + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 14, &oobp[2], + (eccVal >> 8) & 0xff); + + /* Write ECC in oob[3-15] */ + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 13, &oobp[3], + eccVal & 0xff); /* ECC12 */ + + if (numEccBytes >= 9) + eccVal = REG_UMI_BCH_WR_ECC_2; + + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 12, &oobp[4], + (eccVal >> 24) & 0xff); /* ECC11 */ + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 11, &oobp[5], + (eccVal >> 16) & 0xff); /* ECC10 */ + } + + /* Fill in the remainder of ECC locations */ + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 10, &oobp[6], + (eccVal >> 8) & 0xff); /* ECC9 */ + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 9, &oobp[7], + eccVal & 0xff); /* ECC8 */ + + if (numEccBytes >= 5) + eccVal = REG_UMI_BCH_WR_ECC_1; + + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 8, &oobp[8], + (eccVal >> 24) & 0xff); /* ECC7 */ + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 7, &oobp[9], + (eccVal >> 16) & 0xff); /* ECC6 */ + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 6, &oobp[10], + (eccVal >> 8) & 0xff); /* ECC5 */ + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 5, &oobp[11], + eccVal & 0xff); /* ECC4 */ + + if (numEccBytes >= 1) + eccVal = REG_UMI_BCH_WR_ECC_0; + + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 4, &oobp[12], + (eccVal >> 24) & 0xff); /* ECC3 */ + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 3, &oobp[13], + (eccVal >> 16) & 0xff); /* ECC2 */ + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 2, &oobp[14], + (eccVal >> 8) & 0xff); /* ECC1 */ + NAND_BCM_UMI_ECC_WRITE(numEccBytes, 1, &oobp[15], + eccVal & 0xff); /* ECC0 */ +} +#endif + +#endif /* NAND_BCM_UMI_H */ -- cgit v0.10.2 From 6f4e137e9af8745ccaddaf5dcb037a1175089e1c Mon Sep 17 00:00:00 2001 From: hartleys Date: Fri, 16 Oct 2009 12:52:53 +0000 Subject: mtd_blkdevs.c: quiet a "symbol shadows" sparse warning In register_mtd_blktrans(), the symbol 'ret' is already declared as an int at the start of the function. The inner loop declaration is unnecessary. Quiets the following sparse warning: warning: symbol 'ret' shadows an earlier one Signed-off-by: H Hartley Sweeten Signed-off-by: David Woodhouse diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 0acbf4f..955226d 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -388,7 +388,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) tr->blkcore_priv->thread = kthread_run(mtd_blktrans_thread, tr, "%sd", tr->name); if (IS_ERR(tr->blkcore_priv->thread)) { - int ret = PTR_ERR(tr->blkcore_priv->thread); + ret = PTR_ERR(tr->blkcore_priv->thread); blk_cleanup_queue(tr->blkcore_priv->rq); unregister_blkdev(tr->major, tr->name); kfree(tr->blkcore_priv); -- cgit v0.10.2 From 1cc523999e0acd0c21f83bf89b7a44b4ab6f7bd8 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 20 Oct 2009 22:02:41 +0900 Subject: Revert "mtd: mxc_nand: fix 2KiB pagesize NAND on i.MX27" This reverts commit 71b7d0d90d536ae4e70929cc59a1a9f6ba457c6c. The problem which that commit attempted to fix was a bootloader issue, which had been misunderstood. The 'fix' causes lots of false bad blocks for existing users with sane firmware. Thanks to Mathieu Berland for diagnosing the problem coherently. Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index ef3e199..06c5314 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -857,17 +857,6 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, } } -/* Define some generic bad / good block scan pattern which are used - * while scanning a device for factory marked good / bad blocks. */ -static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; - -static struct nand_bbt_descr smallpage_memorybased = { - .options = NAND_BBT_SCAN2NDPAGE, - .offs = 5, - .len = 1, - .pattern = scan_ff_pattern -}; - static int __init mxcnd_probe(struct platform_device *pdev) { struct nand_chip *this; @@ -984,10 +973,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) goto escan; } - if (mtd->writesize == 2048) { - host->pagesize_2k = 1; - this->badblock_pattern = &smallpage_memorybased; - } + host->pagesize_2k = (mtd->writesize == 2048) ? 1 : 0; if (this->ecc.mode == NAND_ECC_HW) { switch (mtd->oobsize) { -- cgit v0.10.2 From 8ce110ac19bc88b82e3feacfbb3a2ee08a07fe22 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 20 Oct 2009 12:23:33 -0400 Subject: mtd: Fix compile failure and error path in physmap.c Commit 4b56ffcacee937a85bf39e14872dd141e23ee85f ("mtd: Fix kernel NULL pointer dereference in physmap.c") introduced a couple of bugs. It neglected to run the loop of map_destroy() calls in physmap_flash_remove(), if !info->cmtd, which would happen if that function was called to clean up errors during probe. It also failed to compile if CONFIG_MTD_PARTITIONS was not defined. Reported-By: Atsushi Nemoto Signed-off-by: H Hartley Sweeten Signed-off-by: David Woodhouse diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 65f52d4..3f13a96 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c @@ -44,12 +44,10 @@ static int physmap_flash_remove(struct platform_device *dev) return 0; platform_set_drvdata(dev, NULL); - if (info->cmtd == NULL) - return 0; - physmap_data = dev->dev.platform_data; - if (mtd_has_partitions()) { + if (info->cmtd) { +#ifdef CONFIG_MTD_PARTITIONS if (info->nr_parts || physmap_data->nr_parts) { del_mtd_partitions(info->cmtd); @@ -58,14 +56,14 @@ static int physmap_flash_remove(struct platform_device *dev) } else { del_mtd_device(info->cmtd); } - } else { +#else del_mtd_device(info->cmtd); - } - +#endif #ifdef CONFIG_MTD_CONCAT - if (info->cmtd != info->mtd[0]) - mtd_concat_destroy(info->cmtd); + if (info->cmtd != info->mtd[0]) + mtd_concat_destroy(info->cmtd); #endif + } for (i = 0; i < MAX_RESOURCES; i++) { if (info->mtd[i] != NULL) @@ -170,22 +168,22 @@ static int physmap_flash_probe(struct platform_device *dev) if (err) goto err_out; - if (mtd_has_partitions()) { - err = parse_mtd_partitions(info->cmtd, part_probe_types, - &info->parts, 0); - if (err > 0) { - add_mtd_partitions(info->cmtd, info->parts, err); - info->nr_parts = err; - return 0; - } +#ifdef CONFIG_MTD_PARTITIONS + err = parse_mtd_partitions(info->cmtd, part_probe_types, + &info->parts, 0); + if (err > 0) { + add_mtd_partitions(info->cmtd, info->parts, err); + info->nr_parts = err; + return 0; + } - if (physmap_data->nr_parts) { - printk(KERN_NOTICE "Using physmap partition information\n"); - add_mtd_partitions(info->cmtd, physmap_data->parts, - physmap_data->nr_parts); - return 0; - } + if (physmap_data->nr_parts) { + printk(KERN_NOTICE "Using physmap partition information\n"); + add_mtd_partitions(info->cmtd, physmap_data->parts, + physmap_data->nr_parts); + return 0; } +#endif add_mtd_device(info->cmtd); return 0; -- cgit v0.10.2 From dc7a08166f3a5f23e79e839a8a88849bd3397c32 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Tue, 27 Oct 2009 14:41:35 -0400 Subject: nfs: new subdir Documentation/filesystems/nfs We're adding enough nfs documentation that it may as well have its own subdirectory. Acked-by: Randy Dunlap Signed-off-by: J. Bruce Fields diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX index f15621e..482151c 100644 --- a/Documentation/filesystems/00-INDEX +++ b/Documentation/filesystems/00-INDEX @@ -1,7 +1,5 @@ 00-INDEX - this file (info on some of the filesystems supported by linux). -Exporting - - explanation of how to make filesystems exportable. Locking - info on locking rules as they pertain to Linux VFS. 9p.txt @@ -66,12 +64,8 @@ mandatory-locking.txt - info on the Linux implementation of Sys V mandatory file locking. ncpfs.txt - info on Novell Netware(tm) filesystem using NCP protocol. -nfs41-server.txt - - info on the Linux server implementation of NFSv4 minor version 1. -nfs-rdma.txt - - how to install and setup the Linux NFS/RDMA client and server software. -nfsroot.txt - - short guide on setting up a diskless box with NFS root filesystem. +nfs/ + - nfs-related documentation. nilfs2.txt - info and mount options for the NILFS2 filesystem. ntfs.txt diff --git a/Documentation/filesystems/Exporting b/Documentation/filesystems/Exporting deleted file mode 100644 index 87019d2..0000000 --- a/Documentation/filesystems/Exporting +++ /dev/null @@ -1,147 +0,0 @@ - -Making Filesystems Exportable -============================= - -Overview --------- - -All filesystem operations require a dentry (or two) as a starting -point. Local applications have a reference-counted hold on suitable -dentries via open file descriptors or cwd/root. However remote -applications that access a filesystem via a remote filesystem protocol -such as NFS may not be able to hold such a reference, and so need a -different way to refer to a particular dentry. As the alternative -form of reference needs to be stable across renames, truncates, and -server-reboot (among other things, though these tend to be the most -problematic), there is no simple answer like 'filename'. - -The mechanism discussed here allows each filesystem implementation to -specify how to generate an opaque (outside of the filesystem) byte -string for any dentry, and how to find an appropriate dentry for any -given opaque byte string. -This byte string will be called a "filehandle fragment" as it -corresponds to part of an NFS filehandle. - -A filesystem which supports the mapping between filehandle fragments -and dentries will be termed "exportable". - - - -Dcache Issues -------------- - -The dcache normally contains a proper prefix of any given filesystem -tree. This means that if any filesystem object is in the dcache, then -all of the ancestors of that filesystem object are also in the dcache. -As normal access is by filename this prefix is created naturally and -maintained easily (by each object maintaining a reference count on -its parent). - -However when objects are included into the dcache by interpreting a -filehandle fragment, there is no automatic creation of a path prefix -for the object. This leads to two related but distinct features of -the dcache that are not needed for normal filesystem access. - -1/ The dcache must sometimes contain objects that are not part of the - proper prefix. i.e that are not connected to the root. -2/ The dcache must be prepared for a newly found (via ->lookup) directory - to already have a (non-connected) dentry, and must be able to move - that dentry into place (based on the parent and name in the - ->lookup). This is particularly needed for directories as - it is a dcache invariant that directories only have one dentry. - -To implement these features, the dcache has: - -a/ A dentry flag DCACHE_DISCONNECTED which is set on - any dentry that might not be part of the proper prefix. - This is set when anonymous dentries are created, and cleared when a - dentry is noticed to be a child of a dentry which is in the proper - prefix. - -b/ A per-superblock list "s_anon" of dentries which are the roots of - subtrees that are not in the proper prefix. These dentries, as - well as the proper prefix, need to be released at unmount time. As - these dentries will not be hashed, they are linked together on the - d_hash list_head. - -c/ Helper routines to allocate anonymous dentries, and to help attach - loose directory dentries at lookup time. They are: - d_alloc_anon(inode) will return a dentry for the given inode. - If the inode already has a dentry, one of those is returned. - If it doesn't, a new anonymous (IS_ROOT and - DCACHE_DISCONNECTED) dentry is allocated and attached. - In the case of a directory, care is taken that only one dentry - can ever be attached. - d_splice_alias(inode, dentry) will make sure that there is a - dentry with the same name and parent as the given dentry, and - which refers to the given inode. - If the inode is a directory and already has a dentry, then that - dentry is d_moved over the given dentry. - If the passed dentry gets attached, care is taken that this is - mutually exclusive to a d_alloc_anon operation. - If the passed dentry is used, NULL is returned, else the used - dentry is returned. This corresponds to the calling pattern of - ->lookup. - - -Filesystem Issues ------------------ - -For a filesystem to be exportable it must: - - 1/ provide the filehandle fragment routines described below. - 2/ make sure that d_splice_alias is used rather than d_add - when ->lookup finds an inode for a given parent and name. - Typically the ->lookup routine will end with a: - - return d_splice_alias(inode, dentry); - } - - - - A file system implementation declares that instances of the filesystem -are exportable by setting the s_export_op field in the struct -super_block. This field must point to a "struct export_operations" -struct which has the following members: - - encode_fh (optional) - Takes a dentry and creates a filehandle fragment which can later be used - to find or create a dentry for the same object. The default - implementation creates a filehandle fragment that encodes a 32bit inode - and generation number for the inode encoded, and if necessary the - same information for the parent. - - fh_to_dentry (mandatory) - Given a filehandle fragment, this should find the implied object and - create a dentry for it (possibly with d_alloc_anon). - - fh_to_parent (optional but strongly recommended) - Given a filehandle fragment, this should find the parent of the - implied object and create a dentry for it (possibly with d_alloc_anon). - May fail if the filehandle fragment is too small. - - get_parent (optional but strongly recommended) - When given a dentry for a directory, this should return a dentry for - the parent. Quite possibly the parent dentry will have been allocated - by d_alloc_anon. The default get_parent function just returns an error - so any filehandle lookup that requires finding a parent will fail. - ->lookup("..") is *not* used as a default as it can leave ".." entries - in the dcache which are too messy to work with. - - get_name (optional) - When given a parent dentry and a child dentry, this should find a name - in the directory identified by the parent dentry, which leads to the - object identified by the child dentry. If no get_name function is - supplied, a default implementation is provided which uses vfs_readdir - to find potential names, and matches inode numbers to find the correct - match. - - -A filehandle fragment consists of an array of 1 or more 4byte words, -together with a one byte "type". -The decode_fh routine should not depend on the stated size that is -passed to it. This size may be larger than the original filehandle -generated by encode_fh, in which case it will have been padded with -nuls. Rather, the encode_fh routine should choose a "type" which -indicates the decode_fh how much of the filehandle is valid, and how -it should be interpreted. diff --git a/Documentation/filesystems/nfs-rdma.txt b/Documentation/filesystems/nfs-rdma.txt deleted file mode 100644 index e386f7e..0000000 --- a/Documentation/filesystems/nfs-rdma.txt +++ /dev/null @@ -1,271 +0,0 @@ -################################################################################ -# # -# NFS/RDMA README # -# # -################################################################################ - - Author: NetApp and Open Grid Computing - Date: May 29, 2008 - -Table of Contents -~~~~~~~~~~~~~~~~~ - - Overview - - Getting Help - - Installation - - Check RDMA and NFS Setup - - NFS/RDMA Setup - -Overview -~~~~~~~~ - - This document describes how to install and setup the Linux NFS/RDMA client - and server software. - - The NFS/RDMA client was first included in Linux 2.6.24. The NFS/RDMA server - was first included in the following release, Linux 2.6.25. - - In our testing, we have obtained excellent performance results (full 10Gbit - wire bandwidth at minimal client CPU) under many workloads. The code passes - the full Connectathon test suite and operates over both Infiniband and iWARP - RDMA adapters. - -Getting Help -~~~~~~~~~~~~ - - If you get stuck, you can ask questions on the - - nfs-rdma-devel@lists.sourceforge.net - - mailing list. - -Installation -~~~~~~~~~~~~ - - These instructions are a step by step guide to building a machine for - use with NFS/RDMA. - - - Install an RDMA device - - Any device supported by the drivers in drivers/infiniband/hw is acceptable. - - Testing has been performed using several Mellanox-based IB cards, the - Ammasso AMS1100 iWARP adapter, and the Chelsio cxgb3 iWARP adapter. - - - Install a Linux distribution and tools - - The first kernel release to contain both the NFS/RDMA client and server was - Linux 2.6.25 Therefore, a distribution compatible with this and subsequent - Linux kernel release should be installed. - - The procedures described in this document have been tested with - distributions from Red Hat's Fedora Project (http://fedora.redhat.com/). - - - Install nfs-utils-1.1.2 or greater on the client - - An NFS/RDMA mount point can be obtained by using the mount.nfs command in - nfs-utils-1.1.2 or greater (nfs-utils-1.1.1 was the first nfs-utils - version with support for NFS/RDMA mounts, but for various reasons we - recommend using nfs-utils-1.1.2 or greater). To see which version of - mount.nfs you are using, type: - - $ /sbin/mount.nfs -V - - If the version is less than 1.1.2 or the command does not exist, - you should install the latest version of nfs-utils. - - Download the latest package from: - - http://www.kernel.org/pub/linux/utils/nfs - - Uncompress the package and follow the installation instructions. - - If you will not need the idmapper and gssd executables (you do not need - these to create an NFS/RDMA enabled mount command), the installation - process can be simplified by disabling these features when running - configure: - - $ ./configure --disable-gss --disable-nfsv4 - - To build nfs-utils you will need the tcp_wrappers package installed. For - more information on this see the package's README and INSTALL files. - - After building the nfs-utils package, there will be a mount.nfs binary in - the utils/mount directory. This binary can be used to initiate NFS v2, v3, - or v4 mounts. To initiate a v4 mount, the binary must be called - mount.nfs4. The standard technique is to create a symlink called - mount.nfs4 to mount.nfs. - - This mount.nfs binary should be installed at /sbin/mount.nfs as follows: - - $ sudo cp utils/mount/mount.nfs /sbin/mount.nfs - - In this location, mount.nfs will be invoked automatically for NFS mounts - by the system mount command. - - NOTE: mount.nfs and therefore nfs-utils-1.1.2 or greater is only needed - on the NFS client machine. You do not need this specific version of - nfs-utils on the server. Furthermore, only the mount.nfs command from - nfs-utils-1.1.2 is needed on the client. - - - Install a Linux kernel with NFS/RDMA - - The NFS/RDMA client and server are both included in the mainline Linux - kernel version 2.6.25 and later. This and other versions of the 2.6 Linux - kernel can be found at: - - ftp://ftp.kernel.org/pub/linux/kernel/v2.6/ - - Download the sources and place them in an appropriate location. - - - Configure the RDMA stack - - Make sure your kernel configuration has RDMA support enabled. Under - Device Drivers -> InfiniBand support, update the kernel configuration - to enable InfiniBand support [NOTE: the option name is misleading. Enabling - InfiniBand support is required for all RDMA devices (IB, iWARP, etc.)]. - - Enable the appropriate IB HCA support (mlx4, mthca, ehca, ipath, etc.) or - iWARP adapter support (amso, cxgb3, etc.). - - If you are using InfiniBand, be sure to enable IP-over-InfiniBand support. - - - Configure the NFS client and server - - Your kernel configuration must also have NFS file system support and/or - NFS server support enabled. These and other NFS related configuration - options can be found under File Systems -> Network File Systems. - - - Build, install, reboot - - The NFS/RDMA code will be enabled automatically if NFS and RDMA - are turned on. The NFS/RDMA client and server are configured via the hidden - SUNRPC_XPRT_RDMA config option that depends on SUNRPC and INFINIBAND. The - value of SUNRPC_XPRT_RDMA will be: - - - N if either SUNRPC or INFINIBAND are N, in this case the NFS/RDMA client - and server will not be built - - M if both SUNRPC and INFINIBAND are on (M or Y) and at least one is M, - in this case the NFS/RDMA client and server will be built as modules - - Y if both SUNRPC and INFINIBAND are Y, in this case the NFS/RDMA client - and server will be built into the kernel - - Therefore, if you have followed the steps above and turned no NFS and RDMA, - the NFS/RDMA client and server will be built. - - Build a new kernel, install it, boot it. - -Check RDMA and NFS Setup -~~~~~~~~~~~~~~~~~~~~~~~~ - - Before configuring the NFS/RDMA software, it is a good idea to test - your new kernel to ensure that the kernel is working correctly. - In particular, it is a good idea to verify that the RDMA stack - is functioning as expected and standard NFS over TCP/IP and/or UDP/IP - is working properly. - - - Check RDMA Setup - - If you built the RDMA components as modules, load them at - this time. For example, if you are using a Mellanox Tavor/Sinai/Arbel - card: - - $ modprobe ib_mthca - $ modprobe ib_ipoib - - If you are using InfiniBand, make sure there is a Subnet Manager (SM) - running on the network. If your IB switch has an embedded SM, you can - use it. Otherwise, you will need to run an SM, such as OpenSM, on one - of your end nodes. - - If an SM is running on your network, you should see the following: - - $ cat /sys/class/infiniband/driverX/ports/1/state - 4: ACTIVE - - where driverX is mthca0, ipath5, ehca3, etc. - - To further test the InfiniBand software stack, use IPoIB (this - assumes you have two IB hosts named host1 and host2): - - host1$ ifconfig ib0 a.b.c.x - host2$ ifconfig ib0 a.b.c.y - host1$ ping a.b.c.y - host2$ ping a.b.c.x - - For other device types, follow the appropriate procedures. - - - Check NFS Setup - - For the NFS components enabled above (client and/or server), - test their functionality over standard Ethernet using TCP/IP or UDP/IP. - -NFS/RDMA Setup -~~~~~~~~~~~~~~ - - We recommend that you use two machines, one to act as the client and - one to act as the server. - - One time configuration: - - - On the server system, configure the /etc/exports file and - start the NFS/RDMA server. - - Exports entries with the following formats have been tested: - - /vol0 192.168.0.47(fsid=0,rw,async,insecure,no_root_squash) - /vol0 192.168.0.0/255.255.255.0(fsid=0,rw,async,insecure,no_root_squash) - - The IP address(es) is(are) the client's IPoIB address for an InfiniBand - HCA or the cleint's iWARP address(es) for an RNIC. - - NOTE: The "insecure" option must be used because the NFS/RDMA client does - not use a reserved port. - - Each time a machine boots: - - - Load and configure the RDMA drivers - - For InfiniBand using a Mellanox adapter: - - $ modprobe ib_mthca - $ modprobe ib_ipoib - $ ifconfig ib0 a.b.c.d - - NOTE: use unique addresses for the client and server - - - Start the NFS server - - If the NFS/RDMA server was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in - kernel config), load the RDMA transport module: - - $ modprobe svcrdma - - Regardless of how the server was built (module or built-in), start the - server: - - $ /etc/init.d/nfs start - - or - - $ service nfs start - - Instruct the server to listen on the RDMA transport: - - $ echo rdma 20049 > /proc/fs/nfsd/portlist - - - On the client system - - If the NFS/RDMA client was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in - kernel config), load the RDMA client module: - - $ modprobe xprtrdma.ko - - Regardless of how the client was built (module or built-in), use this - command to mount the NFS/RDMA server: - - $ mount -o rdma,port=20049 :/ /mnt - - To verify that the mount is using RDMA, run "cat /proc/mounts" and check - the "proto" field for the given mount. - - Congratulations! You're using NFS/RDMA! diff --git a/Documentation/filesystems/nfs.txt b/Documentation/filesystems/nfs.txt deleted file mode 100644 index f50f26c..0000000 --- a/Documentation/filesystems/nfs.txt +++ /dev/null @@ -1,98 +0,0 @@ - -The NFS client -============== - -The NFS version 2 protocol was first documented in RFC1094 (March 1989). -Since then two more major releases of NFS have been published, with NFSv3 -being documented in RFC1813 (June 1995), and NFSv4 in RFC3530 (April -2003). - -The Linux NFS client currently supports all the above published versions, -and work is in progress on adding support for minor version 1 of the NFSv4 -protocol. - -The purpose of this document is to provide information on some of the -upcall interfaces that are used in order to provide the NFS client with -some of the information that it requires in order to fully comply with -the NFS spec. - -The DNS resolver -================ - -NFSv4 allows for one server to refer the NFS client to data that has been -migrated onto another server by means of the special "fs_locations" -attribute. See - http://tools.ietf.org/html/rfc3530#section-6 -and - http://tools.ietf.org/html/draft-ietf-nfsv4-referrals-00 - -The fs_locations information can take the form of either an ip address and -a path, or a DNS hostname and a path. The latter requires the NFS client to -do a DNS lookup in order to mount the new volume, and hence the need for an -upcall to allow userland to provide this service. - -Assuming that the user has the 'rpc_pipefs' filesystem mounted in the usual -/var/lib/nfs/rpc_pipefs, the upcall consists of the following steps: - - (1) The process checks the dns_resolve cache to see if it contains a - valid entry. If so, it returns that entry and exits. - - (2) If no valid entry exists, the helper script '/sbin/nfs_cache_getent' - (may be changed using the 'nfs.cache_getent' kernel boot parameter) - is run, with two arguments: - - the cache name, "dns_resolve" - - the hostname to resolve - - (3) After looking up the corresponding ip address, the helper script - writes the result into the rpc_pipefs pseudo-file - '/var/lib/nfs/rpc_pipefs/cache/dns_resolve/channel' - in the following (text) format: - - " \n" - - Where is in the usual IPv4 (123.456.78.90) or IPv6 - (ffee:ddcc:bbaa:9988:7766:5544:3322:1100, ffee::1100, ...) format. - is identical to the second argument of the helper - script, and is the 'time to live' of this cache entry (in - units of seconds). - - Note: If is invalid, say the string "0", then a negative - entry is created, which will cause the kernel to treat the hostname - as having no valid DNS translation. - - - - -A basic sample /sbin/nfs_cache_getent -===================================== - -#!/bin/bash -# -ttl=600 -# -cut=/usr/bin/cut -getent=/usr/bin/getent -rpc_pipefs=/var/lib/nfs/rpc_pipefs -# -die() -{ - echo "Usage: $0 cache_name entry_name" - exit 1 -} - -[ $# -lt 2 ] && die -cachename="$1" -cache_path=${rpc_pipefs}/cache/${cachename}/channel - -case "${cachename}" in - dns_resolve) - name="$2" - result="$(${getent} hosts ${name} | ${cut} -f1 -d\ )" - [ -z "${result}" ] && result="0" - ;; - *) - die - ;; -esac -echo "${result} ${name} ${ttl}" >${cache_path} - diff --git a/Documentation/filesystems/nfs/00-INDEX b/Documentation/filesystems/nfs/00-INDEX new file mode 100644 index 0000000..6ff3d21 --- /dev/null +++ b/Documentation/filesystems/nfs/00-INDEX @@ -0,0 +1,12 @@ +00-INDEX + - this file (nfs-related documentation). +Exporting + - explanation of how to make filesystems exportable. +nfs.txt + - nfs client, and DNS resolution for fs_locations. +nfs41-server.txt + - info on the Linux server implementation of NFSv4 minor version 1. +nfs-rdma.txt + - how to install and setup the Linux NFS/RDMA client and server software +nfsroot.txt + - short guide on setting up a diskless box with NFS root filesystem. diff --git a/Documentation/filesystems/nfs/Exporting b/Documentation/filesystems/nfs/Exporting new file mode 100644 index 0000000..87019d2 --- /dev/null +++ b/Documentation/filesystems/nfs/Exporting @@ -0,0 +1,147 @@ + +Making Filesystems Exportable +============================= + +Overview +-------- + +All filesystem operations require a dentry (or two) as a starting +point. Local applications have a reference-counted hold on suitable +dentries via open file descriptors or cwd/root. However remote +applications that access a filesystem via a remote filesystem protocol +such as NFS may not be able to hold such a reference, and so need a +different way to refer to a particular dentry. As the alternative +form of reference needs to be stable across renames, truncates, and +server-reboot (among other things, though these tend to be the most +problematic), there is no simple answer like 'filename'. + +The mechanism discussed here allows each filesystem implementation to +specify how to generate an opaque (outside of the filesystem) byte +string for any dentry, and how to find an appropriate dentry for any +given opaque byte string. +This byte string will be called a "filehandle fragment" as it +corresponds to part of an NFS filehandle. + +A filesystem which supports the mapping between filehandle fragments +and dentries will be termed "exportable". + + + +Dcache Issues +------------- + +The dcache normally contains a proper prefix of any given filesystem +tree. This means that if any filesystem object is in the dcache, then +all of the ancestors of that filesystem object are also in the dcache. +As normal access is by filename this prefix is created naturally and +maintained easily (by each object maintaining a reference count on +its parent). + +However when objects are included into the dcache by interpreting a +filehandle fragment, there is no automatic creation of a path prefix +for the object. This leads to two related but distinct features of +the dcache that are not needed for normal filesystem access. + +1/ The dcache must sometimes contain objects that are not part of the + proper prefix. i.e that are not connected to the root. +2/ The dcache must be prepared for a newly found (via ->lookup) directory + to already have a (non-connected) dentry, and must be able to move + that dentry into place (based on the parent and name in the + ->lookup). This is particularly needed for directories as + it is a dcache invariant that directories only have one dentry. + +To implement these features, the dcache has: + +a/ A dentry flag DCACHE_DISCONNECTED which is set on + any dentry that might not be part of the proper prefix. + This is set when anonymous dentries are created, and cleared when a + dentry is noticed to be a child of a dentry which is in the proper + prefix. + +b/ A per-superblock list "s_anon" of dentries which are the roots of + subtrees that are not in the proper prefix. These dentries, as + well as the proper prefix, need to be released at unmount time. As + these dentries will not be hashed, they are linked together on the + d_hash list_head. + +c/ Helper routines to allocate anonymous dentries, and to help attach + loose directory dentries at lookup time. They are: + d_alloc_anon(inode) will return a dentry for the given inode. + If the inode already has a dentry, one of those is returned. + If it doesn't, a new anonymous (IS_ROOT and + DCACHE_DISCONNECTED) dentry is allocated and attached. + In the case of a directory, care is taken that only one dentry + can ever be attached. + d_splice_alias(inode, dentry) will make sure that there is a + dentry with the same name and parent as the given dentry, and + which refers to the given inode. + If the inode is a directory and already has a dentry, then that + dentry is d_moved over the given dentry. + If the passed dentry gets attached, care is taken that this is + mutually exclusive to a d_alloc_anon operation. + If the passed dentry is used, NULL is returned, else the used + dentry is returned. This corresponds to the calling pattern of + ->lookup. + + +Filesystem Issues +----------------- + +For a filesystem to be exportable it must: + + 1/ provide the filehandle fragment routines described below. + 2/ make sure that d_splice_alias is used rather than d_add + when ->lookup finds an inode for a given parent and name. + Typically the ->lookup routine will end with a: + + return d_splice_alias(inode, dentry); + } + + + + A file system implementation declares that instances of the filesystem +are exportable by setting the s_export_op field in the struct +super_block. This field must point to a "struct export_operations" +struct which has the following members: + + encode_fh (optional) + Takes a dentry and creates a filehandle fragment which can later be used + to find or create a dentry for the same object. The default + implementation creates a filehandle fragment that encodes a 32bit inode + and generation number for the inode encoded, and if necessary the + same information for the parent. + + fh_to_dentry (mandatory) + Given a filehandle fragment, this should find the implied object and + create a dentry for it (possibly with d_alloc_anon). + + fh_to_parent (optional but strongly recommended) + Given a filehandle fragment, this should find the parent of the + implied object and create a dentry for it (possibly with d_alloc_anon). + May fail if the filehandle fragment is too small. + + get_parent (optional but strongly recommended) + When given a dentry for a directory, this should return a dentry for + the parent. Quite possibly the parent dentry will have been allocated + by d_alloc_anon. The default get_parent function just returns an error + so any filehandle lookup that requires finding a parent will fail. + ->lookup("..") is *not* used as a default as it can leave ".." entries + in the dcache which are too messy to work with. + + get_name (optional) + When given a parent dentry and a child dentry, this should find a name + in the directory identified by the parent dentry, which leads to the + object identified by the child dentry. If no get_name function is + supplied, a default implementation is provided which uses vfs_readdir + to find potential names, and matches inode numbers to find the correct + match. + + +A filehandle fragment consists of an array of 1 or more 4byte words, +together with a one byte "type". +The decode_fh routine should not depend on the stated size that is +passed to it. This size may be larger than the original filehandle +generated by encode_fh, in which case it will have been padded with +nuls. Rather, the encode_fh routine should choose a "type" which +indicates the decode_fh how much of the filehandle is valid, and how +it should be interpreted. diff --git a/Documentation/filesystems/nfs/nfs-rdma.txt b/Documentation/filesystems/nfs/nfs-rdma.txt new file mode 100644 index 0000000..e386f7e --- /dev/null +++ b/Documentation/filesystems/nfs/nfs-rdma.txt @@ -0,0 +1,271 @@ +################################################################################ +# # +# NFS/RDMA README # +# # +################################################################################ + + Author: NetApp and Open Grid Computing + Date: May 29, 2008 + +Table of Contents +~~~~~~~~~~~~~~~~~ + - Overview + - Getting Help + - Installation + - Check RDMA and NFS Setup + - NFS/RDMA Setup + +Overview +~~~~~~~~ + + This document describes how to install and setup the Linux NFS/RDMA client + and server software. + + The NFS/RDMA client was first included in Linux 2.6.24. The NFS/RDMA server + was first included in the following release, Linux 2.6.25. + + In our testing, we have obtained excellent performance results (full 10Gbit + wire bandwidth at minimal client CPU) under many workloads. The code passes + the full Connectathon test suite and operates over both Infiniband and iWARP + RDMA adapters. + +Getting Help +~~~~~~~~~~~~ + + If you get stuck, you can ask questions on the + + nfs-rdma-devel@lists.sourceforge.net + + mailing list. + +Installation +~~~~~~~~~~~~ + + These instructions are a step by step guide to building a machine for + use with NFS/RDMA. + + - Install an RDMA device + + Any device supported by the drivers in drivers/infiniband/hw is acceptable. + + Testing has been performed using several Mellanox-based IB cards, the + Ammasso AMS1100 iWARP adapter, and the Chelsio cxgb3 iWARP adapter. + + - Install a Linux distribution and tools + + The first kernel release to contain both the NFS/RDMA client and server was + Linux 2.6.25 Therefore, a distribution compatible with this and subsequent + Linux kernel release should be installed. + + The procedures described in this document have been tested with + distributions from Red Hat's Fedora Project (http://fedora.redhat.com/). + + - Install nfs-utils-1.1.2 or greater on the client + + An NFS/RDMA mount point can be obtained by using the mount.nfs command in + nfs-utils-1.1.2 or greater (nfs-utils-1.1.1 was the first nfs-utils + version with support for NFS/RDMA mounts, but for various reasons we + recommend using nfs-utils-1.1.2 or greater). To see which version of + mount.nfs you are using, type: + + $ /sbin/mount.nfs -V + + If the version is less than 1.1.2 or the command does not exist, + you should install the latest version of nfs-utils. + + Download the latest package from: + + http://www.kernel.org/pub/linux/utils/nfs + + Uncompress the package and follow the installation instructions. + + If you will not need the idmapper and gssd executables (you do not need + these to create an NFS/RDMA enabled mount command), the installation + process can be simplified by disabling these features when running + configure: + + $ ./configure --disable-gss --disable-nfsv4 + + To build nfs-utils you will need the tcp_wrappers package installed. For + more information on this see the package's README and INSTALL files. + + After building the nfs-utils package, there will be a mount.nfs binary in + the utils/mount directory. This binary can be used to initiate NFS v2, v3, + or v4 mounts. To initiate a v4 mount, the binary must be called + mount.nfs4. The standard technique is to create a symlink called + mount.nfs4 to mount.nfs. + + This mount.nfs binary should be installed at /sbin/mount.nfs as follows: + + $ sudo cp utils/mount/mount.nfs /sbin/mount.nfs + + In this location, mount.nfs will be invoked automatically for NFS mounts + by the system mount command. + + NOTE: mount.nfs and therefore nfs-utils-1.1.2 or greater is only needed + on the NFS client machine. You do not need this specific version of + nfs-utils on the server. Furthermore, only the mount.nfs command from + nfs-utils-1.1.2 is needed on the client. + + - Install a Linux kernel with NFS/RDMA + + The NFS/RDMA client and server are both included in the mainline Linux + kernel version 2.6.25 and later. This and other versions of the 2.6 Linux + kernel can be found at: + + ftp://ftp.kernel.org/pub/linux/kernel/v2.6/ + + Download the sources and place them in an appropriate location. + + - Configure the RDMA stack + + Make sure your kernel configuration has RDMA support enabled. Under + Device Drivers -> InfiniBand support, update the kernel configuration + to enable InfiniBand support [NOTE: the option name is misleading. Enabling + InfiniBand support is required for all RDMA devices (IB, iWARP, etc.)]. + + Enable the appropriate IB HCA support (mlx4, mthca, ehca, ipath, etc.) or + iWARP adapter support (amso, cxgb3, etc.). + + If you are using InfiniBand, be sure to enable IP-over-InfiniBand support. + + - Configure the NFS client and server + + Your kernel configuration must also have NFS file system support and/or + NFS server support enabled. These and other NFS related configuration + options can be found under File Systems -> Network File Systems. + + - Build, install, reboot + + The NFS/RDMA code will be enabled automatically if NFS and RDMA + are turned on. The NFS/RDMA client and server are configured via the hidden + SUNRPC_XPRT_RDMA config option that depends on SUNRPC and INFINIBAND. The + value of SUNRPC_XPRT_RDMA will be: + + - N if either SUNRPC or INFINIBAND are N, in this case the NFS/RDMA client + and server will not be built + - M if both SUNRPC and INFINIBAND are on (M or Y) and at least one is M, + in this case the NFS/RDMA client and server will be built as modules + - Y if both SUNRPC and INFINIBAND are Y, in this case the NFS/RDMA client + and server will be built into the kernel + + Therefore, if you have followed the steps above and turned no NFS and RDMA, + the NFS/RDMA client and server will be built. + + Build a new kernel, install it, boot it. + +Check RDMA and NFS Setup +~~~~~~~~~~~~~~~~~~~~~~~~ + + Before configuring the NFS/RDMA software, it is a good idea to test + your new kernel to ensure that the kernel is working correctly. + In particular, it is a good idea to verify that the RDMA stack + is functioning as expected and standard NFS over TCP/IP and/or UDP/IP + is working properly. + + - Check RDMA Setup + + If you built the RDMA components as modules, load them at + this time. For example, if you are using a Mellanox Tavor/Sinai/Arbel + card: + + $ modprobe ib_mthca + $ modprobe ib_ipoib + + If you are using InfiniBand, make sure there is a Subnet Manager (SM) + running on the network. If your IB switch has an embedded SM, you can + use it. Otherwise, you will need to run an SM, such as OpenSM, on one + of your end nodes. + + If an SM is running on your network, you should see the following: + + $ cat /sys/class/infiniband/driverX/ports/1/state + 4: ACTIVE + + where driverX is mthca0, ipath5, ehca3, etc. + + To further test the InfiniBand software stack, use IPoIB (this + assumes you have two IB hosts named host1 and host2): + + host1$ ifconfig ib0 a.b.c.x + host2$ ifconfig ib0 a.b.c.y + host1$ ping a.b.c.y + host2$ ping a.b.c.x + + For other device types, follow the appropriate procedures. + + - Check NFS Setup + + For the NFS components enabled above (client and/or server), + test their functionality over standard Ethernet using TCP/IP or UDP/IP. + +NFS/RDMA Setup +~~~~~~~~~~~~~~ + + We recommend that you use two machines, one to act as the client and + one to act as the server. + + One time configuration: + + - On the server system, configure the /etc/exports file and + start the NFS/RDMA server. + + Exports entries with the following formats have been tested: + + /vol0 192.168.0.47(fsid=0,rw,async,insecure,no_root_squash) + /vol0 192.168.0.0/255.255.255.0(fsid=0,rw,async,insecure,no_root_squash) + + The IP address(es) is(are) the client's IPoIB address for an InfiniBand + HCA or the cleint's iWARP address(es) for an RNIC. + + NOTE: The "insecure" option must be used because the NFS/RDMA client does + not use a reserved port. + + Each time a machine boots: + + - Load and configure the RDMA drivers + + For InfiniBand using a Mellanox adapter: + + $ modprobe ib_mthca + $ modprobe ib_ipoib + $ ifconfig ib0 a.b.c.d + + NOTE: use unique addresses for the client and server + + - Start the NFS server + + If the NFS/RDMA server was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in + kernel config), load the RDMA transport module: + + $ modprobe svcrdma + + Regardless of how the server was built (module or built-in), start the + server: + + $ /etc/init.d/nfs start + + or + + $ service nfs start + + Instruct the server to listen on the RDMA transport: + + $ echo rdma 20049 > /proc/fs/nfsd/portlist + + - On the client system + + If the NFS/RDMA client was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in + kernel config), load the RDMA client module: + + $ modprobe xprtrdma.ko + + Regardless of how the client was built (module or built-in), use this + command to mount the NFS/RDMA server: + + $ mount -o rdma,port=20049 :/ /mnt + + To verify that the mount is using RDMA, run "cat /proc/mounts" and check + the "proto" field for the given mount. + + Congratulations! You're using NFS/RDMA! diff --git a/Documentation/filesystems/nfs/nfs.txt b/Documentation/filesystems/nfs/nfs.txt new file mode 100644 index 0000000..f50f26c --- /dev/null +++ b/Documentation/filesystems/nfs/nfs.txt @@ -0,0 +1,98 @@ + +The NFS client +============== + +The NFS version 2 protocol was first documented in RFC1094 (March 1989). +Since then two more major releases of NFS have been published, with NFSv3 +being documented in RFC1813 (June 1995), and NFSv4 in RFC3530 (April +2003). + +The Linux NFS client currently supports all the above published versions, +and work is in progress on adding support for minor version 1 of the NFSv4 +protocol. + +The purpose of this document is to provide information on some of the +upcall interfaces that are used in order to provide the NFS client with +some of the information that it requires in order to fully comply with +the NFS spec. + +The DNS resolver +================ + +NFSv4 allows for one server to refer the NFS client to data that has been +migrated onto another server by means of the special "fs_locations" +attribute. See + http://tools.ietf.org/html/rfc3530#section-6 +and + http://tools.ietf.org/html/draft-ietf-nfsv4-referrals-00 + +The fs_locations information can take the form of either an ip address and +a path, or a DNS hostname and a path. The latter requires the NFS client to +do a DNS lookup in order to mount the new volume, and hence the need for an +upcall to allow userland to provide this service. + +Assuming that the user has the 'rpc_pipefs' filesystem mounted in the usual +/var/lib/nfs/rpc_pipefs, the upcall consists of the following steps: + + (1) The process checks the dns_resolve cache to see if it contains a + valid entry. If so, it returns that entry and exits. + + (2) If no valid entry exists, the helper script '/sbin/nfs_cache_getent' + (may be changed using the 'nfs.cache_getent' kernel boot parameter) + is run, with two arguments: + - the cache name, "dns_resolve" + - the hostname to resolve + + (3) After looking up the corresponding ip address, the helper script + writes the result into the rpc_pipefs pseudo-file + '/var/lib/nfs/rpc_pipefs/cache/dns_resolve/channel' + in the following (text) format: + + " \n" + + Where is in the usual IPv4 (123.456.78.90) or IPv6 + (ffee:ddcc:bbaa:9988:7766:5544:3322:1100, ffee::1100, ...) format. + is identical to the second argument of the helper + script, and is the 'time to live' of this cache entry (in + units of seconds). + + Note: If is invalid, say the string "0", then a negative + entry is created, which will cause the kernel to treat the hostname + as having no valid DNS translation. + + + + +A basic sample /sbin/nfs_cache_getent +===================================== + +#!/bin/bash +# +ttl=600 +# +cut=/usr/bin/cut +getent=/usr/bin/getent +rpc_pipefs=/var/lib/nfs/rpc_pipefs +# +die() +{ + echo "Usage: $0 cache_name entry_name" + exit 1 +} + +[ $# -lt 2 ] && die +cachename="$1" +cache_path=${rpc_pipefs}/cache/${cachename}/channel + +case "${cachename}" in + dns_resolve) + name="$2" + result="$(${getent} hosts ${name} | ${cut} -f1 -d\ )" + [ -z "${result}" ] && result="0" + ;; + *) + die + ;; +esac +echo "${result} ${name} ${ttl}" >${cache_path} + diff --git a/Documentation/filesystems/nfs/nfs41-server.txt b/Documentation/filesystems/nfs/nfs41-server.txt new file mode 100644 index 0000000..1bd0d0c --- /dev/null +++ b/Documentation/filesystems/nfs/nfs41-server.txt @@ -0,0 +1,222 @@ +NFSv4.1 Server Implementation + +Server support for minorversion 1 can be controlled using the +/proc/fs/nfsd/versions control file. The string output returned +by reading this file will contain either "+4.1" or "-4.1" +correspondingly. + +Currently, server support for minorversion 1 is disabled by default. +It can be enabled at run time by writing the string "+4.1" to +the /proc/fs/nfsd/versions control file. Note that to write this +control file, the nfsd service must be taken down. Use your user-mode +nfs-utils to set this up; see rpc.nfsd(8) + +(Warning: older servers will interpret "+4.1" and "-4.1" as "+4" and +"-4", respectively. Therefore, code meant to work on both new and old +kernels must turn 4.1 on or off *before* turning support for version 4 +on or off; rpc.nfsd does this correctly.) + +The NFSv4 minorversion 1 (NFSv4.1) implementation in nfsd is based +on the latest NFSv4.1 Internet Draft: +http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-29 + +From the many new features in NFSv4.1 the current implementation +focuses on the mandatory-to-implement NFSv4.1 Sessions, providing +"exactly once" semantics and better control and throttling of the +resources allocated for each client. + +Other NFSv4.1 features, Parallel NFS operations in particular, +are still under development out of tree. +See http://wiki.linux-nfs.org/wiki/index.php/PNFS_prototype_design +for more information. + +The current implementation is intended for developers only: while it +does support ordinary file operations on clients we have tested against +(including the linux client), it is incomplete in ways which may limit +features unexpectedly, cause known bugs in rare cases, or cause +interoperability problems with future clients. Known issues: + + - gss support is questionable: currently mounts with kerberos + from a linux client are possible, but we aren't really + conformant with the spec (for example, we don't use kerberos + on the backchannel correctly). + - no trunking support: no clients currently take advantage of + trunking, but this is a mandatory feature, and its use is + recommended to clients in a number of places. (E.g. to ensure + timely renewal in case an existing connection's retry timeouts + have gotten too long; see section 8.3 of the draft.) + Therefore, lack of this feature may cause future clients to + fail. + - Incomplete backchannel support: incomplete backchannel gss + support and no support for BACKCHANNEL_CTL mean that + callbacks (hence delegations and layouts) may not be + available and clients confused by the incomplete + implementation may fail. + - Server reboot recovery is unsupported; if the server reboots, + clients may fail. + - We do not support SSV, which provides security for shared + client-server state (thus preventing unauthorized tampering + with locks and opens, for example). It is mandatory for + servers to support this, though no clients use it yet. + - Mandatory operations which we do not support, such as + DESTROY_CLIENTID, FREE_STATEID, SECINFO_NO_NAME, and + TEST_STATEID, are not currently used by clients, but will be + (and the spec recommends their uses in common cases), and + clients should not be expected to know how to recover from the + case where they are not supported. This will eventually cause + interoperability failures. + +In addition, some limitations are inherited from the current NFSv4 +implementation: + + - Incomplete delegation enforcement: if a file is renamed or + unlinked, a client holding a delegation may continue to + indefinitely allow opens of the file under the old name. + +The table below, taken from the NFSv4.1 document, lists +the operations that are mandatory to implement (REQ), optional +(OPT), and NFSv4.0 operations that are required not to implement (MNI) +in minor version 1. The first column indicates the operations that +are not supported yet by the linux server implementation. + +The OPTIONAL features identified and their abbreviations are as follows: + pNFS Parallel NFS + FDELG File Delegations + DDELG Directory Delegations + +The following abbreviations indicate the linux server implementation status. + I Implemented NFSv4.1 operations. + NS Not Supported. + NS* unimplemented optional feature. + P pNFS features implemented out of tree. + PNS pNFS features that are not supported yet (out of tree). + +Operations + + +----------------------+------------+--------------+----------------+ + | Operation | REQ, REC, | Feature | Definition | + | | OPT, or | (REQ, REC, | | + | | MNI | or OPT) | | + +----------------------+------------+--------------+----------------+ + | ACCESS | REQ | | Section 18.1 | +NS | BACKCHANNEL_CTL | REQ | | Section 18.33 | +NS | BIND_CONN_TO_SESSION | REQ | | Section 18.34 | + | CLOSE | REQ | | Section 18.2 | + | COMMIT | REQ | | Section 18.3 | + | CREATE | REQ | | Section 18.4 | +I | CREATE_SESSION | REQ | | Section 18.36 | +NS*| DELEGPURGE | OPT | FDELG (REQ) | Section 18.5 | + | DELEGRETURN | OPT | FDELG, | Section 18.6 | + | | | DDELG, pNFS | | + | | | (REQ) | | +NS | DESTROY_CLIENTID | REQ | | Section 18.50 | +I | DESTROY_SESSION | REQ | | Section 18.37 | +I | EXCHANGE_ID | REQ | | Section 18.35 | +NS | FREE_STATEID | REQ | | Section 18.38 | + | GETATTR | REQ | | Section 18.7 | +P | GETDEVICEINFO | OPT | pNFS (REQ) | Section 18.40 | +P | GETDEVICELIST | OPT | pNFS (OPT) | Section 18.41 | + | GETFH | REQ | | Section 18.8 | +NS*| GET_DIR_DELEGATION | OPT | DDELG (REQ) | Section 18.39 | +P | LAYOUTCOMMIT | OPT | pNFS (REQ) | Section 18.42 | +P | LAYOUTGET | OPT | pNFS (REQ) | Section 18.43 | +P | LAYOUTRETURN | OPT | pNFS (REQ) | Section 18.44 | + | LINK | OPT | | Section 18.9 | + | LOCK | REQ | | Section 18.10 | + | LOCKT | REQ | | Section 18.11 | + | LOCKU | REQ | | Section 18.12 | + | LOOKUP | REQ | | Section 18.13 | + | LOOKUPP | REQ | | Section 18.14 | + | NVERIFY | REQ | | Section 18.15 | + | OPEN | REQ | | Section 18.16 | +NS*| OPENATTR | OPT | | Section 18.17 | + | OPEN_CONFIRM | MNI | | N/A | + | OPEN_DOWNGRADE | REQ | | Section 18.18 | + | PUTFH | REQ | | Section 18.19 | + | PUTPUBFH | REQ | | Section 18.20 | + | PUTROOTFH | REQ | | Section 18.21 | + | READ | REQ | | Section 18.22 | + | READDIR | REQ | | Section 18.23 | + | READLINK | OPT | | Section 18.24 | +NS | RECLAIM_COMPLETE | REQ | | Section 18.51 | + | RELEASE_LOCKOWNER | MNI | | N/A | + | REMOVE | REQ | | Section 18.25 | + | RENAME | REQ | | Section 18.26 | + | RENEW | MNI | | N/A | + | RESTOREFH | REQ | | Section 18.27 | + | SAVEFH | REQ | | Section 18.28 | + | SECINFO | REQ | | Section 18.29 | +NS | SECINFO_NO_NAME | REC | pNFS files | Section 18.45, | + | | | layout (REQ) | Section 13.12 | +I | SEQUENCE | REQ | | Section 18.46 | + | SETATTR | REQ | | Section 18.30 | + | SETCLIENTID | MNI | | N/A | + | SETCLIENTID_CONFIRM | MNI | | N/A | +NS | SET_SSV | REQ | | Section 18.47 | +NS | TEST_STATEID | REQ | | Section 18.48 | + | VERIFY | REQ | | Section 18.31 | +NS*| WANT_DELEGATION | OPT | FDELG (OPT) | Section 18.49 | + | WRITE | REQ | | Section 18.32 | + +Callback Operations + + +-------------------------+-----------+-------------+---------------+ + | Operation | REQ, REC, | Feature | Definition | + | | OPT, or | (REQ, REC, | | + | | MNI | or OPT) | | + +-------------------------+-----------+-------------+---------------+ + | CB_GETATTR | OPT | FDELG (REQ) | Section 20.1 | +P | CB_LAYOUTRECALL | OPT | pNFS (REQ) | Section 20.3 | +NS*| CB_NOTIFY | OPT | DDELG (REQ) | Section 20.4 | +P | CB_NOTIFY_DEVICEID | OPT | pNFS (OPT) | Section 20.12 | +NS*| CB_NOTIFY_LOCK | OPT | | Section 20.11 | +NS*| CB_PUSH_DELEG | OPT | FDELG (OPT) | Section 20.5 | + | CB_RECALL | OPT | FDELG, | Section 20.2 | + | | | DDELG, pNFS | | + | | | (REQ) | | +NS*| CB_RECALL_ANY | OPT | FDELG, | Section 20.6 | + | | | DDELG, pNFS | | + | | | (REQ) | | +NS | CB_RECALL_SLOT | REQ | | Section 20.8 | +NS*| CB_RECALLABLE_OBJ_AVAIL | OPT | DDELG, pNFS | Section 20.7 | + | | | (REQ) | | +I | CB_SEQUENCE | OPT | FDELG, | Section 20.9 | + | | | DDELG, pNFS | | + | | | (REQ) | | +NS*| CB_WANTS_CANCELLED | OPT | FDELG, | Section 20.10 | + | | | DDELG, pNFS | | + | | | (REQ) | | + +-------------------------+-----------+-------------+---------------+ + +Implementation notes: + +DELEGPURGE: +* mandatory only for servers that support CLAIM_DELEGATE_PREV and/or + CLAIM_DELEG_PREV_FH (which allows clients to keep delegations that + persist across client reboots). Thus we need not implement this for + now. + +EXCHANGE_ID: +* only SP4_NONE state protection supported +* implementation ids are ignored + +CREATE_SESSION: +* backchannel attributes are ignored +* backchannel security parameters are ignored + +SEQUENCE: +* no support for dynamic slot table renegotiation (optional) + +nfsv4.1 COMPOUND rules: +The following cases aren't supported yet: +* Enforcing of NFS4ERR_NOT_ONLY_OP for: BIND_CONN_TO_SESSION, CREATE_SESSION, + DESTROY_CLIENTID, DESTROY_SESSION, EXCHANGE_ID. +* DESTROY_SESSION MUST be the final operation in the COMPOUND request. + +Nonstandard compound limitations: +* No support for a sessions fore channel RPC compound that requires both a + ca_maxrequestsize request and a ca_maxresponsesize reply, so we may + fail to live up to the promise we made in CREATE_SESSION fore channel + negotiation. +* No more than one IO operation (read, write, readdir) allowed per + compound. diff --git a/Documentation/filesystems/nfs/nfsroot.txt b/Documentation/filesystems/nfs/nfsroot.txt new file mode 100644 index 0000000..3ba0b94 --- /dev/null +++ b/Documentation/filesystems/nfs/nfsroot.txt @@ -0,0 +1,270 @@ +Mounting the root filesystem via NFS (nfsroot) +=============================================== + +Written 1996 by Gero Kuhlmann +Updated 1997 by Martin Mares +Updated 2006 by Nico Schottelius +Updated 2006 by Horms + + + +In order to use a diskless system, such as an X-terminal or printer server +for example, it is necessary for the root filesystem to be present on a +non-disk device. This may be an initramfs (see Documentation/filesystems/ +ramfs-rootfs-initramfs.txt), a ramdisk (see Documentation/initrd.txt) or a +filesystem mounted via NFS. The following text describes on how to use NFS +for the root filesystem. For the rest of this text 'client' means the +diskless system, and 'server' means the NFS server. + + + + +1.) Enabling nfsroot capabilities + ----------------------------- + +In order to use nfsroot, NFS client support needs to be selected as +built-in during configuration. Once this has been selected, the nfsroot +option will become available, which should also be selected. + +In the networking options, kernel level autoconfiguration can be selected, +along with the types of autoconfiguration to support. Selecting all of +DHCP, BOOTP and RARP is safe. + + + + +2.) Kernel command line + ------------------- + +When the kernel has been loaded by a boot loader (see below) it needs to be +told what root fs device to use. And in the case of nfsroot, where to find +both the server and the name of the directory on the server to mount as root. +This can be established using the following kernel command line parameters: + + +root=/dev/nfs + + This is necessary to enable the pseudo-NFS-device. Note that it's not a + real device but just a synonym to tell the kernel to use NFS instead of + a real device. + + +nfsroot=[:][,] + + If the `nfsroot' parameter is NOT given on the command line, + the default "/tftpboot/%s" will be used. + + Specifies the IP address of the NFS server. + The default address is determined by the `ip' parameter + (see below). This parameter allows the use of different + servers for IP autoconfiguration and NFS. + + Name of the directory on the server to mount as root. + If there is a "%s" token in the string, it will be + replaced by the ASCII-representation of the client's + IP address. + + Standard NFS options. All options are separated by commas. + The following defaults are used: + port = as given by server portmap daemon + rsize = 4096 + wsize = 4096 + timeo = 7 + retrans = 3 + acregmin = 3 + acregmax = 60 + acdirmin = 30 + acdirmax = 60 + flags = hard, nointr, noposix, cto, ac + + +ip=:::::: + + This parameter tells the kernel how to configure IP addresses of devices + and also how to set up the IP routing table. It was originally called + `nfsaddrs', but now the boot-time IP configuration works independently of + NFS, so it was renamed to `ip' and the old name remained as an alias for + compatibility reasons. + + If this parameter is missing from the kernel command line, all fields are + assumed to be empty, and the defaults mentioned below apply. In general + this means that the kernel tries to configure everything using + autoconfiguration. + + The parameter can appear alone as the value to the `ip' + parameter (without all the ':' characters before). If the value is + "ip=off" or "ip=none", no autoconfiguration will take place, otherwise + autoconfiguration will take place. The most common way to use this + is "ip=dhcp". + + IP address of the client. + + Default: Determined using autoconfiguration. + + IP address of the NFS server. If RARP is used to determine + the client address and this parameter is NOT empty only + replies from the specified server are accepted. + + Only required for NFS root. That is autoconfiguration + will not be triggered if it is missing and NFS root is not + in operation. + + Default: Determined using autoconfiguration. + The address of the autoconfiguration server is used. + + IP address of a gateway if the server is on a different subnet. + + Default: Determined using autoconfiguration. + + Netmask for local network interface. If unspecified + the netmask is derived from the client IP address assuming + classful addressing. + + Default: Determined using autoconfiguration. + + Name of the client. May be supplied by autoconfiguration, + but its absence will not trigger autoconfiguration. + + Default: Client IP address is used in ASCII notation. + + Name of network device to use. + + Default: If the host only has one device, it is used. + Otherwise the device is determined using + autoconfiguration. This is done by sending + autoconfiguration requests out of all devices, + and using the device that received the first reply. + + Method to use for autoconfiguration. In the case of options + which specify multiple autoconfiguration protocols, + requests are sent using all protocols, and the first one + to reply is used. + + Only autoconfiguration protocols that have been compiled + into the kernel will be used, regardless of the value of + this option. + + off or none: don't use autoconfiguration + (do static IP assignment instead) + on or any: use any protocol available in the kernel + (default) + dhcp: use DHCP + bootp: use BOOTP + rarp: use RARP + both: use both BOOTP and RARP but not DHCP + (old option kept for backwards compatibility) + + Default: any + + + + +3.) Boot Loader + ---------- + +To get the kernel into memory different approaches can be used. +They depend on various facilities being available: + + +3.1) Booting from a floppy using syslinux + + When building kernels, an easy way to create a boot floppy that uses + syslinux is to use the zdisk or bzdisk make targets which use zimage + and bzimage images respectively. Both targets accept the + FDARGS parameter which can be used to set the kernel command line. + + e.g. + make bzdisk FDARGS="root=/dev/nfs" + + Note that the user running this command will need to have + access to the floppy drive device, /dev/fd0 + + For more information on syslinux, including how to create bootdisks + for prebuilt kernels, see http://syslinux.zytor.com/ + + N.B: Previously it was possible to write a kernel directly to + a floppy using dd, configure the boot device using rdev, and + boot using the resulting floppy. Linux no longer supports this + method of booting. + +3.2) Booting from a cdrom using isolinux + + When building kernels, an easy way to create a bootable cdrom that + uses isolinux is to use the isoimage target which uses a bzimage + image. Like zdisk and bzdisk, this target accepts the FDARGS + parameter which can be used to set the kernel command line. + + e.g. + make isoimage FDARGS="root=/dev/nfs" + + The resulting iso image will be arch//boot/image.iso + This can be written to a cdrom using a variety of tools including + cdrecord. + + e.g. + cdrecord dev=ATAPI:1,0,0 arch/i386/boot/image.iso + + For more information on isolinux, including how to create bootdisks + for prebuilt kernels, see http://syslinux.zytor.com/ + +3.2) Using LILO + When using LILO all the necessary command line parameters may be + specified using the 'append=' directive in the LILO configuration + file. + + However, to use the 'root=' directive you also need to create + a dummy root device, which may be removed after LILO is run. + + mknod /dev/boot255 c 0 255 + + For information on configuring LILO, please refer to its documentation. + +3.3) Using GRUB + When using GRUB, kernel parameter are simply appended after the kernel + specification: kernel + +3.4) Using loadlin + loadlin may be used to boot Linux from a DOS command prompt without + requiring a local hard disk to mount as root. This has not been + thoroughly tested by the authors of this document, but in general + it should be possible configure the kernel command line similarly + to the configuration of LILO. + + Please refer to the loadlin documentation for further information. + +3.5) Using a boot ROM + This is probably the most elegant way of booting a diskless client. + With a boot ROM the kernel is loaded using the TFTP protocol. The + authors of this document are not aware of any no commercial boot + ROMs that support booting Linux over the network. However, there + are two free implementations of a boot ROM, netboot-nfs and + etherboot, both of which are available on sunsite.unc.edu, and both + of which contain everything you need to boot a diskless Linux client. + +3.6) Using pxelinux + Pxelinux may be used to boot linux using the PXE boot loader + which is present on many modern network cards. + + When using pxelinux, the kernel image is specified using + "kernel ". The nfsroot parameters + are passed to the kernel by adding them to the "append" line. + It is common to use serial console in conjunction with pxeliunx, + see Documentation/serial-console.txt for more information. + + For more information on isolinux, including how to create bootdisks + for prebuilt kernels, see http://syslinux.zytor.com/ + + + + +4.) Credits + ------- + + The nfsroot code in the kernel and the RARP support have been written + by Gero Kuhlmann . + + The rest of the IP layer autoconfiguration code has been written + by Martin Mares . + + In order to write the initial version of nfsroot I would like to thank + Jens-Uwe Mager for his help. diff --git a/Documentation/filesystems/nfs41-server.txt b/Documentation/filesystems/nfs41-server.txt deleted file mode 100644 index 1bd0d0c..0000000 --- a/Documentation/filesystems/nfs41-server.txt +++ /dev/null @@ -1,222 +0,0 @@ -NFSv4.1 Server Implementation - -Server support for minorversion 1 can be controlled using the -/proc/fs/nfsd/versions control file. The string output returned -by reading this file will contain either "+4.1" or "-4.1" -correspondingly. - -Currently, server support for minorversion 1 is disabled by default. -It can be enabled at run time by writing the string "+4.1" to -the /proc/fs/nfsd/versions control file. Note that to write this -control file, the nfsd service must be taken down. Use your user-mode -nfs-utils to set this up; see rpc.nfsd(8) - -(Warning: older servers will interpret "+4.1" and "-4.1" as "+4" and -"-4", respectively. Therefore, code meant to work on both new and old -kernels must turn 4.1 on or off *before* turning support for version 4 -on or off; rpc.nfsd does this correctly.) - -The NFSv4 minorversion 1 (NFSv4.1) implementation in nfsd is based -on the latest NFSv4.1 Internet Draft: -http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-29 - -From the many new features in NFSv4.1 the current implementation -focuses on the mandatory-to-implement NFSv4.1 Sessions, providing -"exactly once" semantics and better control and throttling of the -resources allocated for each client. - -Other NFSv4.1 features, Parallel NFS operations in particular, -are still under development out of tree. -See http://wiki.linux-nfs.org/wiki/index.php/PNFS_prototype_design -for more information. - -The current implementation is intended for developers only: while it -does support ordinary file operations on clients we have tested against -(including the linux client), it is incomplete in ways which may limit -features unexpectedly, cause known bugs in rare cases, or cause -interoperability problems with future clients. Known issues: - - - gss support is questionable: currently mounts with kerberos - from a linux client are possible, but we aren't really - conformant with the spec (for example, we don't use kerberos - on the backchannel correctly). - - no trunking support: no clients currently take advantage of - trunking, but this is a mandatory feature, and its use is - recommended to clients in a number of places. (E.g. to ensure - timely renewal in case an existing connection's retry timeouts - have gotten too long; see section 8.3 of the draft.) - Therefore, lack of this feature may cause future clients to - fail. - - Incomplete backchannel support: incomplete backchannel gss - support and no support for BACKCHANNEL_CTL mean that - callbacks (hence delegations and layouts) may not be - available and clients confused by the incomplete - implementation may fail. - - Server reboot recovery is unsupported; if the server reboots, - clients may fail. - - We do not support SSV, which provides security for shared - client-server state (thus preventing unauthorized tampering - with locks and opens, for example). It is mandatory for - servers to support this, though no clients use it yet. - - Mandatory operations which we do not support, such as - DESTROY_CLIENTID, FREE_STATEID, SECINFO_NO_NAME, and - TEST_STATEID, are not currently used by clients, but will be - (and the spec recommends their uses in common cases), and - clients should not be expected to know how to recover from the - case where they are not supported. This will eventually cause - interoperability failures. - -In addition, some limitations are inherited from the current NFSv4 -implementation: - - - Incomplete delegation enforcement: if a file is renamed or - unlinked, a client holding a delegation may continue to - indefinitely allow opens of the file under the old name. - -The table below, taken from the NFSv4.1 document, lists -the operations that are mandatory to implement (REQ), optional -(OPT), and NFSv4.0 operations that are required not to implement (MNI) -in minor version 1. The first column indicates the operations that -are not supported yet by the linux server implementation. - -The OPTIONAL features identified and their abbreviations are as follows: - pNFS Parallel NFS - FDELG File Delegations - DDELG Directory Delegations - -The following abbreviations indicate the linux server implementation status. - I Implemented NFSv4.1 operations. - NS Not Supported. - NS* unimplemented optional feature. - P pNFS features implemented out of tree. - PNS pNFS features that are not supported yet (out of tree). - -Operations - - +----------------------+------------+--------------+----------------+ - | Operation | REQ, REC, | Feature | Definition | - | | OPT, or | (REQ, REC, | | - | | MNI | or OPT) | | - +----------------------+------------+--------------+----------------+ - | ACCESS | REQ | | Section 18.1 | -NS | BACKCHANNEL_CTL | REQ | | Section 18.33 | -NS | BIND_CONN_TO_SESSION | REQ | | Section 18.34 | - | CLOSE | REQ | | Section 18.2 | - | COMMIT | REQ | | Section 18.3 | - | CREATE | REQ | | Section 18.4 | -I | CREATE_SESSION | REQ | | Section 18.36 | -NS*| DELEGPURGE | OPT | FDELG (REQ) | Section 18.5 | - | DELEGRETURN | OPT | FDELG, | Section 18.6 | - | | | DDELG, pNFS | | - | | | (REQ) | | -NS | DESTROY_CLIENTID | REQ | | Section 18.50 | -I | DESTROY_SESSION | REQ | | Section 18.37 | -I | EXCHANGE_ID | REQ | | Section 18.35 | -NS | FREE_STATEID | REQ | | Section 18.38 | - | GETATTR | REQ | | Section 18.7 | -P | GETDEVICEINFO | OPT | pNFS (REQ) | Section 18.40 | -P | GETDEVICELIST | OPT | pNFS (OPT) | Section 18.41 | - | GETFH | REQ | | Section 18.8 | -NS*| GET_DIR_DELEGATION | OPT | DDELG (REQ) | Section 18.39 | -P | LAYOUTCOMMIT | OPT | pNFS (REQ) | Section 18.42 | -P | LAYOUTGET | OPT | pNFS (REQ) | Section 18.43 | -P | LAYOUTRETURN | OPT | pNFS (REQ) | Section 18.44 | - | LINK | OPT | | Section 18.9 | - | LOCK | REQ | | Section 18.10 | - | LOCKT | REQ | | Section 18.11 | - | LOCKU | REQ | | Section 18.12 | - | LOOKUP | REQ | | Section 18.13 | - | LOOKUPP | REQ | | Section 18.14 | - | NVERIFY | REQ | | Section 18.15 | - | OPEN | REQ | | Section 18.16 | -NS*| OPENATTR | OPT | | Section 18.17 | - | OPEN_CONFIRM | MNI | | N/A | - | OPEN_DOWNGRADE | REQ | | Section 18.18 | - | PUTFH | REQ | | Section 18.19 | - | PUTPUBFH | REQ | | Section 18.20 | - | PUTROOTFH | REQ | | Section 18.21 | - | READ | REQ | | Section 18.22 | - | READDIR | REQ | | Section 18.23 | - | READLINK | OPT | | Section 18.24 | -NS | RECLAIM_COMPLETE | REQ | | Section 18.51 | - | RELEASE_LOCKOWNER | MNI | | N/A | - | REMOVE | REQ | | Section 18.25 | - | RENAME | REQ | | Section 18.26 | - | RENEW | MNI | | N/A | - | RESTOREFH | REQ | | Section 18.27 | - | SAVEFH | REQ | | Section 18.28 | - | SECINFO | REQ | | Section 18.29 | -NS | SECINFO_NO_NAME | REC | pNFS files | Section 18.45, | - | | | layout (REQ) | Section 13.12 | -I | SEQUENCE | REQ | | Section 18.46 | - | SETATTR | REQ | | Section 18.30 | - | SETCLIENTID | MNI | | N/A | - | SETCLIENTID_CONFIRM | MNI | | N/A | -NS | SET_SSV | REQ | | Section 18.47 | -NS | TEST_STATEID | REQ | | Section 18.48 | - | VERIFY | REQ | | Section 18.31 | -NS*| WANT_DELEGATION | OPT | FDELG (OPT) | Section 18.49 | - | WRITE | REQ | | Section 18.32 | - -Callback Operations - - +-------------------------+-----------+-------------+---------------+ - | Operation | REQ, REC, | Feature | Definition | - | | OPT, or | (REQ, REC, | | - | | MNI | or OPT) | | - +-------------------------+-----------+-------------+---------------+ - | CB_GETATTR | OPT | FDELG (REQ) | Section 20.1 | -P | CB_LAYOUTRECALL | OPT | pNFS (REQ) | Section 20.3 | -NS*| CB_NOTIFY | OPT | DDELG (REQ) | Section 20.4 | -P | CB_NOTIFY_DEVICEID | OPT | pNFS (OPT) | Section 20.12 | -NS*| CB_NOTIFY_LOCK | OPT | | Section 20.11 | -NS*| CB_PUSH_DELEG | OPT | FDELG (OPT) | Section 20.5 | - | CB_RECALL | OPT | FDELG, | Section 20.2 | - | | | DDELG, pNFS | | - | | | (REQ) | | -NS*| CB_RECALL_ANY | OPT | FDELG, | Section 20.6 | - | | | DDELG, pNFS | | - | | | (REQ) | | -NS | CB_RECALL_SLOT | REQ | | Section 20.8 | -NS*| CB_RECALLABLE_OBJ_AVAIL | OPT | DDELG, pNFS | Section 20.7 | - | | | (REQ) | | -I | CB_SEQUENCE | OPT | FDELG, | Section 20.9 | - | | | DDELG, pNFS | | - | | | (REQ) | | -NS*| CB_WANTS_CANCELLED | OPT | FDELG, | Section 20.10 | - | | | DDELG, pNFS | | - | | | (REQ) | | - +-------------------------+-----------+-------------+---------------+ - -Implementation notes: - -DELEGPURGE: -* mandatory only for servers that support CLAIM_DELEGATE_PREV and/or - CLAIM_DELEG_PREV_FH (which allows clients to keep delegations that - persist across client reboots). Thus we need not implement this for - now. - -EXCHANGE_ID: -* only SP4_NONE state protection supported -* implementation ids are ignored - -CREATE_SESSION: -* backchannel attributes are ignored -* backchannel security parameters are ignored - -SEQUENCE: -* no support for dynamic slot table renegotiation (optional) - -nfsv4.1 COMPOUND rules: -The following cases aren't supported yet: -* Enforcing of NFS4ERR_NOT_ONLY_OP for: BIND_CONN_TO_SESSION, CREATE_SESSION, - DESTROY_CLIENTID, DESTROY_SESSION, EXCHANGE_ID. -* DESTROY_SESSION MUST be the final operation in the COMPOUND request. - -Nonstandard compound limitations: -* No support for a sessions fore channel RPC compound that requires both a - ca_maxrequestsize request and a ca_maxresponsesize reply, so we may - fail to live up to the promise we made in CREATE_SESSION fore channel - negotiation. -* No more than one IO operation (read, write, readdir) allowed per - compound. diff --git a/Documentation/filesystems/nfsroot.txt b/Documentation/filesystems/nfsroot.txt deleted file mode 100644 index 3ba0b94..0000000 --- a/Documentation/filesystems/nfsroot.txt +++ /dev/null @@ -1,270 +0,0 @@ -Mounting the root filesystem via NFS (nfsroot) -=============================================== - -Written 1996 by Gero Kuhlmann -Updated 1997 by Martin Mares -Updated 2006 by Nico Schottelius -Updated 2006 by Horms - - - -In order to use a diskless system, such as an X-terminal or printer server -for example, it is necessary for the root filesystem to be present on a -non-disk device. This may be an initramfs (see Documentation/filesystems/ -ramfs-rootfs-initramfs.txt), a ramdisk (see Documentation/initrd.txt) or a -filesystem mounted via NFS. The following text describes on how to use NFS -for the root filesystem. For the rest of this text 'client' means the -diskless system, and 'server' means the NFS server. - - - - -1.) Enabling nfsroot capabilities - ----------------------------- - -In order to use nfsroot, NFS client support needs to be selected as -built-in during configuration. Once this has been selected, the nfsroot -option will become available, which should also be selected. - -In the networking options, kernel level autoconfiguration can be selected, -along with the types of autoconfiguration to support. Selecting all of -DHCP, BOOTP and RARP is safe. - - - - -2.) Kernel command line - ------------------- - -When the kernel has been loaded by a boot loader (see below) it needs to be -told what root fs device to use. And in the case of nfsroot, where to find -both the server and the name of the directory on the server to mount as root. -This can be established using the following kernel command line parameters: - - -root=/dev/nfs - - This is necessary to enable the pseudo-NFS-device. Note that it's not a - real device but just a synonym to tell the kernel to use NFS instead of - a real device. - - -nfsroot=[:][,] - - If the `nfsroot' parameter is NOT given on the command line, - the default "/tftpboot/%s" will be used. - - Specifies the IP address of the NFS server. - The default address is determined by the `ip' parameter - (see below). This parameter allows the use of different - servers for IP autoconfiguration and NFS. - - Name of the directory on the server to mount as root. - If there is a "%s" token in the string, it will be - replaced by the ASCII-representation of the client's - IP address. - - Standard NFS options. All options are separated by commas. - The following defaults are used: - port = as given by server portmap daemon - rsize = 4096 - wsize = 4096 - timeo = 7 - retrans = 3 - acregmin = 3 - acregmax = 60 - acdirmin = 30 - acdirmax = 60 - flags = hard, nointr, noposix, cto, ac - - -ip=:::::: - - This parameter tells the kernel how to configure IP addresses of devices - and also how to set up the IP routing table. It was originally called - `nfsaddrs', but now the boot-time IP configuration works independently of - NFS, so it was renamed to `ip' and the old name remained as an alias for - compatibility reasons. - - If this parameter is missing from the kernel command line, all fields are - assumed to be empty, and the defaults mentioned below apply. In general - this means that the kernel tries to configure everything using - autoconfiguration. - - The parameter can appear alone as the value to the `ip' - parameter (without all the ':' characters before). If the value is - "ip=off" or "ip=none", no autoconfiguration will take place, otherwise - autoconfiguration will take place. The most common way to use this - is "ip=dhcp". - - IP address of the client. - - Default: Determined using autoconfiguration. - - IP address of the NFS server. If RARP is used to determine - the client address and this parameter is NOT empty only - replies from the specified server are accepted. - - Only required for NFS root. That is autoconfiguration - will not be triggered if it is missing and NFS root is not - in operation. - - Default: Determined using autoconfiguration. - The address of the autoconfiguration server is used. - - IP address of a gateway if the server is on a different subnet. - - Default: Determined using autoconfiguration. - - Netmask for local network interface. If unspecified - the netmask is derived from the client IP address assuming - classful addressing. - - Default: Determined using autoconfiguration. - - Name of the client. May be supplied by autoconfiguration, - but its absence will not trigger autoconfiguration. - - Default: Client IP address is used in ASCII notation. - - Name of network device to use. - - Default: If the host only has one device, it is used. - Otherwise the device is determined using - autoconfiguration. This is done by sending - autoconfiguration requests out of all devices, - and using the device that received the first reply. - - Method to use for autoconfiguration. In the case of options - which specify multiple autoconfiguration protocols, - requests are sent using all protocols, and the first one - to reply is used. - - Only autoconfiguration protocols that have been compiled - into the kernel will be used, regardless of the value of - this option. - - off or none: don't use autoconfiguration - (do static IP assignment instead) - on or any: use any protocol available in the kernel - (default) - dhcp: use DHCP - bootp: use BOOTP - rarp: use RARP - both: use both BOOTP and RARP but not DHCP - (old option kept for backwards compatibility) - - Default: any - - - - -3.) Boot Loader - ---------- - -To get the kernel into memory different approaches can be used. -They depend on various facilities being available: - - -3.1) Booting from a floppy using syslinux - - When building kernels, an easy way to create a boot floppy that uses - syslinux is to use the zdisk or bzdisk make targets which use zimage - and bzimage images respectively. Both targets accept the - FDARGS parameter which can be used to set the kernel command line. - - e.g. - make bzdisk FDARGS="root=/dev/nfs" - - Note that the user running this command will need to have - access to the floppy drive device, /dev/fd0 - - For more information on syslinux, including how to create bootdisks - for prebuilt kernels, see http://syslinux.zytor.com/ - - N.B: Previously it was possible to write a kernel directly to - a floppy using dd, configure the boot device using rdev, and - boot using the resulting floppy. Linux no longer supports this - method of booting. - -3.2) Booting from a cdrom using isolinux - - When building kernels, an easy way to create a bootable cdrom that - uses isolinux is to use the isoimage target which uses a bzimage - image. Like zdisk and bzdisk, this target accepts the FDARGS - parameter which can be used to set the kernel command line. - - e.g. - make isoimage FDARGS="root=/dev/nfs" - - The resulting iso image will be arch//boot/image.iso - This can be written to a cdrom using a variety of tools including - cdrecord. - - e.g. - cdrecord dev=ATAPI:1,0,0 arch/i386/boot/image.iso - - For more information on isolinux, including how to create bootdisks - for prebuilt kernels, see http://syslinux.zytor.com/ - -3.2) Using LILO - When using LILO all the necessary command line parameters may be - specified using the 'append=' directive in the LILO configuration - file. - - However, to use the 'root=' directive you also need to create - a dummy root device, which may be removed after LILO is run. - - mknod /dev/boot255 c 0 255 - - For information on configuring LILO, please refer to its documentation. - -3.3) Using GRUB - When using GRUB, kernel parameter are simply appended after the kernel - specification: kernel - -3.4) Using loadlin - loadlin may be used to boot Linux from a DOS command prompt without - requiring a local hard disk to mount as root. This has not been - thoroughly tested by the authors of this document, but in general - it should be possible configure the kernel command line similarly - to the configuration of LILO. - - Please refer to the loadlin documentation for further information. - -3.5) Using a boot ROM - This is probably the most elegant way of booting a diskless client. - With a boot ROM the kernel is loaded using the TFTP protocol. The - authors of this document are not aware of any no commercial boot - ROMs that support booting Linux over the network. However, there - are two free implementations of a boot ROM, netboot-nfs and - etherboot, both of which are available on sunsite.unc.edu, and both - of which contain everything you need to boot a diskless Linux client. - -3.6) Using pxelinux - Pxelinux may be used to boot linux using the PXE boot loader - which is present on many modern network cards. - - When using pxelinux, the kernel image is specified using - "kernel ". The nfsroot parameters - are passed to the kernel by adding them to the "append" line. - It is common to use serial console in conjunction with pxeliunx, - see Documentation/serial-console.txt for more information. - - For more information on isolinux, including how to create bootdisks - for prebuilt kernels, see http://syslinux.zytor.com/ - - - - -4.) Credits - ------- - - The nfsroot code in the kernel and the RARP support have been written - by Gero Kuhlmann . - - The rest of the IP layer autoconfiguration code has been written - by Martin Mares . - - In order to write the initial version of nfsroot I would like to thank - Jens-Uwe Mager for his help. diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index 92b888d..a7e9746 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting @@ -140,7 +140,7 @@ Callers of notify_change() need ->i_mutex now. New super_block field "struct export_operations *s_export_op" for explicit support for exporting, e.g. via NFS. The structure is fully documented at its declaration in include/linux/fs.h, and in -Documentation/filesystems/Exporting. +Documentation/filesystems/nfs/Exporting. Briefly it allows for the definition of decode_fh and encode_fh operations to encode and decode filehandles, and allows the filesystem to use diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 9107b38..dab0f04 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1017,7 +1017,7 @@ and is between 256 and 4096 characters. It is defined in the file No delay ip= [IP_PNP] - See Documentation/filesystems/nfsroot.txt. + See Documentation/filesystems/nfs/nfsroot.txt. ip2= [HW] Set IO/IRQ pairs for up to 4 IntelliPort boards See comment before ip2_setup() in @@ -1538,10 +1538,10 @@ and is between 256 and 4096 characters. It is defined in the file going to be removed in 2.6.29. nfsaddrs= [NFS] - See Documentation/filesystems/nfsroot.txt. + See Documentation/filesystems/nfs/nfsroot.txt. nfsroot= [NFS] nfs root filesystem for disk-less boxes. - See Documentation/filesystems/nfsroot.txt. + See Documentation/filesystems/nfs/nfsroot.txt. nfs.callback_tcpport= [NFS] set the TCP port on which the NFSv4 callback diff --git a/fs/cifs/export.c b/fs/cifs/export.c index 75949d6..6177f7c 100644 --- a/fs/cifs/export.c +++ b/fs/cifs/export.c @@ -24,7 +24,7 @@ */ /* - * See Documentation/filesystems/Exporting + * See Documentation/filesystems/nfs/Exporting * and examples in fs/exportfs * * Since cifs is a network file system, an "fsid" must be included for diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index 197c7db..e9e1759 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c @@ -6,7 +6,7 @@ * and for mapping back from file handles to dentries. * * For details on why we do all the strange and hairy things in here - * take a look at Documentation/filesystems/Exporting. + * take a look at Documentation/filesystems/nfs/Exporting. */ #include #include diff --git a/fs/isofs/export.c b/fs/isofs/export.c index e81a305..ed752cb 100644 --- a/fs/isofs/export.c +++ b/fs/isofs/export.c @@ -9,7 +9,7 @@ * * The following files are helpful: * - * Documentation/filesystems/Exporting + * Documentation/filesystems/nfs/Exporting * fs/exportfs/expfs.c. */ diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig index 2a77bc2..59e5673 100644 --- a/fs/nfs/Kconfig +++ b/fs/nfs/Kconfig @@ -90,7 +90,7 @@ config ROOT_NFS If you want your system to mount its root file system via NFS, choose Y here. This is common practice for managing systems without local permanent storage. For details, read - . + . Most people say N here. diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index 27e772c..dc12f41 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h @@ -97,7 +97,7 @@ struct fid { * @get_name: find the name for a given inode in a given directory * @get_parent: find the parent of a given directory * - * See Documentation/filesystems/Exporting for details on how to use + * See Documentation/filesystems/nfs/Exporting for details on how to use * this interface correctly. * * encode_fh: diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 70491d9..0c94a1a 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -166,7 +166,7 @@ config IP_PNP_DHCP If unsure, say Y. Note that if you want to use DHCP, a DHCP server must be operating on your network. Read - for details. + for details. config IP_PNP_BOOTP bool "IP: BOOTP support" @@ -181,7 +181,7 @@ config IP_PNP_BOOTP does BOOTP itself, providing all necessary information on the kernel command line, you can say N here. If unsure, say Y. Note that if you want to use BOOTP, a BOOTP server must be operating on your network. - Read for details. + Read for details. config IP_PNP_RARP bool "IP: RARP support" @@ -194,7 +194,7 @@ config IP_PNP_RARP older protocol which is being obsoleted by BOOTP and DHCP), say Y here. Note that if you want to use RARP, a RARP server must be operating on your network. Read - for details. + for details. # not yet ready.. # bool ' IP: ARP support' CONFIG_IP_PNP_ARP diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index f8d04c2..7dcbf47 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1447,7 +1447,7 @@ late_initcall(ip_auto_config); /* * Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel - * command line parameter. See Documentation/filesystems/nfsroot.txt. + * command line parameter. See Documentation/filesystems/nfs/nfsroot.txt. */ static int __init ic_proto_name(char *name) { -- cgit v0.10.2 From dd829c45640ff14d7a039af40b3b3975f1b2e484 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Wed, 21 Oct 2009 17:54:13 -0400 Subject: nfsd4.1: fix session memory use calculation Unbalanced calculations on creation and destruction of sessions could cause our estimate of cache memory used to become negative, sometimes resulting in spurious SERVERFAULT returns to client CREATE_SESSION requests. Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index fcb9817..c171371 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -629,10 +629,13 @@ void free_session(struct kref *kref) { struct nfsd4_session *ses; + int mem; ses = container_of(kref, struct nfsd4_session, se_ref); spin_lock(&nfsd_drc_lock); - nfsd_drc_mem_used -= ses->se_fchannel.maxreqs * NFSD_SLOT_CACHE_SIZE; + mem = ses->se_fchannel.maxreqs + * (ses->se_fchannel.maxresp_cached - NFSD_MIN_HDR_SEQ_SZ); + nfsd_drc_mem_used -= mem; spin_unlock(&nfsd_drc_lock); free_session_slots(ses); kfree(ses); -- cgit v0.10.2 From efe0cb6d5a1f20ad4df045a055048afed4c5e660 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Sat, 24 Oct 2009 20:52:16 -0400 Subject: nfsd4.1: common slot allocation size calculation We do the same calculation in a couple places; use a helper function, and add a little documentation, in the hopes of preventing bugs like that fixed in the last patch. Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index c171371..42dab95 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -524,6 +524,15 @@ free_session_slots(struct nfsd4_session *ses) kfree(ses->se_slots[i]); } +/* + * We don't actually need to cache the rpc and session headers, so we + * can allocate a little less for each slot: + */ +static inline int slot_bytes(struct nfsd4_channel_attrs *ca) +{ + return ca->maxresp_cached - NFSD_MIN_HDR_SEQ_SZ; +} + static int alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, struct nfsd4_create_session *cses) @@ -555,7 +564,7 @@ alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, memcpy(new, &tmp, sizeof(*new)); /* allocate each struct nfsd4_slot and data cache in one piece */ - cachesize = new->se_fchannel.maxresp_cached - NFSD_MIN_HDR_SEQ_SZ; + cachesize = slot_bytes(&new->se_fchannel); for (i = 0; i < new->se_fchannel.maxreqs; i++) { sp = kzalloc(sizeof(*sp) + cachesize, GFP_KERNEL); if (!sp) @@ -633,8 +642,7 @@ free_session(struct kref *kref) ses = container_of(kref, struct nfsd4_session, se_ref); spin_lock(&nfsd_drc_lock); - mem = ses->se_fchannel.maxreqs - * (ses->se_fchannel.maxresp_cached - NFSD_MIN_HDR_SEQ_SZ); + mem = ses->se_fchannel.maxreqs * slot_bytes(&ses->se_fchannel); nfsd_drc_mem_used -= mem; spin_unlock(&nfsd_drc_lock); free_session_slots(ses); -- cgit v0.10.2 From dc83d6e27fa80babe31c80aa8568f125f72edf57 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Tue, 20 Oct 2009 18:51:34 -0400 Subject: nfsd4: don't try to map gid's in generic rpc code For nfsd we provide users the option of mapping uid's to server-side supplementary group lists. That makes sense for nfsd, but not necessarily for other rpc users (such as the callback client). So move that lookup to svcauth_unix_set_client, which is a program-specific method. Signed-off-by: J. Bruce Fields diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 117f68a..97cc3de 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c @@ -655,23 +655,25 @@ static struct unix_gid *unix_gid_lookup(uid_t uid) return NULL; } -static int unix_gid_find(uid_t uid, struct group_info **gip, - struct svc_rqst *rqstp) +static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp) { - struct unix_gid *ug = unix_gid_lookup(uid); + struct unix_gid *ug; + struct group_info *gi; + int ret; + + ug = unix_gid_lookup(uid); if (!ug) - return -EAGAIN; - switch (cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle)) { + return ERR_PTR(-EAGAIN); + ret = cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle); + switch (ret) { case -ENOENT: - *gip = NULL; - return 0; + return ERR_PTR(-ENOENT); case 0: - *gip = ug->gi; - get_group_info(*gip); + gi = get_group_info(ug->gi); cache_put(&ug->h, &unix_gid_cache); - return 0; + return gi; default: - return -EAGAIN; + return ERR_PTR(-EAGAIN); } } @@ -681,6 +683,8 @@ svcauth_unix_set_client(struct svc_rqst *rqstp) struct sockaddr_in *sin; struct sockaddr_in6 *sin6, sin6_storage; struct ip_map *ipm; + struct group_info *gi; + struct svc_cred *cred = &rqstp->rq_cred; switch (rqstp->rq_addr.ss_family) { case AF_INET: @@ -722,6 +726,17 @@ svcauth_unix_set_client(struct svc_rqst *rqstp) ip_map_cached_put(rqstp, ipm); break; } + + gi = unix_gid_find(cred->cr_uid, rqstp); + switch (PTR_ERR(gi)) { + case -EAGAIN: + return SVC_DROP; + case -ENOENT: + break; + default: + put_group_info(cred->cr_group_info); + cred->cr_group_info = gi; + } return SVC_OK; } @@ -818,19 +833,11 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) slen = svc_getnl(argv); /* gids length */ if (slen > 16 || (len -= (slen + 2)*4) < 0) goto badcred; - if (unix_gid_find(cred->cr_uid, &cred->cr_group_info, rqstp) - == -EAGAIN) + cred->cr_group_info = groups_alloc(slen); + if (cred->cr_group_info == NULL) return SVC_DROP; - if (cred->cr_group_info == NULL) { - cred->cr_group_info = groups_alloc(slen); - if (cred->cr_group_info == NULL) - return SVC_DROP; - for (i = 0; i < slen; i++) - GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv); - } else { - for (i = 0; i < slen ; i++) - svc_getnl(argv); - } + for (i = 0; i < slen; i++) + GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv); if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { *authp = rpc_autherr_badverf; return SVC_DENIED; -- cgit v0.10.2 From aba24d71580180dfdf6a1a83a5858a1c048fd785 Mon Sep 17 00:00:00 2001 From: Frank Filz Date: Wed, 21 Oct 2009 16:45:02 -0700 Subject: nfsd: Fix sort_pacl in fs/nfsd/nf4acl.c to actually sort groups We have been doing some extensive testing of Linux support for ACLs on NFDS v4. We have noticed that the server rejects ACLs where the groups are out of order, for example, the following ACL is rejected: A::OWNER@:rwaxtTcCy A::user101@domain:rwaxtcy A::GROUP@:rwaxtcy A:g:group102@domain:rwaxtcy A:g:group101@domain:rwaxtcy A::EVERYONE@:rwaxtcy Examining the server code, I found that after converting an NFS v4 ACL to POSIX, sort_pacl is called to sort the user ACEs and group ACEs. Unfortunately, a minor bug causes the group sort to be skipped. Signed-off-by: Frank Filz Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 725d02f..6d9c6aa 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -389,7 +389,7 @@ sort_pacl(struct posix_acl *pacl) sort_pacl_range(pacl, 1, i-1); BUG_ON(pacl->a_entries[i].e_tag != ACL_GROUP_OBJ); - j = i++; + j = ++i; while (pacl->a_entries[j].e_tag == ACL_GROUP) j++; sort_pacl_range(pacl, i, j-1); -- cgit v0.10.2 From e7cb55b946a2182c347047dc903c6ed0daef100c Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 28 Oct 2009 13:33:08 +0000 Subject: kmemleak: Do not use off-slab management with SLAB_NOLEAKTRACE With the slab allocator, if off-slab management is enabled for the kmem_caches used by kmemleak, it leads to recursive calls into kmemleak_alloc(). Off-slab management can be triggered by other config options increasing the slab size, e.g. DEBUG_PAGEALLOC. Reported-by: Tetsuo Handa Reviewed-by: Pekka Enberg Cc: Christoph Lameter Signed-off-by: Catalin Marinas diff --git a/mm/slab.c b/mm/slab.c index 7dfa481..646db30 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2261,9 +2261,11 @@ kmem_cache_create (const char *name, size_t size, size_t align, /* * Determine if the slab management is 'on' or 'off' slab. * (bootstrapping cannot cope with offslab caches so don't do - * it too early on.) + * it too early on. Always use on-slab management when + * SLAB_NOLEAKTRACE to avoid recursive calls into kmemleak) */ - if ((size >= (PAGE_SIZE >> 3)) && !slab_early_init) + if ((size >= (PAGE_SIZE >> 3)) && !slab_early_init && + !(flags & SLAB_NOLEAKTRACE)) /* * Size is large, assume best to place the slab management obj * off-slab (should allow better packing of objs). -- cgit v0.10.2 From c017b4be3e84176cab10eca5e6c4faeb8cfc6f3e Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 28 Oct 2009 13:33:09 +0000 Subject: kmemleak: Simplify the kmemleak_scan_area() function prototype This function was taking non-necessary arguments which can be determined by kmemleak. The patch also modifies the calling sites. Signed-off-by: Catalin Marinas Cc: Pekka Enberg Cc: Christoph Lameter Cc: Rusty Russell diff --git a/include/linux/kmemleak.h b/include/linux/kmemleak.h index 3c7497d..99d9a67 100644 --- a/include/linux/kmemleak.h +++ b/include/linux/kmemleak.h @@ -32,8 +32,7 @@ extern void kmemleak_padding(const void *ptr, unsigned long offset, size_t size) __ref; extern void kmemleak_not_leak(const void *ptr) __ref; extern void kmemleak_ignore(const void *ptr) __ref; -extern void kmemleak_scan_area(const void *ptr, unsigned long offset, - size_t length, gfp_t gfp) __ref; +extern void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) __ref; extern void kmemleak_no_scan(const void *ptr) __ref; static inline void kmemleak_alloc_recursive(const void *ptr, size_t size, @@ -84,8 +83,7 @@ static inline void kmemleak_not_leak(const void *ptr) static inline void kmemleak_ignore(const void *ptr) { } -static inline void kmemleak_scan_area(const void *ptr, unsigned long offset, - size_t length, gfp_t gfp) +static inline void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) { } static inline void kmemleak_erase(void **ptr) diff --git a/kernel/module.c b/kernel/module.c index 8b7d880..1eb9520 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2043,9 +2043,7 @@ static void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr, unsigned int i; /* only scan the sections containing data */ - kmemleak_scan_area(mod->module_core, (unsigned long)mod - - (unsigned long)mod->module_core, - sizeof(struct module), GFP_KERNEL); + kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL); for (i = 1; i < hdr->e_shnum; i++) { if (!(sechdrs[i].sh_flags & SHF_ALLOC)) @@ -2054,8 +2052,7 @@ static void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr, && strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) != 0) continue; - kmemleak_scan_area(mod->module_core, sechdrs[i].sh_addr - - (unsigned long)mod->module_core, + kmemleak_scan_area((void *)sechdrs[i].sh_addr, sechdrs[i].sh_size, GFP_KERNEL); } } diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 8bf765c..9610635 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -119,8 +119,8 @@ /* scanning area inside a memory block */ struct kmemleak_scan_area { struct hlist_node node; - unsigned long offset; - size_t length; + unsigned long start; + size_t size; }; #define KMEMLEAK_GREY 0 @@ -241,8 +241,6 @@ struct early_log { const void *ptr; /* allocated/freed memory block */ size_t size; /* memory block size */ int min_count; /* minimum reference count */ - unsigned long offset; /* scan area offset */ - size_t length; /* scan area length */ unsigned long trace[MAX_TRACE]; /* stack trace */ unsigned int trace_len; /* stack trace length */ }; @@ -720,14 +718,13 @@ static void make_black_object(unsigned long ptr) * Add a scanning area to the object. If at least one such area is added, * kmemleak will only scan these ranges rather than the whole memory block. */ -static void add_scan_area(unsigned long ptr, unsigned long offset, - size_t length, gfp_t gfp) +static void add_scan_area(unsigned long ptr, size_t size, gfp_t gfp) { unsigned long flags; struct kmemleak_object *object; struct kmemleak_scan_area *area; - object = find_and_get_object(ptr, 0); + object = find_and_get_object(ptr, 1); if (!object) { kmemleak_warn("Adding scan area to unknown object at 0x%08lx\n", ptr); @@ -741,7 +738,7 @@ static void add_scan_area(unsigned long ptr, unsigned long offset, } spin_lock_irqsave(&object->lock, flags); - if (offset + length > object->size) { + if (ptr + size > object->pointer + object->size) { kmemleak_warn("Scan area larger than object 0x%08lx\n", ptr); dump_object_info(object); kmem_cache_free(scan_area_cache, area); @@ -749,8 +746,8 @@ static void add_scan_area(unsigned long ptr, unsigned long offset, } INIT_HLIST_NODE(&area->node); - area->offset = offset; - area->length = length; + area->start = ptr; + area->size = size; hlist_add_head(&area->node, &object->area_list); out_unlock: @@ -786,7 +783,7 @@ static void object_no_scan(unsigned long ptr) * processed later once kmemleak is fully initialized. */ static void __init log_early(int op_type, const void *ptr, size_t size, - int min_count, unsigned long offset, size_t length) + int min_count) { unsigned long flags; struct early_log *log; @@ -808,8 +805,6 @@ static void __init log_early(int op_type, const void *ptr, size_t size, log->ptr = ptr; log->size = size; log->min_count = min_count; - log->offset = offset; - log->length = length; if (op_type == KMEMLEAK_ALLOC) log->trace_len = __save_stack_trace(log->trace); crt_early_log++; @@ -858,7 +853,7 @@ void __ref kmemleak_alloc(const void *ptr, size_t size, int min_count, if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) create_object((unsigned long)ptr, size, min_count, gfp); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_ALLOC, ptr, size, min_count, 0, 0); + log_early(KMEMLEAK_ALLOC, ptr, size, min_count); } EXPORT_SYMBOL_GPL(kmemleak_alloc); @@ -873,7 +868,7 @@ void __ref kmemleak_free(const void *ptr) if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) delete_object_full((unsigned long)ptr); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_FREE, ptr, 0, 0, 0, 0); + log_early(KMEMLEAK_FREE, ptr, 0, 0); } EXPORT_SYMBOL_GPL(kmemleak_free); @@ -888,7 +883,7 @@ void __ref kmemleak_free_part(const void *ptr, size_t size) if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) delete_object_part((unsigned long)ptr, size); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_FREE_PART, ptr, size, 0, 0, 0); + log_early(KMEMLEAK_FREE_PART, ptr, size, 0); } EXPORT_SYMBOL_GPL(kmemleak_free_part); @@ -903,7 +898,7 @@ void __ref kmemleak_not_leak(const void *ptr) if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) make_gray_object((unsigned long)ptr); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_NOT_LEAK, ptr, 0, 0, 0, 0); + log_early(KMEMLEAK_NOT_LEAK, ptr, 0, 0); } EXPORT_SYMBOL(kmemleak_not_leak); @@ -919,22 +914,21 @@ void __ref kmemleak_ignore(const void *ptr) if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) make_black_object((unsigned long)ptr); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_IGNORE, ptr, 0, 0, 0, 0); + log_early(KMEMLEAK_IGNORE, ptr, 0, 0); } EXPORT_SYMBOL(kmemleak_ignore); /* * Limit the range to be scanned in an allocated memory block. */ -void __ref kmemleak_scan_area(const void *ptr, unsigned long offset, - size_t length, gfp_t gfp) +void __ref kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) { pr_debug("%s(0x%p)\n", __func__, ptr); if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) - add_scan_area((unsigned long)ptr, offset, length, gfp); + add_scan_area((unsigned long)ptr, size, gfp); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_SCAN_AREA, ptr, 0, 0, offset, length); + log_early(KMEMLEAK_SCAN_AREA, ptr, size, 0); } EXPORT_SYMBOL(kmemleak_scan_area); @@ -948,7 +942,7 @@ void __ref kmemleak_no_scan(const void *ptr) if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) object_no_scan((unsigned long)ptr); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_NO_SCAN, ptr, 0, 0, 0, 0); + log_early(KMEMLEAK_NO_SCAN, ptr, 0, 0); } EXPORT_SYMBOL(kmemleak_no_scan); @@ -1075,9 +1069,9 @@ static void scan_object(struct kmemleak_object *object) } } else hlist_for_each_entry(area, elem, &object->area_list, node) - scan_block((void *)(object->pointer + area->offset), - (void *)(object->pointer + area->offset - + area->length), object, 0); + scan_block((void *)area->start, + (void *)(area->start + area->size), + object, 0); out: spin_unlock_irqrestore(&object->lock, flags); } @@ -1642,8 +1636,7 @@ void __init kmemleak_init(void) kmemleak_ignore(log->ptr); break; case KMEMLEAK_SCAN_AREA: - kmemleak_scan_area(log->ptr, log->offset, log->length, - GFP_KERNEL); + kmemleak_scan_area(log->ptr, log->size, GFP_KERNEL); break; case KMEMLEAK_NO_SCAN: kmemleak_no_scan(log->ptr); diff --git a/mm/slab.c b/mm/slab.c index 646db30..d2713a9 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2584,8 +2584,8 @@ static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp, * kmemleak does not treat the ->s_mem pointer as a reference * to the object. Otherwise we will not report the leak. */ - kmemleak_scan_area(slabp, offsetof(struct slab, list), - sizeof(struct list_head), local_flags); + kmemleak_scan_area(&slabp->list, sizeof(struct list_head), + local_flags); if (!slabp) return NULL; } else { -- cgit v0.10.2 From a6f5aa1ea05686ad6e84593a00a04161e6dfb3a3 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 28 Oct 2009 13:33:10 +0000 Subject: kmemleak: Scan the _ftrace_events section in modules This section contains pointers to allocated objects and not scanning it leads to false positives. Reported-by: Zdenek Kabelac Acked-by: Rusty Russell Signed-off-by: Catalin Marinas diff --git a/kernel/module.c b/kernel/module.c index 1eb9520..dd29ba4 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2380,6 +2380,12 @@ static noinline struct module *load_module(void __user *umod, "_ftrace_events", sizeof(*mod->trace_events), &mod->num_trace_events); + /* + * This section contains pointers to allocated objects in the trace + * code and not scanning it leads to false positives. + */ + kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) * + mod->num_trace_events, GFP_KERNEL); #endif #ifdef CONFIG_FTRACE_MCOUNT_RECORD /* sechdrs[0].sh_size is always zero */ -- cgit v0.10.2 From 0587da40be78d3704a48d3e9a619183891727f5f Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 28 Oct 2009 13:33:11 +0000 Subject: kmemleak: Release the object lock before calling put_object() The put_object() function may free the object if the use_count dropped to 0. There shouldn't be further accesses to such object unless it is known that the use_count is non-zero. Signed-off-by: Catalin Marinas diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 9610635..f06c092 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -1025,11 +1025,14 @@ static void scan_block(void *_start, void *_end, * added to the gray_list. */ object->count++; - if (color_gray(object)) + if (color_gray(object)) { list_add_tail(&object->gray_list, &gray_list); - else - put_object(object); + spin_unlock_irqrestore(&object->lock, flags); + continue; + } + spin_unlock_irqrestore(&object->lock, flags); + put_object(object); } } -- cgit v0.10.2 From fefdd336b2a2f7617e0c8a0777c731d9ed6454ae Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 28 Oct 2009 13:33:12 +0000 Subject: kmemleak: Show the age of an unreferenced object The jiffies shown for unreferenced objects isn't always meaningful to people debugging kernel memory leaks. This patch adds the age as well to the displayed information. Signed-off-by: Catalin Marinas diff --git a/mm/kmemleak.c b/mm/kmemleak.c index f06c092..ce79d91 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -346,11 +346,13 @@ static void print_unreferenced(struct seq_file *seq, struct kmemleak_object *object) { int i; + unsigned int msecs_age = jiffies_to_msecs(jiffies - object->jiffies); seq_printf(seq, "unreferenced object 0x%08lx (size %zu):\n", object->pointer, object->size); - seq_printf(seq, " comm \"%s\", pid %d, jiffies %lu\n", - object->comm, object->pid, object->jiffies); + seq_printf(seq, " comm \"%s\", pid %d, jiffies %lu (age %d.%03ds)\n", + object->comm, object->pid, object->jiffies, + msecs_age / 1000, msecs_age % 1000); hex_dump_object(seq, object); seq_printf(seq, " backtrace:\n"); -- cgit v0.10.2 From 04609ccc40c4e8f3eabe8894eb0de881c8b984fd Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 28 Oct 2009 13:33:12 +0000 Subject: kmemleak: Reduce the false positives by checking for modified objects If an object was modified since it was previously suspected as leak, do not report it. The modification check is done by calculating the checksum (CRC32) of such object. Several false positives are caused by objects being removed from linked lists (e.g. allocation pools) and temporarily breaking the reference chain since kmemleak runs concurrently with such list mutation primitives. Signed-off-by: Catalin Marinas diff --git a/mm/kmemleak.c b/mm/kmemleak.c index ce79d91..002adc3 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -93,6 +93,7 @@ #include #include #include +#include #include #include @@ -108,7 +109,6 @@ #define MSECS_MIN_AGE 5000 /* minimum object age for reporting */ #define SECS_FIRST_SCAN 60 /* delay before the first scan */ #define SECS_SCAN_WAIT 600 /* subsequent auto scanning delay */ -#define GRAY_LIST_PASSES 25 /* maximum number of gray list scans */ #define MAX_SCAN_SIZE 4096 /* maximum size of a scanned block */ #define BYTES_PER_POINTER sizeof(void *) @@ -149,6 +149,8 @@ struct kmemleak_object { int min_count; /* the total number of pointers found pointing to this object */ int count; + /* checksum for detecting modified objects */ + u32 checksum; /* memory ranges to be scanned inside an object (empty for all) */ struct hlist_head area_list; unsigned long trace[MAX_TRACE]; @@ -164,8 +166,6 @@ struct kmemleak_object { #define OBJECT_REPORTED (1 << 1) /* flag set to not scan the object */ #define OBJECT_NO_SCAN (1 << 2) -/* flag set on newly allocated objects */ -#define OBJECT_NEW (1 << 3) /* number of bytes to print per line; must be 16 or 32 */ #define HEX_ROW_SIZE 16 @@ -321,11 +321,6 @@ static bool color_gray(const struct kmemleak_object *object) object->count >= object->min_count; } -static bool color_black(const struct kmemleak_object *object) -{ - return object->min_count == KMEMLEAK_BLACK; -} - /* * Objects are considered unreferenced only if their color is white, they have * not be deleted and have a minimum age to avoid false positives caused by @@ -333,7 +328,7 @@ static bool color_black(const struct kmemleak_object *object) */ static bool unreferenced_object(struct kmemleak_object *object) { - return (object->flags & OBJECT_ALLOCATED) && color_white(object) && + return (color_white(object) && object->flags & OBJECT_ALLOCATED) && time_before_eq(object->jiffies + jiffies_min_age, jiffies_last_scan); } @@ -381,6 +376,7 @@ static void dump_object_info(struct kmemleak_object *object) pr_notice(" min_count = %d\n", object->min_count); pr_notice(" count = %d\n", object->count); pr_notice(" flags = 0x%lx\n", object->flags); + pr_notice(" checksum = %d\n", object->checksum); pr_notice(" backtrace:\n"); print_stack_trace(&trace, 4); } @@ -522,12 +518,13 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, INIT_HLIST_HEAD(&object->area_list); spin_lock_init(&object->lock); atomic_set(&object->use_count, 1); - object->flags = OBJECT_ALLOCATED | OBJECT_NEW; + object->flags = OBJECT_ALLOCATED; object->pointer = ptr; object->size = size; object->min_count = min_count; - object->count = -1; /* no color initially */ + object->count = 0; /* white color initially */ object->jiffies = jiffies; + object->checksum = 0; /* task information */ if (in_irq()) { @@ -949,6 +946,20 @@ void __ref kmemleak_no_scan(const void *ptr) EXPORT_SYMBOL(kmemleak_no_scan); /* + * Update an object's checksum and return true if it was modified. + */ +static bool update_checksum(struct kmemleak_object *object) +{ + u32 old_csum = object->checksum; + + if (!kmemcheck_is_obj_initialized(object->pointer, object->size)) + return false; + + object->checksum = crc32(0, (void *)object->pointer, object->size); + return object->checksum != old_csum; +} + +/* * Memory scanning is a long process and it needs to be interruptable. This * function checks whether such interrupt condition occured. */ @@ -1082,6 +1093,39 @@ out: } /* + * Scan the objects already referenced (gray objects). More objects will be + * referenced and, if there are no memory leaks, all the objects are scanned. + */ +static void scan_gray_list(void) +{ + struct kmemleak_object *object, *tmp; + + /* + * The list traversal is safe for both tail additions and removals + * from inside the loop. The kmemleak objects cannot be freed from + * outside the loop because their use_count was incremented. + */ + object = list_entry(gray_list.next, typeof(*object), gray_list); + while (&object->gray_list != &gray_list) { + cond_resched(); + + /* may add new objects to the list */ + if (!scan_should_stop()) + scan_object(object); + + tmp = list_entry(object->gray_list.next, typeof(*object), + gray_list); + + /* remove the object from the list and release it */ + list_del(&object->gray_list); + put_object(object); + + object = tmp; + } + WARN_ON(!list_empty(&gray_list)); +} + +/* * Scan data sections and all the referenced memory blocks allocated via the * kernel's standard allocators. This function must be called with the * scan_mutex held. @@ -1089,10 +1133,9 @@ out: static void kmemleak_scan(void) { unsigned long flags; - struct kmemleak_object *object, *tmp; + struct kmemleak_object *object; int i; int new_leaks = 0; - int gray_list_pass = 0; jiffies_last_scan = jiffies; @@ -1113,7 +1156,6 @@ static void kmemleak_scan(void) #endif /* reset the reference count (whiten the object) */ object->count = 0; - object->flags &= ~OBJECT_NEW; if (color_gray(object) && get_object(object)) list_add_tail(&object->gray_list, &gray_list); @@ -1171,62 +1213,36 @@ static void kmemleak_scan(void) /* * Scan the objects already referenced from the sections scanned - * above. More objects will be referenced and, if there are no memory - * leaks, all the objects will be scanned. The list traversal is safe - * for both tail additions and removals from inside the loop. The - * kmemleak objects cannot be freed from outside the loop because their - * use_count was increased. + * above. */ -repeat: - object = list_entry(gray_list.next, typeof(*object), gray_list); - while (&object->gray_list != &gray_list) { - cond_resched(); - - /* may add new objects to the list */ - if (!scan_should_stop()) - scan_object(object); - - tmp = list_entry(object->gray_list.next, typeof(*object), - gray_list); - - /* remove the object from the list and release it */ - list_del(&object->gray_list); - put_object(object); - - object = tmp; - } - - if (scan_should_stop() || ++gray_list_pass >= GRAY_LIST_PASSES) - goto scan_end; + scan_gray_list(); /* - * Check for new objects allocated during this scanning and add them - * to the gray list. + * Check for new or unreferenced objects modified since the previous + * scan and color them gray until the next scan. */ rcu_read_lock(); list_for_each_entry_rcu(object, &object_list, object_list) { spin_lock_irqsave(&object->lock, flags); - if ((object->flags & OBJECT_NEW) && !color_black(object) && - get_object(object)) { - object->flags &= ~OBJECT_NEW; + if (color_white(object) && (object->flags & OBJECT_ALLOCATED) + && update_checksum(object) && get_object(object)) { + /* color it gray temporarily */ + object->count = object->min_count; list_add_tail(&object->gray_list, &gray_list); } spin_unlock_irqrestore(&object->lock, flags); } rcu_read_unlock(); - if (!list_empty(&gray_list)) - goto repeat; - -scan_end: - WARN_ON(!list_empty(&gray_list)); + /* + * Re-scan the gray list for modified unreferenced objects. + */ + scan_gray_list(); /* - * If scanning was stopped or new objects were being allocated at a - * higher rate than gray list scanning, do not report any new - * unreferenced objects. + * If scanning was stopped do not report any new unreferenced objects. */ - if (scan_should_stop() || gray_list_pass >= GRAY_LIST_PASSES) + if (scan_should_stop()) return; /* -- cgit v0.10.2 From e6aabe0cac14a495d42f629a803c5e221089bae8 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 15 Oct 2009 14:54:03 +0200 Subject: ocfs2: Always include ACL support To become consistent with filesystems such as XFS or BTRFS, make posix ACLs always available. This also reduces possibility of misconfiguration on admin's side. Signed-off-by: Jan Kara Signed-off-by: Joel Becker diff --git a/fs/ocfs2/Kconfig b/fs/ocfs2/Kconfig index 701b7a3..0d84066 100644 --- a/fs/ocfs2/Kconfig +++ b/fs/ocfs2/Kconfig @@ -6,6 +6,7 @@ config OCFS2_FS select CRC32 select QUOTA select QUOTA_TREE + select FS_POSIX_ACL help OCFS2 is a general purpose extent based shared disk cluster file system with many similarities to ext3. It supports 64 bit inode @@ -74,12 +75,3 @@ config OCFS2_DEBUG_FS This option will enable expensive consistency checks. Enable this option for debugging only as it is likely to decrease performance of the filesystem. - -config OCFS2_FS_POSIX_ACL - bool "OCFS2 POSIX Access Control Lists" - depends on OCFS2_FS - select FS_POSIX_ACL - default n - help - Posix Access Control Lists (ACLs) support permissions for users and - groups beyond the owner/group/world scheme. diff --git a/fs/ocfs2/Makefile b/fs/ocfs2/Makefile index 31f25ce..600d2d2 100644 --- a/fs/ocfs2/Makefile +++ b/fs/ocfs2/Makefile @@ -39,11 +39,8 @@ ocfs2-objs := \ ver.o \ quota_local.o \ quota_global.o \ - xattr.o - -ifeq ($(CONFIG_OCFS2_FS_POSIX_ACL),y) -ocfs2-objs += acl.o -endif + xattr.o \ + acl.o ocfs2_stackglue-objs := stackglue.o ocfs2_stack_o2cb-objs := stack_o2cb.o diff --git a/fs/ocfs2/acl.h b/fs/ocfs2/acl.h index 8f6389e..5c5d31f 100644 --- a/fs/ocfs2/acl.h +++ b/fs/ocfs2/acl.h @@ -26,8 +26,6 @@ struct ocfs2_acl_entry { __le32 e_id; }; -#ifdef CONFIG_OCFS2_FS_POSIX_ACL - extern int ocfs2_check_acl(struct inode *, int); extern int ocfs2_acl_chmod(struct inode *); extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *, @@ -35,24 +33,4 @@ extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *, struct ocfs2_alloc_context *, struct ocfs2_alloc_context *); -#else /* CONFIG_OCFS2_FS_POSIX_ACL*/ - -#define ocfs2_check_acl NULL -static inline int ocfs2_acl_chmod(struct inode *inode) -{ - return 0; -} -static inline int ocfs2_init_acl(handle_t *handle, - struct inode *inode, - struct inode *dir, - struct buffer_head *di_bh, - struct buffer_head *dir_bh, - struct ocfs2_alloc_context *meta_ac, - struct ocfs2_alloc_context *data_ac) -{ - return 0; -} - -#endif /* CONFIG_OCFS2_FS_POSIX_ACL*/ - #endif /* OCFS2_ACL_H */ diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 9606730..da7d33a 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1413,19 +1413,12 @@ static int ocfs2_parse_options(struct super_block *sb, } mopt->mount_opt |= OCFS2_MOUNT_GRPQUOTA; break; -#ifdef CONFIG_OCFS2_FS_POSIX_ACL case Opt_acl: mopt->mount_opt |= OCFS2_MOUNT_POSIX_ACL; break; case Opt_noacl: mopt->mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; break; -#else - case Opt_acl: - case Opt_noacl: - printk(KERN_INFO "ocfs2 (no)acl options not supported\n"); - break; -#endif default: mlog(ML_ERROR, "Unrecognized mount option \"%s\" " @@ -1502,12 +1495,10 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt) if (opts & OCFS2_MOUNT_INODE64) seq_printf(s, ",inode64"); -#ifdef CONFIG_OCFS2_FS_POSIX_ACL if (opts & OCFS2_MOUNT_POSIX_ACL) seq_printf(s, ",acl"); else seq_printf(s, ",noacl"); -#endif return 0; } diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index fe34190..923e950e 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -98,10 +98,8 @@ static struct ocfs2_xattr_def_value_root def_xv = { struct xattr_handler *ocfs2_xattr_handlers[] = { &ocfs2_xattr_user_handler, -#ifdef CONFIG_OCFS2_FS_POSIX_ACL &ocfs2_xattr_acl_access_handler, &ocfs2_xattr_acl_default_handler, -#endif &ocfs2_xattr_trusted_handler, &ocfs2_xattr_security_handler, NULL @@ -109,12 +107,10 @@ struct xattr_handler *ocfs2_xattr_handlers[] = { static struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = { [OCFS2_XATTR_INDEX_USER] = &ocfs2_xattr_user_handler, -#ifdef CONFIG_OCFS2_FS_POSIX_ACL [OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS] = &ocfs2_xattr_acl_access_handler, [OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT] = &ocfs2_xattr_acl_default_handler, -#endif [OCFS2_XATTR_INDEX_TRUSTED] = &ocfs2_xattr_trusted_handler, [OCFS2_XATTR_INDEX_SECURITY] = &ocfs2_xattr_security_handler, }; diff --git a/fs/ocfs2/xattr.h b/fs/ocfs2/xattr.h index 08e3638..abd72a4 100644 --- a/fs/ocfs2/xattr.h +++ b/fs/ocfs2/xattr.h @@ -40,10 +40,8 @@ struct ocfs2_security_xattr_info { extern struct xattr_handler ocfs2_xattr_user_handler; extern struct xattr_handler ocfs2_xattr_trusted_handler; extern struct xattr_handler ocfs2_xattr_security_handler; -#ifdef CONFIG_OCFS2_FS_POSIX_ACL extern struct xattr_handler ocfs2_xattr_acl_access_handler; extern struct xattr_handler ocfs2_xattr_acl_default_handler; -#endif extern struct xattr_handler *ocfs2_xattr_handlers[]; ssize_t ocfs2_listxattr(struct dentry *, char *, size_t); -- cgit v0.10.2 From 5297aad80cd3a3e62116e0a0b29116ccd8ae397d Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 15 Oct 2009 14:54:04 +0200 Subject: ocfs2: Make acl use the default Change acl mount options handling to match the one of XFS and BTRFS and hopefully it is also easier to use now. When admin does not specify any acl mount option, acls are enabled if and only if the filesystem has xattr feature enabled. If admin specifies 'acl' mount option, we fail the mount if the filesystem does not have xattr feature and thus acls cannot be enabled. Signed-off-by: Jan Kara Signed-off-by: Joel Becker diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index eae4046..35ad46c 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -250,9 +250,11 @@ enum ocfs2_mount_options OCFS2_MOUNT_LOCALFLOCKS = 1 << 5, /* No cluster aware user file locks */ OCFS2_MOUNT_NOUSERXATTR = 1 << 6, /* No user xattr */ OCFS2_MOUNT_INODE64 = 1 << 7, /* Allow inode numbers > 2^32 */ - OCFS2_MOUNT_POSIX_ACL = 1 << 8, /* POSIX access control lists */ - OCFS2_MOUNT_USRQUOTA = 1 << 9, /* We support user quotas */ - OCFS2_MOUNT_GRPQUOTA = 1 << 10, /* We support group quotas */ + OCFS2_MOUNT_POSIX_ACL = 1 << 8, /* Force POSIX access control lists */ + OCFS2_MOUNT_NO_POSIX_ACL = 1 << 9, /* Disable POSIX access + control lists */ + OCFS2_MOUNT_USRQUOTA = 1 << 10, /* We support user quotas */ + OCFS2_MOUNT_GRPQUOTA = 1 << 11, /* We support group quotas */ }; #define OCFS2_OSB_SOFT_RO 0x0001 diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index da7d33a..a5116b9 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -100,6 +100,8 @@ struct mount_options static int ocfs2_parse_options(struct super_block *sb, char *options, struct mount_options *mopt, int is_remount); +static int ocfs2_check_set_options(struct super_block *sb, + struct mount_options *options); static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt); static void ocfs2_put_super(struct super_block *sb); static int ocfs2_mount_volume(struct super_block *sb); @@ -600,7 +602,8 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data) lock_kernel(); - if (!ocfs2_parse_options(sb, data, &parsed_options, 1)) { + if (!ocfs2_parse_options(sb, data, &parsed_options, 1) || + !ocfs2_check_set_options(sb, &parsed_options)) { ret = -EINVAL; goto out; } @@ -691,8 +694,6 @@ unlock_osb: if (!ret) { /* Only save off the new mount options in case of a successful * remount. */ - if (!(osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_XATTR)) - parsed_options.mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; osb->s_mount_opt = parsed_options.mount_opt; osb->s_atime_quantum = parsed_options.atime_quantum; osb->preferred_slot = parsed_options.slot; @@ -1011,31 +1012,16 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) brelse(bh); bh = NULL; - if (!(osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_XATTR)) - parsed_options.mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; - + if (!ocfs2_check_set_options(sb, &parsed_options)) { + status = -EINVAL; + goto read_super_error; + } osb->s_mount_opt = parsed_options.mount_opt; osb->s_atime_quantum = parsed_options.atime_quantum; osb->preferred_slot = parsed_options.slot; osb->osb_commit_interval = parsed_options.commit_interval; osb->local_alloc_default_bits = ocfs2_megabytes_to_clusters(sb, parsed_options.localalloc_opt); osb->local_alloc_bits = osb->local_alloc_default_bits; - if (osb->s_mount_opt & OCFS2_MOUNT_USRQUOTA && - !OCFS2_HAS_RO_COMPAT_FEATURE(sb, - OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) { - status = -EINVAL; - mlog(ML_ERROR, "User quotas were requested, but this " - "filesystem does not have the feature enabled.\n"); - goto read_super_error; - } - if (osb->s_mount_opt & OCFS2_MOUNT_GRPQUOTA && - !OCFS2_HAS_RO_COMPAT_FEATURE(sb, - OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) { - status = -EINVAL; - mlog(ML_ERROR, "Group quotas were requested, but this " - "filesystem does not have the feature enabled.\n"); - goto read_super_error; - } status = ocfs2_verify_userspace_stack(osb, &parsed_options); if (status) @@ -1245,6 +1231,40 @@ static struct file_system_type ocfs2_fs_type = { .next = NULL }; +static int ocfs2_check_set_options(struct super_block *sb, + struct mount_options *options) +{ + if (options->mount_opt & OCFS2_MOUNT_USRQUOTA && + !OCFS2_HAS_RO_COMPAT_FEATURE(sb, + OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) { + mlog(ML_ERROR, "User quotas were requested, but this " + "filesystem does not have the feature enabled.\n"); + return 0; + } + if (options->mount_opt & OCFS2_MOUNT_GRPQUOTA && + !OCFS2_HAS_RO_COMPAT_FEATURE(sb, + OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) { + mlog(ML_ERROR, "Group quotas were requested, but this " + "filesystem does not have the feature enabled.\n"); + return 0; + } + if (options->mount_opt & OCFS2_MOUNT_POSIX_ACL && + !OCFS2_HAS_INCOMPAT_FEATURE(sb, OCFS2_FEATURE_INCOMPAT_XATTR)) { + mlog(ML_ERROR, "ACL support requested but extended attributes " + "feature is not enabled\n"); + return 0; + } + /* No ACL setting specified? Use XATTR feature... */ + if (!(options->mount_opt & (OCFS2_MOUNT_POSIX_ACL | + OCFS2_MOUNT_NO_POSIX_ACL))) { + if (OCFS2_HAS_INCOMPAT_FEATURE(sb, OCFS2_FEATURE_INCOMPAT_XATTR)) + options->mount_opt |= OCFS2_MOUNT_POSIX_ACL; + else + options->mount_opt |= OCFS2_MOUNT_NO_POSIX_ACL; + } + return 1; +} + static int ocfs2_parse_options(struct super_block *sb, char *options, struct mount_options *mopt, @@ -1392,31 +1412,17 @@ static int ocfs2_parse_options(struct super_block *sb, mopt->mount_opt |= OCFS2_MOUNT_INODE64; break; case Opt_usrquota: - /* We check only on remount, otherwise features - * aren't yet initialized. */ - if (is_remount && !OCFS2_HAS_RO_COMPAT_FEATURE(sb, - OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) { - mlog(ML_ERROR, "User quota requested but " - "filesystem feature is not set\n"); - status = 0; - goto bail; - } mopt->mount_opt |= OCFS2_MOUNT_USRQUOTA; break; case Opt_grpquota: - if (is_remount && !OCFS2_HAS_RO_COMPAT_FEATURE(sb, - OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) { - mlog(ML_ERROR, "Group quota requested but " - "filesystem feature is not set\n"); - status = 0; - goto bail; - } mopt->mount_opt |= OCFS2_MOUNT_GRPQUOTA; break; case Opt_acl: mopt->mount_opt |= OCFS2_MOUNT_POSIX_ACL; + mopt->mount_opt &= ~OCFS2_MOUNT_NO_POSIX_ACL; break; case Opt_noacl: + mopt->mount_opt |= OCFS2_MOUNT_NO_POSIX_ACL; mopt->mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; break; default: -- cgit v0.10.2 From 57b09bb5e492c37c1e4273fe4e435ffd1d2ddbe0 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 15 Oct 2009 14:54:05 +0200 Subject: ocfs2: Set MS_POSIXACL on remount We have to set MS_POSIXACL on remount as well. Otherwise VFS would not know we started supporting ACLs after remount and thus ACLs would not work. Signed-off-by: Jan Kara Signed-off-by: Joel Becker diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index a5116b9..45d654c 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -702,6 +702,10 @@ unlock_osb: if (!ocfs2_is_hard_readonly(osb)) ocfs2_set_journal_params(osb); + + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | + ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) ? + MS_POSIXACL : 0); } out: unlock_kernel(); -- cgit v0.10.2 From 5f46c2f25cfbb5faca7550738ac42c4d1491ddc8 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 19 Oct 2009 15:14:24 -0600 Subject: ACPI: dock: convert sysfs attributes to an attribute_group As suggested by Dmitry Torokhov, convert the individual sysfs attributes into an attribute group. This change eliminates quite a bit of copy/paste code in the error handling paths. Signed-off-by: Alex Chiang Reviewed-by: Dmitry Torokhov Acked-by: Shaohua Li Signed-off-by: Len Brown diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 7338b6a..4f2aa98 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -936,6 +936,19 @@ static ssize_t show_dock_type(struct device *dev, } static DEVICE_ATTR(type, S_IRUGO, show_dock_type, NULL); +static struct attribute *dock_attributes[] = { + &dev_attr_docked.attr, + &dev_attr_flags.attr, + &dev_attr_undock.attr, + &dev_attr_uid.attr, + &dev_attr_type.attr, + NULL +}; + +static struct attribute_group dock_attribute_group = { + .attrs = dock_attributes +}; + /** * dock_add - add a new dock station * @handle: the dock station handle @@ -969,9 +982,8 @@ static int dock_add(acpi_handle handle) dock_station_count, NULL, 0); dock_device = dock_station->dock_device; if (IS_ERR(dock_device)) { - kfree(dock_station); - dock_station = NULL; - return PTR_ERR(dock_device); + ret = PTR_ERR(dock_device); + goto out; } platform_device_add_data(dock_device, &dock_station, sizeof(struct dock_station *)); @@ -986,47 +998,9 @@ static int dock_add(acpi_handle handle) if (is_battery(handle)) dock_station->flags |= DOCK_IS_BAT; - ret = device_create_file(&dock_device->dev, &dev_attr_docked); - if (ret) { - printk(KERN_ERR "Error %d adding sysfs file\n", ret); - platform_device_unregister(dock_device); - kfree(dock_station); - dock_station = NULL; - return ret; - } - ret = device_create_file(&dock_device->dev, &dev_attr_undock); - if (ret) { - printk(KERN_ERR "Error %d adding sysfs file\n", ret); - device_remove_file(&dock_device->dev, &dev_attr_docked); - platform_device_unregister(dock_device); - kfree(dock_station); - dock_station = NULL; - return ret; - } - ret = device_create_file(&dock_device->dev, &dev_attr_uid); - if (ret) { - printk(KERN_ERR "Error %d adding sysfs file\n", ret); - device_remove_file(&dock_device->dev, &dev_attr_docked); - device_remove_file(&dock_device->dev, &dev_attr_undock); - platform_device_unregister(dock_device); - kfree(dock_station); - dock_station = NULL; - return ret; - } - ret = device_create_file(&dock_device->dev, &dev_attr_flags); - if (ret) { - printk(KERN_ERR "Error %d adding sysfs file\n", ret); - device_remove_file(&dock_device->dev, &dev_attr_docked); - device_remove_file(&dock_device->dev, &dev_attr_undock); - device_remove_file(&dock_device->dev, &dev_attr_uid); - platform_device_unregister(dock_device); - kfree(dock_station); - dock_station = NULL; - return ret; - } - ret = device_create_file(&dock_device->dev, &dev_attr_type); + ret = sysfs_create_group(&dock_device->dev.kobj, &dock_attribute_group); if (ret) - printk(KERN_ERR"Error %d adding sysfs file\n", ret); + goto err_unregister; /* Find dependent devices */ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, @@ -1036,10 +1010,8 @@ static int dock_add(acpi_handle handle) /* add the dock station as a device dependent on itself */ dd = alloc_dock_dependent_device(handle); if (!dd) { - kfree(dock_station); - dock_station = NULL; ret = -ENOMEM; - goto dock_add_err_unregister; + goto err_rmgroup; } add_dock_dependent_device(dock_station, dd); @@ -1047,15 +1019,14 @@ static int dock_add(acpi_handle handle) list_add(&dock_station->sibling, &dock_stations); return 0; -dock_add_err_unregister: - device_remove_file(&dock_device->dev, &dev_attr_type); - device_remove_file(&dock_device->dev, &dev_attr_docked); - device_remove_file(&dock_device->dev, &dev_attr_undock); - device_remove_file(&dock_device->dev, &dev_attr_uid); - device_remove_file(&dock_device->dev, &dev_attr_flags); +err_rmgroup: + sysfs_remove_group(&dock_device->dev.kobj, &dock_attribute_group); +err_unregister: platform_device_unregister(dock_device); +out: kfree(dock_station); dock_station = NULL; + printk(KERN_ERR "%s encountered error %d\n", __func__, ret); return ret; } @@ -1076,11 +1047,7 @@ static int dock_remove(struct dock_station *dock_station) kfree(dd); /* cleanup sysfs */ - device_remove_file(&dock_device->dev, &dev_attr_type); - device_remove_file(&dock_device->dev, &dev_attr_docked); - device_remove_file(&dock_device->dev, &dev_attr_undock); - device_remove_file(&dock_device->dev, &dev_attr_uid); - device_remove_file(&dock_device->dev, &dev_attr_flags); + sysfs_remove_group(&dock_device->dev.kobj, &dock_attribute_group); platform_device_unregister(dock_device); /* free dock station memory */ -- cgit v0.10.2 From 6ac5c5310ca9d7dd3d7e677c2715b1f06a348330 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 3 Nov 2009 14:58:30 +1030 Subject: cpumask: Use modern cpumask style in arch/x86/kernel/cpu/mcheck/mce-inject.c Note that there's no freeing the cpu var, since this module has no unload function. Signed-off-by: Rusty Russell Cc: Andi Kleen Cc: Huang Ying LKML-Reference: <200911031458.30987.rusty@rustcorp.com.au> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c index 472763d..73734ba 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-inject.c +++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c @@ -74,7 +74,7 @@ static void raise_exception(struct mce *m, struct pt_regs *pregs) m->finished = 0; } -static cpumask_t mce_inject_cpumask; +static cpumask_var_t mce_inject_cpumask; static int mce_raise_notify(struct notifier_block *self, unsigned long val, void *data) @@ -82,9 +82,9 @@ static int mce_raise_notify(struct notifier_block *self, struct die_args *args = (struct die_args *)data; int cpu = smp_processor_id(); struct mce *m = &__get_cpu_var(injectm); - if (val != DIE_NMI_IPI || !cpu_isset(cpu, mce_inject_cpumask)) + if (val != DIE_NMI_IPI || !cpumask_test_cpu(cpu, mce_inject_cpumask)) return NOTIFY_DONE; - cpu_clear(cpu, mce_inject_cpumask); + cpumask_clear_cpu(cpu, mce_inject_cpumask); if (m->inject_flags & MCJ_EXCEPTION) raise_exception(m, args->regs); else if (m->status) @@ -148,22 +148,22 @@ static void raise_mce(struct mce *m) unsigned long start; int cpu; get_online_cpus(); - mce_inject_cpumask = cpu_online_map; - cpu_clear(get_cpu(), mce_inject_cpumask); + cpumask_copy(mce_inject_cpumask, cpu_online_mask); + cpumask_clear_cpu(get_cpu(), mce_inject_cpumask); for_each_online_cpu(cpu) { struct mce *mcpu = &per_cpu(injectm, cpu); if (!mcpu->finished || MCJ_CTX(mcpu->inject_flags) != MCJ_CTX_RANDOM) - cpu_clear(cpu, mce_inject_cpumask); + cpumask_clear_cpu(cpu, mce_inject_cpumask); } - if (!cpus_empty(mce_inject_cpumask)) - apic->send_IPI_mask(&mce_inject_cpumask, NMI_VECTOR); + if (!cpumask_empty(mce_inject_cpumask)) + apic->send_IPI_mask(mce_inject_cpumask, NMI_VECTOR); start = jiffies; - while (!cpus_empty(mce_inject_cpumask)) { + while (!cpumask_empty(mce_inject_cpumask)) { if (!time_before(jiffies, start + 2*HZ)) { printk(KERN_ERR "Timeout waiting for mce inject NMI %lx\n", - *cpus_addr(mce_inject_cpumask)); + *cpumask_bits(mce_inject_cpumask)); break; } cpu_relax(); @@ -210,6 +210,8 @@ static ssize_t mce_write(struct file *filp, const char __user *ubuf, static int inject_init(void) { + if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL)) + return -ENOMEM; printk(KERN_INFO "Machine check injector initialized\n"); mce_chrdev_ops.write = mce_write; register_die_notifier(&mce_raise_nb); -- cgit v0.10.2 From 1b7e0403c6a72d18bebd4f2a6858b6c69c4bd428 Mon Sep 17 00:00:00 2001 From: Peter Staubach Date: Mon, 2 Nov 2009 16:59:07 -0500 Subject: nfsd: register NFS_ACL with rpcbind Modify the NFS server to register the NFS_ACL services with the rpcbind daemon. This allows the client to ping for the existence of the NFS_ACL support via commands such as "rpcinfo -t nfs_acl". This patch also modifies the NFS_ACL support so that responses to version 2 NULLPROC requests can be made. The changelog for the patch which turned off this functionality mentioned something about not registering the NFS_ACL as being part of some tradition. I can't find this tradition and the only other implementation which supports NFS_ACL does register them with the rpcbind daemon. Signed-off-by: Peter Staubach Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c index 4e3219e..e2a17f0 100644 --- a/fs/nfsd/nfs2acl.c +++ b/fs/nfsd/nfs2acl.c @@ -217,6 +217,16 @@ static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p, * XDR encode functions */ +/* + * There must be an encoding function for void results so svc_process + * will work properly. + */ +int +nfsaclsvc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy) +{ + return xdr_ressize_check(rqstp, p); +} + /* GETACL */ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, struct nfsd3_getaclres *resp) @@ -308,7 +318,6 @@ static int nfsaclsvc_release_access(struct svc_rqst *rqstp, __be32 *p, } #define nfsaclsvc_decode_voidargs NULL -#define nfsaclsvc_encode_voidres NULL #define nfsaclsvc_release_void NULL #define nfsd3_fhandleargs nfsd_fhandle #define nfsd3_attrstatres nfsd_attrstat @@ -346,5 +355,5 @@ struct svc_version nfsd_acl_version2 = { .vs_proc = nfsd_acl_procedures2, .vs_dispatch = nfsd_dispatch, .vs_xdrsize = NFS3_SVC_XDRSIZE, - .vs_hidden = 1, + .vs_hidden = 0, }; diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c index 9981dbb..ff73596 100644 --- a/fs/nfsd/nfs3acl.c +++ b/fs/nfsd/nfs3acl.c @@ -264,6 +264,6 @@ struct svc_version nfsd_acl_version3 = { .vs_proc = nfsd_acl_procedures3, .vs_dispatch = nfsd_dispatch, .vs_xdrsize = NFS3_SVC_XDRSIZE, - .vs_hidden = 1, + .vs_hidden = 0, }; -- cgit v0.10.2 From 8c10cbdb4af642d9a2efb45ea89251aaab905360 Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Mon, 19 Oct 2009 12:04:53 +0200 Subject: nfsd: use STATEID_FMT and STATEID_VAL for printing stateids Signed-off-by: Benny Halevy Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 42dab95..c8b621a 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -2416,11 +2416,8 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid)); - dprintk("NFSD: delegation stateid=(%08x/%08x/%08x/%08x)\n\n", - dp->dl_stateid.si_boot, - dp->dl_stateid.si_stateownerid, - dp->dl_stateid.si_fileid, - dp->dl_stateid.si_generation); + dprintk("NFSD: delegation stateid=" STATEID_FMT "\n", + STATEID_VAL(&dp->dl_stateid)); out: if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS && flag == NFS4_OPEN_DELEGATE_NONE @@ -2510,9 +2507,8 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf status = nfs_ok; - dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n", - stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid, - stp->st_stateid.si_fileid, stp->st_stateid.si_generation); + dprintk("%s: stateid=" STATEID_FMT "\n", __func__, + STATEID_VAL(&stp->st_stateid)); out: if (fp) put_nfs4_file(fp); @@ -2678,9 +2674,8 @@ STALE_STATEID(stateid_t *stateid) { if (time_after((unsigned long)boot_time, (unsigned long)stateid->si_boot)) { - dprintk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n", - stateid->si_boot, stateid->si_stateownerid, - stateid->si_fileid, stateid->si_generation); + dprintk("NFSD: stale stateid " STATEID_FMT "!\n", + STATEID_VAL(stateid)); return 1; } return 0; @@ -2692,9 +2687,8 @@ EXPIRED_STATEID(stateid_t *stateid) if (time_before((unsigned long)boot_time, ((unsigned long)stateid->si_boot)) && time_before((unsigned long)(stateid->si_boot + lease_time), get_seconds())) { - dprintk("NFSD: expired stateid (%08x/%08x/%08x/%08x)!\n", - stateid->si_boot, stateid->si_stateownerid, - stateid->si_fileid, stateid->si_generation); + dprintk("NFSD: expired stateid " STATEID_FMT "!\n", + STATEID_VAL(stateid)); return 1; } return 0; @@ -2708,9 +2702,8 @@ stateid_error_map(stateid_t *stateid) if (EXPIRED_STATEID(stateid)) return nfserr_expired; - dprintk("NFSD: bad stateid (%08x/%08x/%08x/%08x)!\n", - stateid->si_boot, stateid->si_stateownerid, - stateid->si_fileid, stateid->si_generation); + dprintk("NFSD: bad stateid " STATEID_FMT "!\n", + STATEID_VAL(stateid)); return nfserr_bad_stateid; } @@ -2896,10 +2889,8 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, struct svc_fh *current_fh = &cstate->current_fh; __be32 status; - dprintk("NFSD: preprocess_seqid_op: seqid=%d " - "stateid = (%08x/%08x/%08x/%08x)\n", seqid, - stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid, - stateid->si_generation); + dprintk("NFSD: %s: seqid=%d stateid = " STATEID_FMT "\n", __func__, + seqid, STATEID_VAL(stateid)); *stpp = NULL; *sopp = NULL; @@ -3031,12 +3022,8 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, sop->so_confirmed = 1; update_stateid(&stp->st_stateid); memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t)); - dprintk("NFSD: nfsd4_open_confirm: success, seqid=%d " - "stateid=(%08x/%08x/%08x/%08x)\n", oc->oc_seqid, - stp->st_stateid.si_boot, - stp->st_stateid.si_stateownerid, - stp->st_stateid.si_fileid, - stp->st_stateid.si_generation); + dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n", + __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stateid)); nfsd4_create_clid_dir(sop->so_client); out: @@ -3295,9 +3282,8 @@ find_delegation_stateid(struct inode *ino, stateid_t *stid) struct nfs4_file *fp; struct nfs4_delegation *dl; - dprintk("NFSD:find_delegation_stateid stateid=(%08x/%08x/%08x/%08x)\n", - stid->si_boot, stid->si_stateownerid, - stid->si_fileid, stid->si_generation); + dprintk("NFSD: %s: stateid=" STATEID_FMT "\n", __func__, + STATEID_VAL(stid)); fp = find_file(ino); if (!fp) diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h index b38d113..5aadf8a 100644 --- a/include/linux/nfsd/state.h +++ b/include/linux/nfsd/state.h @@ -60,6 +60,13 @@ typedef struct { #define si_stateownerid si_opaque.so_stateownerid #define si_fileid si_opaque.so_fileid +#define STATEID_FMT "(%08x/%08x/%08x/%08x)" +#define STATEID_VAL(s) \ + (s)->si_boot, \ + (s)->si_stateownerid, \ + (s)->si_fileid, \ + (s)->si_generation + struct nfsd4_cb_sequence { /* args/res */ u32 cbs_minorversion; -- cgit v0.10.2 From 1caab3c1a90be3aa4ec3599409d8fe044b077478 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 4 Nov 2009 14:17:53 -0500 Subject: wmi: Add support for module autoloading WMI provides interface-specific GUIDs that are exported from modules as modalises, but the core currently generates no events to trigger module loading. This patch adds support for registering devices for each WMI GUID and generating the appropriate uevent. Based heavily on a patch by Carlos Corbacho (). Signed-off-by: Matthew Garrett Tested-by: Carlos Corbacho Acked-by: Carlos Corbacho Signed-off-by: Len Brown diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 177f8d7..e425a86 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,7 @@ struct wmi_block { acpi_handle handle; wmi_notify_handler handler; void *handler_data; + struct device *dev; }; static struct wmi_block wmi_blocks; @@ -195,6 +197,34 @@ static bool wmi_parse_guid(const u8 *src, u8 *dest) return true; } +/* + * Convert a raw GUID to the ACII string representation + */ +static int wmi_gtoa(const char *in, char *out) +{ + int i; + + for (i = 3; i >= 0; i--) + out += sprintf(out, "%02X", in[i] & 0xFF); + + out += sprintf(out, "-"); + out += sprintf(out, "%02X", in[5] & 0xFF); + out += sprintf(out, "%02X", in[4] & 0xFF); + out += sprintf(out, "-"); + out += sprintf(out, "%02X", in[7] & 0xFF); + out += sprintf(out, "%02X", in[6] & 0xFF); + out += sprintf(out, "-"); + out += sprintf(out, "%02X", in[8] & 0xFF); + out += sprintf(out, "%02X", in[9] & 0xFF); + out += sprintf(out, "-"); + + for (i = 10; i <= 15; i++) + out += sprintf(out, "%02X", in[i] & 0xFF); + + out = '\0'; + return 0; +} + static bool find_guid(const char *guid_string, struct wmi_block **out) { char tmp[16], guid_input[16]; @@ -555,6 +585,138 @@ bool wmi_has_guid(const char *guid_string) EXPORT_SYMBOL_GPL(wmi_has_guid); /* + * sysfs interface + */ +static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, + char *buf) +{ + char guid_string[37]; + struct wmi_block *wblock; + + wblock = dev_get_drvdata(dev); + if (!wblock) + return -ENOMEM; + + wmi_gtoa(wblock->gblock.guid, guid_string); + + return sprintf(buf, "wmi:%s\n", guid_string); +} +static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); + +static int wmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + char guid_string[37]; + + struct wmi_block *wblock; + + if (add_uevent_var(env, "MODALIAS=")) + return -ENOMEM; + + wblock = dev_get_drvdata(dev); + if (!wblock) + return -ENOMEM; + + wmi_gtoa(wblock->gblock.guid, guid_string); + + strcpy(&env->buf[env->buflen - 1], "wmi:"); + memcpy(&env->buf[env->buflen - 1 + 4], guid_string, 36); + env->buflen += 40; + + return 0; +} + +static void wmi_dev_free(struct device *dev) +{ + kfree(dev); +} + +static struct class wmi_class = { + .name = "wmi", + .dev_release = wmi_dev_free, + .dev_uevent = wmi_dev_uevent, +}; + +static int wmi_create_devs(void) +{ + int result; + char guid_string[37]; + struct guid_block *gblock; + struct wmi_block *wblock; + struct list_head *p; + struct device *guid_dev; + + /* Create devices for all the GUIDs */ + list_for_each(p, &wmi_blocks.list) { + wblock = list_entry(p, struct wmi_block, list); + + guid_dev = kzalloc(sizeof(struct device), GFP_KERNEL); + if (!guid_dev) + return -ENOMEM; + + wblock->dev = guid_dev; + + guid_dev->class = &wmi_class; + dev_set_drvdata(guid_dev, wblock); + + gblock = &wblock->gblock; + + wmi_gtoa(gblock->guid, guid_string); + dev_set_name(guid_dev, guid_string); + + result = device_register(guid_dev); + if (result) + return result; + + result = device_create_file(guid_dev, &dev_attr_modalias); + if (result) + return result; + } + + return 0; +} + +static void wmi_remove_devs(void) +{ + struct guid_block *gblock; + struct wmi_block *wblock; + struct list_head *p; + struct device *guid_dev; + + /* Delete devices for all the GUIDs */ + list_for_each(p, &wmi_blocks.list) { + wblock = list_entry(p, struct wmi_block, list); + + guid_dev = wblock->dev; + gblock = &wblock->gblock; + + device_remove_file(guid_dev, &dev_attr_modalias); + + device_unregister(guid_dev); + } +} + +static void wmi_class_exit(void) +{ + wmi_remove_devs(); + class_unregister(&wmi_class); +} + +static int wmi_class_init(void) +{ + int ret; + + ret = class_register(&wmi_class); + if (ret) + return ret; + + ret = wmi_create_devs(); + if (ret) + wmi_class_exit(); + + return ret; +} + +/* * Parse the _WDG method for the GUID data blocks */ static __init acpi_status parse_wdg(acpi_handle handle) @@ -709,10 +871,17 @@ static int __init acpi_wmi_init(void) if (result < 0) { printk(KERN_INFO PREFIX "Error loading mapper\n"); - } else { - printk(KERN_INFO PREFIX "Mapper loaded\n"); + return -ENODEV; + } + + result = wmi_class_init(); + if (result) { + acpi_bus_unregister_driver(&acpi_wmi_driver); + return result; } + printk(KERN_INFO PREFIX "Mapper loaded\n"); + return result; } @@ -721,6 +890,8 @@ static void __exit acpi_wmi_exit(void) struct list_head *p, *tmp; struct wmi_block *wblock; + wmi_class_exit(); + acpi_bus_unregister_driver(&acpi_wmi_driver); list_for_each_safe(p, tmp, &wmi_blocks.list) { -- cgit v0.10.2 From 7fb2616e249184e217f9818a7662596165710ea4 Mon Sep 17 00:00:00 2001 From: Frans Pop Date: Mon, 26 Oct 2009 08:39:01 +0100 Subject: acpi: thermal: display forced passive trip points in proc Users can force a passive trip point for a thermal zone that does not have _PSV defined in ACPI by setting the passive attribute in sysfs. It's useful to display such trip points in /proc/acpi/thermal_zone. .../TZ1/cooling_mode: .../TZ1/polling_frequency:polling frequency: 10 seconds .../TZ1/state:state: ok .../TZ1/temperature:temperature: 53 C .../TZ1/trip_points:critical (S5): 110 C .../TZ1/trip_points:passive (forced): 95 C And if not set (passive is 0): .../TZ1/trip_points:passive (forced): Signed-off-by: Frans Pop Acked-by: Zhang Rui Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 65f6781..9073ada 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -1052,6 +1052,13 @@ static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset) acpi_device_bid(device)); } seq_puts(seq, "\n"); + } else { + seq_printf(seq, "passive (forced):"); + if (tz->thermal_zone->forced_passive) + seq_printf(seq, " %i C\n", + tz->thermal_zone->forced_passive / 1000); + else + seq_printf(seq, "\n"); } for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { -- cgit v0.10.2 From 3d8e3ad879441ae14c5957b933028daf39d252b0 Mon Sep 17 00:00:00 2001 From: Frans Pop Date: Mon, 26 Oct 2009 08:39:02 +0100 Subject: thermal: add sanity check for the passive attribute Values below 1000 milli-celsius don't make sense and can cause the system to go into a thermal heart attack: the actual temperature will always be lower and thus the system will be throttled down to its lowest setting. An additional problem is that values below 1000 will show as 0 in /proc/acpi/thermal/TZx/trip_points:passive. cat passive 0 echo -n 90 >passive bash: echo: write error: Invalid argument echo -n 90000 >passive cat passive 90000 Signed-off-by: Frans Pop Acked-by: Zhang Rui Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt index a87dc27..cb3d15b 100644 --- a/Documentation/thermal/sysfs-api.txt +++ b/Documentation/thermal/sysfs-api.txt @@ -206,6 +206,7 @@ passive passive trip point for the zone. Activation is done by polling with an interval of 1 second. Unit: millidegrees Celsius + Valid values: 0 (disabled) or greater than 1000 RW, Optional ***************************** diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 6f8d8f9..310e40a 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -225,6 +225,12 @@ passive_store(struct device *dev, struct device_attribute *attr, if (!sscanf(buf, "%d\n", &state)) return -EINVAL; + /* sanity check: values below 1000 millicelcius don't make sense + * and can cause the system to go into a thermal heart attack + */ + if (state && state < 1000) + return -EINVAL; + if (state && !tz->forced_passive) { mutex_lock(&thermal_list_lock); list_for_each_entry(cdev, &thermal_cdev_list, node) { -- cgit v0.10.2 From e4143b0324a6a468cb00c4341cd20d60cc441252 Mon Sep 17 00:00:00 2001 From: Frans Pop Date: Mon, 26 Oct 2009 08:39:03 +0100 Subject: thermal: Only set passive_delay for forced_passive cooling Setting polling_delay is useless as passive_delay has priority, so the value shown in proc isn't the actual polling delay. It also gives the impression to the user that he can change the polling interval through proc, while in fact he can't. Also, unset passive_delay when the forced passive trip point is unbound to allow polling to be disabled. Signed-off-by: Frans Pop Acked-by: Matthew Garrett Acked-by: Zhang Rui Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 310e40a..663c2fd 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -241,6 +241,8 @@ passive_store(struct device *dev, struct device_attribute *attr, cdev); } mutex_unlock(&thermal_list_lock); + if (!tz->passive_delay) + tz->passive_delay = 1000; } else if (!state && tz->forced_passive) { mutex_lock(&thermal_list_lock); list_for_each_entry(cdev, &thermal_cdev_list, node) { @@ -251,17 +253,12 @@ passive_store(struct device *dev, struct device_attribute *attr, cdev); } mutex_unlock(&thermal_list_lock); + tz->passive_delay = 0; } tz->tc1 = 1; tz->tc2 = 1; - if (!tz->passive_delay) - tz->passive_delay = 1000; - - if (!tz->polling_delay) - tz->polling_delay = 10000; - tz->forced_passive = state; thermal_zone_device_update(tz); -- cgit v0.10.2 From 3767cb54ac718eb049d2a29f7a575ab923550ba5 Mon Sep 17 00:00:00 2001 From: Frans Pop Date: Mon, 26 Oct 2009 08:39:04 +0100 Subject: thermal: disable polling if passive_delay and polling_delay are both unset Otherwise polling will continue for the thermal zone even when it is no longer needed, for example because forced passive cooling was disabled. Signed-off-by: Frans Pop Acked-by: Matthew Garrett Acked-by: Zhang Rui Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 663c2fd..3bc72ea 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -1019,6 +1019,8 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) thermal_zone_device_set_polling(tz, tz->passive_delay); else if (tz->polling_delay) thermal_zone_device_set_polling(tz, tz->polling_delay); + else + thermal_zone_device_set_polling(tz, 0); mutex_unlock(&tz->lock); } EXPORT_SYMBOL(thermal_zone_device_update); -- cgit v0.10.2 From d81c45e1c9369855901420f79114852eba2ea16a Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Fri, 16 Oct 2009 09:20:41 +0800 Subject: ACPI: Notify the _PPC evaluation status to the platform According to the ACPI spec(section 8.4.4.3) OSPM should convey the _PPC evaluations status to the platform if there exists the _OST object. The _OST contains two arguments: The first is the PERFORMANCE notificatin event. The second is the status of _PPC object. OSPM will convey the _PPC evaluation status to the platform. Of course when the module parameter of "ignore_ppc" is added, OSPM won't evaluate the _PPC object. But it will call the _OST object. At the same time the _OST object will be evaluated only when the PERFORMANCE notification event is received. Signed-off-by: Zhao Yakui Signed-off-by: Len Brown diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index c567b46..773d7e7 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -722,7 +722,7 @@ static void acpi_processor_notify(struct acpi_device *device, u32 event) switch (event) { case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: saved = pr->performance_platform_limit; - acpi_processor_ppc_has_changed(pr); + acpi_processor_ppc_has_changed(pr, 1); if (saved == pr->performance_platform_limit) break; acpi_bus_generate_proc_event(device, event, @@ -758,7 +758,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, struct acpi_processor *pr = per_cpu(processors, cpu); if (action == CPU_ONLINE && pr) { - acpi_processor_ppc_has_changed(pr); + acpi_processor_ppc_has_changed(pr, 0); acpi_processor_cst_has_changed(pr); acpi_processor_tstate_has_changed(pr); } @@ -830,7 +830,7 @@ static int acpi_processor_add(struct acpi_device *device) arch_acpi_processor_cleanup_pdc(pr); #ifdef CONFIG_CPU_FREQ - acpi_processor_ppc_has_changed(pr); + acpi_processor_ppc_has_changed(pr, 0); #endif acpi_processor_get_throttling_info(pr); acpi_processor_get_limit_info(pr); diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 8ba0ed0..fc1f49bb 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -152,15 +152,59 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) return 0; } -int acpi_processor_ppc_has_changed(struct acpi_processor *pr) +#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 +/* + * acpi_processor_ppc_ost: Notify firmware the _PPC evaluation status + * @handle: ACPI processor handle + * @status: the status code of _PPC evaluation + * 0: success. OSPM is now using the performance state specificed. + * 1: failure. OSPM has not changed the number of P-states in use + */ +static void acpi_processor_ppc_ost(acpi_handle handle, int status) +{ + union acpi_object params[2] = { + {.type = ACPI_TYPE_INTEGER,}, + {.type = ACPI_TYPE_INTEGER,}, + }; + struct acpi_object_list arg_list = {2, params}; + acpi_handle temp; + + params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE; + params[1].integer.value = status; + + /* when there is no _OST , skip it */ + if (ACPI_FAILURE(acpi_get_handle(handle, "_OST", &temp))) + return; + + acpi_evaluate_object(handle, "_OST", &arg_list, NULL); + return; +} + +int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag) { int ret; - if (ignore_ppc) + if (ignore_ppc) { + /* + * Only when it is notification event, the _OST object + * will be evaluated. Otherwise it is skipped. + */ + if (event_flag) + acpi_processor_ppc_ost(pr->handle, 1); return 0; + } ret = acpi_processor_get_platform_limit(pr); - + /* + * Only when it is notification event, the _OST object + * will be evaluated. Otherwise it is skipped. + */ + if (event_flag) { + if (ret < 0) + acpi_processor_ppc_ost(pr->handle, 1); + else + acpi_processor_ppc_ost(pr->handle, 0); + } if (ret < 0) return (ret); else diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 740ac3a..a920237 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -294,7 +294,7 @@ static inline void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx #ifdef CONFIG_CPU_FREQ void acpi_processor_ppc_init(void); void acpi_processor_ppc_exit(void); -int acpi_processor_ppc_has_changed(struct acpi_processor *pr); +int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag); #else static inline void acpi_processor_ppc_init(void) { @@ -304,7 +304,8 @@ static inline void acpi_processor_ppc_exit(void) { return; } -static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr) +static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr, + int event_flag) { static unsigned int printout = 1; if (printout) { -- cgit v0.10.2 From ea4878a24d7e6a467d369b962bab95bd6a12cbe0 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Fri, 6 Nov 2009 13:59:43 -0500 Subject: nfs: move more to Documentation/filesystems/nfs Oops: I missed two files in the first commit that created this directory. Signed-off-by: J. Bruce Fields diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX index 482151c..658154f 100644 --- a/Documentation/filesystems/00-INDEX +++ b/Documentation/filesystems/00-INDEX @@ -84,8 +84,6 @@ relay.txt - info on relay, for efficient streaming from kernel to user space. romfs.txt - description of the ROMFS filesystem. -rpc-cache.txt - - introduction to the caching mechanisms in the sunrpc layer. seq_file.txt - how to use the seq_file API sharedsubtree.txt diff --git a/Documentation/filesystems/knfsd-stats.txt b/Documentation/filesystems/knfsd-stats.txt deleted file mode 100644 index 64ced51..0000000 --- a/Documentation/filesystems/knfsd-stats.txt +++ /dev/null @@ -1,159 +0,0 @@ - -Kernel NFS Server Statistics -============================ - -This document describes the format and semantics of the statistics -which the kernel NFS server makes available to userspace. These -statistics are available in several text form pseudo files, each of -which is described separately below. - -In most cases you don't need to know these formats, as the nfsstat(8) -program from the nfs-utils distribution provides a helpful command-line -interface for extracting and printing them. - -All the files described here are formatted as a sequence of text lines, -separated by newline '\n' characters. Lines beginning with a hash -'#' character are comments intended for humans and should be ignored -by parsing routines. All other lines contain a sequence of fields -separated by whitespace. - -/proc/fs/nfsd/pool_stats ------------------------- - -This file is available in kernels from 2.6.30 onwards, if the -/proc/fs/nfsd filesystem is mounted (it almost always should be). - -The first line is a comment which describes the fields present in -all the other lines. The other lines present the following data as -a sequence of unsigned decimal numeric fields. One line is shown -for each NFS thread pool. - -All counters are 64 bits wide and wrap naturally. There is no way -to zero these counters, instead applications should do their own -rate conversion. - -pool - The id number of the NFS thread pool to which this line applies. - This number does not change. - - Thread pool ids are a contiguous set of small integers starting - at zero. The maximum value depends on the thread pool mode, but - currently cannot be larger than the number of CPUs in the system. - Note that in the default case there will be a single thread pool - which contains all the nfsd threads and all the CPUs in the system, - and thus this file will have a single line with a pool id of "0". - -packets-arrived - Counts how many NFS packets have arrived. More precisely, this - is the number of times that the network stack has notified the - sunrpc server layer that new data may be available on a transport - (e.g. an NFS or UDP socket or an NFS/RDMA endpoint). - - Depending on the NFS workload patterns and various network stack - effects (such as Large Receive Offload) which can combine packets - on the wire, this may be either more or less than the number - of NFS calls received (which statistic is available elsewhere). - However this is a more accurate and less workload-dependent measure - of how much CPU load is being placed on the sunrpc server layer - due to NFS network traffic. - -sockets-enqueued - Counts how many times an NFS transport is enqueued to wait for - an nfsd thread to service it, i.e. no nfsd thread was considered - available. - - The circumstance this statistic tracks indicates that there was NFS - network-facing work to be done but it couldn't be done immediately, - thus introducing a small delay in servicing NFS calls. The ideal - rate of change for this counter is zero; significantly non-zero - values may indicate a performance limitation. - - This can happen either because there are too few nfsd threads in the - thread pool for the NFS workload (the workload is thread-limited), - or because the NFS workload needs more CPU time than is available in - the thread pool (the workload is CPU-limited). In the former case, - configuring more nfsd threads will probably improve the performance - of the NFS workload. In the latter case, the sunrpc server layer is - already choosing not to wake idle nfsd threads because there are too - many nfsd threads which want to run but cannot, so configuring more - nfsd threads will make no difference whatsoever. The overloads-avoided - statistic (see below) can be used to distinguish these cases. - -threads-woken - Counts how many times an idle nfsd thread is woken to try to - receive some data from an NFS transport. - - This statistic tracks the circumstance where incoming - network-facing NFS work is being handled quickly, which is a good - thing. The ideal rate of change for this counter will be close - to but less than the rate of change of the packets-arrived counter. - -overloads-avoided - Counts how many times the sunrpc server layer chose not to wake an - nfsd thread, despite the presence of idle nfsd threads, because - too many nfsd threads had been recently woken but could not get - enough CPU time to actually run. - - This statistic counts a circumstance where the sunrpc layer - heuristically avoids overloading the CPU scheduler with too many - runnable nfsd threads. The ideal rate of change for this counter - is zero. Significant non-zero values indicate that the workload - is CPU limited. Usually this is associated with heavy CPU usage - on all the CPUs in the nfsd thread pool. - - If a sustained large overloads-avoided rate is detected on a pool, - the top(1) utility should be used to check for the following - pattern of CPU usage on all the CPUs associated with the given - nfsd thread pool. - - - %us ~= 0 (as you're *NOT* running applications on your NFS server) - - - %wa ~= 0 - - - %id ~= 0 - - - %sy + %hi + %si ~= 100 - - If this pattern is seen, configuring more nfsd threads will *not* - improve the performance of the workload. If this patten is not - seen, then something more subtle is wrong. - -threads-timedout - Counts how many times an nfsd thread triggered an idle timeout, - i.e. was not woken to handle any incoming network packets for - some time. - - This statistic counts a circumstance where there are more nfsd - threads configured than can be used by the NFS workload. This is - a clue that the number of nfsd threads can be reduced without - affecting performance. Unfortunately, it's only a clue and not - a strong indication, for a couple of reasons: - - - Currently the rate at which the counter is incremented is quite - slow; the idle timeout is 60 minutes. Unless the NFS workload - remains constant for hours at a time, this counter is unlikely - to be providing information that is still useful. - - - It is usually a wise policy to provide some slack, - i.e. configure a few more nfsds than are currently needed, - to allow for future spikes in load. - - -Note that incoming packets on NFS transports will be dealt with in -one of three ways. An nfsd thread can be woken (threads-woken counts -this case), or the transport can be enqueued for later attention -(sockets-enqueued counts this case), or the packet can be temporarily -deferred because the transport is currently being used by an nfsd -thread. This last case is not very interesting and is not explicitly -counted, but can be inferred from the other counters thus: - -packets-deferred = packets-arrived - ( sockets-enqueued + threads-woken ) - - -More ----- -Descriptions of the other statistics file should go here. - - -Greg Banks -26 Mar 2009 diff --git a/Documentation/filesystems/nfs/00-INDEX b/Documentation/filesystems/nfs/00-INDEX index 6ff3d21..2f68cd6 100644 --- a/Documentation/filesystems/nfs/00-INDEX +++ b/Documentation/filesystems/nfs/00-INDEX @@ -2,6 +2,8 @@ - this file (nfs-related documentation). Exporting - explanation of how to make filesystems exportable. +knfsd-stats.txt + - statistics which the NFS server makes available to user space. nfs.txt - nfs client, and DNS resolution for fs_locations. nfs41-server.txt @@ -10,3 +12,5 @@ nfs-rdma.txt - how to install and setup the Linux NFS/RDMA client and server software nfsroot.txt - short guide on setting up a diskless box with NFS root filesystem. +rpc-cache.txt + - introduction to the caching mechanisms in the sunrpc layer. diff --git a/Documentation/filesystems/nfs/knfsd-stats.txt b/Documentation/filesystems/nfs/knfsd-stats.txt new file mode 100644 index 0000000..64ced51 --- /dev/null +++ b/Documentation/filesystems/nfs/knfsd-stats.txt @@ -0,0 +1,159 @@ + +Kernel NFS Server Statistics +============================ + +This document describes the format and semantics of the statistics +which the kernel NFS server makes available to userspace. These +statistics are available in several text form pseudo files, each of +which is described separately below. + +In most cases you don't need to know these formats, as the nfsstat(8) +program from the nfs-utils distribution provides a helpful command-line +interface for extracting and printing them. + +All the files described here are formatted as a sequence of text lines, +separated by newline '\n' characters. Lines beginning with a hash +'#' character are comments intended for humans and should be ignored +by parsing routines. All other lines contain a sequence of fields +separated by whitespace. + +/proc/fs/nfsd/pool_stats +------------------------ + +This file is available in kernels from 2.6.30 onwards, if the +/proc/fs/nfsd filesystem is mounted (it almost always should be). + +The first line is a comment which describes the fields present in +all the other lines. The other lines present the following data as +a sequence of unsigned decimal numeric fields. One line is shown +for each NFS thread pool. + +All counters are 64 bits wide and wrap naturally. There is no way +to zero these counters, instead applications should do their own +rate conversion. + +pool + The id number of the NFS thread pool to which this line applies. + This number does not change. + + Thread pool ids are a contiguous set of small integers starting + at zero. The maximum value depends on the thread pool mode, but + currently cannot be larger than the number of CPUs in the system. + Note that in the default case there will be a single thread pool + which contains all the nfsd threads and all the CPUs in the system, + and thus this file will have a single line with a pool id of "0". + +packets-arrived + Counts how many NFS packets have arrived. More precisely, this + is the number of times that the network stack has notified the + sunrpc server layer that new data may be available on a transport + (e.g. an NFS or UDP socket or an NFS/RDMA endpoint). + + Depending on the NFS workload patterns and various network stack + effects (such as Large Receive Offload) which can combine packets + on the wire, this may be either more or less than the number + of NFS calls received (which statistic is available elsewhere). + However this is a more accurate and less workload-dependent measure + of how much CPU load is being placed on the sunrpc server layer + due to NFS network traffic. + +sockets-enqueued + Counts how many times an NFS transport is enqueued to wait for + an nfsd thread to service it, i.e. no nfsd thread was considered + available. + + The circumstance this statistic tracks indicates that there was NFS + network-facing work to be done but it couldn't be done immediately, + thus introducing a small delay in servicing NFS calls. The ideal + rate of change for this counter is zero; significantly non-zero + values may indicate a performance limitation. + + This can happen either because there are too few nfsd threads in the + thread pool for the NFS workload (the workload is thread-limited), + or because the NFS workload needs more CPU time than is available in + the thread pool (the workload is CPU-limited). In the former case, + configuring more nfsd threads will probably improve the performance + of the NFS workload. In the latter case, the sunrpc server layer is + already choosing not to wake idle nfsd threads because there are too + many nfsd threads which want to run but cannot, so configuring more + nfsd threads will make no difference whatsoever. The overloads-avoided + statistic (see below) can be used to distinguish these cases. + +threads-woken + Counts how many times an idle nfsd thread is woken to try to + receive some data from an NFS transport. + + This statistic tracks the circumstance where incoming + network-facing NFS work is being handled quickly, which is a good + thing. The ideal rate of change for this counter will be close + to but less than the rate of change of the packets-arrived counter. + +overloads-avoided + Counts how many times the sunrpc server layer chose not to wake an + nfsd thread, despite the presence of idle nfsd threads, because + too many nfsd threads had been recently woken but could not get + enough CPU time to actually run. + + This statistic counts a circumstance where the sunrpc layer + heuristically avoids overloading the CPU scheduler with too many + runnable nfsd threads. The ideal rate of change for this counter + is zero. Significant non-zero values indicate that the workload + is CPU limited. Usually this is associated with heavy CPU usage + on all the CPUs in the nfsd thread pool. + + If a sustained large overloads-avoided rate is detected on a pool, + the top(1) utility should be used to check for the following + pattern of CPU usage on all the CPUs associated with the given + nfsd thread pool. + + - %us ~= 0 (as you're *NOT* running applications on your NFS server) + + - %wa ~= 0 + + - %id ~= 0 + + - %sy + %hi + %si ~= 100 + + If this pattern is seen, configuring more nfsd threads will *not* + improve the performance of the workload. If this patten is not + seen, then something more subtle is wrong. + +threads-timedout + Counts how many times an nfsd thread triggered an idle timeout, + i.e. was not woken to handle any incoming network packets for + some time. + + This statistic counts a circumstance where there are more nfsd + threads configured than can be used by the NFS workload. This is + a clue that the number of nfsd threads can be reduced without + affecting performance. Unfortunately, it's only a clue and not + a strong indication, for a couple of reasons: + + - Currently the rate at which the counter is incremented is quite + slow; the idle timeout is 60 minutes. Unless the NFS workload + remains constant for hours at a time, this counter is unlikely + to be providing information that is still useful. + + - It is usually a wise policy to provide some slack, + i.e. configure a few more nfsds than are currently needed, + to allow for future spikes in load. + + +Note that incoming packets on NFS transports will be dealt with in +one of three ways. An nfsd thread can be woken (threads-woken counts +this case), or the transport can be enqueued for later attention +(sockets-enqueued counts this case), or the packet can be temporarily +deferred because the transport is currently being used by an nfsd +thread. This last case is not very interesting and is not explicitly +counted, but can be inferred from the other counters thus: + +packets-deferred = packets-arrived - ( sockets-enqueued + threads-woken ) + + +More +---- +Descriptions of the other statistics file should go here. + + +Greg Banks +26 Mar 2009 diff --git a/Documentation/filesystems/nfs/rpc-cache.txt b/Documentation/filesystems/nfs/rpc-cache.txt new file mode 100644 index 0000000..8a382be --- /dev/null +++ b/Documentation/filesystems/nfs/rpc-cache.txt @@ -0,0 +1,202 @@ + This document gives a brief introduction to the caching +mechanisms in the sunrpc layer that is used, in particular, +for NFS authentication. + +CACHES +====== +The caching replaces the old exports table and allows for +a wide variety of values to be caches. + +There are a number of caches that are similar in structure though +quite possibly very different in content and use. There is a corpus +of common code for managing these caches. + +Examples of caches that are likely to be needed are: + - mapping from IP address to client name + - mapping from client name and filesystem to export options + - mapping from UID to list of GIDs, to work around NFS's limitation + of 16 gids. + - mappings between local UID/GID and remote UID/GID for sites that + do not have uniform uid assignment + - mapping from network identify to public key for crypto authentication. + +The common code handles such things as: + - general cache lookup with correct locking + - supporting 'NEGATIVE' as well as positive entries + - allowing an EXPIRED time on cache items, and removing + items after they expire, and are no longer in-use. + - making requests to user-space to fill in cache entries + - allowing user-space to directly set entries in the cache + - delaying RPC requests that depend on as-yet incomplete + cache entries, and replaying those requests when the cache entry + is complete. + - clean out old entries as they expire. + +Creating a Cache +---------------- + +1/ A cache needs a datum to store. This is in the form of a + structure definition that must contain a + struct cache_head + as an element, usually the first. + It will also contain a key and some content. + Each cache element is reference counted and contains + expiry and update times for use in cache management. +2/ A cache needs a "cache_detail" structure that + describes the cache. This stores the hash table, some + parameters for cache management, and some operations detailing how + to work with particular cache items. + The operations requires are: + struct cache_head *alloc(void) + This simply allocates appropriate memory and returns + a pointer to the cache_detail embedded within the + structure + void cache_put(struct kref *) + This is called when the last reference to an item is + dropped. The pointer passed is to the 'ref' field + in the cache_head. cache_put should release any + references create by 'cache_init' and, if CACHE_VALID + is set, any references created by cache_update. + It should then release the memory allocated by + 'alloc'. + int match(struct cache_head *orig, struct cache_head *new) + test if the keys in the two structures match. Return + 1 if they do, 0 if they don't. + void init(struct cache_head *orig, struct cache_head *new) + Set the 'key' fields in 'new' from 'orig'. This may + include taking references to shared objects. + void update(struct cache_head *orig, struct cache_head *new) + Set the 'content' fileds in 'new' from 'orig'. + int cache_show(struct seq_file *m, struct cache_detail *cd, + struct cache_head *h) + Optional. Used to provide a /proc file that lists the + contents of a cache. This should show one item, + usually on just one line. + int cache_request(struct cache_detail *cd, struct cache_head *h, + char **bpp, int *blen) + Format a request to be send to user-space for an item + to be instantiated. *bpp is a buffer of size *blen. + bpp should be moved forward over the encoded message, + and *blen should be reduced to show how much free + space remains. Return 0 on success or <0 if not + enough room or other problem. + int cache_parse(struct cache_detail *cd, char *buf, int len) + A message from user space has arrived to fill out a + cache entry. It is in 'buf' of length 'len'. + cache_parse should parse this, find the item in the + cache with sunrpc_cache_lookup, and update the item + with sunrpc_cache_update. + + +3/ A cache needs to be registered using cache_register(). This + includes it on a list of caches that will be regularly + cleaned to discard old data. + +Using a cache +------------- + +To find a value in a cache, call sunrpc_cache_lookup passing a pointer +to the cache_head in a sample item with the 'key' fields filled in. +This will be passed to ->match to identify the target entry. If no +entry is found, a new entry will be create, added to the cache, and +marked as not containing valid data. + +The item returned is typically passed to cache_check which will check +if the data is valid, and may initiate an up-call to get fresh data. +cache_check will return -ENOENT in the entry is negative or if an up +call is needed but not possible, -EAGAIN if an upcall is pending, +or 0 if the data is valid; + +cache_check can be passed a "struct cache_req *". This structure is +typically embedded in the actual request and can be used to create a +deferred copy of the request (struct cache_deferred_req). This is +done when the found cache item is not uptodate, but the is reason to +believe that userspace might provide information soon. When the cache +item does become valid, the deferred copy of the request will be +revisited (->revisit). It is expected that this method will +reschedule the request for processing. + +The value returned by sunrpc_cache_lookup can also be passed to +sunrpc_cache_update to set the content for the item. A second item is +passed which should hold the content. If the item found by _lookup +has valid data, then it is discarded and a new item is created. This +saves any user of an item from worrying about content changing while +it is being inspected. If the item found by _lookup does not contain +valid data, then the content is copied across and CACHE_VALID is set. + +Populating a cache +------------------ + +Each cache has a name, and when the cache is registered, a directory +with that name is created in /proc/net/rpc + +This directory contains a file called 'channel' which is a channel +for communicating between kernel and user for populating the cache. +This directory may later contain other files of interacting +with the cache. + +The 'channel' works a bit like a datagram socket. Each 'write' is +passed as a whole to the cache for parsing and interpretation. +Each cache can treat the write requests differently, but it is +expected that a message written will contain: + - a key + - an expiry time + - a content. +with the intention that an item in the cache with the give key +should be create or updated to have the given content, and the +expiry time should be set on that item. + +Reading from a channel is a bit more interesting. When a cache +lookup fails, or when it succeeds but finds an entry that may soon +expire, a request is lodged for that cache item to be updated by +user-space. These requests appear in the channel file. + +Successive reads will return successive requests. +If there are no more requests to return, read will return EOF, but a +select or poll for read will block waiting for another request to be +added. + +Thus a user-space helper is likely to: + open the channel. + select for readable + read a request + write a response + loop. + +If it dies and needs to be restarted, any requests that have not been +answered will still appear in the file and will be read by the new +instance of the helper. + +Each cache should define a "cache_parse" method which takes a message +written from user-space and processes it. It should return an error +(which propagates back to the write syscall) or 0. + +Each cache should also define a "cache_request" method which +takes a cache item and encodes a request into the buffer +provided. + +Note: If a cache has no active readers on the channel, and has had not +active readers for more than 60 seconds, further requests will not be +added to the channel but instead all lookups that do not find a valid +entry will fail. This is partly for backward compatibility: The +previous nfs exports table was deemed to be authoritative and a +failed lookup meant a definite 'no'. + +request/response format +----------------------- + +While each cache is free to use it's own format for requests +and responses over channel, the following is recommended as +appropriate and support routines are available to help: +Each request or response record should be printable ASCII +with precisely one newline character which should be at the end. +Fields within the record should be separated by spaces, normally one. +If spaces, newlines, or nul characters are needed in a field they +much be quoted. two mechanisms are available: +1/ If a field begins '\x' then it must contain an even number of + hex digits, and pairs of these digits provide the bytes in the + field. +2/ otherwise a \ in the field must be followed by 3 octal digits + which give the code for a byte. Other characters are treated + as them selves. At the very least, space, newline, nul, and + '\' must be quoted in this way. diff --git a/Documentation/filesystems/rpc-cache.txt b/Documentation/filesystems/rpc-cache.txt deleted file mode 100644 index 8a382be..0000000 --- a/Documentation/filesystems/rpc-cache.txt +++ /dev/null @@ -1,202 +0,0 @@ - This document gives a brief introduction to the caching -mechanisms in the sunrpc layer that is used, in particular, -for NFS authentication. - -CACHES -====== -The caching replaces the old exports table and allows for -a wide variety of values to be caches. - -There are a number of caches that are similar in structure though -quite possibly very different in content and use. There is a corpus -of common code for managing these caches. - -Examples of caches that are likely to be needed are: - - mapping from IP address to client name - - mapping from client name and filesystem to export options - - mapping from UID to list of GIDs, to work around NFS's limitation - of 16 gids. - - mappings between local UID/GID and remote UID/GID for sites that - do not have uniform uid assignment - - mapping from network identify to public key for crypto authentication. - -The common code handles such things as: - - general cache lookup with correct locking - - supporting 'NEGATIVE' as well as positive entries - - allowing an EXPIRED time on cache items, and removing - items after they expire, and are no longer in-use. - - making requests to user-space to fill in cache entries - - allowing user-space to directly set entries in the cache - - delaying RPC requests that depend on as-yet incomplete - cache entries, and replaying those requests when the cache entry - is complete. - - clean out old entries as they expire. - -Creating a Cache ----------------- - -1/ A cache needs a datum to store. This is in the form of a - structure definition that must contain a - struct cache_head - as an element, usually the first. - It will also contain a key and some content. - Each cache element is reference counted and contains - expiry and update times for use in cache management. -2/ A cache needs a "cache_detail" structure that - describes the cache. This stores the hash table, some - parameters for cache management, and some operations detailing how - to work with particular cache items. - The operations requires are: - struct cache_head *alloc(void) - This simply allocates appropriate memory and returns - a pointer to the cache_detail embedded within the - structure - void cache_put(struct kref *) - This is called when the last reference to an item is - dropped. The pointer passed is to the 'ref' field - in the cache_head. cache_put should release any - references create by 'cache_init' and, if CACHE_VALID - is set, any references created by cache_update. - It should then release the memory allocated by - 'alloc'. - int match(struct cache_head *orig, struct cache_head *new) - test if the keys in the two structures match. Return - 1 if they do, 0 if they don't. - void init(struct cache_head *orig, struct cache_head *new) - Set the 'key' fields in 'new' from 'orig'. This may - include taking references to shared objects. - void update(struct cache_head *orig, struct cache_head *new) - Set the 'content' fileds in 'new' from 'orig'. - int cache_show(struct seq_file *m, struct cache_detail *cd, - struct cache_head *h) - Optional. Used to provide a /proc file that lists the - contents of a cache. This should show one item, - usually on just one line. - int cache_request(struct cache_detail *cd, struct cache_head *h, - char **bpp, int *blen) - Format a request to be send to user-space for an item - to be instantiated. *bpp is a buffer of size *blen. - bpp should be moved forward over the encoded message, - and *blen should be reduced to show how much free - space remains. Return 0 on success or <0 if not - enough room or other problem. - int cache_parse(struct cache_detail *cd, char *buf, int len) - A message from user space has arrived to fill out a - cache entry. It is in 'buf' of length 'len'. - cache_parse should parse this, find the item in the - cache with sunrpc_cache_lookup, and update the item - with sunrpc_cache_update. - - -3/ A cache needs to be registered using cache_register(). This - includes it on a list of caches that will be regularly - cleaned to discard old data. - -Using a cache -------------- - -To find a value in a cache, call sunrpc_cache_lookup passing a pointer -to the cache_head in a sample item with the 'key' fields filled in. -This will be passed to ->match to identify the target entry. If no -entry is found, a new entry will be create, added to the cache, and -marked as not containing valid data. - -The item returned is typically passed to cache_check which will check -if the data is valid, and may initiate an up-call to get fresh data. -cache_check will return -ENOENT in the entry is negative or if an up -call is needed but not possible, -EAGAIN if an upcall is pending, -or 0 if the data is valid; - -cache_check can be passed a "struct cache_req *". This structure is -typically embedded in the actual request and can be used to create a -deferred copy of the request (struct cache_deferred_req). This is -done when the found cache item is not uptodate, but the is reason to -believe that userspace might provide information soon. When the cache -item does become valid, the deferred copy of the request will be -revisited (->revisit). It is expected that this method will -reschedule the request for processing. - -The value returned by sunrpc_cache_lookup can also be passed to -sunrpc_cache_update to set the content for the item. A second item is -passed which should hold the content. If the item found by _lookup -has valid data, then it is discarded and a new item is created. This -saves any user of an item from worrying about content changing while -it is being inspected. If the item found by _lookup does not contain -valid data, then the content is copied across and CACHE_VALID is set. - -Populating a cache ------------------- - -Each cache has a name, and when the cache is registered, a directory -with that name is created in /proc/net/rpc - -This directory contains a file called 'channel' which is a channel -for communicating between kernel and user for populating the cache. -This directory may later contain other files of interacting -with the cache. - -The 'channel' works a bit like a datagram socket. Each 'write' is -passed as a whole to the cache for parsing and interpretation. -Each cache can treat the write requests differently, but it is -expected that a message written will contain: - - a key - - an expiry time - - a content. -with the intention that an item in the cache with the give key -should be create or updated to have the given content, and the -expiry time should be set on that item. - -Reading from a channel is a bit more interesting. When a cache -lookup fails, or when it succeeds but finds an entry that may soon -expire, a request is lodged for that cache item to be updated by -user-space. These requests appear in the channel file. - -Successive reads will return successive requests. -If there are no more requests to return, read will return EOF, but a -select or poll for read will block waiting for another request to be -added. - -Thus a user-space helper is likely to: - open the channel. - select for readable - read a request - write a response - loop. - -If it dies and needs to be restarted, any requests that have not been -answered will still appear in the file and will be read by the new -instance of the helper. - -Each cache should define a "cache_parse" method which takes a message -written from user-space and processes it. It should return an error -(which propagates back to the write syscall) or 0. - -Each cache should also define a "cache_request" method which -takes a cache item and encodes a request into the buffer -provided. - -Note: If a cache has no active readers on the channel, and has had not -active readers for more than 60 seconds, further requests will not be -added to the channel but instead all lookups that do not find a valid -entry will fail. This is partly for backward compatibility: The -previous nfs exports table was deemed to be authoritative and a -failed lookup meant a definite 'no'. - -request/response format ------------------------ - -While each cache is free to use it's own format for requests -and responses over channel, the following is recommended as -appropriate and support routines are available to help: -Each request or response record should be printable ASCII -with precisely one newline character which should be at the end. -Fields within the record should be separated by spaces, normally one. -If spaces, newlines, or nul characters are needed in a field they -much be quoted. two mechanisms are available: -1/ If a field begins '\x' then it must contain an even number of - hex digits, and pairs of these digits provide the bytes in the - field. -2/ otherwise a \ in the field must be followed by 3 octal digits - which give the code for a byte. Other characters are treated - as them selves. At the very least, space, newline, nul, and - '\' must be quoted in this way. -- cgit v0.10.2 From b60e26a2f03d963f8c79ad7920d64abc4d38ecbc Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 6 Nov 2009 15:33:45 -0800 Subject: kmemleak: fix kconfig for crc32 build error kmemleak uses crc32 functions so it needs to select CRC32. Fixes build error: kmemleak.c:(.text+0x7ce62): undefined reference to `crc32_le' Signed-off-by: Randy Dunlap Signed-off-by: Catalin Marinas diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 30df586..732b9f6 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -352,6 +352,7 @@ config DEBUG_KMEMLEAK select DEBUG_FS if SYSFS select STACKTRACE if STACKTRACE_SUPPORT select KALLSYMS + select CRC32 help Say Y here if you want to enable the memory leak detector. The memory allocation/freeing is traced in a way -- cgit v0.10.2 From 8c1fd89a85f898384df02217c09c98c2f39b4832 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 21 Oct 2009 10:22:01 +0200 Subject: mxc_nand: cleanup eccoob descriptions The original Freescale driver used to have eccoob descriptions like this: static struct nand_ecclayout nand_hw_eccoob_8 = { .eccbytes = 5, .eccpos = {6, 7, 8, 9, 10}, .oobfree = {{0, 5}, {11, 5}} }; static struct nand_ecclayout nand_hw_eccoob_16 = { .eccbytes = 5, .eccpos = {6, 7, 8, 9, 10}, .oobfree = {{0, 6}, {12, 4}} }; The former was used for 8bit flashes and the latter for 16bit flashes. They honored the fact that the bad block marker on 8bit flashes is on byte 5 while on 16bit flashes it is on byte 11. In the Kernel driver this was copied wrong and we ended up with two identical descriptions. Change it so that we have only one description which leaves byte 5 and byte 11 unspecified so that it won't be used by others. Also, rename the descriptions to nand_hw_eccoob_smallpage and nand_hw_eccoob_largepage so that it can't be confused with Nand chip bus widths (what actually happened in this driver) Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 06c5314..2aae5a7 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -129,19 +129,13 @@ struct mxc_nand_host { #define SPARE_SINGLEBIT_ERROR 0x1 /* OOB placement block for use with hardware ecc generation */ -static struct nand_ecclayout nand_hw_eccoob_8 = { +static struct nand_ecclayout nand_hw_eccoob_smallpage = { .eccbytes = 5, .eccpos = {6, 7, 8, 9, 10}, - .oobfree = {{0, 5}, {11, 5}, } + .oobfree = {{0, 5}, {12, 4}, } }; -static struct nand_ecclayout nand_hw_eccoob_16 = { - .eccbytes = 5, - .eccpos = {6, 7, 8, 9, 10}, - .oobfree = {{0, 5}, {11, 5}, } -}; - -static struct nand_ecclayout nand_hw_eccoob_64 = { +static struct nand_ecclayout nand_hw_eccoob_largepage = { .eccbytes = 20, .eccpos = {6, 7, 8, 9, 10, 22, 23, 24, 25, 26, 38, 39, 40, 41, 42, 54, 55, 56, 57, 58}, @@ -940,7 +934,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) } else { this->ecc.size = 512; this->ecc.bytes = 3; - this->ecc.layout = &nand_hw_eccoob_8; + this->ecc.layout = &nand_hw_eccoob_smallpage; this->ecc.mode = NAND_ECC_SOFT; tmp = readw(host->regs + NFC_CONFIG1); tmp &= ~NFC_ECC_EN; @@ -964,7 +958,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) /* NAND bus width determines access funtions used by upper layer */ if (pdata->width == 2) { this->options |= NAND_BUSWIDTH_16; - this->ecc.layout = &nand_hw_eccoob_16; + this->ecc.layout = &nand_hw_eccoob_smallpage; } /* first scan to find the device and get the page size */ @@ -978,20 +972,20 @@ static int __init mxcnd_probe(struct platform_device *pdev) if (this->ecc.mode == NAND_ECC_HW) { switch (mtd->oobsize) { case 8: - this->ecc.layout = &nand_hw_eccoob_8; + this->ecc.layout = &nand_hw_eccoob_smallpage; break; case 16: - this->ecc.layout = &nand_hw_eccoob_16; + this->ecc.layout = &nand_hw_eccoob_smallpage; break; case 64: - this->ecc.layout = &nand_hw_eccoob_64; + this->ecc.layout = &nand_hw_eccoob_largepage; break; default: /* page size not handled by HW ECC */ /* switching back to soft ECC */ this->ecc.size = 512; this->ecc.bytes = 3; - this->ecc.layout = &nand_hw_eccoob_8; + this->ecc.layout = &nand_hw_eccoob_smallpage; this->ecc.mode = NAND_ECC_SOFT; this->ecc.calculate = NULL; this->ecc.correct = NULL; -- cgit v0.10.2 From 13e1add1073f55d5361e5357016b631efc03bff8 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 21 Oct 2009 10:39:05 +0200 Subject: mxc_nand: cleanup initialization The oob layout was initialized several times. Instead, use a smallpage layout by default and switch to a largepage afterwards if necessary. Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 2aae5a7..dafa1f0 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -921,45 +921,42 @@ static int __init mxcnd_probe(struct platform_device *pdev) if (err) goto eirq; + /* Reset NAND */ + this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + + /* preset operation */ + /* Unlock the internal RAM Buffer */ + writew(0x2, host->regs + NFC_CONFIG); + + /* Blocks to be unlocked */ + writew(0x0, host->regs + NFC_UNLOCKSTART_BLKADDR); + writew(0x4000, host->regs + NFC_UNLOCKEND_BLKADDR); + + /* Unlock Block Command for given address range */ + writew(0x4, host->regs + NFC_WRPROT); + + this->ecc.size = 512; + this->ecc.bytes = 3; + this->ecc.layout = &nand_hw_eccoob_smallpage; + if (pdata->hw_ecc) { this->ecc.calculate = mxc_nand_calculate_ecc; this->ecc.hwctl = mxc_nand_enable_hwecc; this->ecc.correct = mxc_nand_correct_data; this->ecc.mode = NAND_ECC_HW; - this->ecc.size = 512; - this->ecc.bytes = 3; tmp = readw(host->regs + NFC_CONFIG1); tmp |= NFC_ECC_EN; writew(tmp, host->regs + NFC_CONFIG1); } else { - this->ecc.size = 512; - this->ecc.bytes = 3; - this->ecc.layout = &nand_hw_eccoob_smallpage; this->ecc.mode = NAND_ECC_SOFT; tmp = readw(host->regs + NFC_CONFIG1); tmp &= ~NFC_ECC_EN; writew(tmp, host->regs + NFC_CONFIG1); } - /* Reset NAND */ - this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); - - /* preset operation */ - /* Unlock the internal RAM Buffer */ - writew(0x2, host->regs + NFC_CONFIG); - - /* Blocks to be unlocked */ - writew(0x0, host->regs + NFC_UNLOCKSTART_BLKADDR); - writew(0x4000, host->regs + NFC_UNLOCKEND_BLKADDR); - - /* Unlock Block Command for given address range */ - writew(0x4, host->regs + NFC_WRPROT); - /* NAND bus width determines access funtions used by upper layer */ - if (pdata->width == 2) { + if (pdata->width == 2) this->options |= NAND_BUSWIDTH_16; - this->ecc.layout = &nand_hw_eccoob_smallpage; - } /* first scan to find the device and get the page size */ if (nand_scan_ident(mtd, 1)) { @@ -967,34 +964,9 @@ static int __init mxcnd_probe(struct platform_device *pdev) goto escan; } - host->pagesize_2k = (mtd->writesize == 2048) ? 1 : 0; - - if (this->ecc.mode == NAND_ECC_HW) { - switch (mtd->oobsize) { - case 8: - this->ecc.layout = &nand_hw_eccoob_smallpage; - break; - case 16: - this->ecc.layout = &nand_hw_eccoob_smallpage; - break; - case 64: - this->ecc.layout = &nand_hw_eccoob_largepage; - break; - default: - /* page size not handled by HW ECC */ - /* switching back to soft ECC */ - this->ecc.size = 512; - this->ecc.bytes = 3; - this->ecc.layout = &nand_hw_eccoob_smallpage; - this->ecc.mode = NAND_ECC_SOFT; - this->ecc.calculate = NULL; - this->ecc.correct = NULL; - this->ecc.hwctl = NULL; - tmp = readw(host->regs + NFC_CONFIG1); - tmp &= ~NFC_ECC_EN; - writew(tmp, host->regs + NFC_CONFIG1); - break; - } + if (mtd->writesize == 2048) { + host->pagesize_2k = 1; + this->ecc.layout = &nand_hw_eccoob_largepage; } /* second phase scan */ -- cgit v0.10.2 From 06ecb04ac5c038248d2bcee92a2a4259f2acfa31 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 2 Jun 2009 11:37:53 +0200 Subject: mxc_nand: merge send_read_page and send_prog_page Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index dafa1f0..8aa8a42 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -226,12 +226,10 @@ static void send_addr(struct mxc_nand_host *host, uint16_t addr, int islast) wait_op_done(host, TROP_US_DELAY, addr, islast); } -/* This function requests the NANDFC to initate the transfer - * of data currently in the NANDFC RAM buffer to the NAND device. */ -static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id, - int spare_only) +static void send_page(struct mxc_nand_host *host, uint8_t buf_id, + int spare_only, unsigned int ops) { - DEBUG(MTD_DEBUG_LEVEL3, "send_prog_page (%d)\n", spare_only); + DEBUG(MTD_DEBUG_LEVEL3, "send_page (%d)\n", spare_only); /* NANDFC buffer 0 is used for page read/write */ writew(buf_id, host->regs + NFC_BUF_ADDR); @@ -246,33 +244,7 @@ static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id, writew(config1, host->regs + NFC_CONFIG1); } - writew(NFC_INPUT, host->regs + NFC_CONFIG2); - - /* Wait for operation to complete */ - wait_op_done(host, TROP_US_DELAY, spare_only, true); -} - -/* Requests NANDFC to initated the transfer of data from the - * NAND device into in the NANDFC ram buffer. */ -static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id, - int spare_only) -{ - DEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", spare_only); - - /* NANDFC buffer 0 is used for page read/write */ - writew(buf_id, host->regs + NFC_BUF_ADDR); - - /* Configure spare or page+spare access */ - if (!host->pagesize_2k) { - uint32_t config1 = readw(host->regs + NFC_CONFIG1); - if (spare_only) - config1 |= NFC_SP_EN; - else - config1 &= ~NFC_SP_EN; - writew(config1, host->regs + NFC_CONFIG1); - } - - writew(NFC_OUTPUT, host->regs + NFC_CONFIG2); + writew(ops, host->regs + NFC_CONFIG2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, spare_only, true); @@ -756,13 +728,13 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, break; case NAND_CMD_PAGEPROG: - send_prog_page(host, 0, host->spare_only); + send_page(host, 0, host->spare_only, NFC_INPUT); if (host->pagesize_2k) { /* data in 4 areas datas */ - send_prog_page(host, 1, host->spare_only); - send_prog_page(host, 2, host->spare_only); - send_prog_page(host, 3, host->spare_only); + send_page(host, 1, host->spare_only, NFC_INPUT); + send_page(host, 2, host->spare_only, NFC_INPUT); + send_page(host, 3, host->spare_only, NFC_INPUT); } break; @@ -827,12 +799,12 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, /* send read confirm command */ send_cmd(host, NAND_CMD_READSTART, true); /* read for each AREA */ - send_read_page(host, 0, host->spare_only); - send_read_page(host, 1, host->spare_only); - send_read_page(host, 2, host->spare_only); - send_read_page(host, 3, host->spare_only); + send_page(host, 0, host->spare_only, NFC_OUTPUT); + send_page(host, 1, host->spare_only, NFC_OUTPUT); + send_page(host, 2, host->spare_only, NFC_OUTPUT); + send_page(host, 3, host->spare_only, NFC_OUTPUT); } else - send_read_page(host, 0, host->spare_only); + send_page(host, 0, host->spare_only, NFC_OUTPUT); break; case NAND_CMD_READID: -- cgit v0.10.2 From a3e65b64d5067f86b929eabde82f132b81437da8 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 2 Jun 2009 11:47:59 +0200 Subject: mxc_nand: introduce mxc_do_addr_cycle This factors the address cycle to a seperate function. This becomes useful in a later patch where we can simplify the command processing by making use of this function. Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 8aa8a42..325645c 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -658,6 +658,52 @@ static void mxc_nand_select_chip(struct mtd_info *mtd, int chip) } } +static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) +{ + struct nand_chip *nand_chip = mtd->priv; + struct mxc_nand_host *host = nand_chip->priv; + + /* Write out column address, if necessary */ + if (column != -1) { + /* + * MXC NANDFC can only perform full page+spare or + * spare-only read/write. When the upper layers + * layers perform a read/write buf operation, + * we will used the saved column adress to index into + * the full page. + */ + send_addr(host, 0, page_addr == -1); + if (host->pagesize_2k) + /* another col addr cycle for 2k page */ + send_addr(host, 0, false); + } + + /* Write out page address, if necessary */ + if (page_addr != -1) { + /* paddr_0 - p_addr_7 */ + send_addr(host, (page_addr & 0xff), false); + + if (host->pagesize_2k) { + if (mtd->size >= 0x10000000) { + /* paddr_8 - paddr_15 */ + send_addr(host, (page_addr >> 8) & 0xff, false); + send_addr(host, (page_addr >> 16) & 0xff, true); + } else + /* paddr_8 - paddr_15 */ + send_addr(host, (page_addr >> 8) & 0xff, true); + } else { + /* One more address cycle for higher density devices */ + if (mtd->size >= 0x4000000) { + /* paddr_8 - paddr_15 */ + send_addr(host, (page_addr >> 8) & 0xff, false); + send_addr(host, (page_addr >> 16) & 0xff, true); + } else + /* paddr_8 - paddr_15 */ + send_addr(host, (page_addr >> 8) & 0xff, true); + } + } +} + /* Used by the upper layer to write command to NAND Flash for * different operations to be carried out on NAND Flash */ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, @@ -746,46 +792,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, /* Write out the command to the device. */ send_cmd(host, command, useirq); - - /* Write out column address, if necessary */ - if (column != -1) { - /* - * MXC NANDFC can only perform full page+spare or - * spare-only read/write. When the upper layers - * layers perform a read/write buf operation, - * we will used the saved column adress to index into - * the full page. - */ - send_addr(host, 0, page_addr == -1); - if (host->pagesize_2k) - /* another col addr cycle for 2k page */ - send_addr(host, 0, false); - } - - /* Write out page address, if necessary */ - if (page_addr != -1) { - /* paddr_0 - p_addr_7 */ - send_addr(host, (page_addr & 0xff), false); - - if (host->pagesize_2k) { - if (mtd->size >= 0x10000000) { - /* paddr_8 - paddr_15 */ - send_addr(host, (page_addr >> 8) & 0xff, false); - send_addr(host, (page_addr >> 16) & 0xff, true); - } else - /* paddr_8 - paddr_15 */ - send_addr(host, (page_addr >> 8) & 0xff, true); - } else { - /* One more address cycle for higher density devices */ - if (mtd->size >= 0x4000000) { - /* paddr_8 - paddr_15 */ - send_addr(host, (page_addr >> 8) & 0xff, false); - send_addr(host, (page_addr >> 16) & 0xff, true); - } else - /* paddr_8 - paddr_15 */ - send_addr(host, (page_addr >> 8) & 0xff, true); - } - } + mxc_do_addr_cycle(mtd, column, page_addr); /* Command post-processing step */ switch (command) { -- cgit v0.10.2 From 624654917476c63287429e005173aa8629c92eac Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 4 Jun 2009 15:57:20 +0200 Subject: mxc nand: remove debug param Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 325645c..f981a1f 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -165,7 +165,7 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) * complete by checking the INT bit of config2 register. */ static void wait_op_done(struct mxc_nand_host *host, int max_retries, - uint16_t param, int useirq) + int useirq) { uint32_t tmp; @@ -194,8 +194,8 @@ static void wait_op_done(struct mxc_nand_host *host, int max_retries, udelay(1); } if (max_retries < 0) - DEBUG(MTD_DEBUG_LEVEL0, "%s(%d): INT not set\n", - __func__, param); + DEBUG(MTD_DEBUG_LEVEL0, "%s: INT not set\n", + __func__); } } @@ -209,7 +209,7 @@ static void send_cmd(struct mxc_nand_host *host, uint16_t cmd, int useirq) writew(NFC_CMD, host->regs + NFC_CONFIG2); /* Wait for operation to complete */ - wait_op_done(host, TROP_US_DELAY, cmd, useirq); + wait_op_done(host, TROP_US_DELAY, useirq); } /* This function sends an address (or partial address) to the @@ -223,7 +223,7 @@ static void send_addr(struct mxc_nand_host *host, uint16_t addr, int islast) writew(NFC_ADDR, host->regs + NFC_CONFIG2); /* Wait for operation to complete */ - wait_op_done(host, TROP_US_DELAY, addr, islast); + wait_op_done(host, TROP_US_DELAY, islast); } static void send_page(struct mxc_nand_host *host, uint8_t buf_id, @@ -247,7 +247,7 @@ static void send_page(struct mxc_nand_host *host, uint8_t buf_id, writew(ops, host->regs + NFC_CONFIG2); /* Wait for operation to complete */ - wait_op_done(host, TROP_US_DELAY, spare_only, true); + wait_op_done(host, TROP_US_DELAY, true); } /* Request the NANDFC to perform a read of the NAND device ID. */ @@ -267,7 +267,7 @@ static void send_read_id(struct mxc_nand_host *host) writew(NFC_ID, host->regs + NFC_CONFIG2); /* Wait for operation to complete */ - wait_op_done(host, TROP_US_DELAY, 0, true); + wait_op_done(host, TROP_US_DELAY, true); if (this->options & NAND_BUSWIDTH_16) { void __iomem *main_buf = host->regs + MAIN_AREA0; @@ -303,7 +303,7 @@ static uint16_t get_dev_status(struct mxc_nand_host *host) writew(NFC_STATUS, host->regs + NFC_CONFIG2); /* Wait for operation to complete */ - wait_op_done(host, TROP_US_DELAY, 0, true); + wait_op_done(host, TROP_US_DELAY, true); /* Status is placed in first word of main buffer */ /* get status, then recovery area 1 data */ -- cgit v0.10.2 From a4ad57f8b320c9d89b7693be82e47347425db918 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 4 Jun 2009 16:12:40 +0200 Subject: mxc nand: remove dead code Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index f981a1f..1ffb854 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -620,23 +620,6 @@ static void mxc_nand_select_chip(struct mtd_info *mtd, int chip) struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; -#ifdef CONFIG_MTD_NAND_MXC_FORCE_CE - if (chip > 0) { - DEBUG(MTD_DEBUG_LEVEL0, - "ERROR: Illegal chip select (chip = %d)\n", chip); - return; - } - - if (chip == -1) { - writew(readw(host->regs + NFC_CONFIG1) & ~NFC_CE, - host->regs + NFC_CONFIG1); - return; - } - - writew(readw(host->regs + NFC_CONFIG1) | NFC_CE, - host->regs + NFC_CONFIG1); -#endif - switch (chip) { case -1: /* Disable the NFC clock */ -- cgit v0.10.2 From d970a0730ba5598b711d42bac287a17db5b6268a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 4 Jun 2009 16:16:01 +0200 Subject: mxc nand: use resource_size() Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 1ffb854..8fcb33d 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -865,7 +865,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) goto eres; } - host->regs = ioremap(res->start, res->end - res->start + 1); + host->regs = ioremap(res->start, resource_size(res)); if (!host->regs) { err = -ENOMEM; goto eres; -- cgit v0.10.2 From f8f9608d9b7a5b3349605284a4f3876e898413f1 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 4 Jun 2009 17:12:26 +0200 Subject: mxc nand: use buffers The NAND controller has some limitations how to access the internal buffers. It only allows 32 bit accesses. The driver used to work around this by having special alignment aware copy routines. We now copy the whole page to a buffer in memory and let the access functions use this buffer. This simplifies the driver. A bonnie++ test showed that this has no negative performance impact on the driver. Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 8fcb33d..03d2008 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -107,15 +107,17 @@ struct mxc_nand_host { struct device *dev; void __iomem *regs; - int spare_only; int status_request; int pagesize_2k; - uint16_t col_addr; struct clk *clk; int clk_act; int irq; wait_queue_head_t irq_waitq; + + uint8_t *data_buf; + unsigned int buf_start; + int spare_len; }; /* Define delays in microsec for NAND device operations */ @@ -227,23 +229,11 @@ static void send_addr(struct mxc_nand_host *host, uint16_t addr, int islast) } static void send_page(struct mxc_nand_host *host, uint8_t buf_id, - int spare_only, unsigned int ops) + unsigned int ops) { - DEBUG(MTD_DEBUG_LEVEL3, "send_page (%d)\n", spare_only); - /* NANDFC buffer 0 is used for page read/write */ writew(buf_id, host->regs + NFC_BUF_ADDR); - /* Configure spare or page+spare access */ - if (!host->pagesize_2k) { - uint16_t config1 = readw(host->regs + NFC_CONFIG1); - if (spare_only) - config1 |= NFC_SP_EN; - else - config1 &= ~(NFC_SP_EN); - writew(config1, host->regs + NFC_CONFIG1); - } - writew(ops, host->regs + NFC_CONFIG2); /* Wait for operation to complete */ @@ -278,6 +268,7 @@ static void send_read_id(struct mxc_nand_host *host) writeb(readb(main_buf + 8), main_buf + 4); writeb(readb(main_buf + 10), main_buf + 5); } + memcpy(host->data_buf, host->regs + MAIN_AREA0, 16); } /* This function requests the NANDFC to perform a read of the @@ -363,32 +354,14 @@ static u_char mxc_nand_read_byte(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; - uint8_t ret = 0; - uint16_t col, rd_word; - uint16_t __iomem *main_buf = host->regs + MAIN_AREA0; - uint16_t __iomem *spare_buf = host->regs + SPARE_AREA0; + uint8_t ret; /* Check for status request */ if (host->status_request) return get_dev_status(host) & 0xFF; - /* Get column for 16-bit access */ - col = host->col_addr >> 1; - - /* If we are accessing the spare region */ - if (host->spare_only) - rd_word = readw(&spare_buf[col]); - else - rd_word = readw(&main_buf[col]); - - /* Pick upper/lower byte of word from RAM buffer */ - if (host->col_addr & 0x1) - ret = (rd_word >> 8) & 0xFF; - else - ret = rd_word & 0xFF; - - /* Update saved column address */ - host->col_addr++; + ret = *(uint8_t *)(host->data_buf + host->buf_start); + host->buf_start++; return ret; } @@ -397,33 +370,10 @@ static uint16_t mxc_nand_read_word(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; - uint16_t col, rd_word, ret; - uint16_t __iomem *p; + uint16_t ret; - DEBUG(MTD_DEBUG_LEVEL3, - "mxc_nand_read_word(col = %d)\n", host->col_addr); - - col = host->col_addr; - /* Adjust saved column address */ - if (col < mtd->writesize && host->spare_only) - col += mtd->writesize; - - if (col < mtd->writesize) - p = (host->regs + MAIN_AREA0) + (col >> 1); - else - p = (host->regs + SPARE_AREA0) + ((col - mtd->writesize) >> 1); - - if (col & 1) { - rd_word = readw(p); - ret = (rd_word >> 8) & 0xff; - rd_word = readw(&p[1]); - ret |= (rd_word << 8) & 0xff00; - - } else - ret = readw(p); - - /* Update saved column address */ - host->col_addr = col + 2; + ret = *(uint16_t *)(host->data_buf + host->buf_start); + host->buf_start += 2; return ret; } @@ -436,94 +386,14 @@ static void mxc_nand_write_buf(struct mtd_info *mtd, { struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; - int n, col, i = 0; - - DEBUG(MTD_DEBUG_LEVEL3, - "mxc_nand_write_buf(col = %d, len = %d)\n", host->col_addr, - len); - - col = host->col_addr; - - /* Adjust saved column address */ - if (col < mtd->writesize && host->spare_only) - col += mtd->writesize; - - n = mtd->writesize + mtd->oobsize - col; - n = min(len, n); - - DEBUG(MTD_DEBUG_LEVEL3, - "%s:%d: col = %d, n = %d\n", __func__, __LINE__, col, n); - - while (n) { - void __iomem *p; - - if (col < mtd->writesize) - p = host->regs + MAIN_AREA0 + (col & ~3); - else - p = host->regs + SPARE_AREA0 - - mtd->writesize + (col & ~3); - - DEBUG(MTD_DEBUG_LEVEL3, "%s:%d: p = %p\n", __func__, - __LINE__, p); - - if (((col | (int)&buf[i]) & 3) || n < 16) { - uint32_t data = 0; - - if (col & 3 || n < 4) - data = readl(p); - - switch (col & 3) { - case 0: - if (n) { - data = (data & 0xffffff00) | - (buf[i++] << 0); - n--; - col++; - } - case 1: - if (n) { - data = (data & 0xffff00ff) | - (buf[i++] << 8); - n--; - col++; - } - case 2: - if (n) { - data = (data & 0xff00ffff) | - (buf[i++] << 16); - n--; - col++; - } - case 3: - if (n) { - data = (data & 0x00ffffff) | - (buf[i++] << 24); - n--; - col++; - } - } - - writel(data, p); - } else { - int m = mtd->writesize - col; + u16 col = host->buf_start; + int n = mtd->oobsize + mtd->writesize - col; - if (col >= mtd->writesize) - m += mtd->oobsize; + n = min(n, len); - m = min(n, m) & ~3; + memcpy(host->data_buf + col, buf, n); - DEBUG(MTD_DEBUG_LEVEL3, - "%s:%d: n = %d, m = %d, i = %d, col = %d\n", - __func__, __LINE__, n, m, i, col); - - memcpy(p, &buf[i], m); - col += m; - i += m; - n -= m; - } - } - /* Update saved column address */ - host->col_addr = col; + host->buf_start += n; } /* Read the data buffer from the NAND Flash. To read the data from NAND @@ -534,75 +404,14 @@ static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) { struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; - int n, col, i = 0; + u16 col = host->buf_start; + int n = mtd->oobsize + mtd->writesize - col; - DEBUG(MTD_DEBUG_LEVEL3, - "mxc_nand_read_buf(col = %d, len = %d)\n", host->col_addr, len); - - col = host->col_addr; - - /* Adjust saved column address */ - if (col < mtd->writesize && host->spare_only) - col += mtd->writesize; - - n = mtd->writesize + mtd->oobsize - col; - n = min(len, n); - - while (n) { - void __iomem *p; - - if (col < mtd->writesize) - p = host->regs + MAIN_AREA0 + (col & ~3); - else - p = host->regs + SPARE_AREA0 - - mtd->writesize + (col & ~3); - - if (((col | (int)&buf[i]) & 3) || n < 16) { - uint32_t data; - - data = readl(p); - switch (col & 3) { - case 0: - if (n) { - buf[i++] = (uint8_t) (data); - n--; - col++; - } - case 1: - if (n) { - buf[i++] = (uint8_t) (data >> 8); - n--; - col++; - } - case 2: - if (n) { - buf[i++] = (uint8_t) (data >> 16); - n--; - col++; - } - case 3: - if (n) { - buf[i++] = (uint8_t) (data >> 24); - n--; - col++; - } - } - } else { - int m = mtd->writesize - col; + n = min(n, len); - if (col >= mtd->writesize) - m += mtd->oobsize; - - m = min(n, m) & ~3; - memcpy(&buf[i], p, m); - col += m; - i += m; - n -= m; - } - } - /* Update saved column address */ - host->col_addr = col; + memcpy(buf, host->data_buf + col, len); + host->buf_start += len; } /* Used by the upper layer to verify the data in NAND Flash @@ -641,6 +450,36 @@ static void mxc_nand_select_chip(struct mtd_info *mtd, int chip) } } +/* + * Function to transfer data to/from spare area. + */ +static void copy_spare(struct mtd_info *mtd, bool bfrom) +{ + struct nand_chip *this = mtd->priv; + struct mxc_nand_host *host = this->priv; + u16 i, j; + u16 n = mtd->writesize >> 9; + u8 *d = host->data_buf + mtd->writesize; + u8 *s = host->regs + SPARE_AREA0; + u16 t = host->spare_len; + + j = (mtd->oobsize / n >> 1) << 1; + + if (bfrom) { + for (i = 0; i < n - 1; i++) + memcpy(d + i * j, s + i * t, j); + + /* the last section */ + memcpy(d + i * j, s + i * t, mtd->oobsize - i * j); + } else { + for (i = 0; i < n - 1; i++) + memcpy(&s[i * t], &d[i * j], j); + + /* the last section */ + memcpy(&s[i * t], &d[i * j], mtd->oobsize - i * j); + } +} + static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) { struct nand_chip *nand_chip = mtd->priv; @@ -707,19 +546,18 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, switch (command) { case NAND_CMD_STATUS: - host->col_addr = 0; + host->buf_start = 0; host->status_request = true; break; case NAND_CMD_READ0: - host->col_addr = column; - host->spare_only = false; + host->buf_start = column; useirq = false; break; case NAND_CMD_READOOB: - host->col_addr = column; - host->spare_only = true; + host->buf_start = column + mtd->writesize; + useirq = false; if (host->pagesize_2k) command = NAND_CMD_READ0; /* only READ0 is valid */ @@ -739,15 +577,13 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, mxc_nand_command(mtd, NAND_CMD_READ0, 0, page_addr); - host->col_addr = column - mtd->writesize; - host->spare_only = true; + host->buf_start = column; /* Set program pointer to spare region */ if (!host->pagesize_2k) send_cmd(host, NAND_CMD_READOOB, false); } else { - host->spare_only = false; - host->col_addr = column; + host->buf_start = column; /* Set program pointer to page start */ if (!host->pagesize_2k) @@ -757,13 +593,15 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, break; case NAND_CMD_PAGEPROG: - send_page(host, 0, host->spare_only, NFC_INPUT); + memcpy(host->regs + MAIN_AREA0, host->data_buf, mtd->writesize); + copy_spare(mtd, false); + send_page(host, 0, NFC_INPUT); if (host->pagesize_2k) { /* data in 4 areas datas */ - send_page(host, 1, host->spare_only, NFC_INPUT); - send_page(host, 2, host->spare_only, NFC_INPUT); - send_page(host, 3, host->spare_only, NFC_INPUT); + send_page(host, 1, NFC_INPUT); + send_page(host, 2, NFC_INPUT); + send_page(host, 3, NFC_INPUT); } break; @@ -789,16 +627,18 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, /* send read confirm command */ send_cmd(host, NAND_CMD_READSTART, true); /* read for each AREA */ - send_page(host, 0, host->spare_only, NFC_OUTPUT); - send_page(host, 1, host->spare_only, NFC_OUTPUT); - send_page(host, 2, host->spare_only, NFC_OUTPUT); - send_page(host, 3, host->spare_only, NFC_OUTPUT); + send_page(host, 0, NFC_OUTPUT); + send_page(host, 1, NFC_OUTPUT); + send_page(host, 2, NFC_OUTPUT); + send_page(host, 3, NFC_OUTPUT); } else - send_page(host, 0, host->spare_only, NFC_OUTPUT); + send_page(host, 0, NFC_OUTPUT); + + memcpy(host->data_buf, host->regs + MAIN_AREA0, mtd->writesize); + copy_spare(mtd, true); break; case NAND_CMD_READID: - host->col_addr = 0; send_read_id(host); break; @@ -824,10 +664,14 @@ static int __init mxcnd_probe(struct platform_device *pdev) int err = 0, nr_parts = 0; /* Allocate memory for MTD device structure and private data */ - host = kzalloc(sizeof(struct mxc_nand_host), GFP_KERNEL); + host = kzalloc(sizeof(struct mxc_nand_host) + NAND_MAX_PAGESIZE + + NAND_MAX_OOBSIZE, GFP_KERNEL); if (!host) return -ENOMEM; + host->data_buf = (uint8_t *)(host + 1); + host->spare_len = 16; + host->dev = &pdev->dev; /* structures must be linked */ this = &host->nand; -- cgit v0.10.2 From 89121a6bfecf4bd81b360fa1b3ae8875ed3e4a71 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 4 Jun 2009 17:18:01 +0200 Subject: mxc nand: simplify command processing Instead of having two switch/case with other operations in between, use only one switch/case Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 03d2008..67ddc35 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -533,7 +533,6 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, { struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; - int useirq = true; DEBUG(MTD_DEBUG_LEVEL3, "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n", @@ -548,19 +547,37 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, case NAND_CMD_STATUS: host->buf_start = 0; host->status_request = true; - break; - case NAND_CMD_READ0: - host->buf_start = column; - useirq = false; + send_cmd(host, command, true); + mxc_do_addr_cycle(mtd, column, page_addr); break; + case NAND_CMD_READ0: case NAND_CMD_READOOB: - host->buf_start = column + mtd->writesize; + if (command == NAND_CMD_READ0) + host->buf_start = column; + else + host->buf_start = column + mtd->writesize; - useirq = false; if (host->pagesize_2k) command = NAND_CMD_READ0; /* only READ0 is valid */ + + send_cmd(host, command, false); + mxc_do_addr_cycle(mtd, column, page_addr); + + if (host->pagesize_2k) { + /* send read confirm command */ + send_cmd(host, NAND_CMD_READSTART, true); + /* read for each AREA */ + send_page(host, 0, NFC_OUTPUT); + send_page(host, 1, NFC_OUTPUT); + send_page(host, 2, NFC_OUTPUT); + send_page(host, 3, NFC_OUTPUT); + } else + send_page(host, 0, NFC_OUTPUT); + + memcpy(host->data_buf, host->regs + MAIN_AREA0, mtd->writesize); + copy_spare(mtd, true); break; case NAND_CMD_SEQIN: @@ -589,7 +606,9 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, if (!host->pagesize_2k) send_cmd(host, NAND_CMD_READ0, false); } - useirq = false; + + send_cmd(host, command, false); + mxc_do_addr_cycle(mtd, column, page_addr); break; case NAND_CMD_PAGEPROG: @@ -604,51 +623,21 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, send_page(host, 3, NFC_INPUT); } - break; - - case NAND_CMD_ERASE1: - useirq = false; - break; - } - - /* Write out the command to the device. */ - send_cmd(host, command, useirq); - mxc_do_addr_cycle(mtd, column, page_addr); - - /* Command post-processing step */ - switch (command) { - - case NAND_CMD_RESET: - break; - - case NAND_CMD_READOOB: - case NAND_CMD_READ0: - if (host->pagesize_2k) { - /* send read confirm command */ - send_cmd(host, NAND_CMD_READSTART, true); - /* read for each AREA */ - send_page(host, 0, NFC_OUTPUT); - send_page(host, 1, NFC_OUTPUT); - send_page(host, 2, NFC_OUTPUT); - send_page(host, 3, NFC_OUTPUT); - } else - send_page(host, 0, NFC_OUTPUT); - - memcpy(host->data_buf, host->regs + MAIN_AREA0, mtd->writesize); - copy_spare(mtd, true); + send_cmd(host, command, true); + mxc_do_addr_cycle(mtd, column, page_addr); break; case NAND_CMD_READID: + send_cmd(host, command, true); + mxc_do_addr_cycle(mtd, column, page_addr); send_read_id(host); break; - case NAND_CMD_PAGEPROG: - break; - - case NAND_CMD_STATUS: - break; - + case NAND_CMD_ERASE1: case NAND_CMD_ERASE2: + send_cmd(host, command, false); + mxc_do_addr_cycle(mtd, column, page_addr); + break; } } -- cgit v0.10.2 From c5d23f1bf384e4a17bc4a014313a4157c015a820 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 4 Jun 2009 17:25:53 +0200 Subject: mxc nand: modify send_page to send all pages, not only one Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 67ddc35..1131ad1 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -228,16 +228,25 @@ static void send_addr(struct mxc_nand_host *host, uint16_t addr, int islast) wait_op_done(host, TROP_US_DELAY, islast); } -static void send_page(struct mxc_nand_host *host, uint8_t buf_id, - unsigned int ops) +static void send_page(struct mxc_nand_host *host, unsigned int ops) { - /* NANDFC buffer 0 is used for page read/write */ - writew(buf_id, host->regs + NFC_BUF_ADDR); + int bufs, i; - writew(ops, host->regs + NFC_CONFIG2); + if (host->pagesize_2k) + bufs = 4; + else + bufs = 1; - /* Wait for operation to complete */ - wait_op_done(host, TROP_US_DELAY, true); + for (i = 0; i < bufs; i++) { + + /* NANDFC buffer 0 is used for page read/write */ + writew(i, host->regs + NFC_BUF_ADDR); + + writew(ops, host->regs + NFC_CONFIG2); + + /* Wait for operation to complete */ + wait_op_done(host, TROP_US_DELAY, true); + } } /* Request the NANDFC to perform a read of the NAND device ID. */ @@ -565,16 +574,10 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, send_cmd(host, command, false); mxc_do_addr_cycle(mtd, column, page_addr); - if (host->pagesize_2k) { - /* send read confirm command */ + if (host->pagesize_2k) send_cmd(host, NAND_CMD_READSTART, true); - /* read for each AREA */ - send_page(host, 0, NFC_OUTPUT); - send_page(host, 1, NFC_OUTPUT); - send_page(host, 2, NFC_OUTPUT); - send_page(host, 3, NFC_OUTPUT); - } else - send_page(host, 0, NFC_OUTPUT); + + send_page(host, NFC_OUTPUT); memcpy(host->data_buf, host->regs + MAIN_AREA0, mtd->writesize); copy_spare(mtd, true); @@ -614,15 +617,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, case NAND_CMD_PAGEPROG: memcpy(host->regs + MAIN_AREA0, host->data_buf, mtd->writesize); copy_spare(mtd, false); - send_page(host, 0, NFC_INPUT); - - if (host->pagesize_2k) { - /* data in 4 areas datas */ - send_page(host, 1, NFC_INPUT); - send_page(host, 2, NFC_INPUT); - send_page(host, 3, NFC_INPUT); - } - + send_page(host, NFC_INPUT); send_cmd(host, command, true); mxc_do_addr_cycle(mtd, column, page_addr); break; -- cgit v0.10.2 From 0e60c7c4015f051ff921e6c30844f31e17f8ad95 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 5 Jun 2009 10:55:32 +0200 Subject: mxc_nand: remove unused defines Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 1131ad1..ab6db69 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -122,13 +122,6 @@ struct mxc_nand_host { /* Define delays in microsec for NAND device operations */ #define TROP_US_DELAY 2000 -/* Macros to get byte and bit positions of ECC */ -#define COLPOS(x) ((x) >> 3) -#define BITPOS(x) ((x) & 0xf) - -/* Define single bit Error positions in Main & Spare area */ -#define MAIN_SINGLEBIT_ERROR 0x4 -#define SPARE_SINGLEBIT_ERROR 0x1 /* OOB placement block for use with hardware ecc generation */ static struct nand_ecclayout nand_hw_eccoob_smallpage = { -- cgit v0.10.2 From c6de7e1bb8d6e1b3ae318bf9fbe84557d7c8baec Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 5 Oct 2009 11:14:35 +0200 Subject: mxc_nand: Make main/spare areas runtime configurable The main/spare areas are on different addresses on later versions of the controller, so make them configurable. Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index ab6db69..c84fd6c 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -52,18 +52,6 @@ #define NFC_CONFIG1 0xE1A #define NFC_CONFIG2 0xE1C -/* Addresses for NFC RAM BUFFER Main area 0 */ -#define MAIN_AREA0 0x000 -#define MAIN_AREA1 0x200 -#define MAIN_AREA2 0x400 -#define MAIN_AREA3 0x600 - -/* Addresses for NFC SPARE BUFFER Spare area 0 */ -#define SPARE_AREA0 0x800 -#define SPARE_AREA1 0x810 -#define SPARE_AREA2 0x820 -#define SPARE_AREA3 0x830 - /* Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register * for Command operation */ #define NFC_CMD 0x1 @@ -106,6 +94,11 @@ struct mxc_nand_host { struct mtd_partition *parts; struct device *dev; + void *spare0; + void *main_area0; + void *main_area1; + + void __iomem *base; void __iomem *regs; int status_request; int pagesize_2k; @@ -262,7 +255,7 @@ static void send_read_id(struct mxc_nand_host *host) wait_op_done(host, TROP_US_DELAY, true); if (this->options & NAND_BUSWIDTH_16) { - void __iomem *main_buf = host->regs + MAIN_AREA0; + void __iomem *main_buf = host->main_area0; /* compress the ID info */ writeb(readb(main_buf + 2), main_buf + 1); writeb(readb(main_buf + 4), main_buf + 2); @@ -270,14 +263,14 @@ static void send_read_id(struct mxc_nand_host *host) writeb(readb(main_buf + 8), main_buf + 4); writeb(readb(main_buf + 10), main_buf + 5); } - memcpy(host->data_buf, host->regs + MAIN_AREA0, 16); + memcpy(host->data_buf, host->main_area0, 16); } /* This function requests the NANDFC to perform a read of the * NAND device status and returns the current status. */ static uint16_t get_dev_status(struct mxc_nand_host *host) { - void __iomem *main_buf = host->regs + MAIN_AREA1; + void __iomem *main_buf = host->main_area1; uint32_t store; uint16_t ret, tmp; /* Issue status request to NAND device */ @@ -462,7 +455,7 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom) u16 i, j; u16 n = mtd->writesize >> 9; u8 *d = host->data_buf + mtd->writesize; - u8 *s = host->regs + SPARE_AREA0; + u8 *s = host->spare0; u16 t = host->spare_len; j = (mtd->oobsize / n >> 1) << 1; @@ -572,7 +565,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, send_page(host, NFC_OUTPUT); - memcpy(host->data_buf, host->regs + MAIN_AREA0, mtd->writesize); + memcpy(host->data_buf, host->main_area0, mtd->writesize); copy_spare(mtd, true); break; @@ -608,7 +601,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, break; case NAND_CMD_PAGEPROG: - memcpy(host->regs + MAIN_AREA0, host->data_buf, mtd->writesize); + memcpy(host->main_area0, host->data_buf, mtd->writesize); copy_spare(mtd, false); send_page(host, NFC_INPUT); send_cmd(host, command, true); @@ -686,12 +679,17 @@ static int __init mxcnd_probe(struct platform_device *pdev) goto eres; } - host->regs = ioremap(res->start, resource_size(res)); - if (!host->regs) { + host->base = ioremap(res->start, resource_size(res)); + if (!host->base) { err = -ENOMEM; goto eres; } + host->regs = host->base; + host->main_area0 = host->base; + host->main_area1 = host->base + 0x200; + host->spare0 = host->base + 0x800; + tmp = readw(host->regs + NFC_CONFIG1); tmp |= NFC_INT_MSK; writew(tmp, host->regs + NFC_CONFIG1); @@ -778,7 +776,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) escan: free_irq(host->irq, host); eirq: - iounmap(host->regs); + iounmap(host->base); eres: clk_put(host->clk); eclk: @@ -797,7 +795,7 @@ static int __exit mxcnd_remove(struct platform_device *pdev) nand_release(&host->mtd); free_irq(host->irq, host); - iounmap(host->regs); + iounmap(host->base); kfree(host); return 0; -- cgit v0.10.2 From 2d69c7fadd8580a7cea3ae0caa90a1c2a92ab021 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 5 Oct 2009 11:24:02 +0200 Subject: mxc_nand: Get rid of pagesize_2k flag Later versions of this controller also allow 4k pagesize, so use mtd->writesize instead of a flag. Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index c84fd6c..09b9aab 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -101,7 +101,6 @@ struct mxc_nand_host { void __iomem *base; void __iomem *regs; int status_request; - int pagesize_2k; struct clk *clk; int clk_act; int irq; @@ -214,11 +213,13 @@ static void send_addr(struct mxc_nand_host *host, uint16_t addr, int islast) wait_op_done(host, TROP_US_DELAY, islast); } -static void send_page(struct mxc_nand_host *host, unsigned int ops) +static void send_page(struct mtd_info *mtd, unsigned int ops) { + struct nand_chip *nand_chip = mtd->priv; + struct mxc_nand_host *host = nand_chip->priv; int bufs, i; - if (host->pagesize_2k) + if (mtd->writesize > 512) bufs = 4; else bufs = 1; @@ -490,7 +491,7 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) * the full page. */ send_addr(host, 0, page_addr == -1); - if (host->pagesize_2k) + if (mtd->writesize > 512) /* another col addr cycle for 2k page */ send_addr(host, 0, false); } @@ -500,7 +501,7 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) /* paddr_0 - p_addr_7 */ send_addr(host, (page_addr & 0xff), false); - if (host->pagesize_2k) { + if (mtd->writesize > 512) { if (mtd->size >= 0x10000000) { /* paddr_8 - paddr_15 */ send_addr(host, (page_addr >> 8) & 0xff, false); @@ -554,16 +555,16 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, else host->buf_start = column + mtd->writesize; - if (host->pagesize_2k) + if (mtd->writesize > 512) command = NAND_CMD_READ0; /* only READ0 is valid */ send_cmd(host, command, false); mxc_do_addr_cycle(mtd, column, page_addr); - if (host->pagesize_2k) + if (mtd->writesize > 512) send_cmd(host, NAND_CMD_READSTART, true); - send_page(host, NFC_OUTPUT); + send_page(mtd, NFC_OUTPUT); memcpy(host->data_buf, host->main_area0, mtd->writesize); copy_spare(mtd, true); @@ -578,7 +579,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, * pointer to spare area, we must write the whole page * including OOB together. */ - if (host->pagesize_2k) + if (mtd->writesize > 512) /* call ourself to read a page */ mxc_nand_command(mtd, NAND_CMD_READ0, 0, page_addr); @@ -586,13 +587,13 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, host->buf_start = column; /* Set program pointer to spare region */ - if (!host->pagesize_2k) + if (mtd->writesize == 512) send_cmd(host, NAND_CMD_READOOB, false); } else { host->buf_start = column; /* Set program pointer to page start */ - if (!host->pagesize_2k) + if (mtd->writesize == 512) send_cmd(host, NAND_CMD_READ0, false); } @@ -603,7 +604,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, case NAND_CMD_PAGEPROG: memcpy(host->main_area0, host->data_buf, mtd->writesize); copy_spare(mtd, false); - send_page(host, NFC_INPUT); + send_page(mtd, NFC_INPUT); send_cmd(host, command, true); mxc_do_addr_cycle(mtd, column, page_addr); break; @@ -745,10 +746,8 @@ static int __init mxcnd_probe(struct platform_device *pdev) goto escan; } - if (mtd->writesize == 2048) { - host->pagesize_2k = 1; + if (mtd->writesize == 2048) this->ecc.layout = &nand_hw_eccoob_largepage; - } /* second phase scan */ if (nand_scan_tail(mtd)) { -- cgit v0.10.2 From 9467114ef43c971f0ae8aee3729d412125a2f432 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 5 Oct 2009 12:14:21 +0200 Subject: mxc_nand: Add NFC V2 support The v2 version of this controller is used on i.MX35/25 SoCs. Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 09b9aab..4a69682 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -33,9 +33,13 @@ #include #include +#include #define DRIVER_NAME "mxc_nand" +#define nfc_is_v21() (cpu_is_mx25() || cpu_is_mx35()) +#define nfc_is_v1() (cpu_is_mx31() || cpu_is_mx27()) + /* Addresses for NFC registers */ #define NFC_BUF_SIZE 0xE00 #define NFC_BUF_ADDR 0xE04 @@ -46,8 +50,10 @@ #define NFC_RSLTMAIN_AREA 0xE0E #define NFC_RSLTSPARE_AREA 0xE10 #define NFC_WRPROT 0xE12 -#define NFC_UNLOCKSTART_BLKADDR 0xE14 -#define NFC_UNLOCKEND_BLKADDR 0xE16 +#define NFC_V1_UNLOCKSTART_BLKADDR 0xe14 +#define NFC_V1_UNLOCKEND_BLKADDR 0xe16 +#define NFC_V21_UNLOCKSTART_BLKADDR 0xe20 +#define NFC_V21_UNLOCKEND_BLKADDR 0xe22 #define NFC_NF_WRPRST 0xE18 #define NFC_CONFIG1 0xE1A #define NFC_CONFIG2 0xE1C @@ -116,19 +122,47 @@ struct mxc_nand_host { #define TROP_US_DELAY 2000 /* OOB placement block for use with hardware ecc generation */ -static struct nand_ecclayout nand_hw_eccoob_smallpage = { +static struct nand_ecclayout nandv1_hw_eccoob_smallpage = { .eccbytes = 5, .eccpos = {6, 7, 8, 9, 10}, .oobfree = {{0, 5}, {12, 4}, } }; -static struct nand_ecclayout nand_hw_eccoob_largepage = { +static struct nand_ecclayout nandv1_hw_eccoob_largepage = { .eccbytes = 20, .eccpos = {6, 7, 8, 9, 10, 22, 23, 24, 25, 26, 38, 39, 40, 41, 42, 54, 55, 56, 57, 58}, .oobfree = {{2, 4}, {11, 10}, {27, 10}, {43, 10}, {59, 5}, } }; +/* OOB description for 512 byte pages with 16 byte OOB */ +static struct nand_ecclayout nandv2_hw_eccoob_smallpage = { + .eccbytes = 1 * 9, + .eccpos = { + 7, 8, 9, 10, 11, 12, 13, 14, 15 + }, + .oobfree = { + {.offset = 0, .length = 5} + } +}; + +/* OOB description for 2048 byte pages with 64 byte OOB */ +static struct nand_ecclayout nandv2_hw_eccoob_largepage = { + .eccbytes = 4 * 9, + .eccpos = { + 7, 8, 9, 10, 11, 12, 13, 14, 15, + 23, 24, 25, 26, 27, 28, 29, 30, 31, + 39, 40, 41, 42, 43, 44, 45, 46, 47, + 55, 56, 57, 58, 59, 60, 61, 62, 63 + }, + .oobfree = { + {.offset = 2, .length = 4}, + {.offset = 16, .length = 7}, + {.offset = 32, .length = 7}, + {.offset = 48, .length = 7} + } +}; + #ifdef CONFIG_MTD_PARTITIONS static const char *part_probes[] = { "RedBoot", "cmdlinepart", NULL }; #endif @@ -219,7 +253,7 @@ static void send_page(struct mtd_info *mtd, unsigned int ops) struct mxc_nand_host *host = nand_chip->priv; int bufs, i; - if (mtd->writesize > 512) + if (nfc_is_v1() && mtd->writesize > 512) bufs = 4; else bufs = 1; @@ -613,6 +647,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, send_cmd(host, command, true); mxc_do_addr_cycle(mtd, column, page_addr); send_read_id(host); + host->buf_start = column; break; case NAND_CMD_ERASE1: @@ -633,6 +668,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) struct resource *res; uint16_t tmp; int err = 0, nr_parts = 0; + struct nand_ecclayout *oob_smallpage, *oob_largepage; /* Allocate memory for MTD device structure and private data */ host = kzalloc(sizeof(struct mxc_nand_host) + NAND_MAX_PAGESIZE + @@ -641,7 +677,6 @@ static int __init mxcnd_probe(struct platform_device *pdev) return -ENOMEM; host->data_buf = (uint8_t *)(host + 1); - host->spare_len = 16; host->dev = &pdev->dev; /* structures must be linked */ @@ -686,10 +721,23 @@ static int __init mxcnd_probe(struct platform_device *pdev) goto eres; } - host->regs = host->base; host->main_area0 = host->base; host->main_area1 = host->base + 0x200; - host->spare0 = host->base + 0x800; + + if (nfc_is_v21()) { + host->regs = host->base + 0x1000; + host->spare0 = host->base + 0x1000; + host->spare_len = 64; + oob_smallpage = &nandv2_hw_eccoob_smallpage; + oob_largepage = &nandv2_hw_eccoob_largepage; + } else if (nfc_is_v1()) { + host->regs = host->base; + host->spare0 = host->base + 0x800; + host->spare_len = 16; + oob_smallpage = &nandv1_hw_eccoob_smallpage; + oob_largepage = &nandv1_hw_eccoob_largepage; + } else + BUG(); tmp = readw(host->regs + NFC_CONFIG1); tmp |= NFC_INT_MSK; @@ -711,15 +759,22 @@ static int __init mxcnd_probe(struct platform_device *pdev) writew(0x2, host->regs + NFC_CONFIG); /* Blocks to be unlocked */ - writew(0x0, host->regs + NFC_UNLOCKSTART_BLKADDR); - writew(0x4000, host->regs + NFC_UNLOCKEND_BLKADDR); + if (nfc_is_v21()) { + writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR); + writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR); + this->ecc.bytes = 9; + } else if (nfc_is_v1()) { + writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR); + writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR); + this->ecc.bytes = 3; + } else + BUG(); /* Unlock Block Command for given address range */ writew(0x4, host->regs + NFC_WRPROT); this->ecc.size = 512; - this->ecc.bytes = 3; - this->ecc.layout = &nand_hw_eccoob_smallpage; + this->ecc.layout = oob_smallpage; if (pdata->hw_ecc) { this->ecc.calculate = mxc_nand_calculate_ecc; @@ -747,7 +802,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) } if (mtd->writesize == 2048) - this->ecc.layout = &nand_hw_eccoob_largepage; + this->ecc.layout = oob_largepage; /* second phase scan */ if (nand_scan_tail(mtd)) { -- cgit v0.10.2 From f06368f7d15f6fc323ba0c71aec67b9b2dd5614a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 5 Oct 2009 17:18:42 +0200 Subject: mxc_nand: disable sp_en bit only once Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 4a69682..2e3f3fb 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -274,16 +274,10 @@ static void send_page(struct mtd_info *mtd, unsigned int ops) static void send_read_id(struct mxc_nand_host *host) { struct nand_chip *this = &host->nand; - uint16_t tmp; /* NANDFC buffer 0 is used for device ID output */ writew(0x0, host->regs + NFC_BUF_ADDR); - /* Read ID into main buffer */ - tmp = readw(host->regs + NFC_CONFIG1); - tmp &= ~NFC_SP_EN; - writew(tmp, host->regs + NFC_CONFIG1); - writew(NFC_ID, host->regs + NFC_CONFIG2); /* Wait for operation to complete */ @@ -307,7 +301,7 @@ static uint16_t get_dev_status(struct mxc_nand_host *host) { void __iomem *main_buf = host->main_area1; uint32_t store; - uint16_t ret, tmp; + uint16_t ret; /* Issue status request to NAND device */ /* store the main area1 first word, later do recovery */ @@ -316,11 +310,6 @@ static uint16_t get_dev_status(struct mxc_nand_host *host) * corruption of read/write buffer on status requests. */ writew(1, host->regs + NFC_BUF_ADDR); - /* Read status into main buffer */ - tmp = readw(host->regs + NFC_CONFIG1); - tmp &= ~NFC_SP_EN; - writew(tmp, host->regs + NFC_CONFIG1); - writew(NFC_STATUS, host->regs + NFC_CONFIG2); /* Wait for operation to complete */ @@ -739,8 +728,10 @@ static int __init mxcnd_probe(struct platform_device *pdev) } else BUG(); + /* disable interrupt and spare enable */ tmp = readw(host->regs + NFC_CONFIG1); tmp |= NFC_INT_MSK; + tmp &= ~NFC_SP_EN; writew(tmp, host->regs + NFC_CONFIG1); init_waitqueue_head(&host->irq_waitq); -- cgit v0.10.2 From f1372055df21734f042f12ab92852e9d350be8d0 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 21 Oct 2009 14:25:27 +0200 Subject: mxc_nand: Allow flash based bbt Signed-off-by: Sascha Hauer diff --git a/arch/arm/plat-mxc/include/mach/mxc_nand.h b/arch/arm/plat-mxc/include/mach/mxc_nand.h index 2b972df..5d2d21d 100644 --- a/arch/arm/plat-mxc/include/mach/mxc_nand.h +++ b/arch/arm/plat-mxc/include/mach/mxc_nand.h @@ -22,6 +22,7 @@ struct mxc_nand_platform_data { int width; /* data bus width in bytes */ - int hw_ecc; /* 0 if supress hardware ECC */ + int hw_ecc:1; /* 0 if supress hardware ECC */ + int flash_bbt:1; /* set to 1 to use a flash based bbt */ }; #endif /* __ASM_ARCH_NAND_H */ diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 2e3f3fb..044a574 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -648,6 +648,33 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, } } +/* + * The generic flash bbt decriptors overlap with our ecc + * hardware, so define some i.MX specific ones. + */ +static uint8_t bbt_pattern[] = { 'B', 'b', 't', '0' }; +static uint8_t mirror_pattern[] = { '1', 't', 'b', 'B' }; + +static struct nand_bbt_descr bbt_main_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE + | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, + .offs = 0, + .len = 4, + .veroffs = 4, + .maxblocks = 4, + .pattern = bbt_pattern, +}; + +static struct nand_bbt_descr bbt_mirror_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE + | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, + .offs = 0, + .len = 4, + .veroffs = 4, + .maxblocks = 4, + .pattern = mirror_pattern, +}; + static int __init mxcnd_probe(struct platform_device *pdev) { struct nand_chip *this; @@ -786,6 +813,13 @@ static int __init mxcnd_probe(struct platform_device *pdev) if (pdata->width == 2) this->options |= NAND_BUSWIDTH_16; + if (pdata->flash_bbt) { + this->bbt_td = &bbt_main_descr; + this->bbt_md = &bbt_mirror_descr; + /* update flash based bbt */ + this->options |= NAND_USE_FLASH_BBT; + } + /* first scan to find the device and get the page size */ if (nand_scan_ident(mtd, 1)) { err = -ENXIO; -- cgit v0.10.2 From c110eaf4659efcb110de2d7c90878240be5a13fa Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 21 Oct 2009 16:01:02 +0200 Subject: mxc_nand: remove TROP_US_DELAY wait_op_done is only called with the same timeout, so code the timeout into the function itself. Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 044a574..30eeb4c 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -118,9 +118,6 @@ struct mxc_nand_host { int spare_len; }; -/* Define delays in microsec for NAND device operations */ -#define TROP_US_DELAY 2000 - /* OOB placement block for use with hardware ecc generation */ static struct nand_ecclayout nandv1_hw_eccoob_smallpage = { .eccbytes = 5, @@ -185,10 +182,10 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) /* This function polls the NANDFC to wait for the basic operation to * complete by checking the INT bit of config2 register. */ -static void wait_op_done(struct mxc_nand_host *host, int max_retries, - int useirq) +static void wait_op_done(struct mxc_nand_host *host, int useirq) { uint32_t tmp; + int max_retries = 2000; if (useirq) { if ((readw(host->regs + NFC_CONFIG2) & NFC_INT) == 0) { @@ -230,7 +227,7 @@ static void send_cmd(struct mxc_nand_host *host, uint16_t cmd, int useirq) writew(NFC_CMD, host->regs + NFC_CONFIG2); /* Wait for operation to complete */ - wait_op_done(host, TROP_US_DELAY, useirq); + wait_op_done(host, useirq); } /* This function sends an address (or partial address) to the @@ -244,7 +241,7 @@ static void send_addr(struct mxc_nand_host *host, uint16_t addr, int islast) writew(NFC_ADDR, host->regs + NFC_CONFIG2); /* Wait for operation to complete */ - wait_op_done(host, TROP_US_DELAY, islast); + wait_op_done(host, islast); } static void send_page(struct mtd_info *mtd, unsigned int ops) @@ -266,7 +263,7 @@ static void send_page(struct mtd_info *mtd, unsigned int ops) writew(ops, host->regs + NFC_CONFIG2); /* Wait for operation to complete */ - wait_op_done(host, TROP_US_DELAY, true); + wait_op_done(host, true); } } @@ -281,7 +278,7 @@ static void send_read_id(struct mxc_nand_host *host) writew(NFC_ID, host->regs + NFC_CONFIG2); /* Wait for operation to complete */ - wait_op_done(host, TROP_US_DELAY, true); + wait_op_done(host, true); if (this->options & NAND_BUSWIDTH_16) { void __iomem *main_buf = host->main_area0; @@ -313,7 +310,7 @@ static uint16_t get_dev_status(struct mxc_nand_host *host) writew(NFC_STATUS, host->regs + NFC_CONFIG2); /* Wait for operation to complete */ - wait_op_done(host, TROP_US_DELAY, true); + wait_op_done(host, true); /* Status is placed in first word of main buffer */ /* get status, then recovery area 1 data */ -- cgit v0.10.2 From 1fbff0a6e975a986032881f139b806c23680f823 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 21 Oct 2009 16:06:27 +0200 Subject: mxc_nand: use DRIVER_NAME where appropriate Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 30eeb4c..53e9412 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -698,7 +698,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) mtd->priv = this; mtd->owner = THIS_MODULE; mtd->dev.parent = &pdev->dev; - mtd->name = "mxc_nand"; + mtd->name = DRIVER_NAME; /* 50 us command delay time */ this->chip_delay = 5; @@ -762,7 +762,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) host->irq = platform_get_irq(pdev, 0); - err = request_irq(host->irq, mxc_nfc_irq, 0, "mxc_nd", host); + err = request_irq(host->irq, mxc_nfc_irq, 0, DRIVER_NAME, host); if (err) goto eirq; -- cgit v0.10.2 From ecdc428e4c5d821a07baf4f8b1718faf67b9026f Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Thu, 12 Nov 2009 11:14:13 -0800 Subject: IB/mlx4: Remove unneeded code There is no such flag DE - the field is reserved and should be zero. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 219b103..518d561 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -897,7 +897,6 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp, context->flags = cpu_to_be32((to_mlx4_state(new_state) << 28) | (to_mlx4_st(ibqp->qp_type) << 16)); - context->flags |= cpu_to_be32(1 << 8); /* DE? */ if (!(attr_mask & IB_QP_PATH_MIG_STATE)) context->flags |= cpu_to_be32(MLX4_QP_PM_MIGRATED << 11); -- cgit v0.10.2 From 417608c20a4c8397bc5307d949ec01ea0a0dd8e5 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Thu, 12 Nov 2009 11:19:44 -0800 Subject: IB/mlx4: Remove limitation on LSO header size Current code has a limitation: an LSO header is not allowed to cross a 64 byte boundary. This patch removes this limitation by setting the WQE RR for large headers thus allowing LSO headers of any size. The extra buffer reserved for MLX4_IB_QP_LSO QPs has been doubled, from 64 to 128 bytes, assuming this is reasonable upper limit for header length. Also, this patch will cause IB_DEVICE_UD_TSO to be set only for HCA FW versions that set MLX4_DEV_CAP_FLAG_BLH; e.g. FW version 2.6.000 and higher. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 3cb3f47..e596537 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -103,7 +103,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, props->device_cap_flags |= IB_DEVICE_UD_AV_PORT_ENFORCE; if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_IPOIB_CSUM) props->device_cap_flags |= IB_DEVICE_UD_IP_CSUM; - if (dev->dev->caps.max_gso_sz) + if (dev->dev->caps.max_gso_sz && dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BLH) props->device_cap_flags |= IB_DEVICE_UD_TSO; if (dev->dev->caps.bmme_flags & MLX4_BMME_FLAG_RESERVED_LKEY) props->device_cap_flags |= IB_DEVICE_LOCAL_DMA_LKEY; diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 518d561..847030c 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -54,7 +54,8 @@ enum { /* * Largest possible UD header: send with GRH and immediate data. */ - MLX4_IB_UD_HEADER_SIZE = 72 + MLX4_IB_UD_HEADER_SIZE = 72, + MLX4_IB_LSO_HEADER_SPARE = 128, }; struct mlx4_ib_sqp { @@ -67,7 +68,8 @@ struct mlx4_ib_sqp { }; enum { - MLX4_IB_MIN_SQ_STRIDE = 6 + MLX4_IB_MIN_SQ_STRIDE = 6, + MLX4_IB_CACHE_LINE_SIZE = 64, }; static const __be32 mlx4_ib_opcode[] = { @@ -261,7 +263,7 @@ static int send_wqe_overhead(enum ib_qp_type type, u32 flags) case IB_QPT_UD: return sizeof (struct mlx4_wqe_ctrl_seg) + sizeof (struct mlx4_wqe_datagram_seg) + - ((flags & MLX4_IB_QP_LSO) ? 64 : 0); + ((flags & MLX4_IB_QP_LSO) ? MLX4_IB_LSO_HEADER_SPARE : 0); case IB_QPT_UC: return sizeof (struct mlx4_wqe_ctrl_seg) + sizeof (struct mlx4_wqe_raddr_seg); @@ -1466,16 +1468,12 @@ static void __set_data_seg(struct mlx4_wqe_data_seg *dseg, struct ib_sge *sg) static int build_lso_seg(struct mlx4_wqe_lso_seg *wqe, struct ib_send_wr *wr, struct mlx4_ib_qp *qp, unsigned *lso_seg_len, - __be32 *lso_hdr_sz) + __be32 *lso_hdr_sz, __be32 *blh) { unsigned halign = ALIGN(sizeof *wqe + wr->wr.ud.hlen, 16); - /* - * This is a temporary limitation and will be removed in - * a forthcoming FW release: - */ - if (unlikely(halign > 64)) - return -EINVAL; + if (unlikely(halign > MLX4_IB_CACHE_LINE_SIZE)) + *blh = cpu_to_be32(1 << 6); if (unlikely(!(qp->flags & MLX4_IB_QP_LSO) && wr->num_sge > qp->sq.max_gs - (halign >> 4))) @@ -1521,6 +1519,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, __be32 dummy; __be32 *lso_wqe; __be32 uninitialized_var(lso_hdr_sz); + __be32 blh; int i; spin_lock_irqsave(&qp->sq.lock, flags); @@ -1529,6 +1528,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, for (nreq = 0; wr; ++nreq, wr = wr->next) { lso_wqe = &dummy; + blh = 0; if (mlx4_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)) { err = -ENOMEM; @@ -1615,7 +1615,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, size += sizeof (struct mlx4_wqe_datagram_seg) / 16; if (wr->opcode == IB_WR_LSO) { - err = build_lso_seg(wqe, wr, qp, &seglen, &lso_hdr_sz); + err = build_lso_seg(wqe, wr, qp, &seglen, &lso_hdr_sz, &blh); if (unlikely(err)) { *bad_wr = wr; goto out; @@ -1686,7 +1686,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, } ctrl->owner_opcode = mlx4_ib_opcode[wr->opcode] | - (ind & qp->sq.wqe_cnt ? cpu_to_be32(1 << 31) : 0); + (ind & qp->sq.wqe_cnt ? cpu_to_be32(1 << 31) : 0) | blh; stamp = ind + qp->sq_spare_wqes; ind += DIV_ROUND_UP(size * 16, 1U << qp->sq.wqe_shift); diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index 3c16602..7194be3 100644 --- a/drivers/net/mlx4/fw.c +++ b/drivers/net/mlx4/fw.c @@ -90,6 +90,7 @@ static void dump_dev_cap_flags(struct mlx4_dev *dev, u32 flags) [ 9] = "Q_Key violation counter", [10] = "VMM", [12] = "DPDP", + [15] = "Big LSO headers", [16] = "MW support", [17] = "APM support", [18] = "Atomic ops support", diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index ce7cc6c..e92d1bf 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -61,6 +61,7 @@ enum { MLX4_DEV_CAP_FLAG_BAD_PKEY_CNTR = 1 << 8, MLX4_DEV_CAP_FLAG_BAD_QKEY_CNTR = 1 << 9, MLX4_DEV_CAP_FLAG_DPDP = 1 << 12, + MLX4_DEV_CAP_FLAG_BLH = 1 << 15, MLX4_DEV_CAP_FLAG_MEM_WINDOW = 1 << 16, MLX4_DEV_CAP_FLAG_APM = 1 << 17, MLX4_DEV_CAP_FLAG_ATOMIC = 1 << 18, -- cgit v0.10.2 From c1ccaf2478f84c2665cf57f981db143aa582d646 Mon Sep 17 00:00:00 2001 From: Or Gerlitz Date: Thu, 12 Nov 2009 11:32:27 -0800 Subject: IB/iser: Rewrite SG handling for RDMA logic After dma-mapping an SG list provided by the SCSI midlayer, iser has to make sure the mapped SG is "aligned for RDMA" in the sense that its possible to produce one mapping in the HCA IOMMU which represents the whole SG. Next, the mapped SG is formatted for registration with the HCA. This patch re-writes the logic that does the above, to make it clearer and simpler. It also fixes a bug in the being aligned for RDMA checks, where a "start" check wasn't done but rather only "end" check. Signed-off-by: Alexander Nezhinsky Signed-off-by: Or Gerlitz Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c index b9453d0..274c883 100644 --- a/drivers/infiniband/ulp/iser/iser_memory.c +++ b/drivers/infiniband/ulp/iser/iser_memory.c @@ -209,6 +209,8 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, mem_copy->copy_buf = NULL; } +#define IS_4K_ALIGNED(addr) ((((unsigned long)addr) & ~MASK_4K) == 0) + /** * iser_sg_to_page_vec - Translates scatterlist entries to physical addresses * and returns the length of resulting physical address array (may be less than @@ -221,62 +223,52 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, * where --few fragments of the same page-- are present in the SG as * consecutive elements. Also, it handles one entry SG. */ + static int iser_sg_to_page_vec(struct iser_data_buf *data, struct iser_page_vec *page_vec, struct ib_device *ibdev) { - struct scatterlist *sgl = (struct scatterlist *)data->buf; - struct scatterlist *sg; - u64 first_addr, last_addr, page; - int end_aligned; - unsigned int cur_page = 0; + struct scatterlist *sg, *sgl = (struct scatterlist *)data->buf; + u64 start_addr, end_addr, page, chunk_start = 0; unsigned long total_sz = 0; - int i; + unsigned int dma_len; + int i, new_chunk, cur_page, last_ent = data->dma_nents - 1; /* compute the offset of first element */ page_vec->offset = (u64) sgl[0].offset & ~MASK_4K; + new_chunk = 1; + cur_page = 0; for_each_sg(sgl, sg, data->dma_nents, i) { - unsigned int dma_len = ib_sg_dma_len(ibdev, sg); - + start_addr = ib_sg_dma_address(ibdev, sg); + if (new_chunk) + chunk_start = start_addr; + dma_len = ib_sg_dma_len(ibdev, sg); + end_addr = start_addr + dma_len; total_sz += dma_len; - first_addr = ib_sg_dma_address(ibdev, sg); - last_addr = first_addr + dma_len; - - end_aligned = !(last_addr & ~MASK_4K); - - /* continue to collect page fragments till aligned or SG ends */ - while (!end_aligned && (i + 1 < data->dma_nents)) { - sg = sg_next(sg); - i++; - dma_len = ib_sg_dma_len(ibdev, sg); - total_sz += dma_len; - last_addr = ib_sg_dma_address(ibdev, sg) + dma_len; - end_aligned = !(last_addr & ~MASK_4K); + /* collect page fragments until aligned or end of SG list */ + if (!IS_4K_ALIGNED(end_addr) && i < last_ent) { + new_chunk = 0; + continue; } - - /* handle the 1st page in the 1st DMA element */ - if (cur_page == 0) { - page = first_addr & MASK_4K; - page_vec->pages[cur_page] = page; - cur_page++; + new_chunk = 1; + + /* address of the first page in the contiguous chunk; + masking relevant for the very first SG entry, + which might be unaligned */ + page = chunk_start & MASK_4K; + do { + page_vec->pages[cur_page++] = page; page += SIZE_4K; - } else - page = first_addr; - - for (; page < last_addr; page += SIZE_4K) { - page_vec->pages[cur_page] = page; - cur_page++; - } - + } while (page < end_addr); } + page_vec->data_size = total_sz; iser_dbg("page_vec->data_size:%d cur_page %d\n", page_vec->data_size,cur_page); return cur_page; } -#define IS_4K_ALIGNED(addr) ((((unsigned long)addr) & ~MASK_4K) == 0) /** * iser_data_buf_aligned_len - Tries to determine the maximal correctly aligned @@ -284,42 +276,40 @@ static int iser_sg_to_page_vec(struct iser_data_buf *data, * the number of entries which are aligned correctly. Supports the case where * consecutive SG elements are actually fragments of the same physcial page. */ -static unsigned int iser_data_buf_aligned_len(struct iser_data_buf *data, - struct ib_device *ibdev) +static int iser_data_buf_aligned_len(struct iser_data_buf *data, + struct ib_device *ibdev) { - struct scatterlist *sgl, *sg; - u64 end_addr, next_addr; - int i, cnt; - unsigned int ret_len = 0; + struct scatterlist *sgl, *sg, *next_sg = NULL; + u64 start_addr, end_addr; + int i, ret_len, start_check = 0; + + if (data->dma_nents == 1) + return 1; sgl = (struct scatterlist *)data->buf; + start_addr = ib_sg_dma_address(ibdev, sgl); - cnt = 0; for_each_sg(sgl, sg, data->dma_nents, i) { - /* iser_dbg("Checking sg iobuf [%d]: phys=0x%08lX " - "offset: %ld sz: %ld\n", i, - (unsigned long)sg_phys(sg), - (unsigned long)sg->offset, - (unsigned long)sg->length); */ - end_addr = ib_sg_dma_address(ibdev, sg) + - ib_sg_dma_len(ibdev, sg); - /* iser_dbg("Checking sg iobuf end address " - "0x%08lX\n", end_addr); */ - if (i + 1 < data->dma_nents) { - next_addr = ib_sg_dma_address(ibdev, sg_next(sg)); - /* are i, i+1 fragments of the same page? */ - if (end_addr == next_addr) { - cnt++; - continue; - } else if (!IS_4K_ALIGNED(end_addr)) { - ret_len = cnt + 1; - break; - } - } - cnt++; + if (start_check && !IS_4K_ALIGNED(start_addr)) + break; + + next_sg = sg_next(sg); + if (!next_sg) + break; + + end_addr = start_addr + ib_sg_dma_len(ibdev, sg); + start_addr = ib_sg_dma_address(ibdev, next_sg); + + if (end_addr == start_addr) { + start_check = 0; + continue; + } else + start_check = 1; + + if (!IS_4K_ALIGNED(end_addr)) + break; } - if (i == data->dma_nents) - ret_len = cnt; /* loop ended */ + ret_len = (next_sg) ? i : i+1; iser_dbg("Found %d aligned entries out of %d in sg:0x%p\n", ret_len, data->dma_nents, data); return ret_len; -- cgit v0.10.2 From be504b0b9fbe9ba447c93ef0f5789f377102d555 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Thu, 12 Nov 2009 15:51:16 -0800 Subject: mlx4_core: Fix parsing of reserved EQ cap Value returned by firmware is the actual value, not a log. Signed-off-by: Liran Liss Signed-off-by: Roland Dreier diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index 7194be3..04f42ae 100644 --- a/drivers/net/mlx4/fw.c +++ b/drivers/net/mlx4/fw.c @@ -236,7 +236,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MPT_OFFSET); dev_cap->max_mpts = 1 << (field & 0x3f); MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_EQ_OFFSET); - dev_cap->reserved_eqs = 1 << (field & 0xf); + dev_cap->reserved_eqs = field & 0xf; MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_EQ_OFFSET); dev_cap->max_eqs = 1 << (field & 0xf); MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_MTT_OFFSET); -- cgit v0.10.2 From 0a3adadee42f2865bb867b8c5f4955b7def9baad Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Wed, 4 Nov 2009 18:12:35 -0500 Subject: nfsd: make fs/nfsd/vfs.h for common includes None of this stuff is used outside nfsd, so move it out of the common linux include directory. Actually, probably none of the stuff in include/linux/nfsd/nfsd.h really belongs there, so later we may remove that file entirely. Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c index b2786a5..812bc64 100644 --- a/fs/nfsd/lockd.c +++ b/fs/nfsd/lockd.c @@ -16,6 +16,7 @@ #include #include #include +#include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_LOCKD diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c index e2a17f0..38c883d 100644 --- a/fs/nfsd/nfs2acl.c +++ b/fs/nfsd/nfs2acl.c @@ -14,6 +14,7 @@ #include #include #include +#include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_PROC #define RETURN_STATUS(st) { resp->status = (st); return (st); } diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c index ff73596..526d85a 100644 --- a/fs/nfsd/nfs3acl.c +++ b/fs/nfsd/nfs3acl.c @@ -13,6 +13,7 @@ #include #include #include +#include "vfs.h" #define RETURN_STATUS(st) { resp->status = (st); return (st); } diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index a713c41..1a259d3 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -25,6 +25,7 @@ #include #include #include +#include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_PROC diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index bebc0c2..60a93cd 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -48,6 +48,7 @@ #include #include #include +#include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_PROC diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index b534840..c7a6b24 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -47,6 +47,7 @@ #include #include #include +#include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_PROC diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index c8b621a..850960e 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -56,6 +56,7 @@ #include #include #include +#include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_PROC diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 0fbd50c..db0fc55 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -57,6 +57,7 @@ #include #include #include +#include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_XDR diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 01965b2..d0d8a21 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -22,6 +22,7 @@ #include #include #include +#include "vfs.h" #include "auth.h" #define NFSDDBG_FACILITY NFSDDBG_FH diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index c5393d1..6c967e1 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -24,6 +24,7 @@ #include #include #include +#include "vfs.h" typedef struct svc_rqst svc_rqst; typedef struct svc_buf svc_buf; diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 67ea83e..2944b31 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -35,6 +35,7 @@ #include #include #include +#include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_SVC diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 6385739..a7038ed 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -56,6 +56,7 @@ #endif /* CONFIG_NFSD_V4 */ #include #include +#include "vfs.h" #include diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h new file mode 100644 index 0000000..b8011fd --- /dev/null +++ b/fs/nfsd/vfs.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 1995-1997 Olaf Kirch + */ + +#ifndef LINUX_NFSD_VFS_H +#define LINUX_NFSD_VFS_H + +/* + * Flags for nfsd_permission + */ +#define NFSD_MAY_NOP 0 +#define NFSD_MAY_EXEC 1 /* == MAY_EXEC */ +#define NFSD_MAY_WRITE 2 /* == MAY_WRITE */ +#define NFSD_MAY_READ 4 /* == MAY_READ */ +#define NFSD_MAY_SATTR 8 +#define NFSD_MAY_TRUNC 16 +#define NFSD_MAY_LOCK 32 +#define NFSD_MAY_OWNER_OVERRIDE 64 +#define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/ +#define NFSD_MAY_BYPASS_GSS_ON_ROOT 256 + +#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) +#define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) + +/* + * Callback function for readdir + */ +typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int); + +/* nfsd/vfs.c */ +int fh_lock_parent(struct svc_fh *, struct dentry *); +int nfsd_racache_init(int); +void nfsd_racache_shutdown(void); +int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, + struct svc_export **expp); +__be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *, + const char *, unsigned int, struct svc_fh *); +__be32 nfsd_lookup_dentry(struct svc_rqst *, struct svc_fh *, + const char *, unsigned int, + struct svc_export **, struct dentry **); +__be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *, + struct iattr *, int, time_t); +#ifdef CONFIG_NFSD_V4 +__be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *, + struct nfs4_acl *); +int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **); +#endif /* CONFIG_NFSD_V4 */ +__be32 nfsd_create(struct svc_rqst *, struct svc_fh *, + char *name, int len, struct iattr *attrs, + int type, dev_t rdev, struct svc_fh *res); +#ifdef CONFIG_NFSD_V3 +__be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); +__be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *, + char *name, int len, struct iattr *attrs, + struct svc_fh *res, int createmode, + u32 *verifier, int *truncp, int *created); +__be32 nfsd_commit(struct svc_rqst *, struct svc_fh *, + loff_t, unsigned long); +#endif /* CONFIG_NFSD_V3 */ +__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, int, + int, struct file **); +void nfsd_close(struct file *); +__be32 nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *, + loff_t, struct kvec *, int, unsigned long *); +__be32 nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *, + loff_t, struct kvec *,int, unsigned long *, int *); +__be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *, + char *, int *); +__be32 nfsd_symlink(struct svc_rqst *, struct svc_fh *, + char *name, int len, char *path, int plen, + struct svc_fh *res, struct iattr *); +__be32 nfsd_link(struct svc_rqst *, struct svc_fh *, + char *, int, struct svc_fh *); +__be32 nfsd_rename(struct svc_rqst *, + struct svc_fh *, char *, int, + struct svc_fh *, char *, int); +__be32 nfsd_remove(struct svc_rqst *, + struct svc_fh *, char *, int); +__be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, + char *name, int len); +int nfsd_truncate(struct svc_rqst *, struct svc_fh *, + unsigned long size); +__be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, + loff_t *, struct readdir_cd *, filldir_t); +__be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, + struct kstatfs *, int access); + +int nfsd_notify_change(struct inode *, struct iattr *); +__be32 nfsd_permission(struct svc_rqst *, struct svc_export *, + struct dentry *, int); +int nfsd_sync_dir(struct dentry *dp); + +#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) +struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int); +int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *); +#endif + +#endif /* LINUX_NFSD_VFS_H */ diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h index 510ffdd..e4518d0 100644 --- a/include/linux/nfsd/nfsd.h +++ b/include/linux/nfsd/nfsd.h @@ -25,30 +25,10 @@ */ #define NFSD_SUPPORTED_MINOR_VERSION 1 -/* - * Flags for nfsd_permission - */ -#define NFSD_MAY_NOP 0 -#define NFSD_MAY_EXEC 1 /* == MAY_EXEC */ -#define NFSD_MAY_WRITE 2 /* == MAY_WRITE */ -#define NFSD_MAY_READ 4 /* == MAY_READ */ -#define NFSD_MAY_SATTR 8 -#define NFSD_MAY_TRUNC 16 -#define NFSD_MAY_LOCK 32 -#define NFSD_MAY_OWNER_OVERRIDE 64 -#define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/ -#define NFSD_MAY_BYPASS_GSS_ON_ROOT 256 - -#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) -#define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) - -/* - * Callback function for readdir - */ struct readdir_cd { __be32 err; /* 0, nfserr, or nfserr_eof */ }; -typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int); + extern struct svc_program nfsd_program; extern struct svc_version nfsd_version2, nfsd_version3, @@ -73,69 +53,6 @@ int nfsd_nrpools(void); int nfsd_get_nrthreads(int n, int *); int nfsd_set_nrthreads(int n, int *); -/* nfsd/vfs.c */ -int fh_lock_parent(struct svc_fh *, struct dentry *); -int nfsd_racache_init(int); -void nfsd_racache_shutdown(void); -int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, - struct svc_export **expp); -__be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *, - const char *, unsigned int, struct svc_fh *); -__be32 nfsd_lookup_dentry(struct svc_rqst *, struct svc_fh *, - const char *, unsigned int, - struct svc_export **, struct dentry **); -__be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *, - struct iattr *, int, time_t); -#ifdef CONFIG_NFSD_V4 -__be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *, - struct nfs4_acl *); -int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **); -#endif /* CONFIG_NFSD_V4 */ -__be32 nfsd_create(struct svc_rqst *, struct svc_fh *, - char *name, int len, struct iattr *attrs, - int type, dev_t rdev, struct svc_fh *res); -#ifdef CONFIG_NFSD_V3 -__be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); -__be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *, - char *name, int len, struct iattr *attrs, - struct svc_fh *res, int createmode, - u32 *verifier, int *truncp, int *created); -__be32 nfsd_commit(struct svc_rqst *, struct svc_fh *, - loff_t, unsigned long); -#endif /* CONFIG_NFSD_V3 */ -__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, int, - int, struct file **); -void nfsd_close(struct file *); -__be32 nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *, - loff_t, struct kvec *, int, unsigned long *); -__be32 nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *, - loff_t, struct kvec *,int, unsigned long *, int *); -__be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *, - char *, int *); -__be32 nfsd_symlink(struct svc_rqst *, struct svc_fh *, - char *name, int len, char *path, int plen, - struct svc_fh *res, struct iattr *); -__be32 nfsd_link(struct svc_rqst *, struct svc_fh *, - char *, int, struct svc_fh *); -__be32 nfsd_rename(struct svc_rqst *, - struct svc_fh *, char *, int, - struct svc_fh *, char *, int); -__be32 nfsd_remove(struct svc_rqst *, - struct svc_fh *, char *, int); -__be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, - char *name, int len); -int nfsd_truncate(struct svc_rqst *, struct svc_fh *, - unsigned long size); -__be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, - loff_t *, struct readdir_cd *, filldir_t); -__be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, - struct kstatfs *, int access); - -int nfsd_notify_change(struct inode *, struct iattr *); -__be32 nfsd_permission(struct svc_rqst *, struct svc_export *, - struct dentry *, int); -int nfsd_sync_dir(struct dentry *dp); - #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) #ifdef CONFIG_NFSD_V2_ACL extern struct svc_version nfsd_acl_version2; @@ -147,8 +64,6 @@ extern struct svc_version nfsd_acl_version3; #else #define nfsd_acl_version3 NULL #endif -struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int); -int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *); #endif enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL }; -- cgit v0.10.2 From c26964ead57f0aa1dff4926aae2982b174798e7b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 1 Oct 2009 15:41:06 +0100 Subject: wm831x: Factor out WM831x backup battery charger The backup battery on WM831x is a separate IP block to the main PMU and is largely unrelated to the main supply functionality. Factor it out into a separate driver in order to reflect this and better support future hardware versions. Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Anton Vorontsov diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 49b7885..6a35f2a2 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -794,6 +794,9 @@ static struct resource wm831x_wdt_resources[] = { static struct mfd_cell wm8310_devs[] = { { + .name = "wm831x-backup", + }, + { .name = "wm831x-buckv", .id = 1, .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources), @@ -947,6 +950,9 @@ static struct mfd_cell wm8310_devs[] = { static struct mfd_cell wm8311_devs[] = { { + .name = "wm831x-backup", + }, + { .name = "wm831x-buckv", .id = 1, .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources), @@ -1081,6 +1087,9 @@ static struct mfd_cell wm8311_devs[] = { static struct mfd_cell wm8312_devs[] = { { + .name = "wm831x-backup", + }, + { .name = "wm831x-buckv", .id = 1, .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources), diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index cea6cef..783e9b7 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -29,6 +29,13 @@ config APM_POWER Say Y here to enable support APM status emulation using battery class devices. +config WM831X_BACKUP + tristate "WM831X backup battery charger support" + depends on MFD_WM831X + help + Say Y here to enable support for the backup battery charger + in the Wolfson Microelectronics WM831x PMICs. + config WM831X_POWER tristate "WM831X PMU support" depends on MFD_WM831X diff --git a/drivers/power/Makefile b/drivers/power/Makefile index b96f29d..d1406b9 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_POWER_SUPPLY) += power_supply.o obj-$(CONFIG_PDA_POWER) += pda_power.o obj-$(CONFIG_APM_POWER) += apm_power.o +obj-$(CONFIG_WM831X_BACKUP) += wm831x_backup.o obj-$(CONFIG_WM831X_POWER) += wm831x_power.o obj-$(CONFIG_WM8350_POWER) += wm8350_power.o diff --git a/drivers/power/wm831x_backup.c b/drivers/power/wm831x_backup.c new file mode 100644 index 0000000..f181076 --- /dev/null +++ b/drivers/power/wm831x_backup.c @@ -0,0 +1,233 @@ +/* + * Backup battery driver for Wolfson Microelectronics wm831x PMICs + * + * Copyright 2009 Wolfson Microelectronics PLC. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +struct wm831x_backup { + struct wm831x *wm831x; + struct power_supply backup; +}; + +static int wm831x_backup_read_voltage(struct wm831x *wm831x, + enum wm831x_auxadc src, + union power_supply_propval *val) +{ + int ret; + + ret = wm831x_auxadc_read_uv(wm831x, src); + if (ret >= 0) + val->intval = ret; + + return ret; +} + +/********************************************************************* + * Backup supply properties + *********************************************************************/ + +static void wm831x_config_backup(struct wm831x *wm831x) +{ + struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data; + struct wm831x_backup_pdata *pdata; + int ret, reg; + + if (!wm831x_pdata || !wm831x_pdata->backup) { + dev_warn(wm831x->dev, + "No backup battery charger configuration\n"); + return; + } + + pdata = wm831x_pdata->backup; + + reg = 0; + + if (pdata->charger_enable) + reg |= WM831X_BKUP_CHG_ENA | WM831X_BKUP_BATT_DET_ENA; + if (pdata->no_constant_voltage) + reg |= WM831X_BKUP_CHG_MODE; + + switch (pdata->vlim) { + case 2500: + break; + case 3100: + reg |= WM831X_BKUP_CHG_VLIM; + break; + default: + dev_err(wm831x->dev, "Invalid backup voltage limit %dmV\n", + pdata->vlim); + } + + switch (pdata->ilim) { + case 100: + break; + case 200: + reg |= 1; + break; + case 300: + reg |= 2; + break; + case 400: + reg |= 3; + break; + default: + dev_err(wm831x->dev, "Invalid backup current limit %duA\n", + pdata->ilim); + } + + ret = wm831x_reg_unlock(wm831x); + if (ret != 0) { + dev_err(wm831x->dev, "Failed to unlock registers: %d\n", ret); + return; + } + + ret = wm831x_set_bits(wm831x, WM831X_BACKUP_CHARGER_CONTROL, + WM831X_BKUP_CHG_ENA_MASK | + WM831X_BKUP_CHG_MODE_MASK | + WM831X_BKUP_BATT_DET_ENA_MASK | + WM831X_BKUP_CHG_VLIM_MASK | + WM831X_BKUP_CHG_ILIM_MASK, + reg); + if (ret != 0) + dev_err(wm831x->dev, + "Failed to set backup charger config: %d\n", ret); + + wm831x_reg_lock(wm831x); +} + +static int wm831x_backup_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct wm831x_backup *devdata = dev_get_drvdata(psy->dev->parent); + struct wm831x *wm831x = devdata->wm831x; + int ret = 0; + + ret = wm831x_reg_read(wm831x, WM831X_BACKUP_CHARGER_CONTROL); + if (ret < 0) + return ret; + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + if (ret & WM831X_BKUP_CHG_STS) + val->intval = POWER_SUPPLY_STATUS_CHARGING; + else + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; + break; + + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + ret = wm831x_backup_read_voltage(wm831x, WM831X_AUX_BKUP_BATT, + val); + break; + + case POWER_SUPPLY_PROP_PRESENT: + if (ret & WM831X_BKUP_CHG_STS) + val->intval = 1; + else + val->intval = 0; + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static enum power_supply_property wm831x_backup_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_PRESENT, +}; + +/********************************************************************* + * Initialisation + *********************************************************************/ + +static __devinit int wm831x_backup_probe(struct platform_device *pdev) +{ + struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); + struct wm831x_backup *devdata; + struct power_supply *backup; + int ret, irq, i; + + devdata = kzalloc(sizeof(struct wm831x_backup), GFP_KERNEL); + if (devdata == NULL) + return -ENOMEM; + + devdata->wm831x = wm831x; + platform_set_drvdata(pdev, devdata); + + backup = &devdata->backup; + + /* We ignore configuration failures since we can still read + * back the status without enabling the charger (which may + * already be enabled anyway). + */ + wm831x_config_backup(wm831x); + + backup->name = "wm831x-backup"; + backup->type = POWER_SUPPLY_TYPE_BATTERY; + backup->properties = wm831x_backup_props; + backup->num_properties = ARRAY_SIZE(wm831x_backup_props); + backup->get_property = wm831x_backup_get_prop; + ret = power_supply_register(&pdev->dev, backup); + if (ret) + goto err_kmalloc; + + return ret; + +err_kmalloc: + kfree(devdata); + return ret; +} + +static __devexit int wm831x_backup_remove(struct platform_device *pdev) +{ + struct wm831x_backup *devdata = platform_get_drvdata(pdev); + + power_supply_unregister(&devdata->backup); + kfree(devdata); + + return 0; +} + +static struct platform_driver wm831x_backup_driver = { + .probe = wm831x_backup_probe, + .remove = __devexit_p(wm831x_backup_remove), + .driver = { + .name = "wm831x-backup", + }, +}; + +static int __init wm831x_backup_init(void) +{ + return platform_driver_register(&wm831x_backup_driver); +} +module_init(wm831x_backup_init); + +static void __exit wm831x_backup_exit(void) +{ + platform_driver_unregister(&wm831x_backup_driver); +} +module_exit(wm831x_backup_exit); + +MODULE_DESCRIPTION("Backup battery charger driver for WM831x PMICs"); +MODULE_AUTHOR("Mark Brown "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:wm831x-backup"); diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c index 2a4c8b0..f85e80b 100644 --- a/drivers/power/wm831x_power.c +++ b/drivers/power/wm831x_power.c @@ -21,7 +21,6 @@ struct wm831x_power { struct wm831x *wm831x; struct power_supply wall; - struct power_supply backup; struct power_supply usb; struct power_supply battery; }; @@ -454,125 +453,6 @@ static irqreturn_t wm831x_bat_irq(int irq, void *data) /********************************************************************* - * Backup supply properties - *********************************************************************/ - -static void wm831x_config_backup(struct wm831x *wm831x) -{ - struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data; - struct wm831x_backup_pdata *pdata; - int ret, reg; - - if (!wm831x_pdata || !wm831x_pdata->backup) { - dev_warn(wm831x->dev, - "No backup battery charger configuration\n"); - return; - } - - pdata = wm831x_pdata->backup; - - reg = 0; - - if (pdata->charger_enable) - reg |= WM831X_BKUP_CHG_ENA | WM831X_BKUP_BATT_DET_ENA; - if (pdata->no_constant_voltage) - reg |= WM831X_BKUP_CHG_MODE; - - switch (pdata->vlim) { - case 2500: - break; - case 3100: - reg |= WM831X_BKUP_CHG_VLIM; - break; - default: - dev_err(wm831x->dev, "Invalid backup voltage limit %dmV\n", - pdata->vlim); - } - - switch (pdata->ilim) { - case 100: - break; - case 200: - reg |= 1; - break; - case 300: - reg |= 2; - break; - case 400: - reg |= 3; - break; - default: - dev_err(wm831x->dev, "Invalid backup current limit %duA\n", - pdata->ilim); - } - - ret = wm831x_reg_unlock(wm831x); - if (ret != 0) { - dev_err(wm831x->dev, "Failed to unlock registers: %d\n", ret); - return; - } - - ret = wm831x_set_bits(wm831x, WM831X_BACKUP_CHARGER_CONTROL, - WM831X_BKUP_CHG_ENA_MASK | - WM831X_BKUP_CHG_MODE_MASK | - WM831X_BKUP_BATT_DET_ENA_MASK | - WM831X_BKUP_CHG_VLIM_MASK | - WM831X_BKUP_CHG_ILIM_MASK, - reg); - if (ret != 0) - dev_err(wm831x->dev, - "Failed to set backup charger config: %d\n", ret); - - wm831x_reg_lock(wm831x); -} - -static int wm831x_backup_get_prop(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev->parent); - struct wm831x *wm831x = wm831x_power->wm831x; - int ret = 0; - - ret = wm831x_reg_read(wm831x, WM831X_BACKUP_CHARGER_CONTROL); - if (ret < 0) - return ret; - - switch (psp) { - case POWER_SUPPLY_PROP_STATUS: - if (ret & WM831X_BKUP_CHG_STS) - val->intval = POWER_SUPPLY_STATUS_CHARGING; - else - val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; - break; - - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - ret = wm831x_power_read_voltage(wm831x, WM831X_AUX_BKUP_BATT, - val); - break; - - case POWER_SUPPLY_PROP_PRESENT: - if (ret & WM831X_BKUP_CHG_STS) - val->intval = 1; - else - val->intval = 0; - break; - - default: - ret = -EINVAL; - break; - } - - return ret; -} - -static enum power_supply_property wm831x_backup_props[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_PRESENT, -}; - -/********************************************************************* * Initialisation *********************************************************************/ @@ -595,10 +475,7 @@ static irqreturn_t wm831x_pwr_src_irq(int irq, void *data) dev_dbg(wm831x->dev, "Power source changed\n"); - /* Just notify for everything - little harm in overnotifying. - * The backup battery is not a power source while the system - * is running so skip that. - */ + /* Just notify for everything - little harm in overnotifying. */ power_supply_changed(&wm831x_power->battery); power_supply_changed(&wm831x_power->usb); power_supply_changed(&wm831x_power->wall); @@ -613,7 +490,6 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) struct power_supply *usb; struct power_supply *battery; struct power_supply *wall; - struct power_supply *backup; int ret, irq, i; power = kzalloc(sizeof(struct wm831x_power), GFP_KERNEL); @@ -626,13 +502,11 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) usb = &power->usb; battery = &power->battery; wall = &power->wall; - backup = &power->backup; /* We ignore configuration failures since we can still read back - * the status without enabling either of the chargers. + * the status without enabling the charger. */ wm831x_config_battery(wm831x); - wm831x_config_backup(wm831x); wall->name = "wm831x-wall"; wall->type = POWER_SUPPLY_TYPE_MAINS; @@ -661,15 +535,6 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) if (ret) goto err_battery; - backup->name = "wm831x-backup"; - backup->type = POWER_SUPPLY_TYPE_BATTERY; - backup->properties = wm831x_backup_props; - backup->num_properties = ARRAY_SIZE(wm831x_backup_props); - backup->get_property = wm831x_backup_get_prop; - ret = power_supply_register(&pdev->dev, backup); - if (ret) - goto err_usb; - irq = platform_get_irq_byname(pdev, "SYSLO"); ret = wm831x_request_irq(wm831x, irq, wm831x_syslo_irq, IRQF_TRIGGER_RISING, "SYSLO", @@ -677,7 +542,7 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) if (ret != 0) { dev_err(&pdev->dev, "Failed to request SYSLO IRQ %d: %d\n", irq, ret); - goto err_backup; + goto err_usb; } irq = platform_get_irq_byname(pdev, "PWR SRC"); @@ -716,8 +581,6 @@ err_bat_irq: err_syslo: irq = platform_get_irq_byname(pdev, "SYSLO"); wm831x_free_irq(wm831x, irq, power); -err_backup: - power_supply_unregister(backup); err_usb: power_supply_unregister(usb); err_battery: @@ -746,7 +609,6 @@ static __devexit int wm831x_power_remove(struct platform_device *pdev) irq = platform_get_irq_byname(pdev, "SYSLO"); wm831x_free_irq(wm831x, irq, wm831x_power); - power_supply_unregister(&wm831x_power->backup); power_supply_unregister(&wm831x_power->battery); power_supply_unregister(&wm831x_power->wall); power_supply_unregister(&wm831x_power->usb); -- cgit v0.10.2 From 7677f33f0a813e98612dce97d5342c1f5046878a Mon Sep 17 00:00:00 2001 From: Sean McNeil Date: Thu, 5 Nov 2009 00:24:54 +0300 Subject: pcf50633: Add ac power supply class to the charger This adds an appropriate ac power_supply class and shows usb only when at the appropriate current limit. Signed-off-by: Sean McNeil Signed-off-by: Paul Fertser Signed-off-by: Anton Vorontsov diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c index e8b278f..48e92c0 100644 --- a/drivers/power/pcf50633-charger.c +++ b/drivers/power/pcf50633-charger.c @@ -36,6 +36,7 @@ struct pcf50633_mbc { struct power_supply usb; struct power_supply adapter; + struct power_supply ac; struct delayed_work charging_restart_work; }; @@ -237,6 +238,7 @@ pcf50633_mbc_irq_handler(int irq, void *data) else if (irq == PCF50633_IRQ_USBLIMOFF) mbc->usb_active = 1; + power_supply_changed(&mbc->ac); power_supply_changed(&mbc->usb); power_supply_changed(&mbc->adapter); @@ -269,10 +271,34 @@ static int usb_get_property(struct power_supply *psy, { struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, usb); int ret = 0; + u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) & + PCF50633_MBCC7_USB_MASK; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = mbc->usb_online && + (usblim <= PCF50633_MBCC7_USB_500mA); + break; + default: + ret = -EINVAL; + break; + } + return ret; +} + +static int ac_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, ac); + int ret = 0; + u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) & + PCF50633_MBCC7_USB_MASK; switch (psp) { case POWER_SUPPLY_PROP_ONLINE: - val->intval = mbc->usb_online; + val->intval = mbc->usb_online && + (usblim == PCF50633_MBCC7_USB_1000mA); break; default: ret = -EINVAL; @@ -337,6 +363,14 @@ static int __devinit pcf50633_mbc_probe(struct platform_device *pdev) mbc->usb.supplied_to = mbc->pcf->pdata->batteries; mbc->usb.num_supplicants = mbc->pcf->pdata->num_batteries; + mbc->ac.name = "ac"; + mbc->ac.type = POWER_SUPPLY_TYPE_MAINS; + mbc->ac.properties = power_props; + mbc->ac.num_properties = ARRAY_SIZE(power_props); + mbc->ac.get_property = ac_get_property; + mbc->ac.supplied_to = mbc->pcf->pdata->batteries; + mbc->ac.num_supplicants = mbc->pcf->pdata->num_batteries; + ret = power_supply_register(&pdev->dev, &mbc->adapter); if (ret) { dev_err(mbc->pcf->dev, "failed to register adapter\n"); @@ -352,6 +386,15 @@ static int __devinit pcf50633_mbc_probe(struct platform_device *pdev) return ret; } + ret = power_supply_register(&pdev->dev, &mbc->ac); + if (ret) { + dev_err(mbc->pcf->dev, "failed to register ac\n"); + power_supply_unregister(&mbc->adapter); + power_supply_unregister(&mbc->usb); + kfree(mbc); + return ret; + } + INIT_DELAYED_WORK(&mbc->charging_restart_work, pcf50633_mbc_charging_restart); @@ -379,6 +422,7 @@ static int __devexit pcf50633_mbc_remove(struct platform_device *pdev) power_supply_unregister(&mbc->usb); power_supply_unregister(&mbc->adapter); + power_supply_unregister(&mbc->ac); cancel_delayed_work_sync(&mbc->charging_restart_work); -- cgit v0.10.2 From 31b4ff06e01a9a98a8e6ae6e8c42213648eec1d1 Mon Sep 17 00:00:00 2001 From: Balaji Rao Date: Thu, 5 Nov 2009 00:24:55 +0300 Subject: pcf50633: introduces battery charging current control Implement a new sysfs attribute to allow changing MBC charging limit on the fly independently of usb current limit. It also gets set automatically every time usb current limit is changed. Limiting charging current also prevents violating USB specification in the case when the whole device is shut down and usb current limit is reset to the factory default by the pcf50633 state transition. Signed-off-by: Balaji Rao Signed-off-by: Paul Fertser Signed-off-by: Anton Vorontsov diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c index 48e92c0..21b6e64 100644 --- a/drivers/power/pcf50633-charger.c +++ b/drivers/power/pcf50633-charger.c @@ -48,16 +48,21 @@ int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma) u8 bits; int charging_start = 1; u8 mbcs2, chgmod; + unsigned int mbcc5; - if (ma >= 1000) + if (ma >= 1000) { bits = PCF50633_MBCC7_USB_1000mA; - else if (ma >= 500) + ma = 1000; + } else if (ma >= 500) { bits = PCF50633_MBCC7_USB_500mA; - else if (ma >= 100) + ma = 500; + } else if (ma >= 100) { bits = PCF50633_MBCC7_USB_100mA; - else { + ma = 100; + } else { bits = PCF50633_MBCC7_USB_SUSPEND; charging_start = 0; + ma = 0; } ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC7, @@ -67,7 +72,24 @@ int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma) else dev_info(pcf->dev, "usb curlim to %d mA\n", ma); - /* Manual charging start */ + /* + * We limit the charging current to be the USB current limit. + * The reason is that on pcf50633, when it enters PMU Standby mode, + * which it does when the device goes "off", the USB current limit + * reverts to the variant default. In at least one common case, that + * default is 500mA. By setting the charging current to be the same + * as the USB limit we set here before PMU standby, we enforce it only + * using the correct amount of current even when the USB current limit + * gets reset to the wrong thing + */ + + if (mbc->pcf->pdata->charger_reference_current_ma) { + mbcc5 = (ma << 8) / mbc->pcf->pdata->charger_reference_current_ma; + if (mbcc5 > 255) + mbcc5 = 255; + pcf50633_reg_write(mbc->pcf, PCF50633_REG_MBCC5, mbcc5); + } + mbcs2 = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK); @@ -157,9 +179,55 @@ static ssize_t set_usblim(struct device *dev, static DEVICE_ATTR(usb_curlim, S_IRUGO | S_IWUSR, show_usblim, set_usblim); +static ssize_t +show_chglim(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct pcf50633_mbc *mbc = dev_get_drvdata(dev); + u8 mbcc5 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC5); + unsigned int ma; + + if (!mbc->pcf->pdata->charger_reference_current_ma) + return -ENODEV; + + ma = (mbc->pcf->pdata->charger_reference_current_ma * mbcc5) >> 8; + + return sprintf(buf, "%u\n", ma); +} + +static ssize_t set_chglim(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct pcf50633_mbc *mbc = dev_get_drvdata(dev); + unsigned long ma; + unsigned int mbcc5; + int ret; + + if (!mbc->pcf->pdata->charger_reference_current_ma) + return -ENODEV; + + ret = strict_strtoul(buf, 10, &ma); + if (ret) + return -EINVAL; + + mbcc5 = (ma << 8) / mbc->pcf->pdata->charger_reference_current_ma; + if (mbcc5 > 255) + mbcc5 = 255; + pcf50633_reg_write(mbc->pcf, PCF50633_REG_MBCC5, mbcc5); + + return count; +} + +/* + * This attribute allows to change MBC charging limit on the fly + * independently of usb current limit. It also gets set automatically every + * time usb current limit is changed. + */ +static DEVICE_ATTR(chg_curlim, S_IRUGO | S_IWUSR, show_chglim, set_chglim); + static struct attribute *pcf50633_mbc_sysfs_entries[] = { &dev_attr_chgmode.attr, &dev_attr_usb_curlim.attr, + &dev_attr_chg_curlim.attr, NULL, }; diff --git a/include/linux/mfd/pcf50633/core.h b/include/linux/mfd/pcf50633/core.h index 9aba7b7..09af8fd 100644 --- a/include/linux/mfd/pcf50633/core.h +++ b/include/linux/mfd/pcf50633/core.h @@ -31,6 +31,13 @@ struct pcf50633_platform_data { int charging_restart_interval; + /* + * Should be set accordingly to the reference resistor used, see + * I_{ch(ref)} charger reference current in the pcf50633 User + * Manual. + */ + int charger_reference_current_ma; + /* Callbacks */ void (*probe_done)(struct pcf50633 *); void (*mbc_event_callback)(struct pcf50633 *, int); -- cgit v0.10.2 From e98c73a24f33d6f54402f5cef2e7bf282d1d1fcc Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Thu, 5 Nov 2009 00:24:57 +0300 Subject: pcf50633: Get rid of charging restart software auto-triggering After reaching Battery Full condition MBC state machine switches back into charging mode when the battery voltage falls below 96% of a battery float voltage. The voltage drop in Li-Ion batteries is marginal (1-2%) till about 80% of its capacity - which means, after a BATFULL, charging won't be restarted until 75-80%. That is a desired behaviour recommended by battery manufacturers, don't mess with it. Signed-off-by: Paul Fertser Signed-off-by: Anton Vorontsov diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c index 21b6e64..3383119 100644 --- a/drivers/power/pcf50633-charger.c +++ b/drivers/power/pcf50633-charger.c @@ -37,8 +37,6 @@ struct pcf50633_mbc { struct power_supply usb; struct power_supply adapter; struct power_supply ac; - - struct delayed_work charging_restart_work; }; int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma) @@ -236,44 +234,10 @@ static struct attribute_group mbc_attr_group = { .attrs = pcf50633_mbc_sysfs_entries, }; -/* MBC state machine switches into charging mode when the battery voltage - * falls below 96% of a battery float voltage. But the voltage drop in Li-ion - * batteries is marginal(1~2 %) till about 80% of its capacity - which means, - * after a BATFULL, charging won't be restarted until 80%. - * - * This work_struct function restarts charging at regular intervals to make - * sure we don't discharge too much - */ - -static void pcf50633_mbc_charging_restart(struct work_struct *work) -{ - struct pcf50633_mbc *mbc; - u8 mbcs2, chgmod; - - mbc = container_of(work, struct pcf50633_mbc, - charging_restart_work.work); - - mbcs2 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS2); - chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK); - - if (chgmod != PCF50633_MBCS2_MBC_BAT_FULL) - return; - - /* Restart charging */ - pcf50633_reg_set_bit_mask(mbc->pcf, PCF50633_REG_MBCC1, - PCF50633_MBCC1_RESUME, PCF50633_MBCC1_RESUME); - mbc->usb_active = 1; - power_supply_changed(&mbc->usb); - - dev_info(mbc->pcf->dev, "Charging restarted\n"); -} - static void pcf50633_mbc_irq_handler(int irq, void *data) { struct pcf50633_mbc *mbc = data; - int chg_restart_interval = - mbc->pcf->pdata->charging_restart_interval; /* USB */ if (irq == PCF50633_IRQ_USBINS) { @@ -282,7 +246,6 @@ pcf50633_mbc_irq_handler(int irq, void *data) mbc->usb_online = 0; mbc->usb_active = 0; pcf50633_mbc_usb_curlim_set(mbc->pcf, 0); - cancel_delayed_work_sync(&mbc->charging_restart_work); } /* Adapter */ @@ -297,10 +260,6 @@ pcf50633_mbc_irq_handler(int irq, void *data) if (irq == PCF50633_IRQ_BATFULL) { mbc->usb_active = 0; mbc->adapter_active = 0; - - if (chg_restart_interval > 0) - schedule_delayed_work(&mbc->charging_restart_work, - chg_restart_interval); } else if (irq == PCF50633_IRQ_USBLIMON) mbc->usb_active = 0; else if (irq == PCF50633_IRQ_USBLIMOFF) @@ -463,9 +422,6 @@ static int __devinit pcf50633_mbc_probe(struct platform_device *pdev) return ret; } - INIT_DELAYED_WORK(&mbc->charging_restart_work, - pcf50633_mbc_charging_restart); - ret = sysfs_create_group(&pdev->dev.kobj, &mbc_attr_group); if (ret) dev_err(mbc->pcf->dev, "failed to create sysfs entries\n"); @@ -492,8 +448,6 @@ static int __devexit pcf50633_mbc_remove(struct platform_device *pdev) power_supply_unregister(&mbc->adapter); power_supply_unregister(&mbc->ac); - cancel_delayed_work_sync(&mbc->charging_restart_work); - kfree(mbc); return 0; diff --git a/include/linux/mfd/pcf50633/core.h b/include/linux/mfd/pcf50633/core.h index 09af8fd..46df7f0 100644 --- a/include/linux/mfd/pcf50633/core.h +++ b/include/linux/mfd/pcf50633/core.h @@ -29,8 +29,6 @@ struct pcf50633_platform_data { char **batteries; int num_batteries; - int charging_restart_interval; - /* * Should be set accordingly to the reference resistor used, see * I_{ch(ref)} charger reference current in the pcf50633 User -- cgit v0.10.2 From 1282b35a1edf5f12ae58a2b16ae8615dfe0d9ecc Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Thu, 5 Nov 2009 00:24:58 +0300 Subject: pcf50633: Properly reenable charging when the supply conditions change If chgmod == BATFULL, setting chgena has no effect. Datasheet says we need to set resume instead but when autoresume is used resume doesn't work. Clear and set chgena instead. This enables a user to force charging by re-plugging USB even when the charger entered Battery Full mode, might be handy before a long trip. Signed-off-by: Paul Fertser Signed-off-by: Anton Vorontsov diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c index 3383119..4718733 100644 --- a/drivers/power/pcf50633-charger.c +++ b/drivers/power/pcf50633-charger.c @@ -92,14 +92,18 @@ int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma) chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK); /* If chgmod == BATFULL, setting chgena has no effect. - * We need to set resume instead. + * Datasheet says we need to set resume instead but when autoresume is + * used resume doesn't work. Clear and set chgena instead. */ if (chgmod != PCF50633_MBCS2_MBC_BAT_FULL) pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1, PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA); - else + else { + pcf50633_reg_clear_bits(pcf, PCF50633_REG_MBCC1, + PCF50633_MBCC1_CHGENA); pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1, - PCF50633_MBCC1_RESUME, PCF50633_MBCC1_RESUME); + PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA); + } mbc->usb_active = charging_start; -- cgit v0.10.2 From c329795052aa339850a45fab649ab97a36905136 Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Thu, 5 Nov 2009 00:24:59 +0300 Subject: pcf50633: Query charger status directly Current scheme is fragile and is likely to go off sync, especially on batfull->adapter charging automatic MBC transition. Query the status bit every time we need it instead. We need to export another function to query for USB presence because we can't read anything from PCF50633 (via I2C) inside irq context and that is needed by usb gadgets. Signed-off-by: Paul Fertser Signed-off-by: Anton Vorontsov diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c index 4718733..b915a00 100644 --- a/drivers/power/pcf50633-charger.c +++ b/drivers/power/pcf50633-charger.c @@ -29,9 +29,7 @@ struct pcf50633_mbc { struct pcf50633 *pcf; - int adapter_active; int adapter_online; - int usb_active; int usb_online; struct power_supply usb; @@ -88,7 +86,7 @@ int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma) pcf50633_reg_write(mbc->pcf, PCF50633_REG_MBCC5, mbcc5); } - mbcs2 = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); + mbcs2 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS2); chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK); /* If chgmod == BATFULL, setting chgena has no effect. @@ -105,8 +103,6 @@ int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma) PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA); } - mbc->usb_active = charging_start; - power_supply_changed(&mbc->usb); return ret; @@ -117,20 +113,44 @@ int pcf50633_mbc_get_status(struct pcf50633 *pcf) { struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev); int status = 0; + u8 chgmod; + + if (!mbc) + return 0; + + chgmod = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS2) + & PCF50633_MBCS2_MBC_MASK; if (mbc->usb_online) status |= PCF50633_MBC_USB_ONLINE; - if (mbc->usb_active) + if (chgmod == PCF50633_MBCS2_MBC_USB_PRE || + chgmod == PCF50633_MBCS2_MBC_USB_PRE_WAIT || + chgmod == PCF50633_MBCS2_MBC_USB_FAST || + chgmod == PCF50633_MBCS2_MBC_USB_FAST_WAIT) status |= PCF50633_MBC_USB_ACTIVE; if (mbc->adapter_online) status |= PCF50633_MBC_ADAPTER_ONLINE; - if (mbc->adapter_active) + if (chgmod == PCF50633_MBCS2_MBC_ADP_PRE || + chgmod == PCF50633_MBCS2_MBC_ADP_PRE_WAIT || + chgmod == PCF50633_MBCS2_MBC_ADP_FAST || + chgmod == PCF50633_MBCS2_MBC_ADP_FAST_WAIT) status |= PCF50633_MBC_ADAPTER_ACTIVE; return status; } EXPORT_SYMBOL_GPL(pcf50633_mbc_get_status); +int pcf50633_mbc_get_usb_online_status(struct pcf50633 *pcf) +{ + struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev); + + if (!mbc) + return 0; + + return mbc->usb_online; +} +EXPORT_SYMBOL_GPL(pcf50633_mbc_get_usb_online_status); + static ssize_t show_chgmode(struct device *dev, struct device_attribute *attr, char *buf) { @@ -248,26 +268,14 @@ pcf50633_mbc_irq_handler(int irq, void *data) mbc->usb_online = 1; } else if (irq == PCF50633_IRQ_USBREM) { mbc->usb_online = 0; - mbc->usb_active = 0; pcf50633_mbc_usb_curlim_set(mbc->pcf, 0); } /* Adapter */ - if (irq == PCF50633_IRQ_ADPINS) { + if (irq == PCF50633_IRQ_ADPINS) mbc->adapter_online = 1; - mbc->adapter_active = 1; - } else if (irq == PCF50633_IRQ_ADPREM) { + else if (irq == PCF50633_IRQ_ADPREM) mbc->adapter_online = 0; - mbc->adapter_active = 0; - } - - if (irq == PCF50633_IRQ_BATFULL) { - mbc->usb_active = 0; - mbc->adapter_active = 0; - } else if (irq == PCF50633_IRQ_USBLIMON) - mbc->usb_active = 0; - else if (irq == PCF50633_IRQ_USBLIMOFF) - mbc->usb_active = 1; power_supply_changed(&mbc->ac); power_supply_changed(&mbc->usb); diff --git a/include/linux/mfd/pcf50633/mbc.h b/include/linux/mfd/pcf50633/mbc.h index 4119579..df4f5fa 100644 --- a/include/linux/mfd/pcf50633/mbc.h +++ b/include/linux/mfd/pcf50633/mbc.h @@ -128,6 +128,7 @@ enum pcf50633_reg_mbcs3 { int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma); int pcf50633_mbc_get_status(struct pcf50633 *); +int pcf50633_mbc_get_usb_online_status(struct pcf50633 *); #endif -- cgit v0.10.2 From 2f745dde1f5659d8d6ff5b36996039b3f5a0a20a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 5 Nov 2009 00:24:56 +0300 Subject: gta02: Set pcf50633 charger_reference_current_ma This value is board-specific and is needed for calculations to set charging current limit properly. Signed-off-by: Lars-Peter Clausen Acked-by: Nelson Castillo Signed-off-by: Paul Fertser Cc: Russell King Cc: Ben Dooks Signed-off-by: Anton Vorontsov diff --git a/arch/arm/mach-s3c2442/mach-gta02.c b/arch/arm/mach-s3c2442/mach-gta02.c index 0fb385b..99d4244 100644 --- a/arch/arm/mach-s3c2442/mach-gta02.c +++ b/arch/arm/mach-s3c2442/mach-gta02.c @@ -268,6 +268,9 @@ struct pcf50633_platform_data gta02_pcf_pdata = { .batteries = gta02_batteries, .num_batteries = ARRAY_SIZE(gta02_batteries), + + .charger_reference_current_ma = 1000, + .reg_init_data = { [PCF50633_REGULATOR_AUTO] = { .constraints = { -- cgit v0.10.2 From a7ca1f00ed2921b804d7ebda0f6fca8c9078fa42 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Mon, 16 Nov 2009 09:30:33 -0800 Subject: RDMA/ucma: Add option to manually set IB path Export rdma_set_ib_paths to user space to allow applications to manually set the IB path used for connections. This allows alternative ways for a user space application or library to obtain path record information, including retrieving path information from cached data, avoiding direct interaction with the IB SA. The IB SA is a single, centralized entity that can limit scaling on large clusters running MPI applications. Future changes to the rdma cm can expand on this framework to support the full range of features allowed by the IB CM, such as separate forward and reverse paths and APM. Signed-off-by: Sean Hefty Reviewed-By: Jason Gunthorpe Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 8254371..7e1ffd8c 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -604,6 +604,12 @@ retry: return ret ? ret : id; } +void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec) +{ + ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table), attribute, rec); +} +EXPORT_SYMBOL(ib_sa_unpack_path); + static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query, int status, struct ib_sa_mad *mad) diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index bb96d3c..f1cbd26 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -43,6 +43,7 @@ #include #include #include +#include MODULE_AUTHOR("Sean Hefty"); MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access"); @@ -812,6 +813,51 @@ static int ucma_set_option_id(struct ucma_context *ctx, int optname, return ret; } +static int ucma_set_ib_path(struct ucma_context *ctx, + struct ib_path_rec_data *path_data, size_t optlen) +{ + struct ib_sa_path_rec sa_path; + struct rdma_cm_event event; + int ret; + + if (optlen % sizeof(*path_data)) + return -EINVAL; + + for (; optlen; optlen -= sizeof(*path_data), path_data++) { + if (path_data->flags == (IB_PATH_GMP | IB_PATH_PRIMARY | + IB_PATH_BIDIRECTIONAL)) + break; + } + + if (!optlen) + return -EINVAL; + + ib_sa_unpack_path(path_data->path_rec, &sa_path); + ret = rdma_set_ib_paths(ctx->cm_id, &sa_path, 1); + if (ret) + return ret; + + memset(&event, 0, sizeof event); + event.event = RDMA_CM_EVENT_ROUTE_RESOLVED; + return ucma_event_handler(ctx->cm_id, &event); +} + +static int ucma_set_option_ib(struct ucma_context *ctx, int optname, + void *optval, size_t optlen) +{ + int ret; + + switch (optname) { + case RDMA_OPTION_IB_PATH: + ret = ucma_set_ib_path(ctx, optval, optlen); + break; + default: + ret = -ENOSYS; + } + + return ret; +} + static int ucma_set_option_level(struct ucma_context *ctx, int level, int optname, void *optval, size_t optlen) { @@ -821,6 +867,9 @@ static int ucma_set_option_level(struct ucma_context *ctx, int level, case RDMA_OPTION_ID: ret = ucma_set_option_id(ctx, optname, optval, optlen); break; + case RDMA_OPTION_IB: + ret = ucma_set_option_ib(ctx, optname, optval, optlen); + break; default: ret = -ENOSYS; } diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h index 3841c1a..1082afa 100644 --- a/include/rdma/ib_sa.h +++ b/include/rdma/ib_sa.h @@ -379,4 +379,10 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num, struct ib_sa_path_rec *rec, struct ib_ah_attr *ah_attr); +/** + * ib_sa_unpack_path - Convert a path record from MAD format to struct + * ib_sa_path_rec. + */ +void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec); + #endif /* IB_SA_H */ diff --git a/include/rdma/ib_user_sa.h b/include/rdma/ib_user_sa.h index 6591201..cfc7c9b 100644 --- a/include/rdma/ib_user_sa.h +++ b/include/rdma/ib_user_sa.h @@ -35,6 +35,22 @@ #include +enum { + IB_PATH_GMP = 1, + IB_PATH_PRIMARY = (1<<1), + IB_PATH_ALTERNATE = (1<<2), + IB_PATH_OUTBOUND = (1<<3), + IB_PATH_INBOUND = (1<<4), + IB_PATH_INBOUND_REVERSE = (1<<5), + IB_PATH_BIDIRECTIONAL = IB_PATH_OUTBOUND | IB_PATH_INBOUND_REVERSE +}; + +struct ib_path_rec_data { + __u32 flags; + __u32 reserved; + __u32 path_rec[16]; +}; + struct ib_user_path_rec { __u8 dgid[16]; __u8 sgid[16]; diff --git a/include/rdma/rdma_user_cm.h b/include/rdma/rdma_user_cm.h index c557054..1d16502 100644 --- a/include/rdma/rdma_user_cm.h +++ b/include/rdma/rdma_user_cm.h @@ -215,12 +215,14 @@ struct rdma_ucm_event_resp { /* Option levels */ enum { - RDMA_OPTION_ID = 0 + RDMA_OPTION_ID = 0, + RDMA_OPTION_IB = 1 }; /* Option details */ enum { - RDMA_OPTION_ID_TOS = 0 + RDMA_OPTION_ID_TOS = 0, + RDMA_OPTION_IB_PATH = 1 }; struct rdma_ucm_set_option { -- cgit v0.10.2 From 0e19dbb73eab1f5de328e297b8b6d9887c3e73c2 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 17 Nov 2009 15:44:54 +0000 Subject: wm831x_backup: Remove unused variables Signed-off-by: Alan Cox Acked-by: Mark Brown Signed-off-by: Anton Vorontsov diff --git a/drivers/power/wm831x_backup.c b/drivers/power/wm831x_backup.c index f181076..bf4f387 100644 --- a/drivers/power/wm831x_backup.c +++ b/drivers/power/wm831x_backup.c @@ -164,7 +164,7 @@ static __devinit int wm831x_backup_probe(struct platform_device *pdev) struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x_backup *devdata; struct power_supply *backup; - int ret, irq, i; + int ret; devdata = kzalloc(sizeof(struct wm831x_backup), GFP_KERNEL); if (devdata == NULL) -- cgit v0.10.2 From 0f9ea5d2ab5cef732d5abbe62b9e9af3007bae81 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 18 Nov 2009 14:24:34 -0800 Subject: RDMA/addr: Use appropriate locking with for_each_netdev() for_each_netdev() should be used with RTNL or dev_base_lock held, or else we risk a crash. Signed-off-by: Eric Dumazet Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index bd07803..373f111 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -131,6 +131,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr) #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) case AF_INET6: + read_lock(&dev_base_lock); for_each_netdev(&init_net, dev) { if (ipv6_chk_addr(&init_net, &((struct sockaddr_in6 *) addr)->sin6_addr, @@ -139,6 +140,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr) break; } } + read_unlock(&dev_base_lock); break; #endif } @@ -391,14 +393,17 @@ static int addr_resolve_local(struct sockaddr *src_in, { struct in6_addr *a; + read_lock(&dev_base_lock); for_each_netdev(&init_net, dev) if (ipv6_chk_addr(&init_net, &((struct sockaddr_in6 *) dst_in)->sin6_addr, dev, 1)) break; - if (!dev) + if (!dev) { + read_unlock(&dev_base_lock); return -EADDRNOTAVAIL; + } a = &((struct sockaddr_in6 *) src_in)->sin6_addr; @@ -416,6 +421,7 @@ static int addr_resolve_local(struct sockaddr *src_in, if (!ret) memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN); } + read_unlock(&dev_base_lock); break; } #endif -- cgit v0.10.2 From 1c9b281997b5876c0c8ed62506b56db89d262b57 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 19 Nov 2009 12:55:21 -0800 Subject: RDMA/cma: Correct detection of SA Created MGID RDMA CM treats AF_INET6 addresses that are either 0 or prefixed with FF1x:A01B::/32 as MGIDs, but the detection for the prefix was buggy; fix it up. Signed-off-by: Jason Gunthorpe Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 0753178..8bb2cf4 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -2687,7 +2687,7 @@ static void cma_set_mgid(struct rdma_id_private *id_priv, if (cma_any_addr(addr)) { memset(mgid, 0, sizeof *mgid); } else if ((addr->sa_family == AF_INET6) && - ((be32_to_cpu(sin6->sin6_addr.s6_addr32[0]) & 0xFF10A01B) == + ((be32_to_cpu(sin6->sin6_addr.s6_addr32[0]) & 0xFFF0FFFF) == 0xFF10A01B)) { /* IPv6 address is an SA assigned MGID. */ memcpy(mgid, &sin6->sin6_addr, sizeof *mgid); -- cgit v0.10.2 From e2e626972e652d18520f84d69fc06cfa307d11ff Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 19 Nov 2009 12:55:22 -0800 Subject: RDMA/cma: Fix AF_INET6 support in multicast joining If joining to an AF_INET6 address, we need to map the address to a MGID in the same way as the IP stack. The old code would just fall through to the IPv4 case and generate garbage. Signed-off-by: Jason Gunthorpe Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 8bb2cf4..052b4c0 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -2691,6 +2691,11 @@ static void cma_set_mgid(struct rdma_id_private *id_priv, 0xFF10A01B)) { /* IPv6 address is an SA assigned MGID. */ memcpy(mgid, &sin6->sin6_addr, sizeof *mgid); + } else if ((addr->sa_family == AF_INET6)) { + ipv6_ib_mc_map(&sin6->sin6_addr, dev_addr->broadcast, mc_map); + if (id_priv->id.ps == RDMA_PS_UDP) + mc_map[7] = 0x01; /* Use RDMA CM signature */ + *mgid = *(union ib_gid *) (mc_map + 4); } else { ip_ib_mc_map(sin->sin_addr.s_addr, dev_addr->broadcast, mc_map); if (id_priv->id.ps == RDMA_PS_UDP) -- cgit v0.10.2 From 6266ed6e4164466177238b11ecb825a3a108a3e4 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Thu, 19 Nov 2009 12:55:22 -0800 Subject: RDMA/cma: Replace net_device pointer with index Provide the device interface when resolving route information to ensure that the correct outbound device is used. This will also simplify processing of sin6_scope_id for IPv6 support. Based on work from: David Wilder Jason Gunthorpe Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 373f111..788a02e 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -107,7 +107,7 @@ int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev, memcpy(dev_addr->broadcast, dev->broadcast, MAX_ADDR_LEN); if (dst_dev_addr) memcpy(dev_addr->dst_dev_addr, dst_dev_addr, MAX_ADDR_LEN); - dev_addr->src_dev = dev; + dev_addr->bound_dev_if = dev->ifindex; return 0; } EXPORT_SYMBOL(rdma_copy_addr); @@ -117,6 +117,15 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr) struct net_device *dev; int ret = -EADDRNOTAVAIL; + if (dev_addr->bound_dev_if) { + dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if); + if (!dev) + return -ENODEV; + ret = rdma_copy_addr(dev_addr, dev, NULL); + dev_put(dev); + return ret; + } + switch (addr->sa_family) { case AF_INET: dev = ip_dev_find(&init_net, @@ -231,6 +240,8 @@ static int addr4_resolve_remote(struct sockaddr_in *src_in, memset(&fl, 0, sizeof fl); fl.nl_u.ip4_u.daddr = dst_ip; fl.nl_u.ip4_u.saddr = src_ip; + fl.oif = addr->bound_dev_if; + ret = ip_route_output_key(&init_net, &rt, &fl); if (ret) goto out; @@ -279,6 +290,7 @@ static int addr6_resolve_remote(struct sockaddr_in6 *src_in, memset(&fl, 0, sizeof fl); fl.nl_u.ip6_u.daddr = dst_in->sin6_addr; fl.nl_u.ip6_u.saddr = src_in->sin6_addr; + fl.oif = addr->bound_dev_if; dst = ip6_route_output(&init_net, NULL, &fl); if (!dst) diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 052b4c0..699ad12 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -2820,7 +2820,7 @@ static int cma_netdev_change(struct net_device *ndev, struct rdma_id_private *id dev_addr = &id_priv->id.route.addr.dev_addr; - if ((dev_addr->src_dev == ndev) && + if ((dev_addr->bound_dev_if == ndev->ifindex) && memcmp(dev_addr->src_dev_addr, ndev->dev_addr, ndev->addr_len)) { printk(KERN_INFO "RDMA CM addr change for ndev %s used by id %p\n", ndev->name, &id_priv->id); diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index 483057b..27f17cc 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h @@ -61,7 +61,7 @@ struct rdma_dev_addr { unsigned char dst_dev_addr[MAX_ADDR_LEN]; unsigned char broadcast[MAX_ADDR_LEN]; enum rdma_node_type dev_type; - struct net_device *src_dev; + int bound_dev_if; }; /** -- cgit v0.10.2 From d2e0886245aa9eebc1a4710c861d263b09eac493 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Thu, 19 Nov 2009 12:55:22 -0800 Subject: IB/addr: Verify source and destination address families match If a source address is provided, verify that the address family matches that of the destination address. If the source is not specified, use the same address family as the destination. Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 788a02e..b59ba7c 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -461,18 +461,27 @@ int rdma_resolve_ip(struct rdma_addr_client *client, if (!req) return -ENOMEM; - if (src_addr) - memcpy(&req->src_addr, src_addr, ip_addr_size(src_addr)); - memcpy(&req->dst_addr, dst_addr, ip_addr_size(dst_addr)); + src_in = (struct sockaddr *) &req->src_addr; + dst_in = (struct sockaddr *) &req->dst_addr; + + if (src_addr) { + if (src_addr->sa_family != dst_addr->sa_family) { + ret = -EINVAL; + goto err; + } + + memcpy(src_in, src_addr, ip_addr_size(src_addr)); + } else { + src_in->sa_family = dst_addr->sa_family; + } + + memcpy(dst_in, dst_addr, ip_addr_size(dst_addr)); req->addr = addr; req->callback = callback; req->context = context; req->client = client; atomic_inc(&client->refcount); - src_in = (struct sockaddr *) &req->src_addr; - dst_in = (struct sockaddr *) &req->dst_addr; - req->status = addr_resolve_local(src_in, dst_in, addr); if (req->status == -EADDRNOTAVAIL) req->status = addr_resolve_remote(src_in, dst_in, addr); @@ -490,10 +499,12 @@ int rdma_resolve_ip(struct rdma_addr_client *client, default: ret = req->status; atomic_dec(&client->refcount); - kfree(req); - break; + goto err; } return ret; +err: + kfree(req); + return ret; } EXPORT_SYMBOL(rdma_resolve_ip); -- cgit v0.10.2 From c4315d85f9b76834289fd503796c01b8311c4b84 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Thu, 19 Nov 2009 12:57:18 -0800 Subject: IB/addr: Store net_device type instead of translating to RDMA transport The struct rdma_dev_addr stores net_device address information: the source device address, destination hardware address, and broadcast address. For consistency, store the net_device type rather than converting it to the rdma_node_type. The type indicates the format of the various hardware addresses, which is what we're concerned with, and not the RDMA node type that the address may map to. Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index b59ba7c..de5fe16 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -92,17 +91,7 @@ EXPORT_SYMBOL(rdma_addr_unregister_client); int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev, const unsigned char *dst_dev_addr) { - switch (dev->type) { - case ARPHRD_INFINIBAND: - dev_addr->dev_type = RDMA_NODE_IB_CA; - break; - case ARPHRD_ETHER: - dev_addr->dev_type = RDMA_NODE_RNIC; - break; - default: - return -EADDRNOTAVAIL; - } - + dev_addr->dev_type = dev->type; memcpy(dev_addr->src_dev_addr, dev->dev_addr, MAX_ADDR_LEN); memcpy(dev_addr->broadcast, dev->broadcast, MAX_ADDR_LEN); if (dst_dev_addr) diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 699ad12..b305b5c 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -330,11 +330,11 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv) union ib_gid gid; int ret = -ENODEV; - switch (rdma_node_get_transport(dev_addr->dev_type)) { - case RDMA_TRANSPORT_IB: + switch (dev_addr->dev_type) { + case ARPHRD_INFINIBAND: ib_addr_get_sgid(dev_addr, &gid); break; - case RDMA_TRANSPORT_IWARP: + case ARPHRD_ETHER: iw_addr_get_sgid(dev_addr, &gid); break; default: diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index 27f17cc..3a39c55 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -60,7 +61,7 @@ struct rdma_dev_addr { unsigned char src_dev_addr[MAX_ADDR_LEN]; unsigned char dst_dev_addr[MAX_ADDR_LEN]; unsigned char broadcast[MAX_ADDR_LEN]; - enum rdma_node_type dev_type; + unsigned short dev_type; int bound_dev_if; }; -- cgit v0.10.2 From 6f8372b69c3198e06cecb1df2cb9682d0c55e657 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Thu, 19 Nov 2009 13:26:06 -0800 Subject: RDMA/cm: fix loopback address support The RDMA CM is intended to support the use of a loopback address when establishing a connection; however, the behavior of the CM when loopback addresses are used is confusing and does not always work, depending on whether loopback was specified by the server, the client, or both. The defined behavior of rdma_bind_addr is to associate an RDMA device with an rdma_cm_id, as long as the user specified a non- zero address. (ie they weren't just trying to reserve a port) Currently, if the loopback address is passed to rdam_bind_addr, no device is associated with the rdma_cm_id. Fix this. If a loopback address is specified by the client as the destination address for a connection, it will fail to establish a connection. This is true even if the server is listing across all addresses or on the loopback address itself. The issue is that the server tries to translate the IP address carried in the REQ message to a local net_device address, which fails. The translation is not needed in this case, since the REQ carries the actual HW address that should be used. Finally, cleanup loopback support to be more transport neutral. Replace separate calls to get/set the sgid and dgid from the device address to a single call that behaves correctly depending on the format of the device address. And support both IPv4 and IPv6 address formats. Signed-off-by: Sean Hefty [ Fixed RDS build by s/ib_addr_get/rdma_addr_get/ - Roland ] Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index b305b5c..38867a4 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -330,17 +330,7 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv) union ib_gid gid; int ret = -ENODEV; - switch (dev_addr->dev_type) { - case ARPHRD_INFINIBAND: - ib_addr_get_sgid(dev_addr, &gid); - break; - case ARPHRD_ETHER: - iw_addr_get_sgid(dev_addr, &gid); - break; - default: - return -ENODEV; - } - + rdma_addr_get_sgid(dev_addr, &gid); list_for_each_entry(cma_dev, &dev_list, list) { ret = ib_find_cached_gid(cma_dev->device, &gid, &id_priv->id.port_num, NULL); @@ -1032,11 +1022,17 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id, if (rt->num_paths == 2) rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path; - ib_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid); - ret = rdma_translate_ip((struct sockaddr *) &id->route.addr.src_addr, - &id->route.addr.dev_addr); - if (ret) - goto destroy_id; + if (cma_any_addr((struct sockaddr *) &rt->addr.src_addr)) { + rt->addr.dev_addr.dev_type = ARPHRD_INFINIBAND; + rdma_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid); + ib_addr_set_pkey(&rt->addr.dev_addr, rt->path_rec[0].pkey); + } else { + ret = rdma_translate_ip((struct sockaddr *) &rt->addr.src_addr, + &rt->addr.dev_addr); + if (ret) + goto destroy_id; + } + rdma_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid); id_priv = container_of(id, struct rdma_id_private, id); id_priv->state = CMA_CONNECT; @@ -1071,10 +1067,12 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id, cma_save_net_info(&id->route.addr, &listen_id->route.addr, ip_ver, port, src, dst); - ret = rdma_translate_ip((struct sockaddr *) &id->route.addr.src_addr, - &id->route.addr.dev_addr); - if (ret) - goto err; + if (!cma_any_addr((struct sockaddr *) &id->route.addr.src_addr)) { + ret = rdma_translate_ip((struct sockaddr *) &id->route.addr.src_addr, + &id->route.addr.dev_addr); + if (ret) + goto err; + } id_priv = container_of(id, struct rdma_id_private, id); id_priv->state = CMA_CONNECT; @@ -1565,8 +1563,8 @@ static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms, struct sockaddr_in6 *sin6; memset(&path_rec, 0, sizeof path_rec); - ib_addr_get_sgid(&addr->dev_addr, &path_rec.sgid); - ib_addr_get_dgid(&addr->dev_addr, &path_rec.dgid); + rdma_addr_get_sgid(&addr->dev_addr, &path_rec.sgid); + rdma_addr_get_dgid(&addr->dev_addr, &path_rec.dgid); path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(&addr->dev_addr)); path_rec.numb_path = 1; path_rec.reversible = 1; @@ -1781,7 +1779,11 @@ port_found: if (ret) goto out; - ib_addr_set_sgid(&id_priv->id.route.addr.dev_addr, &gid); + id_priv->id.route.addr.dev_addr.dev_type = + (rdma_node_get_transport(cma_dev->device->node_type) == RDMA_TRANSPORT_IB) ? + ARPHRD_INFINIBAND : ARPHRD_ETHER; + + rdma_addr_set_sgid(&id_priv->id.route.addr.dev_addr, &gid); ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey); id_priv->id.port_num = p; cma_attach_to_dev(id_priv, cma_dev); @@ -1839,7 +1841,7 @@ out: static int cma_resolve_loopback(struct rdma_id_private *id_priv) { struct cma_work *work; - struct sockaddr_in *src_in, *dst_in; + struct sockaddr *src, *dst; union ib_gid gid; int ret; @@ -1853,14 +1855,19 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv) goto err; } - ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid); - ib_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid); + rdma_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid); + rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid); - if (cma_zero_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr)) { - src_in = (struct sockaddr_in *)&id_priv->id.route.addr.src_addr; - dst_in = (struct sockaddr_in *)&id_priv->id.route.addr.dst_addr; - src_in->sin_family = dst_in->sin_family; - src_in->sin_addr.s_addr = dst_in->sin_addr.s_addr; + src = (struct sockaddr *) &id_priv->id.route.addr.src_addr; + if (cma_zero_addr(src)) { + dst = (struct sockaddr *) &id_priv->id.route.addr.dst_addr; + if ((src->sa_family = dst->sa_family) == AF_INET) { + ((struct sockaddr_in *) src)->sin_addr.s_addr = + ((struct sockaddr_in *) dst)->sin_addr.s_addr; + } else { + ipv6_addr_copy(&((struct sockaddr_in6 *) src)->sin6_addr, + &((struct sockaddr_in6 *) dst)->sin6_addr); + } } work->id = id_priv; @@ -2089,7 +2096,9 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) if (!cma_comp_exch(id_priv, CMA_IDLE, CMA_ADDR_BOUND)) return -EINVAL; - if (!cma_any_addr(addr)) { + if (cma_loopback_addr(addr)) { + ret = cma_bind_loopback(id_priv); + } else if (!cma_zero_addr(addr)) { ret = rdma_translate_ip(addr, &id->route.addr.dev_addr); if (ret) goto err1; @@ -2108,7 +2117,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) return 0; err2: - if (!cma_any_addr(addr)) { + if (id_priv->cma_dev) { mutex_lock(&lock); cma_detach_from_dev(id_priv); mutex_unlock(&lock); @@ -2721,7 +2730,7 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv, cma_set_mgid(id_priv, (struct sockaddr *) &mc->addr, &rec.mgid); if (id_priv->id.ps == RDMA_PS_UDP) rec.qkey = cpu_to_be32(RDMA_UDP_QKEY); - ib_addr_get_sgid(dev_addr, &rec.port_gid); + rdma_addr_get_sgid(dev_addr, &rec.port_gid); rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr)); rec.join_state = 1; diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index f1cbd26..b2e16c3 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -563,10 +563,10 @@ static void ucma_copy_ib_route(struct rdma_ucm_query_route_resp *resp, switch (route->num_paths) { case 0: dev_addr = &route->addr.dev_addr; - ib_addr_get_dgid(dev_addr, - (union ib_gid *) &resp->ib_route[0].dgid); - ib_addr_get_sgid(dev_addr, - (union ib_gid *) &resp->ib_route[0].sgid); + rdma_addr_get_dgid(dev_addr, + (union ib_gid *) &resp->ib_route[0].dgid); + rdma_addr_get_sgid(dev_addr, + (union ib_gid *) &resp->ib_route[0].sgid); resp->ib_route[0].pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr)); break; case 2: diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index 3a39c55..fa0d52b 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h @@ -122,40 +122,29 @@ static inline void ib_addr_get_mgid(struct rdma_dev_addr *dev_addr, memcpy(gid, dev_addr->broadcast + 4, sizeof *gid); } -static inline void ib_addr_get_sgid(struct rdma_dev_addr *dev_addr, - union ib_gid *gid) +static inline int rdma_addr_gid_offset(struct rdma_dev_addr *dev_addr) { - memcpy(gid, dev_addr->src_dev_addr + 4, sizeof *gid); + return dev_addr->dev_type == ARPHRD_INFINIBAND ? 4 : 0; } -static inline void ib_addr_set_sgid(struct rdma_dev_addr *dev_addr, - union ib_gid *gid) +static inline void rdma_addr_get_sgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid) { - memcpy(dev_addr->src_dev_addr + 4, gid, sizeof *gid); + memcpy(gid, dev_addr->src_dev_addr + rdma_addr_gid_offset(dev_addr), sizeof *gid); } -static inline void ib_addr_get_dgid(struct rdma_dev_addr *dev_addr, - union ib_gid *gid) +static inline void rdma_addr_set_sgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid) { - memcpy(gid, dev_addr->dst_dev_addr + 4, sizeof *gid); + memcpy(dev_addr->src_dev_addr + rdma_addr_gid_offset(dev_addr), gid, sizeof *gid); } -static inline void ib_addr_set_dgid(struct rdma_dev_addr *dev_addr, - union ib_gid *gid) +static inline void rdma_addr_get_dgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid) { - memcpy(dev_addr->dst_dev_addr + 4, gid, sizeof *gid); + memcpy(gid, dev_addr->dst_dev_addr + rdma_addr_gid_offset(dev_addr), sizeof *gid); } -static inline void iw_addr_get_sgid(struct rdma_dev_addr *dev_addr, - union ib_gid *gid) -{ - memcpy(gid, dev_addr->src_dev_addr, sizeof *gid); -} - -static inline void iw_addr_get_dgid(struct rdma_dev_addr *dev_addr, - union ib_gid *gid) +static inline void rdma_addr_set_dgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid) { - memcpy(gid, dev_addr->dst_dev_addr, sizeof *gid); + memcpy(dev_addr->dst_dev_addr + rdma_addr_gid_offset(dev_addr), gid, sizeof *gid); } #endif /* IB_ADDR_H */ diff --git a/net/rds/ib.c b/net/rds/ib.c index 536ebe5..3b89923 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -182,8 +182,8 @@ static int rds_ib_conn_info_visitor(struct rds_connection *conn, ic = conn->c_transport_data; dev_addr = &ic->i_cm_id->route.addr.dev_addr; - ib_addr_get_sgid(dev_addr, (union ib_gid *) &iinfo->src_gid); - ib_addr_get_dgid(dev_addr, (union ib_gid *) &iinfo->dst_gid); + rdma_addr_get_sgid(dev_addr, (union ib_gid *) &iinfo->src_gid); + rdma_addr_get_dgid(dev_addr, (union ib_gid *) &iinfo->dst_gid); rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client); iinfo->max_send_wr = ic->i_send_ring.w_nr; diff --git a/net/rds/iw.c b/net/rds/iw.c index db224f7..b28fa85 100644 --- a/net/rds/iw.c +++ b/net/rds/iw.c @@ -184,8 +184,8 @@ static int rds_iw_conn_info_visitor(struct rds_connection *conn, ic = conn->c_transport_data; dev_addr = &ic->i_cm_id->route.addr.dev_addr; - ib_addr_get_sgid(dev_addr, (union ib_gid *) &iinfo->src_gid); - ib_addr_get_dgid(dev_addr, (union ib_gid *) &iinfo->dst_gid); + rdma_addr_get_sgid(dev_addr, (union ib_gid *) &iinfo->src_gid); + rdma_addr_get_dgid(dev_addr, (union ib_gid *) &iinfo->dst_gid); rds_iwdev = ib_get_client_data(ic->i_cm_id->device, &rds_iw_client); iinfo->max_send_wr = ic->i_send_ring.w_nr; -- cgit v0.10.2 From 923c100ef019bf15fb89b6fa3d3ad0485d25d59b Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Thu, 19 Nov 2009 13:26:51 -0800 Subject: IB/addr: Simplify resolving IPv4 addresses Merge resolve local/remote address resolution into a single data flow to ensure consistent access and use of the local routing tables. Based on work from: David Wilder Jason Gunthorpe Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index de5fe16..38a7184 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -184,17 +184,6 @@ static void addr_send_arp(struct sockaddr *dst_in) memset(&fl, 0, sizeof fl); switch (dst_in->sa_family) { - case AF_INET: - fl.nl_u.ip4_u.daddr = - ((struct sockaddr_in *) dst_in)->sin_addr.s_addr; - - if (ip_route_output_key(&init_net, &rt, &fl)) - return; - - neigh_event_send(rt->u.dst.neighbour, NULL); - ip_rt_put(rt); - break; - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) case AF_INET6: { @@ -215,9 +204,9 @@ static void addr_send_arp(struct sockaddr *dst_in) } } -static int addr4_resolve_remote(struct sockaddr_in *src_in, - struct sockaddr_in *dst_in, - struct rdma_dev_addr *addr) +static int addr4_resolve(struct sockaddr_in *src_in, + struct sockaddr_in *dst_in, + struct rdma_dev_addr *addr) { __be32 src_ip = src_in->sin_addr.s_addr; __be32 dst_ip = dst_in->sin_addr.s_addr; @@ -235,6 +224,16 @@ static int addr4_resolve_remote(struct sockaddr_in *src_in, if (ret) goto out; + src_in->sin_family = AF_INET; + src_in->sin_addr.s_addr = rt->rt_src; + + if (rt->idev->dev->flags & IFF_LOOPBACK) { + ret = rdma_translate_ip((struct sockaddr *) dst_in, addr); + if (!ret) + memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN); + goto put; + } + /* If the device does ARP internally, return 'done' */ if (rt->idev->dev->flags & IFF_NOARP) { rdma_copy_addr(addr, rt->idev->dev, NULL); @@ -242,21 +241,14 @@ static int addr4_resolve_remote(struct sockaddr_in *src_in, } neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->idev->dev); - if (!neigh) { + if (!neigh || !(neigh->nud_state & NUD_VALID)) { + neigh_event_send(rt->u.dst.neighbour, NULL); ret = -ENODATA; + if (neigh) + goto release; goto put; } - if (!(neigh->nud_state & NUD_VALID)) { - ret = -ENODATA; - goto release; - } - - if (!src_ip) { - src_in->sin_family = dst_in->sin_family; - src_in->sin_addr.s_addr = rt->rt_src; - } - ret = rdma_copy_addr(addr, neigh->dev, neigh->ha); release: neigh_release(neigh); @@ -305,12 +297,12 @@ static int addr6_resolve_remote(struct sockaddr_in6 *src_in, } #endif -static int addr_resolve_remote(struct sockaddr *src_in, - struct sockaddr *dst_in, - struct rdma_dev_addr *addr) +static int addr_resolve(struct sockaddr *src_in, + struct sockaddr *dst_in, + struct rdma_dev_addr *addr) { if (src_in->sa_family == AF_INET) { - return addr4_resolve_remote((struct sockaddr_in *) src_in, + return addr4_resolve((struct sockaddr_in *) src_in, (struct sockaddr_in *) dst_in, addr); } else return addr6_resolve_remote((struct sockaddr_in6 *) src_in, @@ -330,8 +322,7 @@ static void process_req(struct work_struct *work) if (req->status == -ENODATA) { src_in = (struct sockaddr *) &req->src_addr; dst_in = (struct sockaddr *) &req->dst_addr; - req->status = addr_resolve_remote(src_in, dst_in, - req->addr); + req->status = addr_resolve(src_in, dst_in, req->addr); if (req->status && time_after_eq(jiffies, req->timeout)) req->status = -ETIMEDOUT; else if (req->status == -ENODATA) @@ -363,32 +354,6 @@ static int addr_resolve_local(struct sockaddr *src_in, int ret; switch (dst_in->sa_family) { - case AF_INET: - { - __be32 src_ip = ((struct sockaddr_in *) src_in)->sin_addr.s_addr; - __be32 dst_ip = ((struct sockaddr_in *) dst_in)->sin_addr.s_addr; - - dev = ip_dev_find(&init_net, dst_ip); - if (!dev) - return -EADDRNOTAVAIL; - - if (ipv4_is_zeronet(src_ip)) { - src_in->sa_family = dst_in->sa_family; - ((struct sockaddr_in *) src_in)->sin_addr.s_addr = dst_ip; - ret = rdma_copy_addr(addr, dev, dev->dev_addr); - } else if (ipv4_is_loopback(src_ip)) { - ret = rdma_translate_ip(dst_in, addr); - if (!ret) - memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN); - } else { - ret = rdma_translate_ip(src_in, addr); - if (!ret) - memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN); - } - dev_put(dev); - break; - } - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) case AF_INET6: { @@ -473,7 +438,7 @@ int rdma_resolve_ip(struct rdma_addr_client *client, req->status = addr_resolve_local(src_in, dst_in, addr); if (req->status == -EADDRNOTAVAIL) - req->status = addr_resolve_remote(src_in, dst_in, addr); + req->status = addr_resolve(src_in, dst_in, addr); switch (req->status) { case 0: -- cgit v0.10.2 -- cgit v0.10.2 From d14714df61681cfecf945a58436edf197327e87f Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Thu, 19 Nov 2009 16:46:25 -0800 Subject: IB/addr: Fix IPv6 routing lookup Include link scope as part of address resolution. Combine local and remote address resolution into a single, simpler code path. Fix error checking in the IPv6 routing lookups. Based on work from: David Wilder Jason Gunthorpe Signed-off-by: Sean Hefty [ Fix up cma_check_linklocal() for !IPV6 case. - Roland ] Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 38a7184..abbb069 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -176,34 +176,6 @@ static void queue_req(struct addr_req *req) mutex_unlock(&lock); } -static void addr_send_arp(struct sockaddr *dst_in) -{ - struct rtable *rt; - struct flowi fl; - - memset(&fl, 0, sizeof fl); - - switch (dst_in->sa_family) { -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - case AF_INET6: - { - struct dst_entry *dst; - - fl.nl_u.ip6_u.daddr = - ((struct sockaddr_in6 *) dst_in)->sin6_addr; - - dst = ip6_route_output(&init_net, NULL, &fl); - if (!dst) - return; - - neigh_event_send(dst->neighbour, NULL); - dst_release(dst); - break; - } -#endif - } -} - static int addr4_resolve(struct sockaddr_in *src_in, struct sockaddr_in *dst_in, struct rdma_dev_addr *addr) @@ -259,39 +231,63 @@ out: } #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -static int addr6_resolve_remote(struct sockaddr_in6 *src_in, - struct sockaddr_in6 *dst_in, - struct rdma_dev_addr *addr) +static int addr6_resolve(struct sockaddr_in6 *src_in, + struct sockaddr_in6 *dst_in, + struct rdma_dev_addr *addr) { struct flowi fl; struct neighbour *neigh; struct dst_entry *dst; - int ret = -ENODATA; + int ret; memset(&fl, 0, sizeof fl); - fl.nl_u.ip6_u.daddr = dst_in->sin6_addr; - fl.nl_u.ip6_u.saddr = src_in->sin6_addr; + ipv6_addr_copy(&fl.fl6_dst, &dst_in->sin6_addr); + ipv6_addr_copy(&fl.fl6_src, &src_in->sin6_addr); fl.oif = addr->bound_dev_if; dst = ip6_route_output(&init_net, NULL, &fl); - if (!dst) - return ret; + if ((ret = dst->error)) + goto put; + + if (ipv6_addr_any(&fl.fl6_src)) { + ret = ipv6_dev_get_saddr(&init_net, ip6_dst_idev(dst)->dev, + &fl.fl6_dst, 0, &fl.fl6_src); + if (ret) + goto put; + src_in->sin6_family = AF_INET6; + ipv6_addr_copy(&src_in->sin6_addr, &fl.fl6_src); + } + + if (dst->dev->flags & IFF_LOOPBACK) { + ret = rdma_translate_ip((struct sockaddr *) dst_in, addr); + if (!ret) + memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN); + goto put; + } + + /* If the device does ARP internally, return 'done' */ if (dst->dev->flags & IFF_NOARP) { ret = rdma_copy_addr(addr, dst->dev, NULL); - } else { - neigh = dst->neighbour; - if (neigh && (neigh->nud_state & NUD_VALID)) - ret = rdma_copy_addr(addr, neigh->dev, neigh->ha); + goto put; } + neigh = dst->neighbour; + if (!neigh || !(neigh->nud_state & NUD_VALID)) { + neigh_event_send(dst->neighbour, NULL); + ret = -ENODATA; + goto put; + } + + ret = rdma_copy_addr(addr, dst->dev, neigh->ha); +put: dst_release(dst); return ret; } #else -static int addr6_resolve_remote(struct sockaddr_in6 *src_in, - struct sockaddr_in6 *dst_in, - struct rdma_dev_addr *addr) +static int addr6_resolve(struct sockaddr_in6 *src_in, + struct sockaddr_in6 *dst_in, + struct rdma_dev_addr *addr) { return -EADDRNOTAVAIL; } @@ -305,7 +301,7 @@ static int addr_resolve(struct sockaddr *src_in, return addr4_resolve((struct sockaddr_in *) src_in, (struct sockaddr_in *) dst_in, addr); } else - return addr6_resolve_remote((struct sockaddr_in6 *) src_in, + return addr6_resolve((struct sockaddr_in6 *) src_in, (struct sockaddr_in6 *) dst_in, addr); } @@ -346,60 +342,6 @@ static void process_req(struct work_struct *work) } } -static int addr_resolve_local(struct sockaddr *src_in, - struct sockaddr *dst_in, - struct rdma_dev_addr *addr) -{ - struct net_device *dev; - int ret; - - switch (dst_in->sa_family) { -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - case AF_INET6: - { - struct in6_addr *a; - - read_lock(&dev_base_lock); - for_each_netdev(&init_net, dev) - if (ipv6_chk_addr(&init_net, - &((struct sockaddr_in6 *) dst_in)->sin6_addr, - dev, 1)) - break; - - if (!dev) { - read_unlock(&dev_base_lock); - return -EADDRNOTAVAIL; - } - - a = &((struct sockaddr_in6 *) src_in)->sin6_addr; - - if (ipv6_addr_any(a)) { - src_in->sa_family = dst_in->sa_family; - ((struct sockaddr_in6 *) src_in)->sin6_addr = - ((struct sockaddr_in6 *) dst_in)->sin6_addr; - ret = rdma_copy_addr(addr, dev, dev->dev_addr); - } else if (ipv6_addr_loopback(a)) { - ret = rdma_translate_ip(dst_in, addr); - if (!ret) - memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN); - } else { - ret = rdma_translate_ip(src_in, addr); - if (!ret) - memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN); - } - read_unlock(&dev_base_lock); - break; - } -#endif - - default: - ret = -EADDRNOTAVAIL; - break; - } - - return ret; -} - int rdma_resolve_ip(struct rdma_addr_client *client, struct sockaddr *src_addr, struct sockaddr *dst_addr, struct rdma_dev_addr *addr, int timeout_ms, @@ -436,10 +378,7 @@ int rdma_resolve_ip(struct rdma_addr_client *client, req->client = client; atomic_inc(&client->refcount); - req->status = addr_resolve_local(src_in, dst_in, addr); - if (req->status == -EADDRNOTAVAIL) - req->status = addr_resolve(src_in, dst_in, addr); - + req->status = addr_resolve(src_in, dst_in, addr); switch (req->status) { case 0: req->timeout = jiffies; @@ -448,7 +387,6 @@ int rdma_resolve_ip(struct rdma_addr_client *client, case -ENODATA: req->timeout = msecs_to_jiffies(timeout_ms) + jiffies; queue_req(req); - addr_send_arp(dst_in); break; default: ret = req->status; diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 38867a4..fbdd731 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -1472,15 +1472,6 @@ static void cma_listen_on_all(struct rdma_id_private *id_priv) mutex_unlock(&lock); } -static int cma_bind_any(struct rdma_cm_id *id, sa_family_t af) -{ - struct sockaddr_storage addr_in; - - memset(&addr_in, 0, sizeof addr_in); - addr_in.ss_family = af; - return rdma_bind_addr(id, (struct sockaddr *) &addr_in); -} - int rdma_listen(struct rdma_cm_id *id, int backlog) { struct rdma_id_private *id_priv; @@ -1488,7 +1479,8 @@ int rdma_listen(struct rdma_cm_id *id, int backlog) id_priv = container_of(id, struct rdma_id_private, id); if (id_priv->state == CMA_IDLE) { - ret = cma_bind_any(id, AF_INET); + ((struct sockaddr *) &id->route.addr.src_addr)->sa_family = AF_INET; + ret = rdma_bind_addr(id, (struct sockaddr *) &id->route.addr.src_addr); if (ret) return ret; } @@ -1885,10 +1877,14 @@ err: static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, struct sockaddr *dst_addr) { - if (src_addr && src_addr->sa_family) - return rdma_bind_addr(id, src_addr); - else - return cma_bind_any(id, dst_addr->sa_family); + if (!src_addr || !src_addr->sa_family) { + src_addr = (struct sockaddr *) &id->route.addr.src_addr; + if ((src_addr->sa_family = dst_addr->sa_family) == AF_INET6) { + ((struct sockaddr_in6 *) src_addr)->sin6_scope_id = + ((struct sockaddr_in6 *) dst_addr)->sin6_scope_id; + } + } + return rdma_bind_addr(id, src_addr); } int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, @@ -2084,6 +2080,25 @@ static int cma_get_port(struct rdma_id_private *id_priv) return ret; } +static int cma_check_linklocal(struct rdma_dev_addr *dev_addr, + struct sockaddr *addr) +{ +#if defined(CONFIG_IPv6) || defined(CONFIG_IPV6_MODULE) + struct sockaddr_in6 *sin6; + + if (addr->sa_family != AF_INET6) + return 0; + + sin6 = (struct sockaddr_in6 *) addr; + if ((ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) && + !sin6->sin6_scope_id) + return -EINVAL; + + dev_addr->bound_dev_if = sin6->sin6_scope_id; +#endif + return 0; +} + int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) { struct rdma_id_private *id_priv; @@ -2096,6 +2111,10 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) if (!cma_comp_exch(id_priv, CMA_IDLE, CMA_ADDR_BOUND)) return -EINVAL; + ret = cma_check_linklocal(&id->route.addr.dev_addr, addr); + if (ret) + goto err1; + if (cma_loopback_addr(addr)) { ret = cma_bind_loopback(id_priv); } else if (!cma_zero_addr(addr)) { -- cgit v0.10.2 From 61f135b92f4758bc4d4767cd0a5d2da954e27f14 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 19 Nov 2009 19:49:17 +0100 Subject: Add COH 901 318 DMA block driver v5 This patch adds support for the ST-Ericsson COH 901 318 DMA block, found in the U300 series platforms. It registers a DMA slave for device I/O and also a memcpy slave for memcpy. Signed-off-by: Linus Walleij Acked-by: Maciej Sosnowski Signed-off-by: Dan Williams diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h new file mode 100644 index 0000000..f4cfee9 --- /dev/null +++ b/arch/arm/mach-u300/include/mach/coh901318.h @@ -0,0 +1,281 @@ +/* + * + * include/linux/coh901318.h + * + * + * Copyright (C) 2007-2009 ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + * DMA driver for COH 901 318 + * Author: Per Friden + */ + +#ifndef COH901318_H +#define COH901318_H + +#include +#include + +#define MAX_DMA_PACKET_SIZE_SHIFT 11 +#define MAX_DMA_PACKET_SIZE (1 << MAX_DMA_PACKET_SIZE_SHIFT) + +/** + * struct coh901318_lli - linked list item for DMAC + * @control: control settings for DMAC + * @src_addr: transfer source address + * @dst_addr: transfer destination address + * @link_addr: physical address to next lli + * @virt_link_addr: virtual addres of next lli (only used by pool_free) + * @phy_this: physical address of current lli (only used by pool_free) + */ +struct coh901318_lli { + u32 control; + dma_addr_t src_addr; + dma_addr_t dst_addr; + dma_addr_t link_addr; + + void *virt_link_addr; + dma_addr_t phy_this; +}; +/** + * struct coh901318_params - parameters for DMAC configuration + * @config: DMA config register + * @ctrl_lli_last: DMA control register for the last lli in the list + * @ctrl_lli: DMA control register for an lli + * @ctrl_lli_chained: DMA control register for a chained lli + */ +struct coh901318_params { + u32 config; + u32 ctrl_lli_last; + u32 ctrl_lli; + u32 ctrl_lli_chained; +}; +/** + * struct coh_dma_channel - dma channel base + * @name: ascii name of dma channel + * @number: channel id number + * @desc_nbr_max: number of preallocated descriptortors + * @priority_high: prio of channel, 0 low otherwise high. + * @param: configuration parameters + * @dev_addr: physical address of periphal connected to channel + */ +struct coh_dma_channel { + const char name[32]; + const int number; + const int desc_nbr_max; + const int priority_high; + const struct coh901318_params param; + const dma_addr_t dev_addr; +}; + +/** + * dma_access_memory_state_t - register dma for memory access + * + * @dev: The dma device + * @active: 1 means dma intends to access memory + * 0 means dma wont access memory + */ +typedef void (*dma_access_memory_state_t)(struct device *dev, + bool active); + +/** + * struct powersave - DMA power save structure + * @lock: lock protecting data in this struct + * @started_channels: bit mask indicating active dma channels + */ +struct powersave { + spinlock_t lock; + u64 started_channels; +}; +/** + * struct coh901318_platform - platform arch structure + * @chans_slave: specifying dma slave channels + * @chans_memcpy: specifying dma memcpy channels + * @access_memory_state: requesting DMA memeory access (on / off) + * @chan_conf: dma channel configurations + * @max_channels: max number of dma chanenls + */ +struct coh901318_platform { + const int *chans_slave; + const int *chans_memcpy; + const dma_access_memory_state_t access_memory_state; + const struct coh_dma_channel *chan_conf; + const int max_channels; +}; + +/** + * coh901318_get_bytes_left() - Get number of bytes left on a current transfer + * @chan: dma channel handle + * return number of bytes left, or negative on error + */ +u32 coh901318_get_bytes_left(struct dma_chan *chan); + +/** + * coh901318_stop() - Stops dma transfer + * @chan: dma channel handle + * return 0 on success otherwise negative value + */ +void coh901318_stop(struct dma_chan *chan); + +/** + * coh901318_continue() - Resumes a stopped dma transfer + * @chan: dma channel handle + * return 0 on success otherwise negative value + */ +void coh901318_continue(struct dma_chan *chan); + +/** + * coh901318_filter_id() - DMA channel filter function + * @chan: dma channel handle + * @chan_id: id of dma channel to be filter out + * + * In dma_request_channel() it specifies what channel id to be requested + */ +bool coh901318_filter_id(struct dma_chan *chan, void *chan_id); + +/* + * DMA Controller - this access the static mappings of the coh901318 dma. + * + */ + +#define COH901318_MOD32_MASK (0x1F) +#define COH901318_WORD_MASK (0xFFFFFFFF) +/* INT_STATUS - Interrupt Status Registers 32bit (R/-) */ +#define COH901318_INT_STATUS1 (0x0000) +#define COH901318_INT_STATUS2 (0x0004) +/* TC_INT_STATUS - Terminal Count Interrupt Status Registers 32bit (R/-) */ +#define COH901318_TC_INT_STATUS1 (0x0008) +#define COH901318_TC_INT_STATUS2 (0x000C) +/* TC_INT_CLEAR - Terminal Count Interrupt Clear Registers 32bit (-/W) */ +#define COH901318_TC_INT_CLEAR1 (0x0010) +#define COH901318_TC_INT_CLEAR2 (0x0014) +/* RAW_TC_INT_STATUS - Raw Term Count Interrupt Status Registers 32bit (R/-) */ +#define COH901318_RAW_TC_INT_STATUS1 (0x0018) +#define COH901318_RAW_TC_INT_STATUS2 (0x001C) +/* BE_INT_STATUS - Bus Error Interrupt Status Registers 32bit (R/-) */ +#define COH901318_BE_INT_STATUS1 (0x0020) +#define COH901318_BE_INT_STATUS2 (0x0024) +/* BE_INT_CLEAR - Bus Error Interrupt Clear Registers 32bit (-/W) */ +#define COH901318_BE_INT_CLEAR1 (0x0028) +#define COH901318_BE_INT_CLEAR2 (0x002C) +/* RAW_BE_INT_STATUS - Raw Term Count Interrupt Status Registers 32bit (R/-) */ +#define COH901318_RAW_BE_INT_STATUS1 (0x0030) +#define COH901318_RAW_BE_INT_STATUS2 (0x0034) + +/* + * CX_CFG - Channel Configuration Registers 32bit (R/W) + */ +#define COH901318_CX_CFG (0x0100) +#define COH901318_CX_CFG_SPACING (0x04) +/* Channel enable activates tha dma job */ +#define COH901318_CX_CFG_CH_ENABLE (0x00000001) +#define COH901318_CX_CFG_CH_DISABLE (0x00000000) +/* Request Mode */ +#define COH901318_CX_CFG_RM_MASK (0x00000006) +#define COH901318_CX_CFG_RM_MEMORY_TO_MEMORY (0x0 << 1) +#define COH901318_CX_CFG_RM_PRIMARY_TO_MEMORY (0x1 << 1) +#define COH901318_CX_CFG_RM_MEMORY_TO_PRIMARY (0x1 << 1) +#define COH901318_CX_CFG_RM_PRIMARY_TO_SECONDARY (0x3 << 1) +#define COH901318_CX_CFG_RM_SECONDARY_TO_PRIMARY (0x3 << 1) +/* Linked channel request field. RM must == 11 */ +#define COH901318_CX_CFG_LCRF_SHIFT 3 +#define COH901318_CX_CFG_LCRF_MASK (0x000001F8) +#define COH901318_CX_CFG_LCR_DISABLE (0x00000000) +/* Terminal Counter Interrupt Request Mask */ +#define COH901318_CX_CFG_TC_IRQ_ENABLE (0x00000200) +#define COH901318_CX_CFG_TC_IRQ_DISABLE (0x00000000) +/* Bus Error interrupt Mask */ +#define COH901318_CX_CFG_BE_IRQ_ENABLE (0x00000400) +#define COH901318_CX_CFG_BE_IRQ_DISABLE (0x00000000) + +/* + * CX_STAT - Channel Status Registers 32bit (R/-) + */ +#define COH901318_CX_STAT (0x0200) +#define COH901318_CX_STAT_SPACING (0x04) +#define COH901318_CX_STAT_RBE_IRQ_IND (0x00000008) +#define COH901318_CX_STAT_RTC_IRQ_IND (0x00000004) +#define COH901318_CX_STAT_ACTIVE (0x00000002) +#define COH901318_CX_STAT_ENABLED (0x00000001) + +/* + * CX_CTRL - Channel Control Registers 32bit (R/W) + */ +#define COH901318_CX_CTRL (0x0400) +#define COH901318_CX_CTRL_SPACING (0x10) +/* Transfer Count Enable */ +#define COH901318_CX_CTRL_TC_ENABLE (0x00001000) +#define COH901318_CX_CTRL_TC_DISABLE (0x00000000) +/* Transfer Count Value 0 - 4095 */ +#define COH901318_CX_CTRL_TC_VALUE_MASK (0x00000FFF) +/* Burst count */ +#define COH901318_CX_CTRL_BURST_COUNT_MASK (0x0000E000) +#define COH901318_CX_CTRL_BURST_COUNT_64_BYTES (0x7 << 13) +#define COH901318_CX_CTRL_BURST_COUNT_48_BYTES (0x6 << 13) +#define COH901318_CX_CTRL_BURST_COUNT_32_BYTES (0x5 << 13) +#define COH901318_CX_CTRL_BURST_COUNT_16_BYTES (0x4 << 13) +#define COH901318_CX_CTRL_BURST_COUNT_8_BYTES (0x3 << 13) +#define COH901318_CX_CTRL_BURST_COUNT_4_BYTES (0x2 << 13) +#define COH901318_CX_CTRL_BURST_COUNT_2_BYTES (0x1 << 13) +#define COH901318_CX_CTRL_BURST_COUNT_1_BYTE (0x0 << 13) +/* Source bus size */ +#define COH901318_CX_CTRL_SRC_BUS_SIZE_MASK (0x00030000) +#define COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS (0x2 << 16) +#define COH901318_CX_CTRL_SRC_BUS_SIZE_16_BITS (0x1 << 16) +#define COH901318_CX_CTRL_SRC_BUS_SIZE_8_BITS (0x0 << 16) +/* Source address increment */ +#define COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE (0x00040000) +#define COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE (0x00000000) +/* Destination Bus Size */ +#define COH901318_CX_CTRL_DST_BUS_SIZE_MASK (0x00180000) +#define COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS (0x2 << 19) +#define COH901318_CX_CTRL_DST_BUS_SIZE_16_BITS (0x1 << 19) +#define COH901318_CX_CTRL_DST_BUS_SIZE_8_BITS (0x0 << 19) +/* Destination address increment */ +#define COH901318_CX_CTRL_DST_ADDR_INC_ENABLE (0x00200000) +#define COH901318_CX_CTRL_DST_ADDR_INC_DISABLE (0x00000000) +/* Master Mode (Master2 is only connected to MSL) */ +#define COH901318_CX_CTRL_MASTER_MODE_MASK (0x00C00000) +#define COH901318_CX_CTRL_MASTER_MODE_M2R_M1W (0x3 << 22) +#define COH901318_CX_CTRL_MASTER_MODE_M1R_M2W (0x2 << 22) +#define COH901318_CX_CTRL_MASTER_MODE_M2RW (0x1 << 22) +#define COH901318_CX_CTRL_MASTER_MODE_M1RW (0x0 << 22) +/* Terminal Count flag to PER enable */ +#define COH901318_CX_CTRL_TCP_ENABLE (0x01000000) +#define COH901318_CX_CTRL_TCP_DISABLE (0x00000000) +/* Terminal Count flags to CPU enable */ +#define COH901318_CX_CTRL_TC_IRQ_ENABLE (0x02000000) +#define COH901318_CX_CTRL_TC_IRQ_DISABLE (0x00000000) +/* Hand shake to peripheral */ +#define COH901318_CX_CTRL_HSP_ENABLE (0x04000000) +#define COH901318_CX_CTRL_HSP_DISABLE (0x00000000) +#define COH901318_CX_CTRL_HSS_ENABLE (0x08000000) +#define COH901318_CX_CTRL_HSS_DISABLE (0x00000000) +/* DMA mode */ +#define COH901318_CX_CTRL_DDMA_MASK (0x30000000) +#define COH901318_CX_CTRL_DDMA_LEGACY (0x0 << 28) +#define COH901318_CX_CTRL_DDMA_DEMAND_DMA1 (0x1 << 28) +#define COH901318_CX_CTRL_DDMA_DEMAND_DMA2 (0x2 << 28) +/* Primary Request Data Destination */ +#define COH901318_CX_CTRL_PRDD_MASK (0x40000000) +#define COH901318_CX_CTRL_PRDD_DEST (0x1 << 30) +#define COH901318_CX_CTRL_PRDD_SOURCE (0x0 << 30) + +/* + * CX_SRC_ADDR - Channel Source Address Registers 32bit (R/W) + */ +#define COH901318_CX_SRC_ADDR (0x0404) +#define COH901318_CX_SRC_ADDR_SPACING (0x10) + +/* + * CX_DST_ADDR - Channel Destination Address Registers 32bit R/W + */ +#define COH901318_CX_DST_ADDR (0x0408) +#define COH901318_CX_DST_ADDR_SPACING (0x10) + +/* + * CX_LNK_ADDR - Channel Link Address Registers 32bit (R/W) + */ +#define COH901318_CX_LNK_ADDR (0x040C) +#define COH901318_CX_LNK_ADDR_SPACING (0x10) +#define COH901318_CX_LNK_LINK_IMMEDIATE (0x00000001) +#endif /* COH901318_H */ diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 5903a88..24cdd20 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -109,6 +109,13 @@ config SH_DMAE help Enable support for the Renesas SuperH DMA controllers. +config COH901318 + bool "ST-Ericsson COH901318 DMA support" + select DMA_ENGINE + depends on ARCH_U300 + help + Enable support for ST-Ericsson COH 901 318 DMA. + config DMA_ENGINE bool diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index eca71ba..4db768e 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_AT_HDMAC) += at_hdmac.o obj-$(CONFIG_MX3_IPU) += ipu/ obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o obj-$(CONFIG_SH_DMAE) += shdma.o +obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c new file mode 100644 index 0000000..4a99cd9 --- /dev/null +++ b/drivers/dma/coh901318.c @@ -0,0 +1,1325 @@ +/* + * driver/dma/coh901318.c + * + * Copyright (C) 2007-2009 ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + * DMA driver for COH 901 318 + * Author: Per Friden + */ + +#include +#include +#include /* printk() */ +#include /* everything... */ +#include /* kmalloc() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "coh901318_lli.h" + +#define COHC_2_DEV(cohc) (&cohc->chan.dev->device) + +#ifdef VERBOSE_DEBUG +#define COH_DBG(x) ({ if (1) x; 0; }) +#else +#define COH_DBG(x) ({ if (0) x; 0; }) +#endif + +struct coh901318_desc { + struct dma_async_tx_descriptor desc; + struct list_head node; + struct scatterlist *sg; + unsigned int sg_len; + struct coh901318_lli *data; + enum dma_data_direction dir; + int pending_irqs; + unsigned long flags; +}; + +struct coh901318_base { + struct device *dev; + void __iomem *virtbase; + struct coh901318_pool pool; + struct powersave pm; + struct dma_device dma_slave; + struct dma_device dma_memcpy; + struct coh901318_chan *chans; + struct coh901318_platform *platform; +}; + +struct coh901318_chan { + spinlock_t lock; + int allocated; + int completed; + int id; + int stopped; + + struct work_struct free_work; + struct dma_chan chan; + + struct tasklet_struct tasklet; + + struct list_head active; + struct list_head queue; + struct list_head free; + + unsigned long nbr_active_done; + unsigned long busy; + int pending_irqs; + + struct coh901318_base *base; +}; + +static void coh901318_list_print(struct coh901318_chan *cohc, + struct coh901318_lli *lli) +{ + struct coh901318_lli *l; + dma_addr_t addr = virt_to_phys(lli); + int i = 0; + + while (addr) { + l = phys_to_virt(addr); + dev_vdbg(COHC_2_DEV(cohc), "i %d, lli %p, ctrl 0x%x, src 0x%x" + ", dst 0x%x, link 0x%x link_virt 0x%p\n", + i, l, l->control, l->src_addr, l->dst_addr, + l->link_addr, phys_to_virt(l->link_addr)); + i++; + addr = l->link_addr; + } +} + +#ifdef CONFIG_DEBUG_FS + +#define COH901318_DEBUGFS_ASSIGN(x, y) (x = y) + +static struct coh901318_base *debugfs_dma_base; +static struct dentry *dma_dentry; + +static int coh901318_debugfs_open(struct inode *inode, struct file *file) +{ + + file->private_data = inode->i_private; + return 0; +} + +static int coh901318_debugfs_read(struct file *file, char __user *buf, + size_t count, loff_t *f_pos) +{ + u64 started_channels = debugfs_dma_base->pm.started_channels; + int pool_count = debugfs_dma_base->pool.debugfs_pool_counter; + int i; + int ret = 0; + char *dev_buf; + char *tmp; + int dev_size; + + dev_buf = kmalloc(4*1024, GFP_KERNEL); + if (dev_buf == NULL) + goto err_kmalloc; + tmp = dev_buf; + + tmp += sprintf(tmp, "DMA -- enable dma channels\n"); + + for (i = 0; i < debugfs_dma_base->platform->max_channels; i++) + if (started_channels & (1 << i)) + tmp += sprintf(tmp, "channel %d\n", i); + + tmp += sprintf(tmp, "Pool alloc nbr %d\n", pool_count); + dev_size = tmp - dev_buf; + + /* No more to read if offset != 0 */ + if (*f_pos > dev_size) + goto out; + + if (count > dev_size - *f_pos) + count = dev_size - *f_pos; + + if (copy_to_user(buf, dev_buf + *f_pos, count)) + ret = -EINVAL; + ret = count; + *f_pos += count; + + out: + kfree(dev_buf); + return ret; + + err_kmalloc: + return 0; +} + +static const struct file_operations coh901318_debugfs_status_operations = { + .owner = THIS_MODULE, + .open = coh901318_debugfs_open, + .read = coh901318_debugfs_read, +}; + + +static int __init init_coh901318_debugfs(void) +{ + + dma_dentry = debugfs_create_dir("dma", NULL); + + (void) debugfs_create_file("status", + S_IFREG | S_IRUGO, + dma_dentry, NULL, + &coh901318_debugfs_status_operations); + return 0; +} + +static void __exit exit_coh901318_debugfs(void) +{ + debugfs_remove_recursive(dma_dentry); +} + +module_init(init_coh901318_debugfs); +module_exit(exit_coh901318_debugfs); +#else + +#define COH901318_DEBUGFS_ASSIGN(x, y) + +#endif /* CONFIG_DEBUG_FS */ + +static inline struct coh901318_chan *to_coh901318_chan(struct dma_chan *chan) +{ + return container_of(chan, struct coh901318_chan, chan); +} + +static inline dma_addr_t +cohc_dev_addr(struct coh901318_chan *cohc) +{ + return cohc->base->platform->chan_conf[cohc->id].dev_addr; +} + +static inline const struct coh901318_params * +cohc_chan_param(struct coh901318_chan *cohc) +{ + return &cohc->base->platform->chan_conf[cohc->id].param; +} + +static inline const struct coh_dma_channel * +cohc_chan_conf(struct coh901318_chan *cohc) +{ + return &cohc->base->platform->chan_conf[cohc->id]; +} + +static void enable_powersave(struct coh901318_chan *cohc) +{ + unsigned long flags; + struct powersave *pm = &cohc->base->pm; + + spin_lock_irqsave(&pm->lock, flags); + + pm->started_channels &= ~(1ULL << cohc->id); + + if (!pm->started_channels) { + /* DMA no longer intends to access memory */ + cohc->base->platform->access_memory_state(cohc->base->dev, + false); + } + + spin_unlock_irqrestore(&pm->lock, flags); +} +static void disable_powersave(struct coh901318_chan *cohc) +{ + unsigned long flags; + struct powersave *pm = &cohc->base->pm; + + spin_lock_irqsave(&pm->lock, flags); + + if (!pm->started_channels) { + /* DMA intends to access memory */ + cohc->base->platform->access_memory_state(cohc->base->dev, + true); + } + + pm->started_channels |= (1ULL << cohc->id); + + spin_unlock_irqrestore(&pm->lock, flags); +} + +static inline int coh901318_set_ctrl(struct coh901318_chan *cohc, u32 control) +{ + int channel = cohc->id; + void __iomem *virtbase = cohc->base->virtbase; + + writel(control, + virtbase + COH901318_CX_CTRL + + COH901318_CX_CTRL_SPACING * channel); + return 0; +} + +static inline int coh901318_set_conf(struct coh901318_chan *cohc, u32 conf) +{ + int channel = cohc->id; + void __iomem *virtbase = cohc->base->virtbase; + + writel(conf, + virtbase + COH901318_CX_CFG + + COH901318_CX_CFG_SPACING*channel); + return 0; +} + + +static int coh901318_start(struct coh901318_chan *cohc) +{ + u32 val; + int channel = cohc->id; + void __iomem *virtbase = cohc->base->virtbase; + + disable_powersave(cohc); + + val = readl(virtbase + COH901318_CX_CFG + + COH901318_CX_CFG_SPACING * channel); + + /* Enable channel */ + val |= COH901318_CX_CFG_CH_ENABLE; + writel(val, virtbase + COH901318_CX_CFG + + COH901318_CX_CFG_SPACING * channel); + + return 0; +} + +static int coh901318_prep_linked_list(struct coh901318_chan *cohc, + struct coh901318_lli *data) +{ + int channel = cohc->id; + void __iomem *virtbase = cohc->base->virtbase; + + BUG_ON(readl(virtbase + COH901318_CX_STAT + + COH901318_CX_STAT_SPACING*channel) & + COH901318_CX_STAT_ACTIVE); + + writel(data->src_addr, + virtbase + COH901318_CX_SRC_ADDR + + COH901318_CX_SRC_ADDR_SPACING * channel); + + writel(data->dst_addr, virtbase + + COH901318_CX_DST_ADDR + + COH901318_CX_DST_ADDR_SPACING * channel); + + writel(data->link_addr, virtbase + COH901318_CX_LNK_ADDR + + COH901318_CX_LNK_ADDR_SPACING * channel); + + writel(data->control, virtbase + COH901318_CX_CTRL + + COH901318_CX_CTRL_SPACING * channel); + + return 0; +} +static dma_cookie_t +coh901318_assign_cookie(struct coh901318_chan *cohc, + struct coh901318_desc *cohd) +{ + dma_cookie_t cookie = cohc->chan.cookie; + + if (++cookie < 0) + cookie = 1; + + cohc->chan.cookie = cookie; + cohd->desc.cookie = cookie; + + return cookie; +} + +static struct coh901318_desc * +coh901318_desc_get(struct coh901318_chan *cohc) +{ + struct coh901318_desc *desc; + + if (list_empty(&cohc->free)) { + /* alloc new desc because we're out of used ones + * TODO: alloc a pile of descs instead of just one, + * avoid many small allocations. + */ + desc = kmalloc(sizeof(struct coh901318_desc), GFP_NOWAIT); + if (desc == NULL) + goto out; + INIT_LIST_HEAD(&desc->node); + } else { + /* Reuse an old desc. */ + desc = list_first_entry(&cohc->free, + struct coh901318_desc, + node); + list_del(&desc->node); + } + + out: + return desc; +} + +static void +coh901318_desc_free(struct coh901318_chan *cohc, struct coh901318_desc *cohd) +{ + list_add_tail(&cohd->node, &cohc->free); +} + +/* call with irq lock held */ +static void +coh901318_desc_submit(struct coh901318_chan *cohc, struct coh901318_desc *desc) +{ + list_add_tail(&desc->node, &cohc->active); + + BUG_ON(cohc->pending_irqs != 0); + + cohc->pending_irqs = desc->pending_irqs; +} + +static struct coh901318_desc * +coh901318_first_active_get(struct coh901318_chan *cohc) +{ + struct coh901318_desc *d; + + if (list_empty(&cohc->active)) + return NULL; + + d = list_first_entry(&cohc->active, + struct coh901318_desc, + node); + return d; +} + +static void +coh901318_desc_remove(struct coh901318_desc *cohd) +{ + list_del(&cohd->node); +} + +static void +coh901318_desc_queue(struct coh901318_chan *cohc, struct coh901318_desc *desc) +{ + list_add_tail(&desc->node, &cohc->queue); +} + +static struct coh901318_desc * +coh901318_first_queued(struct coh901318_chan *cohc) +{ + struct coh901318_desc *d; + + if (list_empty(&cohc->queue)) + return NULL; + + d = list_first_entry(&cohc->queue, + struct coh901318_desc, + node); + return d; +} + +/* + * DMA start/stop controls + */ +u32 coh901318_get_bytes_left(struct dma_chan *chan) +{ + unsigned long flags; + u32 ret; + struct coh901318_chan *cohc = to_coh901318_chan(chan); + + spin_lock_irqsave(&cohc->lock, flags); + + /* Read transfer count value */ + ret = readl(cohc->base->virtbase + + COH901318_CX_CTRL+COH901318_CX_CTRL_SPACING * + cohc->id) & COH901318_CX_CTRL_TC_VALUE_MASK; + + spin_unlock_irqrestore(&cohc->lock, flags); + + return ret; +} +EXPORT_SYMBOL(coh901318_get_bytes_left); + + +/* Stops a transfer without losing data. Enables power save. + Use this function in conjunction with coh901318_continue(..) +*/ +void coh901318_stop(struct dma_chan *chan) +{ + u32 val; + unsigned long flags; + struct coh901318_chan *cohc = to_coh901318_chan(chan); + int channel = cohc->id; + void __iomem *virtbase = cohc->base->virtbase; + + spin_lock_irqsave(&cohc->lock, flags); + + /* Disable channel in HW */ + val = readl(virtbase + COH901318_CX_CFG + + COH901318_CX_CFG_SPACING * channel); + + /* Stopping infinit transfer */ + if ((val & COH901318_CX_CTRL_TC_ENABLE) == 0 && + (val & COH901318_CX_CFG_CH_ENABLE)) + cohc->stopped = 1; + + + val &= ~COH901318_CX_CFG_CH_ENABLE; + /* Enable twice, HW bug work around */ + writel(val, virtbase + COH901318_CX_CFG + + COH901318_CX_CFG_SPACING * channel); + writel(val, virtbase + COH901318_CX_CFG + + COH901318_CX_CFG_SPACING * channel); + + /* Spin-wait for it to actually go inactive */ + while (readl(virtbase + COH901318_CX_STAT+COH901318_CX_STAT_SPACING * + channel) & COH901318_CX_STAT_ACTIVE) + cpu_relax(); + + /* Check if we stopped an active job */ + if ((readl(virtbase + COH901318_CX_CTRL+COH901318_CX_CTRL_SPACING * + channel) & COH901318_CX_CTRL_TC_VALUE_MASK) > 0) + cohc->stopped = 1; + + enable_powersave(cohc); + + spin_unlock_irqrestore(&cohc->lock, flags); +} +EXPORT_SYMBOL(coh901318_stop); + +/* Continues a transfer that has been stopped via 300_dma_stop(..). + Power save is handled. +*/ +void coh901318_continue(struct dma_chan *chan) +{ + u32 val; + unsigned long flags; + struct coh901318_chan *cohc = to_coh901318_chan(chan); + int channel = cohc->id; + + spin_lock_irqsave(&cohc->lock, flags); + + disable_powersave(cohc); + + if (cohc->stopped) { + /* Enable channel in HW */ + val = readl(cohc->base->virtbase + COH901318_CX_CFG + + COH901318_CX_CFG_SPACING * channel); + + val |= COH901318_CX_CFG_CH_ENABLE; + + writel(val, cohc->base->virtbase + COH901318_CX_CFG + + COH901318_CX_CFG_SPACING*channel); + + cohc->stopped = 0; + } + + spin_unlock_irqrestore(&cohc->lock, flags); +} +EXPORT_SYMBOL(coh901318_continue); + +bool coh901318_filter_id(struct dma_chan *chan, void *chan_id) +{ + unsigned int ch_nr = (unsigned int) chan_id; + + if (ch_nr == to_coh901318_chan(chan)->id) + return true; + + return false; +} +EXPORT_SYMBOL(coh901318_filter_id); + +/* + * DMA channel allocation + */ +static int coh901318_config(struct coh901318_chan *cohc, + struct coh901318_params *param) +{ + unsigned long flags; + const struct coh901318_params *p; + int channel = cohc->id; + void __iomem *virtbase = cohc->base->virtbase; + + spin_lock_irqsave(&cohc->lock, flags); + + if (param) + p = param; + else + p = &cohc->base->platform->chan_conf[channel].param; + + /* Clear any pending BE or TC interrupt */ + if (channel < 32) { + writel(1 << channel, virtbase + COH901318_BE_INT_CLEAR1); + writel(1 << channel, virtbase + COH901318_TC_INT_CLEAR1); + } else { + writel(1 << (channel - 32), virtbase + + COH901318_BE_INT_CLEAR2); + writel(1 << (channel - 32), virtbase + + COH901318_TC_INT_CLEAR2); + } + + coh901318_set_conf(cohc, p->config); + coh901318_set_ctrl(cohc, p->ctrl_lli_last); + + spin_unlock_irqrestore(&cohc->lock, flags); + + return 0; +} + +/* must lock when calling this function + * start queued jobs, if any + * TODO: start all queued jobs in one go + * + * Returns descriptor if queued job is started otherwise NULL. + * If the queue is empty NULL is returned. + */ +static struct coh901318_desc *coh901318_queue_start(struct coh901318_chan *cohc) +{ + struct coh901318_desc *cohd_que; + + /* start queued jobs, if any + * TODO: transmit all queued jobs in one go + */ + cohd_que = coh901318_first_queued(cohc); + + if (cohd_que != NULL) { + /* Remove from queue */ + coh901318_desc_remove(cohd_que); + /* initiate DMA job */ + cohc->busy = 1; + + coh901318_desc_submit(cohc, cohd_que); + + coh901318_prep_linked_list(cohc, cohd_que->data); + + /* start dma job */ + coh901318_start(cohc); + + } + + return cohd_que; +} + +static void dma_tasklet(unsigned long data) +{ + struct coh901318_chan *cohc = (struct coh901318_chan *) data; + struct coh901318_desc *cohd_fin; + unsigned long flags; + dma_async_tx_callback callback; + void *callback_param; + + spin_lock_irqsave(&cohc->lock, flags); + + /* get first active entry from list */ + cohd_fin = coh901318_first_active_get(cohc); + + BUG_ON(cohd_fin->pending_irqs == 0); + + if (cohd_fin == NULL) + goto err; + + cohd_fin->pending_irqs--; + cohc->completed = cohd_fin->desc.cookie; + + BUG_ON(cohc->nbr_active_done && cohd_fin == NULL); + + if (cohc->nbr_active_done == 0) + return; + + if (!cohd_fin->pending_irqs) { + /* release the lli allocation*/ + coh901318_lli_free(&cohc->base->pool, &cohd_fin->data); + } + + dev_vdbg(COHC_2_DEV(cohc), "[%s] chan_id %d pending_irqs %d" + " nbr_active_done %ld\n", __func__, + cohc->id, cohc->pending_irqs, cohc->nbr_active_done); + + /* callback to client */ + callback = cohd_fin->desc.callback; + callback_param = cohd_fin->desc.callback_param; + + if (!cohd_fin->pending_irqs) { + coh901318_desc_remove(cohd_fin); + + /* return desc to free-list */ + coh901318_desc_free(cohc, cohd_fin); + } + + if (cohc->nbr_active_done) + cohc->nbr_active_done--; + + if (cohc->nbr_active_done) { + if (cohc_chan_conf(cohc)->priority_high) + tasklet_hi_schedule(&cohc->tasklet); + else + tasklet_schedule(&cohc->tasklet); + } + spin_unlock_irqrestore(&cohc->lock, flags); + + if (callback) + callback(callback_param); + + return; + + err: + spin_unlock_irqrestore(&cohc->lock, flags); + dev_err(COHC_2_DEV(cohc), "[%s] No active dma desc\n", __func__); +} + + +/* called from interrupt context */ +static void dma_tc_handle(struct coh901318_chan *cohc) +{ + BUG_ON(!cohc->allocated && (list_empty(&cohc->active) || + list_empty(&cohc->queue))); + + if (!cohc->allocated) + return; + + BUG_ON(cohc->pending_irqs == 0); + + cohc->pending_irqs--; + cohc->nbr_active_done++; + + if (cohc->pending_irqs == 0 && coh901318_queue_start(cohc) == NULL) + cohc->busy = 0; + + BUG_ON(list_empty(&cohc->active)); + + if (cohc_chan_conf(cohc)->priority_high) + tasklet_hi_schedule(&cohc->tasklet); + else + tasklet_schedule(&cohc->tasklet); +} + + +static irqreturn_t dma_irq_handler(int irq, void *dev_id) +{ + u32 status1; + u32 status2; + int i; + int ch; + struct coh901318_base *base = dev_id; + struct coh901318_chan *cohc; + void __iomem *virtbase = base->virtbase; + + status1 = readl(virtbase + COH901318_INT_STATUS1); + status2 = readl(virtbase + COH901318_INT_STATUS2); + + if (unlikely(status1 == 0 && status2 == 0)) { + dev_warn(base->dev, "spurious DMA IRQ from no channel!\n"); + return IRQ_HANDLED; + } + + /* TODO: consider handle IRQ in tasklet here to + * minimize interrupt latency */ + + /* Check the first 32 DMA channels for IRQ */ + while (status1) { + /* Find first bit set, return as a number. */ + i = ffs(status1) - 1; + ch = i; + + cohc = &base->chans[ch]; + spin_lock(&cohc->lock); + + /* Mask off this bit */ + status1 &= ~(1 << i); + /* Check the individual channel bits */ + if (test_bit(i, virtbase + COH901318_BE_INT_STATUS1)) { + dev_crit(COHC_2_DEV(cohc), + "DMA bus error on channel %d!\n", ch); + BUG_ON(1); + /* Clear BE interrupt */ + __set_bit(i, virtbase + COH901318_BE_INT_CLEAR1); + } else { + /* Caused by TC, really? */ + if (unlikely(!test_bit(i, virtbase + + COH901318_TC_INT_STATUS1))) { + dev_warn(COHC_2_DEV(cohc), + "ignoring interrupt not caused by terminal count on channel %d\n", ch); + /* Clear TC interrupt */ + BUG_ON(1); + __set_bit(i, virtbase + COH901318_TC_INT_CLEAR1); + } else { + /* Enable powersave if transfer has finished */ + if (!(readl(virtbase + COH901318_CX_STAT + + COH901318_CX_STAT_SPACING*ch) & + COH901318_CX_STAT_ENABLED)) { + enable_powersave(cohc); + } + + /* Must clear TC interrupt before calling + * dma_tc_handle + * in case tc_handle initate a new dma job + */ + __set_bit(i, virtbase + COH901318_TC_INT_CLEAR1); + + dma_tc_handle(cohc); + } + } + spin_unlock(&cohc->lock); + } + + /* Check the remaining 32 DMA channels for IRQ */ + while (status2) { + /* Find first bit set, return as a number. */ + i = ffs(status2) - 1; + ch = i + 32; + cohc = &base->chans[ch]; + spin_lock(&cohc->lock); + + /* Mask off this bit */ + status2 &= ~(1 << i); + /* Check the individual channel bits */ + if (test_bit(i, virtbase + COH901318_BE_INT_STATUS2)) { + dev_crit(COHC_2_DEV(cohc), + "DMA bus error on channel %d!\n", ch); + /* Clear BE interrupt */ + BUG_ON(1); + __set_bit(i, virtbase + COH901318_BE_INT_CLEAR2); + } else { + /* Caused by TC, really? */ + if (unlikely(!test_bit(i, virtbase + + COH901318_TC_INT_STATUS2))) { + dev_warn(COHC_2_DEV(cohc), + "ignoring interrupt not caused by terminal count on channel %d\n", ch); + /* Clear TC interrupt */ + __set_bit(i, virtbase + COH901318_TC_INT_CLEAR2); + BUG_ON(1); + } else { + /* Enable powersave if transfer has finished */ + if (!(readl(virtbase + COH901318_CX_STAT + + COH901318_CX_STAT_SPACING*ch) & + COH901318_CX_STAT_ENABLED)) { + enable_powersave(cohc); + } + /* Must clear TC interrupt before calling + * dma_tc_handle + * in case tc_handle initate a new dma job + */ + __set_bit(i, virtbase + COH901318_TC_INT_CLEAR2); + + dma_tc_handle(cohc); + } + } + spin_unlock(&cohc->lock); + } + + return IRQ_HANDLED; +} + +static int coh901318_alloc_chan_resources(struct dma_chan *chan) +{ + struct coh901318_chan *cohc = to_coh901318_chan(chan); + + dev_vdbg(COHC_2_DEV(cohc), "[%s] DMA channel %d\n", + __func__, cohc->id); + + if (chan->client_count > 1) + return -EBUSY; + + coh901318_config(cohc, NULL); + + cohc->allocated = 1; + cohc->completed = chan->cookie = 1; + + return 1; +} + +static void +coh901318_free_chan_resources(struct dma_chan *chan) +{ + struct coh901318_chan *cohc = to_coh901318_chan(chan); + int channel = cohc->id; + unsigned long flags; + + spin_lock_irqsave(&cohc->lock, flags); + + /* Disable HW */ + writel(0x00000000U, cohc->base->virtbase + COH901318_CX_CFG + + COH901318_CX_CFG_SPACING*channel); + writel(0x00000000U, cohc->base->virtbase + COH901318_CX_CTRL + + COH901318_CX_CTRL_SPACING*channel); + + cohc->allocated = 0; + + spin_unlock_irqrestore(&cohc->lock, flags); + + chan->device->device_terminate_all(chan); +} + + +static dma_cookie_t +coh901318_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct coh901318_desc *cohd = container_of(tx, struct coh901318_desc, + desc); + struct coh901318_chan *cohc = to_coh901318_chan(tx->chan); + unsigned long flags; + + spin_lock_irqsave(&cohc->lock, flags); + + tx->cookie = coh901318_assign_cookie(cohc, cohd); + + coh901318_desc_queue(cohc, cohd); + + spin_unlock_irqrestore(&cohc->lock, flags); + + return tx->cookie; +} + +static struct dma_async_tx_descriptor * +coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, + size_t size, unsigned long flags) +{ + struct coh901318_lli *data; + struct coh901318_desc *cohd; + unsigned long flg; + struct coh901318_chan *cohc = to_coh901318_chan(chan); + int lli_len; + u32 ctrl_last = cohc_chan_param(cohc)->ctrl_lli_last; + + spin_lock_irqsave(&cohc->lock, flg); + + dev_vdbg(COHC_2_DEV(cohc), + "[%s] channel %d src 0x%x dest 0x%x size %d\n", + __func__, cohc->id, src, dest, size); + + if (flags & DMA_PREP_INTERRUPT) + /* Trigger interrupt after last lli */ + ctrl_last |= COH901318_CX_CTRL_TC_IRQ_ENABLE; + + lli_len = size >> MAX_DMA_PACKET_SIZE_SHIFT; + if ((lli_len << MAX_DMA_PACKET_SIZE_SHIFT) < size) + lli_len++; + + data = coh901318_lli_alloc(&cohc->base->pool, lli_len); + + if (data == NULL) + goto err; + + cohd = coh901318_desc_get(cohc); + cohd->sg = NULL; + cohd->sg_len = 0; + cohd->data = data; + + cohd->pending_irqs = + coh901318_lli_fill_memcpy( + &cohc->base->pool, data, src, size, dest, + cohc_chan_param(cohc)->ctrl_lli_chained, + ctrl_last); + cohd->flags = flags; + + COH_DBG(coh901318_list_print(cohc, data)); + + dma_async_tx_descriptor_init(&cohd->desc, chan); + + cohd->desc.tx_submit = coh901318_tx_submit; + + spin_unlock_irqrestore(&cohc->lock, flg); + + return &cohd->desc; + err: + spin_unlock_irqrestore(&cohc->lock, flg); + return NULL; +} + +static struct dma_async_tx_descriptor * +coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + unsigned int sg_len, enum dma_data_direction direction, + unsigned long flags) +{ + struct coh901318_chan *cohc = to_coh901318_chan(chan); + struct coh901318_lli *data; + struct coh901318_desc *cohd; + struct scatterlist *sg; + int len = 0; + int size; + int i; + u32 ctrl_chained = cohc_chan_param(cohc)->ctrl_lli_chained; + u32 ctrl = cohc_chan_param(cohc)->ctrl_lli; + u32 ctrl_last = cohc_chan_param(cohc)->ctrl_lli_last; + unsigned long flg; + + if (!sgl) + goto out; + if (sgl->length == 0) + goto out; + + spin_lock_irqsave(&cohc->lock, flg); + + dev_vdbg(COHC_2_DEV(cohc), "[%s] sg_len %d dir %d\n", + __func__, sg_len, direction); + + if (flags & DMA_PREP_INTERRUPT) + /* Trigger interrupt after last lli */ + ctrl_last |= COH901318_CX_CTRL_TC_IRQ_ENABLE; + + cohd = coh901318_desc_get(cohc); + cohd->sg = NULL; + cohd->sg_len = 0; + cohd->dir = direction; + + if (direction == DMA_TO_DEVICE) { + u32 tx_flags = COH901318_CX_CTRL_PRDD_SOURCE | + COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE; + + ctrl_chained |= tx_flags; + ctrl_last |= tx_flags; + ctrl |= tx_flags; + } else if (direction == DMA_FROM_DEVICE) { + u32 rx_flags = COH901318_CX_CTRL_PRDD_DEST | + COH901318_CX_CTRL_DST_ADDR_INC_ENABLE; + + ctrl_chained |= rx_flags; + ctrl_last |= rx_flags; + ctrl |= rx_flags; + } else + goto err_direction; + + dma_async_tx_descriptor_init(&cohd->desc, chan); + + cohd->desc.tx_submit = coh901318_tx_submit; + + + /* The dma only supports transmitting packages up to + * MAX_DMA_PACKET_SIZE. Calculate to total number of + * dma elemts required to send the entire sg list + */ + for_each_sg(sgl, sg, sg_len, i) { + unsigned int factor; + size = sg_dma_len(sg); + + if (size <= MAX_DMA_PACKET_SIZE) { + len++; + continue; + } + + factor = size >> MAX_DMA_PACKET_SIZE_SHIFT; + if ((factor << MAX_DMA_PACKET_SIZE_SHIFT) < size) + factor++; + + len += factor; + } + + data = coh901318_lli_alloc(&cohc->base->pool, len); + + if (data == NULL) + goto err_dma_alloc; + + /* initiate allocated data list */ + cohd->pending_irqs = + coh901318_lli_fill_sg(&cohc->base->pool, data, sgl, sg_len, + cohc_dev_addr(cohc), + ctrl_chained, + ctrl, + ctrl_last, + direction, COH901318_CX_CTRL_TC_IRQ_ENABLE); + cohd->data = data; + + cohd->flags = flags; + + COH_DBG(coh901318_list_print(cohc, data)); + + spin_unlock_irqrestore(&cohc->lock, flg); + + return &cohd->desc; + err_dma_alloc: + err_direction: + coh901318_desc_remove(cohd); + coh901318_desc_free(cohc, cohd); + spin_unlock_irqrestore(&cohc->lock, flg); + out: + return NULL; +} + +static enum dma_status +coh901318_is_tx_complete(struct dma_chan *chan, + dma_cookie_t cookie, dma_cookie_t *done, + dma_cookie_t *used) +{ + struct coh901318_chan *cohc = to_coh901318_chan(chan); + dma_cookie_t last_used; + dma_cookie_t last_complete; + int ret; + + last_complete = cohc->completed; + last_used = chan->cookie; + + ret = dma_async_is_complete(cookie, last_complete, last_used); + + if (done) + *done = last_complete; + if (used) + *used = last_used; + + return ret; +} + +static void +coh901318_issue_pending(struct dma_chan *chan) +{ + struct coh901318_chan *cohc = to_coh901318_chan(chan); + unsigned long flags; + + spin_lock_irqsave(&cohc->lock, flags); + + /* Busy means that pending jobs are already being processed */ + if (!cohc->busy) + coh901318_queue_start(cohc); + + spin_unlock_irqrestore(&cohc->lock, flags); +} + +static void +coh901318_terminate_all(struct dma_chan *chan) +{ + unsigned long flags; + struct coh901318_chan *cohc = to_coh901318_chan(chan); + struct coh901318_desc *cohd; + void __iomem *virtbase = cohc->base->virtbase; + + coh901318_stop(chan); + + spin_lock_irqsave(&cohc->lock, flags); + + /* Clear any pending BE or TC interrupt */ + if (cohc->id < 32) { + writel(1 << cohc->id, virtbase + COH901318_BE_INT_CLEAR1); + writel(1 << cohc->id, virtbase + COH901318_TC_INT_CLEAR1); + } else { + writel(1 << (cohc->id - 32), virtbase + + COH901318_BE_INT_CLEAR2); + writel(1 << (cohc->id - 32), virtbase + + COH901318_TC_INT_CLEAR2); + } + + enable_powersave(cohc); + + while ((cohd = coh901318_first_active_get(cohc))) { + /* release the lli allocation*/ + coh901318_lli_free(&cohc->base->pool, &cohd->data); + + coh901318_desc_remove(cohd); + + /* return desc to free-list */ + coh901318_desc_free(cohc, cohd); + } + + while ((cohd = coh901318_first_queued(cohc))) { + /* release the lli allocation*/ + coh901318_lli_free(&cohc->base->pool, &cohd->data); + + coh901318_desc_remove(cohd); + + /* return desc to free-list */ + coh901318_desc_free(cohc, cohd); + } + + + cohc->nbr_active_done = 0; + cohc->busy = 0; + cohc->pending_irqs = 0; + + spin_unlock_irqrestore(&cohc->lock, flags); +} +void coh901318_base_init(struct dma_device *dma, const int *pick_chans, + struct coh901318_base *base) +{ + int chans_i; + int i = 0; + struct coh901318_chan *cohc; + + INIT_LIST_HEAD(&dma->channels); + + for (chans_i = 0; pick_chans[chans_i] != -1; chans_i += 2) { + for (i = pick_chans[chans_i]; i <= pick_chans[chans_i+1]; i++) { + cohc = &base->chans[i]; + + cohc->base = base; + cohc->chan.device = dma; + cohc->id = i; + + /* TODO: do we really need this lock if only one + * client is connected to each channel? + */ + + spin_lock_init(&cohc->lock); + + cohc->pending_irqs = 0; + cohc->nbr_active_done = 0; + cohc->busy = 0; + INIT_LIST_HEAD(&cohc->free); + INIT_LIST_HEAD(&cohc->active); + INIT_LIST_HEAD(&cohc->queue); + + tasklet_init(&cohc->tasklet, dma_tasklet, + (unsigned long) cohc); + + list_add_tail(&cohc->chan.device_node, + &dma->channels); + } + } +} + +static int __init coh901318_probe(struct platform_device *pdev) +{ + int err = 0; + struct coh901318_platform *pdata; + struct coh901318_base *base; + int irq; + struct resource *io; + + io = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!io) + goto err_get_resource; + + /* Map DMA controller registers to virtual memory */ + if (request_mem_region(io->start, + resource_size(io), + pdev->dev.driver->name) == NULL) { + err = -EBUSY; + goto err_request_mem; + } + + pdata = pdev->dev.platform_data; + if (!pdata) + goto err_no_platformdata; + + base = kmalloc(ALIGN(sizeof(struct coh901318_base), 4) + + pdata->max_channels * + sizeof(struct coh901318_chan), + GFP_KERNEL); + if (!base) + goto err_alloc_coh_dma_channels; + + base->chans = ((void *)base) + ALIGN(sizeof(struct coh901318_base), 4); + + base->virtbase = ioremap(io->start, resource_size(io)); + if (!base->virtbase) { + err = -ENOMEM; + goto err_no_ioremap; + } + + base->dev = &pdev->dev; + base->platform = pdata; + spin_lock_init(&base->pm.lock); + base->pm.started_channels = 0; + + COH901318_DEBUGFS_ASSIGN(debugfs_dma_base, base); + + platform_set_drvdata(pdev, base); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + goto err_no_irq; + + err = request_irq(irq, dma_irq_handler, IRQF_DISABLED, + "coh901318", base); + if (err) { + dev_crit(&pdev->dev, + "Cannot allocate IRQ for DMA controller!\n"); + goto err_request_irq; + } + + err = coh901318_pool_create(&base->pool, &pdev->dev, + sizeof(struct coh901318_lli), + 32); + if (err) + goto err_pool_create; + + /* init channels for device transfers */ + coh901318_base_init(&base->dma_slave, base->platform->chans_slave, + base); + + dma_cap_zero(base->dma_slave.cap_mask); + dma_cap_set(DMA_SLAVE, base->dma_slave.cap_mask); + + base->dma_slave.device_alloc_chan_resources = coh901318_alloc_chan_resources; + base->dma_slave.device_free_chan_resources = coh901318_free_chan_resources; + base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg; + base->dma_slave.device_is_tx_complete = coh901318_is_tx_complete; + base->dma_slave.device_issue_pending = coh901318_issue_pending; + base->dma_slave.device_terminate_all = coh901318_terminate_all; + base->dma_slave.dev = &pdev->dev; + + err = dma_async_device_register(&base->dma_slave); + + if (err) + goto err_register_slave; + + /* init channels for memcpy */ + coh901318_base_init(&base->dma_memcpy, base->platform->chans_memcpy, + base); + + dma_cap_zero(base->dma_memcpy.cap_mask); + dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask); + + base->dma_memcpy.device_alloc_chan_resources = coh901318_alloc_chan_resources; + base->dma_memcpy.device_free_chan_resources = coh901318_free_chan_resources; + base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy; + base->dma_memcpy.device_is_tx_complete = coh901318_is_tx_complete; + base->dma_memcpy.device_issue_pending = coh901318_issue_pending; + base->dma_memcpy.device_terminate_all = coh901318_terminate_all; + base->dma_memcpy.dev = &pdev->dev; + err = dma_async_device_register(&base->dma_memcpy); + + if (err) + goto err_register_memcpy; + + dev_dbg(&pdev->dev, "Initialized COH901318 DMA on virtual base 0x%08x\n", + (u32) base->virtbase); + + return err; + + err_register_memcpy: + dma_async_device_unregister(&base->dma_slave); + err_register_slave: + coh901318_pool_destroy(&base->pool); + err_pool_create: + free_irq(platform_get_irq(pdev, 0), base); + err_request_irq: + err_no_irq: + iounmap(base->virtbase); + err_no_ioremap: + kfree(base); + err_alloc_coh_dma_channels: + err_no_platformdata: + release_mem_region(pdev->resource->start, + resource_size(pdev->resource)); + err_request_mem: + err_get_resource: + return err; +} + +static int __exit coh901318_remove(struct platform_device *pdev) +{ + struct coh901318_base *base = platform_get_drvdata(pdev); + + dma_async_device_unregister(&base->dma_memcpy); + dma_async_device_unregister(&base->dma_slave); + coh901318_pool_destroy(&base->pool); + free_irq(platform_get_irq(pdev, 0), base); + kfree(base); + iounmap(base->virtbase); + release_mem_region(pdev->resource->start, + resource_size(pdev->resource)); + return 0; +} + + +static struct platform_driver coh901318_driver = { + .remove = __exit_p(coh901318_remove), + .driver = { + .name = "coh901318", + }, +}; + +int __init coh901318_init(void) +{ + return platform_driver_probe(&coh901318_driver, coh901318_probe); +} +subsys_initcall(coh901318_init); + +void __exit coh901318_exit(void) +{ + platform_driver_unregister(&coh901318_driver); +} +module_exit(coh901318_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Per Friden"); diff --git a/drivers/dma/coh901318_lli.c b/drivers/dma/coh901318_lli.c new file mode 100644 index 0000000..f5120f2 --- /dev/null +++ b/drivers/dma/coh901318_lli.c @@ -0,0 +1,318 @@ +/* + * driver/dma/coh901318_lli.c + * + * Copyright (C) 2007-2009 ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + * Support functions for handling lli for dma + * Author: Per Friden + */ + +#include +#include +#include +#include +#include + +#include "coh901318_lli.h" + +#if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG)) +#define DEBUGFS_POOL_COUNTER_RESET(pool) (pool->debugfs_pool_counter = 0) +#define DEBUGFS_POOL_COUNTER_ADD(pool, add) (pool->debugfs_pool_counter += add) +#else +#define DEBUGFS_POOL_COUNTER_RESET(pool) +#define DEBUGFS_POOL_COUNTER_ADD(pool, add) +#endif + +static struct coh901318_lli * +coh901318_lli_next(struct coh901318_lli *data) +{ + if (data == NULL || data->link_addr == 0) + return NULL; + + return (struct coh901318_lli *) data->virt_link_addr; +} + +int coh901318_pool_create(struct coh901318_pool *pool, + struct device *dev, + size_t size, size_t align) +{ + spin_lock_init(&pool->lock); + pool->dev = dev; + pool->dmapool = dma_pool_create("lli_pool", dev, size, align, 0); + + DEBUGFS_POOL_COUNTER_RESET(pool); + return 0; +} + +int coh901318_pool_destroy(struct coh901318_pool *pool) +{ + + dma_pool_destroy(pool->dmapool); + return 0; +} + +struct coh901318_lli * +coh901318_lli_alloc(struct coh901318_pool *pool, unsigned int len) +{ + int i; + struct coh901318_lli *head; + struct coh901318_lli *lli; + struct coh901318_lli *lli_prev; + dma_addr_t phy; + + if (len == 0) + goto err; + + spin_lock(&pool->lock); + + head = dma_pool_alloc(pool->dmapool, GFP_NOWAIT, &phy); + + if (head == NULL) + goto err; + + DEBUGFS_POOL_COUNTER_ADD(pool, 1); + + lli = head; + lli->phy_this = phy; + + for (i = 1; i < len; i++) { + lli_prev = lli; + + lli = dma_pool_alloc(pool->dmapool, GFP_NOWAIT, &phy); + + if (lli == NULL) + goto err_clean_up; + + DEBUGFS_POOL_COUNTER_ADD(pool, 1); + lli->phy_this = phy; + + lli_prev->link_addr = phy; + lli_prev->virt_link_addr = lli; + } + + lli->link_addr = 0x00000000U; + + spin_unlock(&pool->lock); + + return head; + + err: + spin_unlock(&pool->lock); + return NULL; + + err_clean_up: + lli_prev->link_addr = 0x00000000U; + spin_unlock(&pool->lock); + coh901318_lli_free(pool, &head); + return NULL; +} + +void coh901318_lli_free(struct coh901318_pool *pool, + struct coh901318_lli **lli) +{ + struct coh901318_lli *l; + struct coh901318_lli *next; + + if (lli == NULL) + return; + + l = *lli; + + if (l == NULL) + return; + + spin_lock(&pool->lock); + + while (l->link_addr) { + next = l->virt_link_addr; + dma_pool_free(pool->dmapool, l, l->phy_this); + DEBUGFS_POOL_COUNTER_ADD(pool, -1); + l = next; + } + dma_pool_free(pool->dmapool, l, l->phy_this); + DEBUGFS_POOL_COUNTER_ADD(pool, -1); + + spin_unlock(&pool->lock); + *lli = NULL; +} + +int +coh901318_lli_fill_memcpy(struct coh901318_pool *pool, + struct coh901318_lli *lli, + dma_addr_t source, unsigned int size, + dma_addr_t destination, u32 ctrl_chained, + u32 ctrl_eom) +{ + int s = size; + dma_addr_t src = source; + dma_addr_t dst = destination; + + lli->src_addr = src; + lli->dst_addr = dst; + + while (lli->link_addr) { + lli->control = ctrl_chained | MAX_DMA_PACKET_SIZE; + lli->src_addr = src; + lli->dst_addr = dst; + + s -= MAX_DMA_PACKET_SIZE; + lli = coh901318_lli_next(lli); + + src += MAX_DMA_PACKET_SIZE; + dst += MAX_DMA_PACKET_SIZE; + } + + lli->control = ctrl_eom | s; + lli->src_addr = src; + lli->dst_addr = dst; + + /* One irq per single transfer */ + return 1; +} + +int +coh901318_lli_fill_single(struct coh901318_pool *pool, + struct coh901318_lli *lli, + dma_addr_t buf, unsigned int size, + dma_addr_t dev_addr, u32 ctrl_chained, u32 ctrl_eom, + enum dma_data_direction dir) +{ + int s = size; + dma_addr_t src; + dma_addr_t dst; + + + if (dir == DMA_TO_DEVICE) { + src = buf; + dst = dev_addr; + + } else if (dir == DMA_FROM_DEVICE) { + + src = dev_addr; + dst = buf; + } else { + return -EINVAL; + } + + while (lli->link_addr) { + size_t block_size = MAX_DMA_PACKET_SIZE; + lli->control = ctrl_chained | MAX_DMA_PACKET_SIZE; + + /* If we are on the next-to-final block and there will + * be less than half a DMA packet left for the last + * block, then we want to make this block a little + * smaller to balance the sizes. This is meant to + * avoid too small transfers if the buffer size is + * (MAX_DMA_PACKET_SIZE*N + 1) */ + if (s < (MAX_DMA_PACKET_SIZE + MAX_DMA_PACKET_SIZE/2)) + block_size = MAX_DMA_PACKET_SIZE/2; + + s -= block_size; + lli->src_addr = src; + lli->dst_addr = dst; + + lli = coh901318_lli_next(lli); + + if (dir == DMA_TO_DEVICE) + src += block_size; + else if (dir == DMA_FROM_DEVICE) + dst += block_size; + } + + lli->control = ctrl_eom | s; + lli->src_addr = src; + lli->dst_addr = dst; + + /* One irq per single transfer */ + return 1; +} + +int +coh901318_lli_fill_sg(struct coh901318_pool *pool, + struct coh901318_lli *lli, + struct scatterlist *sgl, unsigned int nents, + dma_addr_t dev_addr, u32 ctrl_chained, u32 ctrl, + u32 ctrl_last, + enum dma_data_direction dir, u32 ctrl_irq_mask) +{ + int i; + struct scatterlist *sg; + u32 ctrl_sg; + dma_addr_t src = 0; + dma_addr_t dst = 0; + int nbr_of_irq = 0; + u32 bytes_to_transfer; + u32 elem_size; + + if (lli == NULL) + goto err; + + spin_lock(&pool->lock); + + if (dir == DMA_TO_DEVICE) + dst = dev_addr; + else if (dir == DMA_FROM_DEVICE) + src = dev_addr; + else + goto err; + + for_each_sg(sgl, sg, nents, i) { + if (sg_is_chain(sg)) { + /* sg continues to the next sg-element don't + * send ctrl_finish until the last + * sg-element in the chain + */ + ctrl_sg = ctrl_chained; + } else if (i == nents - 1) + ctrl_sg = ctrl_last; + else + ctrl_sg = ctrl ? ctrl : ctrl_last; + + + if ((ctrl_sg & ctrl_irq_mask)) + nbr_of_irq++; + + if (dir == DMA_TO_DEVICE) + /* increment source address */ + src = sg_dma_address(sg); + else + /* increment destination address */ + dst = sg_dma_address(sg); + + bytes_to_transfer = sg_dma_len(sg); + + while (bytes_to_transfer) { + u32 val; + + if (bytes_to_transfer > MAX_DMA_PACKET_SIZE) { + elem_size = MAX_DMA_PACKET_SIZE; + val = ctrl_chained; + } else { + elem_size = bytes_to_transfer; + val = ctrl_sg; + } + + lli->control = val | elem_size; + lli->src_addr = src; + lli->dst_addr = dst; + + if (dir == DMA_FROM_DEVICE) + dst += elem_size; + else + src += elem_size; + + BUG_ON(lli->link_addr & 3); + + bytes_to_transfer -= elem_size; + lli = coh901318_lli_next(lli); + } + + } + spin_unlock(&pool->lock); + + /* There can be many IRQs per sg transfer */ + return nbr_of_irq; + err: + spin_unlock(&pool->lock); + return -EINVAL; +} diff --git a/drivers/dma/coh901318_lli.h b/drivers/dma/coh901318_lli.h new file mode 100644 index 0000000..7bf713b --- /dev/null +++ b/drivers/dma/coh901318_lli.h @@ -0,0 +1,124 @@ +/* + * driver/dma/coh901318_lli.h + * + * Copyright (C) 2007-2009 ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + * Support functions for handling lli for coh901318 + * Author: Per Friden + */ + +#ifndef COH901318_LLI_H +#define COH901318_LLI_H + +#include + +struct device; + +struct coh901318_pool { + spinlock_t lock; + struct dma_pool *dmapool; + struct device *dev; + +#ifdef CONFIG_DEBUG_FS + int debugfs_pool_counter; +#endif +}; + +struct device; +/** + * coh901318_pool_create() - Creates an dma pool for lli:s + * @pool: pool handle + * @dev: dma device + * @lli_nbr: number of lli:s in the pool + * @algin: adress alignemtn of lli:s + * returns 0 on success otherwise none zero + */ +int coh901318_pool_create(struct coh901318_pool *pool, + struct device *dev, + size_t lli_nbr, size_t align); + +/** + * coh901318_pool_destroy() - Destroys the dma pool + * @pool: pool handle + * returns 0 on success otherwise none zero + */ +int coh901318_pool_destroy(struct coh901318_pool *pool); + +/** + * coh901318_lli_alloc() - Allocates a linked list + * + * @pool: pool handle + * @len: length to list + * return: none NULL if success otherwise NULL + */ +struct coh901318_lli * +coh901318_lli_alloc(struct coh901318_pool *pool, + unsigned int len); + +/** + * coh901318_lli_free() - Returns the linked list items to the pool + * @pool: pool handle + * @lli: reference to lli pointer to be freed + */ +void coh901318_lli_free(struct coh901318_pool *pool, + struct coh901318_lli **lli); + +/** + * coh901318_lli_fill_memcpy() - Prepares the lli:s for dma memcpy + * @pool: pool handle + * @lli: allocated lli + * @src: src address + * @size: transfer size + * @dst: destination address + * @ctrl_chained: ctrl for chained lli + * @ctrl_last: ctrl for the last lli + * returns number of CPU interrupts for the lli, negative on error. + */ +int +coh901318_lli_fill_memcpy(struct coh901318_pool *pool, + struct coh901318_lli *lli, + dma_addr_t src, unsigned int size, + dma_addr_t dst, u32 ctrl_chained, u32 ctrl_last); + +/** + * coh901318_lli_fill_single() - Prepares the lli:s for dma single transfer + * @pool: pool handle + * @lli: allocated lli + * @buf: transfer buffer + * @size: transfer size + * @dev_addr: address of periphal + * @ctrl_chained: ctrl for chained lli + * @ctrl_last: ctrl for the last lli + * @dir: direction of transfer (to or from device) + * returns number of CPU interrupts for the lli, negative on error. + */ +int +coh901318_lli_fill_single(struct coh901318_pool *pool, + struct coh901318_lli *lli, + dma_addr_t buf, unsigned int size, + dma_addr_t dev_addr, u32 ctrl_chained, u32 ctrl_last, + enum dma_data_direction dir); + +/** + * coh901318_lli_fill_single() - Prepares the lli:s for dma scatter list transfer + * @pool: pool handle + * @lli: allocated lli + * @sg: scatter gather list + * @nents: number of entries in sg + * @dev_addr: address of periphal + * @ctrl_chained: ctrl for chained lli + * @ctrl: ctrl of middle lli + * @ctrl_last: ctrl for the last lli + * @dir: direction of transfer (to or from device) + * @ctrl_irq_mask: ctrl mask for CPU interrupt + * returns number of CPU interrupts for the lli, negative on error. + */ +int +coh901318_lli_fill_sg(struct coh901318_pool *pool, + struct coh901318_lli *lli, + struct scatterlist *sg, unsigned int nents, + dma_addr_t dev_addr, u32 ctrl_chained, + u32 ctrl, u32 ctrl_last, + enum dma_data_direction dir, u32 ctrl_irq_mask); + +#endif /* COH901318_LLI_H */ -- cgit v0.10.2 From 782e5711d61b2cda45dea447badba3ab07c236f0 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 20 Nov 2009 14:56:07 +0900 Subject: mtd: vmu-flash: Use hweight_long Use hweight_long instead of Brian Kernighan's/Peter Wegner's method Signed-off-by: Akinobu Mita Signed-off-by: David Woodhouse diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c index 1f73297..1008462 100644 --- a/drivers/mtd/maps/vmu-flash.c +++ b/drivers/mtd/maps/vmu-flash.c @@ -612,10 +612,9 @@ static int __devinit vmu_connect(struct maple_device *mdev) test_flash_data = be32_to_cpu(mdev->devinfo.function); /* Need to count how many bits are set - to find out which - * function_data element has details of the memory card: - * using Brian Kernighan's/Peter Wegner's method */ - for (c = 0; test_flash_data; c++) - test_flash_data &= test_flash_data - 1; + * function_data element has details of the memory card + */ + c = hweight_long(test_flash_data); basic_flash_data = be32_to_cpu(mdev->devinfo.function_data[c - 1]); -- cgit v0.10.2 From 681142f9211b23e6aa2984259d38b76d7bdc05a8 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 21 Nov 2009 20:28:52 +0900 Subject: fat: make discard a mount option Currently shipping discard capable SSDs and arrays have rather sub-optimal implementations of the command and can the use of it can cause massive slowdowns. Make issueing these commands option as it's already in btrfs and gfs2. Signed-off-by: Christoph Hellwig [hirofumi@mail.parknet.co.jp: tweaks, and add "discard" to fat_show_options] Signed-off-by: OGAWA Hirofumi diff --git a/fs/fat/fat.h b/fs/fat/fat.h index 7db0979..e6efdfa 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -44,7 +44,8 @@ struct fat_mount_options { nocase:1, /* Does this need case conversion? 0=need case conversion*/ usefree:1, /* Use free_clusters for FAT32 */ tz_utc:1, /* Filesystem timestamps are in UTC */ - rodir:1; /* allow ATTR_RO for directory */ + rodir:1, /* allow ATTR_RO for directory */ + discard:1; /* Issue discard requests on deletions */ }; #define FAT_HASH_BITS 8 diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c index a810377..81184d3 100644 --- a/fs/fat/fatent.c +++ b/fs/fat/fatent.c @@ -566,16 +566,21 @@ int fat_free_clusters(struct inode *inode, int cluster) goto error; } - /* - * Issue discard for the sectors we no longer care about, - * batching contiguous clusters into one request - */ - if (cluster != fatent.entry + 1) { - int nr_clus = fatent.entry - first_cl + 1; - - sb_issue_discard(sb, fat_clus_to_blknr(sbi, first_cl), - nr_clus * sbi->sec_per_clus); - first_cl = cluster; + if (sbi->options.discard) { + /* + * Issue discard for the sectors we no longer + * care about, batching contiguous clusters + * into one request + */ + if (cluster != fatent.entry + 1) { + int nr_clus = fatent.entry - first_cl + 1; + + sb_issue_discard(sb, + fat_clus_to_blknr(sbi, first_cl), + nr_clus * sbi->sec_per_clus); + + first_cl = cluster; + } } ops->ent_put(&fatent, FAT_ENT_FREE); diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 76b7961..14da530 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -858,6 +858,8 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt) seq_puts(m, ",errors=panic"); else seq_puts(m, ",errors=remount-ro"); + if (opts->discard) + seq_puts(m, ",discard"); return 0; } @@ -871,7 +873,7 @@ enum { Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, Opt_obsolate, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont, - Opt_err_panic, Opt_err_ro, Opt_err, + Opt_err_panic, Opt_err_ro, Opt_discard, Opt_err, }; static const match_table_t fat_tokens = { @@ -899,6 +901,7 @@ static const match_table_t fat_tokens = { {Opt_err_cont, "errors=continue"}, {Opt_err_panic, "errors=panic"}, {Opt_err_ro, "errors=remount-ro"}, + {Opt_discard, "discard"}, {Opt_obsolate, "conv=binary"}, {Opt_obsolate, "conv=text"}, {Opt_obsolate, "conv=auto"}, @@ -1136,6 +1139,9 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, case Opt_rodir: opts->rodir = 1; break; + case Opt_discard: + opts->discard = 1; + break; /* obsolete mount options */ case Opt_obsolate: -- cgit v0.10.2 From 78c210efdefe07131f91ed512a3308b15bb14e2f Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Thu, 6 Aug 2009 15:41:34 -0400 Subject: Revert "knfsd: avoid overloading the CPU scheduler with enormous load averages" This reverts commit 59a252ff8c0f2fa32c896f69d56ae33e641ce7ad. This helps in an entirely cached workload but not necessarily in workloads that require waiting on disk. Conflicts: include/linux/sunrpc/svc.h net/sunrpc/svc_xprt.c Reported-by: Simon Kirby Tested-by: Jesper Krogh Signed-off-by: J. Bruce Fields diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 52e8cb0..d1567d6 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -29,7 +29,6 @@ struct svc_pool_stats { unsigned long packets; unsigned long sockets_queued; unsigned long threads_woken; - unsigned long overloads_avoided; unsigned long threads_timedout; }; @@ -50,7 +49,6 @@ struct svc_pool { struct list_head sp_sockets; /* pending sockets */ unsigned int sp_nrthreads; /* # of threads in pool */ struct list_head sp_all_threads; /* all server threads */ - int sp_nwaking; /* number of threads woken but not yet active */ struct svc_pool_stats sp_stats; /* statistics on pool operation */ } ____cacheline_aligned_in_smp; @@ -284,7 +282,6 @@ struct svc_rqst { * cache pages */ wait_queue_head_t rq_wait; /* synchronization */ struct task_struct *rq_task; /* service thread */ - int rq_waking; /* 1 if thread is being woken */ }; /* diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index df124f7..2c58b75 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -16,8 +16,6 @@ #define RPCDBG_FACILITY RPCDBG_SVCXPRT -#define SVC_MAX_WAKING 5 - static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt); static int svc_deferred_recv(struct svc_rqst *rqstp); static struct cache_deferred_req *svc_defer(struct cache_req *req); @@ -306,7 +304,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) struct svc_pool *pool; struct svc_rqst *rqstp; int cpu; - int thread_avail; if (!(xprt->xpt_flags & ((1<sp_lock); + if (!list_empty(&pool->sp_threads) && + !list_empty(&pool->sp_sockets)) + printk(KERN_ERR + "svc_xprt_enqueue: " + "threads and transports both waiting??\n"); + if (test_bit(XPT_DEAD, &xprt->xpt_flags)) { /* Don't enqueue dead transports */ dprintk("svc: transport %p is dead, not enqueued\n", xprt); @@ -358,15 +361,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) } process: - /* Work out whether threads are available */ - thread_avail = !list_empty(&pool->sp_threads); /* threads are asleep */ - if (pool->sp_nwaking >= SVC_MAX_WAKING) { - /* too many threads are runnable and trying to wake up */ - thread_avail = 0; - pool->sp_stats.overloads_avoided++; - } - - if (thread_avail) { + if (!list_empty(&pool->sp_threads)) { rqstp = list_entry(pool->sp_threads.next, struct svc_rqst, rq_list); @@ -381,8 +376,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) svc_xprt_get(xprt); rqstp->rq_reserved = serv->sv_max_mesg; atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); - rqstp->rq_waking = 1; - pool->sp_nwaking++; pool->sp_stats.threads_woken++; BUG_ON(xprt->xpt_pool != pool); wake_up(&rqstp->rq_wait); @@ -651,11 +644,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) return -EINTR; spin_lock_bh(&pool->sp_lock); - if (rqstp->rq_waking) { - rqstp->rq_waking = 0; - pool->sp_nwaking--; - BUG_ON(pool->sp_nwaking < 0); - } xprt = svc_xprt_dequeue(pool); if (xprt) { rqstp->rq_xprt = xprt; @@ -1204,16 +1192,15 @@ static int svc_pool_stats_show(struct seq_file *m, void *p) struct svc_pool *pool = p; if (p == SEQ_START_TOKEN) { - seq_puts(m, "# pool packets-arrived sockets-enqueued threads-woken overloads-avoided threads-timedout\n"); + seq_puts(m, "# pool packets-arrived sockets-enqueued threads-woken threads-timedout\n"); return 0; } - seq_printf(m, "%u %lu %lu %lu %lu %lu\n", + seq_printf(m, "%u %lu %lu %lu %lu\n", pool->sp_id, pool->sp_stats.packets, pool->sp_stats.sockets_queued, pool->sp_stats.threads_woken, - pool->sp_stats.overloads_avoided, pool->sp_stats.threads_timedout); return 0; -- cgit v0.10.2 From 864f0f61f829bac5f150a903aad9619322a25424 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Wed, 25 Nov 2009 17:42:05 -0500 Subject: nfsd: simplify fh_verify access checks All nfsd security depends on the security checks in fh_verify, and especially on nfsd_setuser(). It therefore bothers me that the nfsd_setuser call may be made from three different places, depending on whether the filehandle has already been mapped to a dentry, and on whether subtreechecking is in force. Instead, make an unconditional call in fh_verify(), so it's trivial to verify that the call always occurs. That leaves us with a redundant nfsd_setuser() call in the subtreecheck case--it needs the correct user set earlier in order to check execute permissions on the path to this filehandle--but I'm willing to accept that minor inefficiency in the subtreecheck case in return for more straightforward permission checking. Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index d0d8a21..a77efb8 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -233,14 +233,6 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) goto out; } - if (exp->ex_flags & NFSEXP_NOSUBTREECHECK) { - error = nfsd_setuser_and_check_port(rqstp, exp); - if (error) { - dput(dentry); - goto out; - } - } - if (S_ISDIR(dentry->d_inode->i_mode) && (dentry->d_flags & DCACHE_DISCONNECTED)) { printk("nfsd: find_fh_dentry returned a DISCONNECTED directory: %s/%s\n", @@ -295,28 +287,28 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) error = nfsd_set_fh_dentry(rqstp, fhp); if (error) goto out; - dentry = fhp->fh_dentry; - exp = fhp->fh_export; - } else { - /* - * just rechecking permissions - * (e.g. nfsproc_create calls fh_verify, then nfsd_create - * does as well) - */ - dprintk("nfsd: fh_verify - just checking\n"); - dentry = fhp->fh_dentry; - exp = fhp->fh_export; - /* - * Set user creds for this exportpoint; necessary even - * in the "just checking" case because this may be a - * filehandle that was created by fh_compose, and that - * is about to be used in another nfsv4 compound - * operation. - */ - error = nfsd_setuser_and_check_port(rqstp, exp); - if (error) - goto out; } + dentry = fhp->fh_dentry; + exp = fhp->fh_export; + /* + * We still have to do all these permission checks, even when + * fh_dentry is already set: + * - fh_verify may be called multiple times with different + * "access" arguments (e.g. nfsd_proc_create calls + * fh_verify(...,NFSD_MAY_EXEC) first, then later (in + * nfsd_create) calls fh_verify(...,NFSD_MAY_CREATE). + * - in the NFSv4 case, the filehandle may have been filled + * in by fh_compose, and given a dentry, but further + * compound operations performed with that filehandle + * still need permissions checks. In the worst case, a + * mountpoint crossing may have changed the export + * options, and we may now need to use a different uid + * (for example, if different id-squashing options are in + * effect on the new filesystem). + */ + error = nfsd_setuser_and_check_port(rqstp, exp); + if (error) + goto out; error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type); if (error) -- cgit v0.10.2 From 3cf602532c535ec655725e9833378e04c9fd7783 Mon Sep 17 00:00:00 2001 From: Amul Kumar Saha Date: Wed, 21 Oct 2009 17:00:05 +0530 Subject: mtd: OneNAND OTP support rework What is OTP in OneNAND? The device includes, 1. one block-sized OTP (One Time Programmable) area and 2. user-controlled 1st block OTP(Block 0) that can be used to increase system security or to provide identification capabilities. What is done? In OneNAND, one block of the NAND Array is set aside as an OTP memory area, and 1st Block (Block 0) can be used as OTP area. This area, available to the user, can be configured and locked with secured user information. The OTP block can be read, programmed and locked using the same operations as any other NAND Flash Array memory block. After issuing an OTP-Lock, OTP block cannot be erased. OTP block is fully-guaranteed to be a good block. Why it is done? Locking the 1st Block OTP has the effect of a 'Write-protect' to guard against accidental re-programming of data stored in the 1st block and OTP Block. Which problem it solves? OTP support is provided in the existing implementation of OneNAND/Flex-OneNAND driver, but it is not working with OneNAND devices. Have observed the following in current OTP OneNAND Implmentation, 1. DataSheet specific sequence to lock the OTP Area is not followed. 2. Certain functions are quiet generic to cope with OTP specific activity. This patch re-implements OTP support for OneNAND device. How it is done? For all blocks, 8th word is available to the user. However, in case of OTP Block, 8th word of sector 0, page 0 is reserved as OTP Locking Bit area. Therefore, in case of OTP Block, user usage on this area is prohibited. Condition specific values are entered in the 8th word, sector0, page 0 of the OTP block during the process of issuing an OTP-Lock. The possible conditions are: 1. Only 1st Block Lock 2. Only OTP Block Lock 3. Lock both the 1st Block and the OTP Block What Other feature additions have been done in this patch? This patch adds feature for: 1. Only 1st Block Lock 2. Lock both the 1st Block and the OTP Blocks Re-implemented OTP support for OneNAND Added following features to OneNAND 1. Lock only 1st Block in OneNAND 2. Lock BOTH 1st Block and OTP Block in OneNAND [comments were slightly tweaked by Artem] Signed-off-by: Amul Kumar Saha Reviewed-by: Adrian Hunter Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 6e250f3..7bd6ad3 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1,17 +1,19 @@ /* * linux/drivers/mtd/onenand/onenand_base.c * - * Copyright (C) 2005-2007 Samsung Electronics + * Copyright © 2005-2009 Samsung Electronics + * Copyright © 2007 Nokia Corporation + * * Kyungmin Park * * Credits: * Adrian Hunter : * auto-placement support, read-while load support, various fixes - * Copyright (C) Nokia Corporation, 2007 * * Vishak G , Rohit Hagargundgi * Flex-OneNAND support - * Copyright (C) Samsung Electronics, 2008 + * Amul Kumar Saha + * OTP support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -43,6 +45,18 @@ MODULE_PARM_DESC(flex_bdry, "SLC Boundary information for Flex-OneNAND" " : 0->Set boundary in unlocked status" " : 1->Set boundary in locked status"); +/* Default OneNAND/Flex-OneNAND OTP options*/ +static int otp; + +module_param(otp, int, 0400); +MODULE_PARM_DESC(otp, "Corresponding behaviour of OneNAND in OTP" + "Syntax : otp=LOCK_TYPE" + "LOCK_TYPE : Keys issued, for specific OTP Lock type" + " : 0 -> Default (No Blocks Locked)" + " : 1 -> OTP Block lock" + " : 2 -> 1st Block lock" + " : 3 -> BOTH OTP Block and 1st Block lock"); + /** * onenand_oob_128 - oob info for Flex-Onenand with 4KB page * For now, we expose only 64 out of 80 ecc bytes @@ -2591,6 +2605,208 @@ static void onenand_unlock_all(struct mtd_info *mtd) #ifdef CONFIG_MTD_ONENAND_OTP +/** + * onenand_otp_command - Send OTP specific command to OneNAND device + * @param mtd MTD device structure + * @param cmd the command to be sent + * @param addr offset to read from or write to + * @param len number of bytes to read or write + */ +static int onenand_otp_command(struct mtd_info *mtd, int cmd, loff_t addr, + size_t len) +{ + struct onenand_chip *this = mtd->priv; + int value, block, page; + + /* Address translation */ + switch (cmd) { + case ONENAND_CMD_OTP_ACCESS: + block = (int) (addr >> this->erase_shift); + page = -1; + break; + + default: + block = (int) (addr >> this->erase_shift); + page = (int) (addr >> this->page_shift); + + if (ONENAND_IS_2PLANE(this)) { + /* Make the even block number */ + block &= ~1; + /* Is it the odd plane? */ + if (addr & this->writesize) + block++; + page >>= 1; + } + page &= this->page_mask; + break; + } + + if (block != -1) { + /* Write 'DFS, FBA' of Flash */ + value = onenand_block_address(this, block); + this->write_word(value, this->base + + ONENAND_REG_START_ADDRESS1); + } + + if (page != -1) { + /* Now we use page size operation */ + int sectors = 4, count = 4; + int dataram; + + switch (cmd) { + default: + if (ONENAND_IS_2PLANE(this) && cmd == ONENAND_CMD_PROG) + cmd = ONENAND_CMD_2X_PROG; + dataram = ONENAND_CURRENT_BUFFERRAM(this); + break; + } + + /* Write 'FPA, FSA' of Flash */ + value = onenand_page_address(page, sectors); + this->write_word(value, this->base + + ONENAND_REG_START_ADDRESS8); + + /* Write 'BSA, BSC' of DataRAM */ + value = onenand_buffer_address(dataram, sectors, count); + this->write_word(value, this->base + ONENAND_REG_START_BUFFER); + } + + /* Interrupt clear */ + this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT); + + /* Write command */ + this->write_word(cmd, this->base + ONENAND_REG_COMMAND); + + return 0; +} + +/** + * onenand_otp_write_oob_nolock - [Internal] OneNAND write out-of-band, specific to OTP + * @param mtd MTD device structure + * @param to offset to write to + * @param len number of bytes to write + * @param retlen pointer to variable to store the number of written bytes + * @param buf the data to write + * + * OneNAND write out-of-band only for OTP + */ +static int onenand_otp_write_oob_nolock(struct mtd_info *mtd, loff_t to, + struct mtd_oob_ops *ops) +{ + struct onenand_chip *this = mtd->priv; + int column, ret = 0, oobsize; + int written = 0; + u_char *oobbuf; + size_t len = ops->ooblen; + const u_char *buf = ops->oobbuf; + int block, value, status; + + to += ops->ooboffs; + + /* Initialize retlen, in case of early exit */ + ops->oobretlen = 0; + + oobsize = mtd->oobsize; + + column = to & (mtd->oobsize - 1); + + oobbuf = this->oob_buf; + + /* Loop until all data write */ + while (written < len) { + int thislen = min_t(int, oobsize, len - written); + + cond_resched(); + + block = (int) (to >> this->erase_shift); + /* + * Write 'DFS, FBA' of Flash + * Add: F100h DQ=DFS, FBA + */ + + value = onenand_block_address(this, block); + this->write_word(value, this->base + + ONENAND_REG_START_ADDRESS1); + + /* + * Select DataRAM for DDP + * Add: F101h DQ=DBS + */ + + value = onenand_bufferram_address(this, block); + this->write_word(value, this->base + + ONENAND_REG_START_ADDRESS2); + ONENAND_SET_NEXT_BUFFERRAM(this); + + /* + * Enter OTP access mode + */ + this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); + this->wait(mtd, FL_OTPING); + + /* We send data to spare ram with oobsize + * to prevent byte access */ + memcpy(oobbuf + column, buf, thislen); + + /* + * Write Data into DataRAM + * Add: 8th Word + * in sector0/spare/page0 + * DQ=XXFCh + */ + this->write_bufferram(mtd, ONENAND_SPARERAM, + oobbuf, 0, mtd->oobsize); + + onenand_otp_command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize); + onenand_update_bufferram(mtd, to, 0); + if (ONENAND_IS_2PLANE(this)) { + ONENAND_SET_BUFFERRAM1(this); + onenand_update_bufferram(mtd, to + this->writesize, 0); + } + + ret = this->wait(mtd, FL_WRITING); + if (ret) { + printk(KERN_ERR "%s: write failed %d\n", __func__, ret); + break; + } + + /* Exit OTP access mode */ + this->command(mtd, ONENAND_CMD_RESET, 0, 0); + this->wait(mtd, FL_RESETING); + + status = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); + status &= 0x60; + + if (status == 0x60) { + printk(KERN_DEBUG "\nBLOCK\tSTATUS\n"); + printk(KERN_DEBUG "1st Block\tLOCKED\n"); + printk(KERN_DEBUG "OTP Block\tLOCKED\n"); + } else if (status == 0x20) { + printk(KERN_DEBUG "\nBLOCK\tSTATUS\n"); + printk(KERN_DEBUG "1st Block\tLOCKED\n"); + printk(KERN_DEBUG "OTP Block\tUN-LOCKED\n"); + } else if (status == 0x40) { + printk(KERN_DEBUG "\nBLOCK\tSTATUS\n"); + printk(KERN_DEBUG "1st Block\tUN-LOCKED\n"); + printk(KERN_DEBUG "OTP Block\tLOCKED\n"); + } else { + printk(KERN_DEBUG "Reboot to check\n"); + } + + written += thislen; + if (written == len) + break; + + to += mtd->writesize; + buf += thislen; + column = 0; + } + + ops->oobretlen = written; + + return ret; +} + /* Internal OTP operation */ typedef int (*otp_op_t)(struct mtd_info *mtd, loff_t form, size_t len, size_t *retlen, u_char *buf); @@ -2693,11 +2909,11 @@ static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len, struct mtd_oob_ops ops; int ret; - /* Enter OTP access mode */ - this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); - this->wait(mtd, FL_OTPING); - if (FLEXONENAND(this)) { + + /* Enter OTP access mode */ + this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); + this->wait(mtd, FL_OTPING); /* * For Flex-OneNAND, we write lock mark to 1st word of sector 4 of * main area of page 49. @@ -2708,19 +2924,19 @@ static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len, ops.oobbuf = NULL; ret = onenand_write_ops_nolock(mtd, mtd->writesize * 49, &ops); *retlen = ops.retlen; + + /* Exit OTP access mode */ + this->command(mtd, ONENAND_CMD_RESET, 0, 0); + this->wait(mtd, FL_RESETING); } else { ops.mode = MTD_OOB_PLACE; ops.ooblen = len; ops.oobbuf = buf; ops.ooboffs = 0; - ret = onenand_write_oob_nolock(mtd, from, &ops); + ret = onenand_otp_write_oob_nolock(mtd, from, &ops); *retlen = ops.oobretlen; } - /* Exit OTP access mode */ - this->command(mtd, ONENAND_CMD_RESET, 0, 0); - this->wait(mtd, FL_RESETING); - return ret; } @@ -2751,16 +2967,21 @@ static int onenand_otp_walk(struct mtd_info *mtd, loff_t from, size_t len, if (density < ONENAND_DEVICE_DENSITY_512Mb) otp_pages = 20; else - otp_pages = 10; + otp_pages = 50; if (mode == MTD_OTP_FACTORY) { from += mtd->writesize * otp_pages; - otp_pages = 64 - otp_pages; + otp_pages = ONENAND_PAGES_PER_BLOCK - otp_pages; } /* Check User/Factory boundary */ - if (((mtd->writesize * otp_pages) - (from + len)) < 0) - return 0; + if (mode == MTD_OTP_USER) { + if (((mtd->writesize * otp_pages) - (from + len)) < 0) + return 0; + } else { + if (((mtd->writesize * otp_pages) - len) < 0) + return 0; + } onenand_get_device(mtd, FL_OTPING); while (len > 0 && otp_pages > 0) { @@ -2783,13 +3004,12 @@ static int onenand_otp_walk(struct mtd_info *mtd, loff_t from, size_t len, *retlen += sizeof(struct otp_info); } else { size_t tmp_retlen; - int size = len; ret = action(mtd, from, len, &tmp_retlen, buf); - buf += size; - len -= size; - *retlen += size; + buf += tmp_retlen; + len -= tmp_retlen; + *retlen += tmp_retlen; if (ret) break; @@ -2902,21 +3122,11 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, u_char *buf = FLEXONENAND(this) ? this->page_buf : this->oob_buf; size_t retlen; int ret; + unsigned int otp_lock_offset = ONENAND_OTP_LOCK_OFFSET; memset(buf, 0xff, FLEXONENAND(this) ? this->writesize : mtd->oobsize); /* - * Note: OTP lock operation - * OTP block : 0xXXFC - * 1st block : 0xXXF3 (If chip support) - * Both : 0xXXF0 (If chip support) - */ - if (FLEXONENAND(this)) - buf[FLEXONENAND_OTP_LOCK_OFFSET] = 0xFC; - else - buf[ONENAND_OTP_LOCK_OFFSET] = 0xFC; - - /* * Write lock mark to 8th word of sector0 of page0 of the spare0. * We write 16 bytes spare area instead of 2 bytes. * For Flex-OneNAND, we write lock mark to 1st word of sector 4 of @@ -2926,10 +3136,30 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, from = 0; len = FLEXONENAND(this) ? mtd->writesize : 16; + /* + * Note: OTP lock operation + * OTP block : 0xXXFC XX 1111 1100 + * 1st block : 0xXXF3 (If chip support) XX 1111 0011 + * Both : 0xXXF0 (If chip support) XX 1111 0000 + */ + if (FLEXONENAND(this)) + otp_lock_offset = FLEXONENAND_OTP_LOCK_OFFSET; + + /* ONENAND_OTP_AREA | ONENAND_OTP_BLOCK0 | ONENAND_OTP_AREA_BLOCK0 */ + if (otp == 1) + buf[otp_lock_offset] = 0xFC; + else if (otp == 2) + buf[otp_lock_offset] = 0xF3; + else if (otp == 3) + buf[otp_lock_offset] = 0xF0; + else if (otp != 0) + printk(KERN_DEBUG "[OneNAND] Invalid option selected for OTP\n"); + ret = onenand_otp_walk(mtd, from, len, &retlen, buf, do_otp_lock, MTD_OTP_USER); return ret ? : retlen; } + #endif /* CONFIG_MTD_ONENAND_OTP */ /** diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index f57e29e..5509eb0 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h @@ -1,7 +1,7 @@ /* * linux/include/linux/mtd/onenand.h * - * Copyright (C) 2005-2007 Samsung Electronics + * Copyright © 2005-2009 Samsung Electronics * Kyungmin Park * * This program is free software; you can redistribute it and/or modify @@ -137,6 +137,8 @@ struct onenand_chip { /* * Helper macros */ +#define ONENAND_PAGES_PER_BLOCK (1<<6) + #define ONENAND_CURRENT_BUFFERRAM(this) (this->bufferram_index) #define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1) #define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1) -- cgit v0.10.2 From 1c63aca32903efc219fb9df72bae5344f3e54ed5 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Thu, 22 Oct 2009 16:53:32 +0900 Subject: mtd: Add __nand_calculate_ecc() to NAND ECC functions Add __nand_calculate_ecc() which does not take struct mtd_info. The built-in 256/512 software ECC calculation and correction tester will use it. Signed-off-by: Akinobu Mita Acked-by: Vimal Singh Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c index db7ae9d..809fb53 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/nand_ecc.c @@ -150,20 +150,19 @@ static const char addressbits[256] = { }; /** - * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256/512-byte + * __nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256/512-byte * block - * @mtd: MTD block structure * @buf: input buffer with raw data + * @eccsize: data bytes per ecc step (256 or 512) * @code: output buffer with ECC */ -int nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf, +void __nand_calculate_ecc(const unsigned char *buf, unsigned int eccsize, unsigned char *code) { int i; const uint32_t *bp = (uint32_t *)buf; /* 256 or 512 bytes/ecc */ - const uint32_t eccsize_mult = - (((struct nand_chip *)mtd->priv)->ecc.size) >> 8; + const uint32_t eccsize_mult = eccsize >> 8; uint32_t cur; /* current value in buffer */ /* rp0..rp15..rp17 are the various accumulated parities (per byte) */ uint32_t rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7; @@ -412,6 +411,22 @@ int nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf, (invparity[par & 0x55] << 2) | (invparity[rp17] << 1) | (invparity[rp16] << 0); +} +EXPORT_SYMBOL(__nand_calculate_ecc); + +/** + * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256/512-byte + * block + * @mtd: MTD block structure + * @buf: input buffer with raw data + * @code: output buffer with ECC + */ +int nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf, + unsigned char *code) +{ + __nand_calculate_ecc(buf, + ((struct nand_chip *)mtd->priv)->ecc.size, code); + return 0; } EXPORT_SYMBOL(nand_calculate_ecc); diff --git a/include/linux/mtd/nand_ecc.h b/include/linux/mtd/nand_ecc.h index 052ea8c..41bc013 100644 --- a/include/linux/mtd/nand_ecc.h +++ b/include/linux/mtd/nand_ecc.h @@ -16,7 +16,13 @@ struct mtd_info; /* - * Calculate 3 byte ECC code for 256 byte block + * Calculate 3 byte ECC code for eccsize byte block + */ +void __nand_calculate_ecc(const u_char *dat, unsigned int eccsize, + u_char *ecc_code); + +/* + * Calculate 3 byte ECC code for 256/512 byte block */ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); @@ -27,7 +33,7 @@ int __nand_correct_data(u_char *dat, u_char *read_ecc, u_char *calc_ecc, unsigned int eccsize); /* - * Detect and correct a 1 bit error for 256 byte block + * Detect and correct a 1 bit error for 256/512 byte block */ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); -- cgit v0.10.2 From 7126bd8be4ee009c56c4ec037f07f2c0884413fc Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Thu, 22 Oct 2009 16:53:33 +0900 Subject: mtd: add nand_ecc test module This module tests NAND ECC functions. The test is simple. 1. Create a 256 or 512 bytes block of data filled with random bytes (data) 2. Duplicate the data block and inject single bit error (error_data) 3. Try to correct error_data 4. Compare data and error_data Signed-off-by: Akinobu Mita Acked-by: Vimal Singh Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/tests/Makefile b/drivers/mtd/tests/Makefile index c1d5013..b44dcab 100644 --- a/drivers/mtd/tests/Makefile +++ b/drivers/mtd/tests/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_MTD_TESTS) += mtd_speedtest.o obj-$(CONFIG_MTD_TESTS) += mtd_stresstest.o obj-$(CONFIG_MTD_TESTS) += mtd_subpagetest.o obj-$(CONFIG_MTD_TESTS) += mtd_torturetest.o +obj-$(CONFIG_MTD_TESTS) += mtd_nandecctest.o diff --git a/drivers/mtd/tests/mtd_nandecctest.c b/drivers/mtd/tests/mtd_nandecctest.c new file mode 100644 index 0000000..c1f3105 --- /dev/null +++ b/drivers/mtd/tests/mtd_nandecctest.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_MTD_NAND) || defined(CONFIG_MTD_NAND_MODULE) + +static void inject_single_bit_error(void *data, size_t size) +{ + unsigned long offset = random32() % (size * BITS_PER_BYTE); + + __change_bit(offset, data); +} + +static unsigned char data[512]; +static unsigned char error_data[512]; + +static int nand_ecc_test(const size_t size) +{ + unsigned char code[3]; + unsigned char error_code[3]; + char testname[30]; + + BUG_ON(sizeof(data) < size); + + sprintf(testname, "nand-ecc-%zu", size); + + get_random_bytes(data, size); + + memcpy(error_data, data, size); + inject_single_bit_error(error_data, size); + + __nand_calculate_ecc(data, size, code); + __nand_calculate_ecc(error_data, size, error_code); + __nand_correct_data(error_data, code, error_code, size); + + if (!memcmp(data, error_data, size)) { + printk(KERN_INFO "mtd_nandecctest: ok - %s\n", testname); + return 0; + } + + printk(KERN_ERR "mtd_nandecctest: not ok - %s\n", testname); + + printk(KERN_DEBUG "hexdump of data:\n"); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4, + data, size, false); + printk(KERN_DEBUG "hexdump of error data:\n"); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4, + error_data, size, false); + + return -1; +} + +#else + +static int nand_ecc_test(const size_t size) +{ + return 0; +} + +#endif + +static int __init ecc_test_init(void) +{ + srandom32(jiffies); + + nand_ecc_test(256); + nand_ecc_test(512); + + return 0; +} + +static void __exit ecc_test_exit(void) +{ +} + +module_init(ecc_test_init); +module_exit(ecc_test_exit); + +MODULE_DESCRIPTION("NAND ECC function test module"); +MODULE_AUTHOR("Akinobu Mita"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 73885aeaca046a21183db598c2da46529e46fdab Mon Sep 17 00:00:00 2001 From: Mika Korhonen Date: Fri, 23 Oct 2009 07:50:42 +0200 Subject: mtd: OneNAND: move erase method to a separate function Separate the actual execution of erase to a new function: onenand_block_by_block_erase(). This is done in preparation for the multiblock erase support. Signed-off-by: Mika Korhonen Reviewed-by: Adrian Hunter Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 7bd6ad3..894ebad 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -2183,69 +2183,33 @@ static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allo } /** - * onenand_erase - [MTD Interface] erase block(s) + * onenand_block_by_block_erase - [Internal] erase block(s) using regular erase * @param mtd MTD device structure * @param instr erase instruction + * @param region erase region + * @param block_size erase block size * - * Erase one ore more blocks + * Erase one or more blocks one block at a time */ -static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) +static int onenand_block_by_block_erase(struct mtd_info *mtd, + struct erase_info *instr, + struct mtd_erase_region_info *region, + unsigned int block_size) { struct onenand_chip *this = mtd->priv; - unsigned int block_size; loff_t addr = instr->addr; - loff_t len = instr->len; - int ret = 0, i; - struct mtd_erase_region_info *region = NULL; + int len = instr->len; loff_t region_end = 0; + int ret = 0; - DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%012llx, len = %llu\n", (unsigned long long) instr->addr, (unsigned long long) instr->len); - - /* Do not allow erase past end of device */ - if (unlikely((len + addr) > mtd->size)) { - printk(KERN_ERR "%s: Erase past end of device\n", __func__); - return -EINVAL; - } - - if (FLEXONENAND(this)) { - /* Find the eraseregion of this address */ - i = flexonenand_region(mtd, addr); - region = &mtd->eraseregions[i]; - - block_size = region->erasesize; + if (region) { + /* region is set for Flex-OneNAND */ region_end = region->offset + region->erasesize * region->numblocks; - - /* Start address within region must align on block boundary. - * Erase region's start offset is always block start address. - */ - if (unlikely((addr - region->offset) & (block_size - 1))) { - printk(KERN_ERR "%s: Unaligned address\n", __func__); - return -EINVAL; - } - } else { - block_size = 1 << this->erase_shift; - - /* Start address must align on block boundary */ - if (unlikely(addr & (block_size - 1))) { - printk(KERN_ERR "%s: Unaligned address\n", __func__); - return -EINVAL; - } - } - - /* Length must align on block boundary */ - if (unlikely(len & (block_size - 1))) { - printk(KERN_ERR "%s: Length not block aligned\n", __func__); - return -EINVAL; } - instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; - - /* Grab the lock and see if the device is available */ - onenand_get_device(mtd, FL_ERASING); - - /* Loop through the blocks */ instr->state = MTD_ERASING; + /* Loop through the blocks */ while (len) { cond_resched(); @@ -2255,7 +2219,7 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) "at addr 0x%012llx\n", __func__, (unsigned long long) addr); instr->state = MTD_ERASE_FAILED; - goto erase_exit; + return -EIO; } this->command(mtd, ONENAND_CMD_ERASE, addr, block_size); @@ -2269,7 +2233,7 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) __func__, onenand_block(this, addr)); instr->state = MTD_ERASE_FAILED; instr->fail_addr = addr; - goto erase_exit; + return -EIO; } len -= block_size; @@ -2287,24 +2251,80 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) /* FIXME: This should be handled at MTD partitioning level. */ printk(KERN_ERR "%s: Unaligned address\n", __func__); - goto erase_exit; + return -EIO; } } + } + return 0; +} + +/** + * onenand_erase - [MTD Interface] erase block(s) + * @param mtd MTD device structure + * @param instr erase instruction + * + * Erase one or more blocks + */ +static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) +{ + struct onenand_chip *this = mtd->priv; + unsigned int block_size; + loff_t addr = instr->addr; + loff_t len = instr->len; + int ret = 0; + struct mtd_erase_region_info *region = NULL; + loff_t region_offset = 0; + + DEBUG(MTD_DEBUG_LEVEL3, "%s: start=0x%012llx, len=%llu\n", __func__, + (unsigned long long) instr->addr, (unsigned long long) instr->len); + + /* Do not allow erase past end of device */ + if (unlikely((len + addr) > mtd->size)) { + printk(KERN_ERR "%s: Erase past end of device\n", __func__); + return -EINVAL; + } + + if (FLEXONENAND(this)) { + /* Find the eraseregion of this address */ + int i = flexonenand_region(mtd, addr); + + region = &mtd->eraseregions[i]; + block_size = region->erasesize; + + /* Start address within region must align on block boundary. + * Erase region's start offset is always block start address. + */ + region_offset = region->offset; + } else + block_size = 1 << this->erase_shift; + + /* Start address must align on block boundary */ + if (unlikely((addr - region_offset) & (block_size - 1))) { + printk(KERN_ERR "%s: Unaligned address\n", __func__); + return -EINVAL; + } + /* Length must align on block boundary */ + if (unlikely(len & (block_size - 1))) { + printk(KERN_ERR "%s: Length not block aligned\n", __func__); + return -EINVAL; } - instr->state = MTD_ERASE_DONE; + instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; -erase_exit: + /* Grab the lock and see if the device is available */ + onenand_get_device(mtd, FL_ERASING); - ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; + ret = onenand_block_by_block_erase(mtd, instr, region, block_size); /* Deselect and wake up anyone waiting on the device */ onenand_release_device(mtd); /* Do call back function */ - if (!ret) + if (!ret) { + instr->state = MTD_ERASE_DONE; mtd_erase_callback(instr); + } return ret; } -- cgit v0.10.2 From 72073027ee95d059eb5a064da4a978efab36d4ab Mon Sep 17 00:00:00 2001 From: Mika Korhonen Date: Fri, 23 Oct 2009 07:50:43 +0200 Subject: mtd: OneNAND: multiblock erase support Add support for multiblock erase command. OneNANDs (excluding Flex-OneNAND) are capable of simultaneous erase of up to 64 eraseblocks which is much faster. This changes the erase requests for regions covering multiple eraseblocks to be performed using multiblock erase. Signed-off-by: Mika Korhonen Reviewed-by: Adrian Hunter Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 0108ed4..2dafd09 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c @@ -112,10 +112,24 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state) unsigned long timeout; u32 syscfg; - if (state == FL_RESETING) { - int i; + if (state == FL_RESETING || state == FL_PREPARING_ERASE || + state == FL_VERIFYING_ERASE) { + int i = 21; + unsigned int intr_flags = ONENAND_INT_MASTER; + + switch (state) { + case FL_RESETING: + intr_flags |= ONENAND_INT_RESET; + break; + case FL_PREPARING_ERASE: + intr_flags |= ONENAND_INT_ERASE; + break; + case FL_VERIFYING_ERASE: + i = 101; + break; + } - for (i = 0; i < 20; i++) { + while (--i) { udelay(1); intr = read_reg(c, ONENAND_REG_INTERRUPT); if (intr & ONENAND_INT_MASTER) @@ -126,7 +140,7 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state) wait_err("controller error", state, ctrl, intr); return -EIO; } - if (!(intr & ONENAND_INT_RESET)) { + if ((intr & intr_flags) != intr_flags) { wait_err("timeout", state, ctrl, intr); return -EIO; } diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 894ebad..266f471 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -34,6 +34,13 @@ #include +/* + * Multiblock erase if number of blocks to erase is 2 or more. + * Maximum number of blocks for simultaneous erase is 64. + */ +#define MB_ERASE_MIN_BLK_COUNT 2 +#define MB_ERASE_MAX_BLK_COUNT 64 + /* Default Flex-OneNAND boundary and lock respectively */ static int flex_bdry[MAX_DIES * 2] = { -1, 0, -1, 0 }; @@ -353,6 +360,8 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le break; case ONENAND_CMD_ERASE: + case ONENAND_CMD_MULTIBLOCK_ERASE: + case ONENAND_CMD_ERASE_VERIFY: case ONENAND_CMD_BUFFERRAM: case ONENAND_CMD_OTP_ACCESS: block = onenand_block(this, addr); @@ -497,7 +506,7 @@ static int onenand_wait(struct mtd_info *mtd, int state) if (interrupt & flags) break; - if (state != FL_READING) + if (state != FL_READING && state != FL_PREPARING_ERASE) cond_resched(); } /* To get correct interrupt status in timeout case */ @@ -530,6 +539,18 @@ static int onenand_wait(struct mtd_info *mtd, int state) return -EIO; } + if (state == FL_PREPARING_ERASE && !(interrupt & ONENAND_INT_ERASE)) { + printk(KERN_ERR "%s: mb erase timeout! ctrl=0x%04x intr=0x%04x\n", + __func__, ctrl, interrupt); + return -EIO; + } + + if (!(interrupt & ONENAND_INT_MASTER)) { + printk(KERN_ERR "%s: timeout! ctrl=0x%04x intr=0x%04x\n", + __func__, ctrl, interrupt); + return -EIO; + } + /* If there's controller error, it's a real error */ if (ctrl & ONENAND_CTRL_ERROR) { printk(KERN_ERR "%s: controller error = 0x%04x\n", @@ -2182,6 +2203,148 @@ static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allo return bbm->isbad_bbt(mtd, ofs, allowbbt); } + +static int onenand_multiblock_erase_verify(struct mtd_info *mtd, + struct erase_info *instr) +{ + struct onenand_chip *this = mtd->priv; + loff_t addr = instr->addr; + int len = instr->len; + unsigned int block_size = (1 << this->erase_shift); + int ret = 0; + + while (len) { + this->command(mtd, ONENAND_CMD_ERASE_VERIFY, addr, block_size); + ret = this->wait(mtd, FL_VERIFYING_ERASE); + if (ret) { + printk(KERN_ERR "%s: Failed verify, block %d\n", + __func__, onenand_block(this, addr)); + instr->state = MTD_ERASE_FAILED; + instr->fail_addr = addr; + return -1; + } + len -= block_size; + addr += block_size; + } + return 0; +} + +/** + * onenand_multiblock_erase - [Internal] erase block(s) using multiblock erase + * @param mtd MTD device structure + * @param instr erase instruction + * @param region erase region + * + * Erase one or more blocks up to 64 block at a time + */ +static int onenand_multiblock_erase(struct mtd_info *mtd, + struct erase_info *instr, + unsigned int block_size) +{ + struct onenand_chip *this = mtd->priv; + loff_t addr = instr->addr; + int len = instr->len; + int eb_count = 0; + int ret = 0; + int bdry_block = 0; + + instr->state = MTD_ERASING; + + if (ONENAND_IS_DDP(this)) { + loff_t bdry_addr = this->chipsize >> 1; + if (addr < bdry_addr && (addr + len) > bdry_addr) + bdry_block = bdry_addr >> this->erase_shift; + } + + /* Pre-check bbs */ + while (len) { + /* Check if we have a bad block, we do not erase bad blocks */ + if (onenand_block_isbad_nolock(mtd, addr, 0)) { + printk(KERN_WARNING "%s: attempt to erase a bad block " + "at addr 0x%012llx\n", + __func__, (unsigned long long) addr); + instr->state = MTD_ERASE_FAILED; + return -EIO; + } + len -= block_size; + addr += block_size; + } + + len = instr->len; + addr = instr->addr; + + /* loop over 64 eb batches */ + while (len) { + struct erase_info verify_instr = *instr; + int max_eb_count = MB_ERASE_MAX_BLK_COUNT; + + verify_instr.addr = addr; + verify_instr.len = 0; + + /* do not cross chip boundary */ + if (bdry_block) { + int this_block = (addr >> this->erase_shift); + + if (this_block < bdry_block) { + max_eb_count = min(max_eb_count, + (bdry_block - this_block)); + } + } + + eb_count = 0; + + while (len > block_size && eb_count < (max_eb_count - 1)) { + this->command(mtd, ONENAND_CMD_MULTIBLOCK_ERASE, + addr, block_size); + onenand_invalidate_bufferram(mtd, addr, block_size); + + ret = this->wait(mtd, FL_PREPARING_ERASE); + if (ret) { + printk(KERN_ERR "%s: Failed multiblock erase, " + "block %d\n", __func__, + onenand_block(this, addr)); + instr->state = MTD_ERASE_FAILED; + instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; + return -EIO; + } + + len -= block_size; + addr += block_size; + eb_count++; + } + + /* last block of 64-eb series */ + cond_resched(); + this->command(mtd, ONENAND_CMD_ERASE, addr, block_size); + onenand_invalidate_bufferram(mtd, addr, block_size); + + ret = this->wait(mtd, FL_ERASING); + /* Check if it is write protected */ + if (ret) { + printk(KERN_ERR "%s: Failed erase, block %d\n", + __func__, onenand_block(this, addr)); + instr->state = MTD_ERASE_FAILED; + instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; + return -EIO; + } + + len -= block_size; + addr += block_size; + eb_count++; + + /* verify */ + verify_instr.len = eb_count * block_size; + if (onenand_multiblock_erase_verify(mtd, &verify_instr)) { + instr->state = verify_instr.state; + instr->fail_addr = verify_instr.fail_addr; + return -EIO; + } + + } + return 0; +} + + /** * onenand_block_by_block_erase - [Internal] erase block(s) using regular erase * @param mtd MTD device structure @@ -2315,7 +2478,13 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) /* Grab the lock and see if the device is available */ onenand_get_device(mtd, FL_ERASING); - ret = onenand_block_by_block_erase(mtd, instr, region, block_size); + if (region || instr->len < MB_ERASE_MIN_BLK_COUNT * block_size) { + /* region is set for Flex-OneNAND (no mb erase) */ + ret = onenand_block_by_block_erase(mtd, instr, + region, block_size); + } else { + ret = onenand_multiblock_erase(mtd, instr, block_size); + } /* Deselect and wake up anyone waiting on the device */ onenand_release_device(mtd); diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h index f350a48..d0bf422 100644 --- a/include/linux/mtd/flashchip.h +++ b/include/linux/mtd/flashchip.h @@ -41,9 +41,11 @@ typedef enum { /* These 2 come from nand_state_t, which has been unified here */ FL_READING, FL_CACHEDPRG, - /* These 2 come from onenand_state_t, which has been unified here */ + /* These 4 come from onenand_state_t, which has been unified here */ FL_RESETING, FL_OTPING, + FL_PREPARING_ERASE, + FL_VERIFYING_ERASE, FL_UNKNOWN } flstate_t; diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h index acadbf5..cd6f3b4 100644 --- a/include/linux/mtd/onenand_regs.h +++ b/include/linux/mtd/onenand_regs.h @@ -131,6 +131,8 @@ #define ONENAND_CMD_LOCK_TIGHT (0x2C) #define ONENAND_CMD_UNLOCK_ALL (0x27) #define ONENAND_CMD_ERASE (0x94) +#define ONENAND_CMD_MULTIBLOCK_ERASE (0x95) +#define ONENAND_CMD_ERASE_VERIFY (0x71) #define ONENAND_CMD_RESET (0xF0) #define ONENAND_CMD_OTP_ACCESS (0x65) #define ONENAND_CMD_READID (0x90) -- cgit v0.10.2 From f369c7ec94da63fc68cf7fa43516414888865c14 Mon Sep 17 00:00:00 2001 From: Mika Korhonen Date: Fri, 23 Oct 2009 07:50:44 +0200 Subject: mtd: OneNAND: fix double printing of function name Signed-off-by: Mika Korhonen Reviewed-by: Adrian Hunter Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 266f471..3330ea0 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -3698,8 +3698,8 @@ int flexonenand_set_boundary(struct mtd_info *mtd, int die, this->command(mtd, ONENAND_CMD_ERASE, addr, 0); ret = this->wait(mtd, FL_ERASING); if (ret) { - printk(KERN_ERR "%s: flexonenand_set_boundary: " - "Failed PI erase for Die %d\n", __func__, die); + printk(KERN_ERR "%s: Failed PI erase for Die %d\n", + __func__, die); goto out; } -- cgit v0.10.2 From c9f7ec30848637989b85a9f0ac5d4aa33c49916e Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 23 Oct 2009 16:02:42 -0400 Subject: mtd: add missing put_chip() in cfi_intelext_reset() Signed-off-by: Nicolas Pitre Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index e7563a9..d923a2d 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -2564,6 +2564,7 @@ static int cfi_intelext_reset(struct mtd_info *mtd) if (!ret) { map_write(map, CMD(0xff), chip->start); chip->state = FL_SHUTDOWN; + put_chip(map, chip, chip->start); } spin_unlock(chip->mutex); } -- cgit v0.10.2 From 2af7c653993199fb32dc6d9504064a0c9c57e5d6 Mon Sep 17 00:00:00 2001 From: Simon Kagstrom Date: Mon, 5 Oct 2009 15:55:52 +0200 Subject: mtd: Add panic_write for NAND flashes This is a quick and dirty patch to add panic_write for NAND flashes. The patch seems to work OK on my CRIS board running a 2.6.26 kernel with a ID: 0x20, Chip ID: 0xf1 (ST Micro NAND 128MiB 3,3V 8-bit), and also on a OpenRD base (Marvell Kirkwood) board with a Toshiba NAND 512MiB 3,3V 8-bit flash with 2.6.32-pre1. Signed-off-by: Edgar E. Iglesias Signed-off-by: Simon Kagstrom Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 2957cc7..ba06473 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -428,6 +428,28 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, return nand_isbad_bbt(mtd, ofs, allowbbt); } +/** + * panic_nand_wait_ready - [GENERIC] Wait for the ready pin after commands. + * @mtd: MTD device structure + * @timeo: Timeout + * + * Helper function for nand_wait_ready used when needing to wait in interrupt + * context. + */ +static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo) +{ + struct nand_chip *chip = mtd->priv; + int i; + + /* Wait for the device to get ready */ + for (i = 0; i < timeo; i++) { + if (chip->dev_ready(mtd)) + break; + touch_softlockup_watchdog(); + mdelay(1); + } +} + /* * Wait for the ready pin, after a command * The timeout is catched later. @@ -437,6 +459,10 @@ void nand_wait_ready(struct mtd_info *mtd) struct nand_chip *chip = mtd->priv; unsigned long timeo = jiffies + 2; + /* 400ms timeout */ + if (in_interrupt() || oops_in_progress) + return panic_nand_wait_ready(mtd, 400); + led_trigger_event(nand_led_trigger, LED_FULL); /* wait until command is processed or timeout occures */ do { @@ -672,6 +698,22 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, } /** + * panic_nand_get_device - [GENERIC] Get chip for selected access + * @chip: the nand chip descriptor + * @mtd: MTD device structure + * @new_state: the state which is requested + * + * Used when in panic, no locks are taken. + */ +static void panic_nand_get_device(struct nand_chip *chip, + struct mtd_info *mtd, int new_state) +{ + /* Hardware controller shared among independend devices */ + chip->controller->active = chip; + chip->state = new_state; +} + +/** * nand_get_device - [GENERIC] Get chip for selected access * @chip: the nand chip descriptor * @mtd: MTD device structure @@ -710,6 +752,32 @@ nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state) } /** + * panic_nand_wait - [GENERIC] wait until the command is done + * @mtd: MTD device structure + * @chip: NAND chip structure + * @timeo: Timeout + * + * Wait for command done. This is a helper function for nand_wait used when + * we are in interrupt context. May happen when in panic and trying to write + * an oops trough mtdoops. + */ +static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip, + unsigned long timeo) +{ + int i; + for (i = 0; i < timeo; i++) { + if (chip->dev_ready) { + if (chip->dev_ready(mtd)) + break; + } else { + if (chip->read_byte(mtd) & NAND_STATUS_READY) + break; + } + mdelay(1); + } +} + +/** * nand_wait - [DEFAULT] wait until the command is done * @mtd: MTD device structure * @chip: NAND chip structure @@ -740,15 +808,19 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip) else chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); - while (time_before(jiffies, timeo)) { - if (chip->dev_ready) { - if (chip->dev_ready(mtd)) - break; - } else { - if (chip->read_byte(mtd) & NAND_STATUS_READY) - break; + if (in_interrupt() || oops_in_progress) + panic_nand_wait(mtd, chip, timeo); + else { + while (time_before(jiffies, timeo)) { + if (chip->dev_ready) { + if (chip->dev_ready(mtd)) + break; + } else { + if (chip->read_byte(mtd) & NAND_STATUS_READY) + break; + } + cond_resched(); } - cond_resched(); } led_trigger_event(nand_led_trigger, LED_OFF); @@ -1949,6 +2021,45 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, } /** + * panic_nand_write - [MTD Interface] NAND write with ECC + * @mtd: MTD device structure + * @to: offset to write to + * @len: number of bytes to write + * @retlen: pointer to variable to store the number of written bytes + * @buf: the data to write + * + * NAND write with ECC. Used when performing writes in interrupt context, this + * may for example be called by mtdoops when writing an oops while in panic. + */ +static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const uint8_t *buf) +{ + struct nand_chip *chip = mtd->priv; + int ret; + + /* Do not allow reads past end of device */ + if ((to + len) > mtd->size) + return -EINVAL; + if (!len) + return 0; + + /* Wait for the device to get ready. */ + panic_nand_wait(mtd, chip, 400); + + /* Grab the device. */ + panic_nand_get_device(chip, mtd, FL_WRITING); + + chip->ops.len = len; + chip->ops.datbuf = (uint8_t *)buf; + chip->ops.oobbuf = NULL; + + ret = nand_do_write_ops(mtd, to, &chip->ops); + + *retlen = chip->ops.retlen; + return ret; +} + +/** * nand_write - [MTD Interface] NAND write with ECC * @mtd: MTD device structure * @to: offset to write to @@ -2877,6 +2988,7 @@ int nand_scan_tail(struct mtd_info *mtd) mtd->unpoint = NULL; mtd->read = nand_read; mtd->write = nand_write; + mtd->panic_write = panic_nand_write; mtd->read_oob = nand_read_oob; mtd->write_oob = nand_write_oob; mtd->sync = nand_sync; -- cgit v0.10.2 From d6587feaf0ed7511b3d0b52bcaae8ecd0949d3af Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 30 Oct 2009 17:54:33 +0100 Subject: mtd: ixp4xx map: use resource_size Use the resource_size inline function instead of manually calculating the resource size. This reduces the chance of introducing off-by-one errors. Signed-off-by: Tobias Klauser Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c index 7214b87..7b05152 100644 --- a/drivers/mtd/maps/ixp4xx.c +++ b/drivers/mtd/maps/ixp4xx.c @@ -210,7 +210,7 @@ static int ixp4xx_flash_probe(struct platform_device *dev) * not attempt to do a direct access on us. */ info->map.phys = NO_XIP; - info->map.size = dev->resource->end - dev->resource->start + 1; + info->map.size = resource_size(dev->resource); /* * We only support 16-bit accesses for now. If and when @@ -224,7 +224,7 @@ static int ixp4xx_flash_probe(struct platform_device *dev) info->map.copy_from = ixp4xx_copy_from, info->res = request_mem_region(dev->resource->start, - dev->resource->end - dev->resource->start + 1, + resource_size(dev->resource), "IXP4XXFlash"); if (!info->res) { printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n"); @@ -233,7 +233,7 @@ static int ixp4xx_flash_probe(struct platform_device *dev) } info->map.virt = ioremap(dev->resource->start, - dev->resource->end - dev->resource->start + 1); + resource_size(dev->resource)); if (!info->map.virt) { printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n"); err = -EIO; -- cgit v0.10.2 From 6eb4feffb9d619a44fe434e777ef095a29cf4759 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 2 Nov 2009 23:40:48 +0900 Subject: mtd: txx9ndfmc: Use nand_release to free resources This patch fixes memory leak on chip->bbt and chip->buffers. Signed-off-by: Atsushi Nemoto Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c index 73af832..863513c 100644 --- a/drivers/mtd/nand/txx9ndfmc.c +++ b/drivers/mtd/nand/txx9ndfmc.c @@ -429,11 +429,10 @@ static int __exit txx9ndfmc_remove(struct platform_device *dev) chip = mtd->priv; txx9_priv = chip->priv; + nand_release(mtd); #ifdef CONFIG_MTD_PARTITIONS - del_mtd_partitions(mtd); kfree(drvdata->parts[i]); #endif - del_mtd_device(mtd); kfree(txx9_priv->mtdname); kfree(txx9_priv); } -- cgit v0.10.2 From b1c6e6db5bb7acad82e1c64914c6a9404dae3ee1 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 2 Nov 2009 18:12:33 +0000 Subject: mtd: nand: add option to quieten off the no device found messgae Add NAND_SCAN_SILENT_NODEV to chip->options to the user-worrying messages 'No NAND device found!!!'. This message often worries users (was three exclamation marks really necessary?) and especially in systems such as the Simtec Osiris where there may be optional NAND devices which are not known until probe time. Revised version of the original NAND_PROBE_SPECULATIVE patch after comments by Artem Bityutskiy about adding a whole new call. Signed-off-by: Ben Dooks Signed-off-by: Simtec Linux Team Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index ba06473..724cb2c 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2756,7 +2756,8 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips) type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id); if (IS_ERR(type)) { - printk(KERN_WARNING "No NAND device found!!!\n"); + if (!(chip->options & NAND_SCAN_SILENT_NODEV)) + printk(KERN_WARNING "No NAND device found.\n"); chip->select_chip(mtd, -1); return PTR_ERR(type); } diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 2476078..ccab9df 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -170,7 +170,6 @@ typedef enum { /* Chip does not allow subpage writes */ #define NAND_NO_SUBPAGE_WRITE 0x00000200 - /* Options valid for Samsung large page devices */ #define NAND_SAMSUNG_LP_OPTIONS \ (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK) @@ -196,6 +195,9 @@ typedef enum { /* This option is defined if the board driver allocates its own buffers (e.g. because it needs them DMA-coherent */ #define NAND_OWN_BUFFERS 0x00040000 +/* Chip may not exist, so silence any errors in scan */ +#define NAND_SCAN_SILENT_NODEV 0x00080000 + /* Options set by nand scan */ /* Nand scan has allocated controller struct */ #define NAND_CONTROLLER_ALLOC 0x80000000 -- cgit v0.10.2 From 74218fedf478323cce831b51507eebd1faf0bf7f Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 2 Nov 2009 18:12:51 +0000 Subject: mtd: s3c2410: propagate nand options from the platform data Update the nand information passed to the core from the platform data to setup the initial option value, so that flags such as NAND_SCAN_SILENT_NODEV can pass through. Signed-off-by: Ben Dooks Signed-off-by: Simtec Linux Team Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/arch/arm/plat-s3c/include/plat/nand.h b/arch/arm/plat-s3c/include/plat/nand.h index 18f9588..afd1673 100644 --- a/arch/arm/plat-s3c/include/plat/nand.h +++ b/arch/arm/plat-s3c/include/plat/nand.h @@ -17,6 +17,7 @@ * Setting this flag will allow the kernel to * look for it at boot time and also skip the NAND * scan. + * @options: Default value to set into 'struct nand_chip' options. * @nr_chips: Number of chips in this set * @nr_partitions: Number of partitions pointed to by @partitions * @name: Name of set (optional) @@ -31,6 +32,7 @@ struct s3c2410_nand_set { unsigned int disable_ecc:1; unsigned int flash_bbt:1; + unsigned int options; int nr_chips; int nr_partitions; char *name; diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 11dc7e6..6e88bd3 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -774,7 +774,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, chip->select_chip = s3c2410_nand_select_chip; chip->chip_delay = 50; chip->priv = nmtd; - chip->options = 0; + chip->options = set->options; chip->controller = &info->controller; switch (info->cpu_type) { -- cgit v0.10.2 From 61c3506c2cabe58bcdfe438d1e57b62994db1616 Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Wed, 28 Oct 2009 14:21:37 +0100 Subject: mtd: m25p80: make command buffer DMA-safe spi_write() requires the buffer to be DMA-safe, kmalloc() it seperately to ensure this. Signed-off-by: Johannes Stezenbach Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 933267a..291d5d9 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -78,7 +78,7 @@ struct m25p { struct mtd_info mtd; unsigned partitioned:1; u8 erase_opcode; - u8 command[CMD_SIZE + FAST_READ_DUMMY_BYTE]; + u8 *command; }; static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) @@ -769,6 +769,11 @@ static int __devinit m25p_probe(struct spi_device *spi) flash = kzalloc(sizeof *flash, GFP_KERNEL); if (!flash) return -ENOMEM; + flash->command = kmalloc(CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL); + if (!flash->command) { + kfree(flash); + return -ENOMEM; + } flash->spi = spi; mutex_init(&flash->lock); @@ -888,8 +893,10 @@ static int __devexit m25p_remove(struct spi_device *spi) status = del_mtd_partitions(&flash->mtd); else status = del_mtd_device(&flash->mtd); - if (status == 0) + if (status == 0) { + kfree(flash->command); kfree(flash); + } return 0; } -- cgit v0.10.2 From 35016dd7e92cf0eb5ae2e811445dd52320c348d0 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Tue, 3 Nov 2009 20:49:18 +0100 Subject: mtd: ensure index is positive The index is signed, make sure it is not negative when we read the array element. Signed-off-by: Roel Kluin Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 467a4f1..c356c0a 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -447,7 +447,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) for (i=0; i< MAX_MTD_DEVICES; i++) if (mtd_table[i] == mtd) ret = mtd_table[i]; - } else if (num < MAX_MTD_DEVICES) { + } else if (num >= 0 && num < MAX_MTD_DEVICES) { ret = mtd_table[num]; if (mtd && mtd != ret) ret = NULL; diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index d120cd8..071a60c 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -112,7 +112,7 @@ static void fun_select_chip(struct mtd_info *mtd, int mchip_nr) if (mchip_nr == -1) { chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE); - } else if (mchip_nr >= 0) { + } else if (mchip_nr >= 0 && mchip_nr < NAND_MAX_CHIPS) { fun->mchip_number = mchip_nr; chip->IO_ADDR_R = fun->io_base + fun->mchip_offsets[mchip_nr]; chip->IO_ADDR_W = chip->IO_ADDR_R; -- cgit v0.10.2 From 8dbaea4bfcecacaf496a3e2ae92867baedbcab8e Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Thu, 5 Nov 2009 15:53:37 +0100 Subject: mtd: add lock fixup for AT49BV640D and AT49BV640DT chips This patch sets the MTD_POWERUP_LOCK flag for AT49BV640D and AT49BV640DT devices, since the devices are locked when powered up and needs to be unlocked before interfaced. Quote datasheet; "At power-up and reset, all sectors have their Softlock protection mode enabled.". Tested on AVR32 hardware platform with an AT49BV640D flash device. Signed-off-by: Hans-Christian Egtvedt Acked-by: Nicolas Pitre Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index d923a2d..94be67e 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -51,7 +51,9 @@ #define M50LPW080 0x002F #define M50FLW080A 0x0080 #define M50FLW080B 0x0081 +/* Atmel chips */ #define AT49BV640D 0x02de +#define AT49BV640DT 0x02db static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); @@ -199,6 +201,16 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) cfi->cfiq->BufWriteTimeoutMax = 0; } +static void fixup_at49bv640dx_lock(struct mtd_info *mtd, void *param) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + struct cfi_pri_intelext *cfip = cfi->cmdset_priv; + + cfip->FeatureSupport |= (1 << 5); + mtd->flags |= MTD_POWERUP_LOCK; +} + #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE /* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) @@ -283,6 +295,8 @@ static void fixup_unlock_powerup_lock(struct mtd_info *mtd, void *param) static struct cfi_fixup cfi_fixup_table[] = { { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, + { CFI_MFR_ATMEL, AT49BV640D, fixup_at49bv640dx_lock, NULL }, + { CFI_MFR_ATMEL, AT49BV640DT, fixup_at49bv640dx_lock, NULL }, #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, #endif -- cgit v0.10.2 From b2ef1a2bb2eb49cd7c75b22f1ea40ead0bdfdb8a Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Thu, 5 Nov 2009 15:53:43 +0100 Subject: mtd: move manufacturer to the common cfi.h header file This patch moves the MANUFACTURER_ST and MANUFACTURER_INTEL to the include/linux/mtd/cfi.h header file and renames them to CFI_MFR_ST and CFI_MFR_INTEL. CFI_MFR_ST was already present there. All references in drivers/mtd/chips/cfi_cmdset_0001.c are updated to reflect this. Signed-off-by: Hans-Christian Egtvedt Acked-by: Nicolas Pitre Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 94be67e..5fbf29e 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -43,11 +43,11 @@ // debugging, turns off buffer write mode if set to 1 #define FORCE_WORD_WRITE 0 -#define MANUFACTURER_INTEL 0x0089 +/* Intel chips */ #define I82802AB 0x00ad #define I82802AC 0x00ac #define PF38F4476 0x881c -#define MANUFACTURER_ST 0x0020 +/* STMicroelectronics chips */ #define M50LPW080 0x002F #define M50FLW080A 0x0080 #define M50FLW080B 0x0081 @@ -308,16 +308,16 @@ static struct cfi_fixup cfi_fixup_table[] = { #endif { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct, NULL }, { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb, NULL }, - { MANUFACTURER_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock, NULL, }, + { CFI_MFR_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock, NULL, }, { 0, 0, NULL, NULL } }; static struct cfi_fixup jedec_fixup_table[] = { - { MANUFACTURER_INTEL, I82802AB, fixup_use_fwh_lock, NULL, }, - { MANUFACTURER_INTEL, I82802AC, fixup_use_fwh_lock, NULL, }, - { MANUFACTURER_ST, M50LPW080, fixup_use_fwh_lock, NULL, }, - { MANUFACTURER_ST, M50FLW080A, fixup_use_fwh_lock, NULL, }, - { MANUFACTURER_ST, M50FLW080B, fixup_use_fwh_lock, NULL, }, + { CFI_MFR_INTEL, I82802AB, fixup_use_fwh_lock, NULL, }, + { CFI_MFR_INTEL, I82802AC, fixup_use_fwh_lock, NULL, }, + { CFI_MFR_ST, M50LPW080, fixup_use_fwh_lock, NULL, }, + { CFI_MFR_ST, M50FLW080A, fixup_use_fwh_lock, NULL, }, + { CFI_MFR_ST, M50FLW080B, fixup_use_fwh_lock, NULL, }, { 0, 0, NULL, NULL } }; static struct cfi_fixup fixup_table[] = { @@ -333,7 +333,7 @@ static struct cfi_fixup fixup_table[] = { static void cfi_fixup_major_minor(struct cfi_private *cfi, struct cfi_pri_intelext *extp) { - if (cfi->mfr == MANUFACTURER_INTEL && + if (cfi->mfr == CFI_MFR_INTEL && cfi->id == PF38F4476 && extp->MinorVersion == '3') extp->MinorVersion = '1'; } @@ -2249,7 +2249,7 @@ static int cfi_intelext_otp_walk(struct mtd_info *mtd, loff_t from, size_t len, /* Some chips have OTP located in the _top_ partition only. For example: Intel 28F256L18T (T means top-parameter device) */ - if (cfi->mfr == MANUFACTURER_INTEL) { + if (cfi->mfr == CFI_MFR_INTEL) { switch (cfi->id) { case 0x880b: case 0x880c: diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index 88d3d8f..df89f42 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h @@ -518,10 +518,11 @@ struct cfi_fixup { #define CFI_MFR_ANY 0xffff #define CFI_ID_ANY 0xffff -#define CFI_MFR_AMD 0x0001 -#define CFI_MFR_ATMEL 0x001F -#define CFI_MFR_SAMSUNG 0x00EC -#define CFI_MFR_ST 0x0020 /* STMicroelectronics */ +#define CFI_MFR_AMD 0x0001 +#define CFI_MFR_INTEL 0x0089 +#define CFI_MFR_ATMEL 0x001F +#define CFI_MFR_SAMSUNG 0x00EC +#define CFI_MFR_ST 0x0020 /* STMicroelectronics */ void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup* fixups); -- cgit v0.10.2 From 895fb49459227edbb4a4e5a2b5e9d12c34640f84 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Wed, 11 Nov 2009 21:47:06 +0100 Subject: mtd: error return -EIO instead of EIO Return a negative error value instead of a positive Signed-off-by: Roel Kluin Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 3f13a96..d9603f7 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c @@ -129,7 +129,7 @@ static int physmap_flash_probe(struct platform_device *dev) info->map[i].size); if (info->map[i].virt == NULL) { dev_err(&dev->dev, "Failed to ioremap flash region\n"); - err = EIO; + err = -EIO; goto err_out; } diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c index 1008462..82afad0 100644 --- a/drivers/mtd/maps/vmu-flash.c +++ b/drivers/mtd/maps/vmu-flash.c @@ -620,7 +620,7 @@ static int __devinit vmu_connect(struct maple_device *mdev) card = kmalloc(sizeof(struct memcard), GFP_KERNEL); if (!card) { - error = ENOMEM; + error = -ENOMEM; goto fail_nomem; } diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 4f62d20..524e6c9 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -463,7 +463,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev) if (host->board->det_pin) { if (gpio_get_value(host->board->det_pin)) { printk(KERN_INFO "No SmartMedia card inserted.\n"); - res = ENXIO; + res = -ENXIO; goto err_no_card; } } @@ -534,7 +534,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev) if ((!partitions) || (num_partitions == 0)) { printk(KERN_ERR "atmel_nand: No partitions defined, or unsupported device.\n"); - res = ENXIO; + res = -ENXIO; goto err_no_partitions; } -- cgit v0.10.2 From e670e41ae0f329487e5a5c357510c6798b0d80b4 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Thu, 12 Nov 2009 18:09:48 +0100 Subject: jffs2: Fix error return in jffs2_do_read_inode_internal() The returned error should stay negative Signed-off-by: Roel Kluin Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 1a80301..9c26738 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c @@ -1284,7 +1284,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, f->target = NULL; mutex_unlock(&f->sem); jffs2_do_clear_inode(c, f); - return -ret; + return ret; } f->target[je32_to_cpu(latest_node->csize)] = '\0'; -- cgit v0.10.2 From 54c69cc25064c1d333a12b5883aaa3bfa3041dee Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 13 Nov 2009 16:02:22 +0900 Subject: mtd: alauda: Use hweight8 Signed-off-by: Akinobu Mita Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/alauda.c b/drivers/mtd/nand/alauda.c index 6d96491..2d67732 100644 --- a/drivers/mtd/nand/alauda.c +++ b/drivers/mtd/nand/alauda.c @@ -372,15 +372,6 @@ static int alauda_read_oob(struct mtd_info *mtd, loff_t from, void *oob) return __alauda_read_page(mtd, from, ignore_buf, oob); } -static int popcount8(u8 c) -{ - int ret = 0; - - for ( ; c; c>>=1) - ret += c & 1; - return ret; -} - static int alauda_isbad(struct mtd_info *mtd, loff_t ofs) { u8 oob[16]; @@ -391,7 +382,7 @@ static int alauda_isbad(struct mtd_info *mtd, loff_t ofs) return err; /* A block is marked bad if two or more bits are zero */ - return popcount8(oob[5]) >= 7 ? 0 : 1; + return hweight8(oob[5]) >= 7 ? 0 : 1; } static int alauda_bounce_read(struct mtd_info *mtd, loff_t from, size_t len, -- cgit v0.10.2 From b3a70f0bc32d1b70584bcaa6019fa4260b0da92e Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Fri, 13 Nov 2009 14:12:16 -0600 Subject: mtd: eLBC NAND: increase bus timeout to maximum When a NAND operation is in progress, all other localbus operations (including NOR flash) will have to wait for access to the bus. However, the NAND operation may take longer to complete than the default timeout. Thus, if NOR is accessed while a NAND operation is in progress, the NAND operation will fail. Signed-off-by: Scott Wood Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index ddd37d2..58db278 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -946,6 +946,13 @@ static int __devinit fsl_elbc_ctrl_init(struct fsl_elbc_ctrl *ctrl) { struct fsl_lbc_regs __iomem *lbc = ctrl->regs; + /* + * NAND transactions can tie up the bus for a long time, so set the + * bus timeout to max by clearing LBCR[BMT] (highest base counter + * value) and setting LBCR[BMTPS] to the highest prescaler value. + */ + clrsetbits_be32(&lbc->lbcr, LBCR_BMT, 15); + /* clear event registers */ setbits32(&lbc->ltesr, LTESR_NAND_MASK); out_be32(&lbc->lteatr, 0); -- cgit v0.10.2 From 476459a6cf46d20ec73d9b211f3894ced5f9871e Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Fri, 13 Nov 2009 14:13:01 -0600 Subject: mtd: eLBC NAND: use recommended command sequences Currently, the program and erase sequences do not wait for completion, instead relying on a subsequent waitfunc() callback. However, this causes the chipselect to be deasserted while the NAND chip is still asserting the busy pin, which can corrupt activity on other chipselects. This patch switches to using the sequences recommended by the manual, in which a wait is performed within the initial command sequence. We can now re-use the status byte from the initial command sequence, rather than having to do another status read in the waitfunc. Since we're already touching the command sequences, it also cleans up some cruft in SEQIN that isn't needed since we cannot program partial pages outside of OOB. Signed-off-by: Scott Wood Reported-by: Suchit Lepcha Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 58db278..5b51ed3 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -253,17 +253,17 @@ static void fsl_elbc_do_read(struct nand_chip *chip, int oob) if (priv->page_size) { out_be32(&lbc->fir, - (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_CM0 << FIR_OP0_SHIFT) | (FIR_OP_CA << FIR_OP1_SHIFT) | (FIR_OP_PA << FIR_OP2_SHIFT) | - (FIR_OP_CW1 << FIR_OP3_SHIFT) | + (FIR_OP_CM1 << FIR_OP3_SHIFT) | (FIR_OP_RBW << FIR_OP4_SHIFT)); out_be32(&lbc->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) | (NAND_CMD_READSTART << FCR_CMD1_SHIFT)); } else { out_be32(&lbc->fir, - (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_CM0 << FIR_OP0_SHIFT) | (FIR_OP_CA << FIR_OP1_SHIFT) | (FIR_OP_PA << FIR_OP2_SHIFT) | (FIR_OP_RBW << FIR_OP3_SHIFT)); @@ -332,7 +332,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, case NAND_CMD_READID: dev_vdbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_READID.\n"); - out_be32(&lbc->fir, (FIR_OP_CW0 << FIR_OP0_SHIFT) | + out_be32(&lbc->fir, (FIR_OP_CM0 << FIR_OP0_SHIFT) | (FIR_OP_UA << FIR_OP1_SHIFT) | (FIR_OP_RBW << FIR_OP2_SHIFT)); out_be32(&lbc->fcr, NAND_CMD_READID << FCR_CMD0_SHIFT); @@ -359,16 +359,20 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, dev_vdbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_ERASE2.\n"); out_be32(&lbc->fir, - (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_CM0 << FIR_OP0_SHIFT) | (FIR_OP_PA << FIR_OP1_SHIFT) | - (FIR_OP_CM1 << FIR_OP2_SHIFT)); + (FIR_OP_CM2 << FIR_OP2_SHIFT) | + (FIR_OP_CW1 << FIR_OP3_SHIFT) | + (FIR_OP_RS << FIR_OP4_SHIFT)); out_be32(&lbc->fcr, (NAND_CMD_ERASE1 << FCR_CMD0_SHIFT) | - (NAND_CMD_ERASE2 << FCR_CMD1_SHIFT)); + (NAND_CMD_STATUS << FCR_CMD1_SHIFT) | + (NAND_CMD_ERASE2 << FCR_CMD2_SHIFT)); out_be32(&lbc->fbcr, 0); ctrl->read_bytes = 0; + ctrl->use_mdr = 1; fsl_elbc_run_command(mtd); return; @@ -383,40 +387,41 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, ctrl->column = column; ctrl->oob = 0; + ctrl->use_mdr = 1; - if (priv->page_size) { - fcr = (NAND_CMD_SEQIN << FCR_CMD0_SHIFT) | - (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT); + fcr = (NAND_CMD_STATUS << FCR_CMD1_SHIFT) | + (NAND_CMD_SEQIN << FCR_CMD2_SHIFT) | + (NAND_CMD_PAGEPROG << FCR_CMD3_SHIFT); + if (priv->page_size) { out_be32(&lbc->fir, - (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_CM2 << FIR_OP0_SHIFT) | (FIR_OP_CA << FIR_OP1_SHIFT) | (FIR_OP_PA << FIR_OP2_SHIFT) | (FIR_OP_WB << FIR_OP3_SHIFT) | - (FIR_OP_CW1 << FIR_OP4_SHIFT)); + (FIR_OP_CM3 << FIR_OP4_SHIFT) | + (FIR_OP_CW1 << FIR_OP5_SHIFT) | + (FIR_OP_RS << FIR_OP6_SHIFT)); } else { - fcr = (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT) | - (NAND_CMD_SEQIN << FCR_CMD2_SHIFT); - out_be32(&lbc->fir, - (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_CM0 << FIR_OP0_SHIFT) | (FIR_OP_CM2 << FIR_OP1_SHIFT) | (FIR_OP_CA << FIR_OP2_SHIFT) | (FIR_OP_PA << FIR_OP3_SHIFT) | (FIR_OP_WB << FIR_OP4_SHIFT) | - (FIR_OP_CW1 << FIR_OP5_SHIFT)); + (FIR_OP_CM3 << FIR_OP5_SHIFT) | + (FIR_OP_CW1 << FIR_OP6_SHIFT) | + (FIR_OP_RS << FIR_OP7_SHIFT)); if (column >= mtd->writesize) { /* OOB area --> READOOB */ column -= mtd->writesize; fcr |= NAND_CMD_READOOB << FCR_CMD0_SHIFT; ctrl->oob = 1; - } else if (column < 256) { + } else { + WARN_ON(column != 0); /* First 256 bytes --> READ0 */ fcr |= NAND_CMD_READ0 << FCR_CMD0_SHIFT; - } else { - /* Second 256 bytes --> READ1 */ - fcr |= NAND_CMD_READ1 << FCR_CMD0_SHIFT; } } @@ -628,22 +633,6 @@ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip) { struct fsl_elbc_mtd *priv = chip->priv; struct fsl_elbc_ctrl *ctrl = priv->ctrl; - struct fsl_lbc_regs __iomem *lbc = ctrl->regs; - - if (ctrl->status != LTESR_CC) - return NAND_STATUS_FAIL; - - /* Use READ_STATUS command, but wait for the device to be ready */ - ctrl->use_mdr = 0; - out_be32(&lbc->fir, - (FIR_OP_CW0 << FIR_OP0_SHIFT) | - (FIR_OP_RBW << FIR_OP1_SHIFT)); - out_be32(&lbc->fcr, NAND_CMD_STATUS << FCR_CMD0_SHIFT); - out_be32(&lbc->fbcr, 1); - set_addr(mtd, 0, 0, 0); - ctrl->read_bytes = 1; - - fsl_elbc_run_command(mtd); if (ctrl->status != LTESR_CC) return NAND_STATUS_FAIL; @@ -651,8 +640,7 @@ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip) /* The chip always seems to report that it is * write-protected, even when it is not. */ - setbits8(ctrl->addr, NAND_STATUS_WP); - return fsl_elbc_read_byte(mtd); + return (ctrl->mdr & 0xff) | NAND_STATUS_WP; } static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) -- cgit v0.10.2 From c1317f7163d287805b8e12af12d04a2a6ead865c Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Fri, 13 Nov 2009 14:14:15 -0600 Subject: mtd: eLBC NAND: give more verbose output on error We want error information even if the kernel hasn't been built for verbose debugging. Signed-off-by: Scott Wood Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 5b51ed3..ae30fb6 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -237,12 +237,15 @@ static int fsl_elbc_run_command(struct mtd_info *mtd) ctrl->use_mdr = 0; - dev_vdbg(ctrl->dev, - "fsl_elbc_run_command: stat=%08x mdr=%08x fmr=%08x\n", - ctrl->status, ctrl->mdr, in_be32(&lbc->fmr)); + if (ctrl->status != LTESR_CC) { + dev_info(ctrl->dev, + "command failed: fir %x fcr %x status %x mdr %x\n", + in_be32(&lbc->fir), in_be32(&lbc->fcr), + ctrl->status, ctrl->mdr); + return -EIO; + } - /* returns 0 on success otherwise non-zero) */ - return ctrl->status == LTESR_CC ? 0 : -EIO; + return 0; } static void fsl_elbc_do_read(struct nand_chip *chip, int oob) -- cgit v0.10.2 From 2695eab964efaa382168e0351705967bd9deb7ea Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Thu, 19 Nov 2009 12:01:58 +0100 Subject: mtd: CFI cmdset_0002: enable erase-suspend-program Erase-suspend for writing is required to avoid blocking applications that wish to write some data (to a NOR block other than the one being erased). Particularly, it solves some huge delays that an application (which writes to a UBIFS) will experience if UBI attaches to empty NOR flash. In this case the UBI background thread will erase a lot of blocks and the application can be blocked for minutes because of the "MTD/CFI chip lock". This feature has been disabled for years. Maybe this was because the old code turned it on for erase-suspend read-only chips also (cfip->EraseSuspend & 0x1). This is wrong and corrected now. This patch was tweaked by Norbert van Bolhuis. Signed-off-by: Norbert van Bolhuis Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 94bb61e..1d49e18 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -490,10 +490,6 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd) } #endif - /* FIXME: erase-suspend-program is broken. See - http://lists.infradead.org/pipermail/linux-mtd/2003-December/009001.html */ - printk(KERN_NOTICE "cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.\n"); - __module_get(THIS_MODULE); return mtd; @@ -589,15 +585,9 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr return 0; case FL_ERASING: - if (mode == FL_WRITING) /* FIXME: Erase-suspend-program appears broken. */ - goto sleep; - - if (!( mode == FL_READY - || mode == FL_POINT - || !cfip - || (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)) - || (mode == FL_WRITING && (cfip->EraseSuspend & 0x1) - ))) + if (!cfip || !(cfip->EraseSuspend & (0x1|0x2)) || + !(mode == FL_READY || mode == FL_POINT || + (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)))) goto sleep; /* We could check to see if we're trying to access the sector -- cgit v0.10.2 From 0fed784b0f1ecf57d568ae60b2cada43f9d90759 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sat, 21 Nov 2009 16:34:36 +0100 Subject: JFFS2: fix min/max confusion MAX_SUMMARY_SIZE was meant as a limit, not as a minimum Signed-off-by: Roel Kluin Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c index 6caf1e1e..800171d 100644 --- a/fs/jffs2/summary.c +++ b/fs/jffs2/summary.c @@ -23,7 +23,7 @@ int jffs2_sum_init(struct jffs2_sb_info *c) { - uint32_t sum_size = max_t(uint32_t, c->sector_size, MAX_SUMMARY_SIZE); + uint32_t sum_size = min_t(uint32_t, c->sector_size, MAX_SUMMARY_SIZE); c->summary = kzalloc(sizeof(struct jffs2_summary), GFP_KERNEL); -- cgit v0.10.2 From 8fead79c96c68164372c47c7b3c79d2da0871c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 24 Nov 2009 22:06:58 +0100 Subject: mtd: move excite_nand_remove to .devexit.text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function excite_nand_remove is used only wrapped by __devexit_p so define it using __devexit. Signed-off-by: Uwe Kleine-König Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/excite_nandflash.c b/drivers/mtd/nand/excite_nandflash.c index 72446fb..af6a6a5 100644 --- a/drivers/mtd/nand/excite_nandflash.c +++ b/drivers/mtd/nand/excite_nandflash.c @@ -128,7 +128,7 @@ static int excite_nand_devready(struct mtd_info *mtd) * The binding to the mtd and all allocated * resources are released. */ -static int __exit excite_nand_remove(struct platform_device *dev) +static int __devexit excite_nand_remove(struct platform_device *dev) { struct excite_nand_drvdata * const this = platform_get_drvdata(dev); -- cgit v0.10.2 From daa0f15a8dc6ef81655c7853f84a3670be7d144a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 24 Nov 2009 22:07:08 +0100 Subject: mtd: don't use __exit_p to wrap mxcnd_remove MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function mxcnd_remove is defined using __devexit, so don't use __exit_p but __devexit_p to wrap it. Signed-off-by: Uwe Kleine-König Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 06c5314..4bc43eb 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -1099,7 +1099,7 @@ static struct platform_driver mxcnd_driver = { .driver = { .name = DRIVER_NAME, }, - .remove = __exit_p(mxcnd_remove), + .remove = __devexit_p(mxcnd_remove), .suspend = mxcnd_suspend, .resume = mxcnd_resume, }; -- cgit v0.10.2 From 4c2b8a62bb0e35f2db0f713b4101b265be7fa985 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 27 Nov 2009 16:58:08 +0200 Subject: mtd: make pagetest work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mtd_pagetest test did not initialize the pgsize variable, which basically means it did not work. This problem was reported by Török Edwin Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/tests/mtd_pagetest.c b/drivers/mtd/tests/mtd_pagetest.c index 103cac4..ce17cbe 100644 --- a/drivers/mtd/tests/mtd_pagetest.c +++ b/drivers/mtd/tests/mtd_pagetest.c @@ -523,6 +523,7 @@ static int __init mtd_pagetest_init(void) do_div(tmp, mtd->erasesize); ebcnt = tmp; pgcnt = mtd->erasesize / mtd->writesize; + pgsize = mtd->writesize; printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " "page size %u, count of eraseblocks %u, pages per " -- cgit v0.10.2 From b34bc037b26e621e5fc13466767e4da110a7b3d3 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 12 Oct 2009 20:24:35 +0400 Subject: mtd: m25p80: Convert to device table matching This patch converts the m25p80 driver so that now it uses .id_table for device matching, making it properly detect devices on OpenFirmware platforms (prior to this patch the driver misdetected non-JEDEC chips, seeing all chips as "m25p80"). Also, now jedec_probe() only does jedec probing, nothing else. If it is not able to detect a chip, NULL is returned and the driver fall backs to the information specified by the platform (platform_data, or exact ID). Signed-off-by: Anton Vorontsov Signed-off-by: David Woodhouse diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 291d5d9..47486fb 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -581,8 +582,6 @@ time_out: */ struct flash_info { - char *name; - /* JEDEC id zero means "no ID" (most older chips); otherwise it has * a high byte of zero plus three data bytes: the manufacturer id, * then a two byte device id. @@ -600,83 +599,92 @@ struct flash_info { #define SECT_4K 0x01 /* OPCODE_BE_4K works uniformly */ }; +#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ + ((kernel_ulong_t)&(struct flash_info) { \ + .jedec_id = (_jedec_id), \ + .ext_id = (_ext_id), \ + .sector_size = (_sector_size), \ + .n_sectors = (_n_sectors), \ + .flags = (_flags), \ + }) /* NOTE: double check command sets and memory organization when you add * more flash chips. This current list focusses on newer chips, which * have been converging on command sets which including JEDEC ID. */ -static struct flash_info __devinitdata m25p_data [] = { - +static const struct spi_device_id m25p_ids[] = { /* Atmel -- some are (confusingly) marketed as "DataFlash" */ - { "at25fs010", 0x1f6601, 0, 32 * 1024, 4, SECT_4K, }, - { "at25fs040", 0x1f6604, 0, 64 * 1024, 8, SECT_4K, }, + { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) }, + { "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) }, - { "at25df041a", 0x1f4401, 0, 64 * 1024, 8, SECT_4K, }, - { "at25df641", 0x1f4800, 0, 64 * 1024, 128, SECT_4K, }, + { "at25df041a", INFO(0x1f4401, 0, 64 * 1024, 8, SECT_4K) }, + { "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) }, - { "at26f004", 0x1f0400, 0, 64 * 1024, 8, SECT_4K, }, - { "at26df081a", 0x1f4501, 0, 64 * 1024, 16, SECT_4K, }, - { "at26df161a", 0x1f4601, 0, 64 * 1024, 32, SECT_4K, }, - { "at26df321", 0x1f4701, 0, 64 * 1024, 64, SECT_4K, }, + { "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8, SECT_4K) }, + { "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) }, + { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) }, + { "at26df321", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) }, /* Macronix */ - { "mx25l3205d", 0xc22016, 0, 64 * 1024, 64, }, - { "mx25l6405d", 0xc22017, 0, 64 * 1024, 128, }, - { "mx25l12805d", 0xc22018, 0, 64 * 1024, 256, }, - { "mx25l12855e", 0xc22618, 0, 64 * 1024, 256, }, + { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) }, + { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) }, + { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, + { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, /* Spansion -- single (large) sector size only, at least * for the chips listed here (without boot sectors). */ - { "s25sl004a", 0x010212, 0, 64 * 1024, 8, }, - { "s25sl008a", 0x010213, 0, 64 * 1024, 16, }, - { "s25sl016a", 0x010214, 0, 64 * 1024, 32, }, - { "s25sl032a", 0x010215, 0, 64 * 1024, 64, }, - { "s25sl064a", 0x010216, 0, 64 * 1024, 128, }, - { "s25sl12800", 0x012018, 0x0300, 256 * 1024, 64, }, - { "s25sl12801", 0x012018, 0x0301, 64 * 1024, 256, }, - { "s25fl129p0", 0x012018, 0x4d00, 256 * 1024, 64, }, - { "s25fl129p1", 0x012018, 0x4d01, 64 * 1024, 256, }, + { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) }, + { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) }, + { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) }, + { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, + { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, + { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, + { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, + { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, 0) }, + { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, 0) }, /* SST -- large erase sizes are "overlays", "sectors" are 4K */ - { "sst25vf040b", 0xbf258d, 0, 64 * 1024, 8, SECT_4K, }, - { "sst25vf080b", 0xbf258e, 0, 64 * 1024, 16, SECT_4K, }, - { "sst25vf016b", 0xbf2541, 0, 64 * 1024, 32, SECT_4K, }, - { "sst25vf032b", 0xbf254a, 0, 64 * 1024, 64, SECT_4K, }, - { "sst25wf512", 0xbf2501, 0, 64 * 1024, 1, SECT_4K, }, - { "sst25wf010", 0xbf2502, 0, 64 * 1024, 2, SECT_4K, }, - { "sst25wf020", 0xbf2503, 0, 64 * 1024, 4, SECT_4K, }, - { "sst25wf040", 0xbf2504, 0, 64 * 1024, 8, SECT_4K, }, + { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K) }, + { "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K) }, + { "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K) }, + { "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K) }, + { "sst25wf512", INFO(0xbf2501, 0, 64 * 1024, 1, SECT_4K) }, + { "sst25wf010", INFO(0xbf2502, 0, 64 * 1024, 2, SECT_4K) }, + { "sst25wf020", INFO(0xbf2503, 0, 64 * 1024, 4, SECT_4K) }, + { "sst25wf040", INFO(0xbf2504, 0, 64 * 1024, 8, SECT_4K) }, /* ST Microelectronics -- newer production may have feature updates */ - { "m25p05", 0x202010, 0, 32 * 1024, 2, }, - { "m25p10", 0x202011, 0, 32 * 1024, 4, }, - { "m25p20", 0x202012, 0, 64 * 1024, 4, }, - { "m25p40", 0x202013, 0, 64 * 1024, 8, }, - { "m25p80", 0, 0, 64 * 1024, 16, }, - { "m25p16", 0x202015, 0, 64 * 1024, 32, }, - { "m25p32", 0x202016, 0, 64 * 1024, 64, }, - { "m25p64", 0x202017, 0, 64 * 1024, 128, }, - { "m25p128", 0x202018, 0, 256 * 1024, 64, }, - - { "m45pe10", 0x204011, 0, 64 * 1024, 2, }, - { "m45pe80", 0x204014, 0, 64 * 1024, 16, }, - { "m45pe16", 0x204015, 0, 64 * 1024, 32, }, - - { "m25pe80", 0x208014, 0, 64 * 1024, 16, }, - { "m25pe16", 0x208015, 0, 64 * 1024, 32, SECT_4K, }, + { "m25p05", INFO(0x202010, 0, 32 * 1024, 2, 0) }, + { "m25p10", INFO(0x202011, 0, 32 * 1024, 4, 0) }, + { "m25p20", INFO(0x202012, 0, 64 * 1024, 4, 0) }, + { "m25p40", INFO(0x202013, 0, 64 * 1024, 8, 0) }, + { "m25p80", INFO(0x202014, 0, 64 * 1024, 16, 0) }, + { "m25p16", INFO(0x202015, 0, 64 * 1024, 32, 0) }, + { "m25p32", INFO(0x202016, 0, 64 * 1024, 64, 0) }, + { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) }, + { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) }, + + { "m45pe10", INFO(0x204011, 0, 64 * 1024, 2, 0) }, + { "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) }, + { "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) }, + + { "m25pe80", INFO(0x208014, 0, 64 * 1024, 16, 0) }, + { "m25pe16", INFO(0x208015, 0, 64 * 1024, 32, SECT_4K) }, /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ - { "w25x10", 0xef3011, 0, 64 * 1024, 2, SECT_4K, }, - { "w25x20", 0xef3012, 0, 64 * 1024, 4, SECT_4K, }, - { "w25x40", 0xef3013, 0, 64 * 1024, 8, SECT_4K, }, - { "w25x80", 0xef3014, 0, 64 * 1024, 16, SECT_4K, }, - { "w25x16", 0xef3015, 0, 64 * 1024, 32, SECT_4K, }, - { "w25x32", 0xef3016, 0, 64 * 1024, 64, SECT_4K, }, - { "w25x64", 0xef3017, 0, 64 * 1024, 128, SECT_4K, }, + { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, + { "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) }, + { "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) }, + { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) }, + { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, + { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, + { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, + { }, }; +MODULE_DEVICE_TABLE(spi, m25p_ids); -static struct flash_info *__devinit jedec_probe(struct spi_device *spi) +static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) { int tmp; u8 code = OPCODE_RDID; @@ -703,16 +711,14 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi) ext_jedec = id[3] << 8 | id[4]; - for (tmp = 0, info = m25p_data; - tmp < ARRAY_SIZE(m25p_data); - tmp++, info++) { + for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) { + info = (void *)m25p_ids[tmp].driver_data; if (info->jedec_id == jedec) { if (info->ext_id != 0 && info->ext_id != ext_jedec) continue; - return info; + return &m25p_ids[tmp]; } } - dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec); return NULL; } @@ -724,6 +730,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi) */ static int __devinit m25p_probe(struct spi_device *spi) { + const struct spi_device_id *id; struct flash_platform_data *data; struct m25p *flash; struct flash_info *info; @@ -736,32 +743,38 @@ static int __devinit m25p_probe(struct spi_device *spi) */ data = spi->dev.platform_data; if (data && data->type) { - for (i = 0, info = m25p_data; - i < ARRAY_SIZE(m25p_data); - i++, info++) { - if (strcmp(data->type, info->name) == 0) - break; + for (i = 0; i < ARRAY_SIZE(m25p_ids) - 1; i++) { + id = &m25p_ids[i]; + info = (void *)m25p_ids[i].driver_data; + if (strcmp(data->type, id->name)) + continue; + break; } /* unrecognized chip? */ - if (i == ARRAY_SIZE(m25p_data)) { + if (i == ARRAY_SIZE(m25p_ids) - 1) { DEBUG(MTD_DEBUG_LEVEL0, "%s: unrecognized id %s\n", dev_name(&spi->dev), data->type); info = NULL; /* recognized; is that chip really what's there? */ } else if (info->jedec_id) { - struct flash_info *chip = jedec_probe(spi); + id = jedec_probe(spi); - if (!chip || chip != info) { + if (id != &m25p_ids[i]) { dev_warn(&spi->dev, "found %s, expected %s\n", - chip ? chip->name : "UNKNOWN", - info->name); + id ? id->name : "UNKNOWN", + m25p_ids[i].name); info = NULL; } } - } else - info = jedec_probe(spi); + } else { + id = jedec_probe(spi); + if (!id) + id = spi_get_device_id(spi); + + info = (void *)id->driver_data; + } if (!info) return -ENODEV; @@ -819,7 +832,7 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd.dev.parent = &spi->dev; - dev_info(&spi->dev, "%s (%lld Kbytes)\n", info->name, + dev_info(&spi->dev, "%s (%lld Kbytes)\n", id->name, (long long)flash->mtd.size >> 10); DEBUG(MTD_DEBUG_LEVEL2, @@ -907,6 +920,7 @@ static struct spi_driver m25p80_driver = { .bus = &spi_bus_type, .owner = THIS_MODULE, }, + .id_table = m25p_ids, .probe = m25p_probe, .remove = __devexit_p(m25p_remove), -- cgit v0.10.2 From 18c6182bae0acca220ed6611f741034d563cd19f Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 12 Oct 2009 20:24:38 +0400 Subject: mtd: m25p80: Rework probing/JEDEC code Previosly the driver always tried JEDEC probing, assuming that non-JEDEC chips will return '0'. But truly non-JEDEC chips (like CAT25) won't do that, their behaviour on RDID command is undefined, so the driver should not call jedec_probe() for these chips. Also, be less strict on error conditions, don't fail to probe if JEDEC found a chip that is different from what platform code told, instead just print some warnings and use an information obtained via JEDEC. In that case we should not trust partitions any longer, but they might be still useful (i.e. they could protect some parts of the chip). Signed-off-by: Anton Vorontsov Signed-off-by: David Woodhouse diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 47486fb..e689285 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -709,6 +709,14 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) jedec = jedec << 8; jedec |= id[2]; + /* + * Some chips (like Numonyx M25P80) have JEDEC and non-JEDEC variants, + * which depend on technology process. Officially RDID command doesn't + * exist for non-JEDEC chips, but for compatibility they return ID 0. + */ + if (jedec == 0) + return NULL; + ext_jedec = id[3] << 8 | id[4]; for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) { @@ -730,7 +738,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) */ static int __devinit m25p_probe(struct spi_device *spi) { - const struct spi_device_id *id; + const struct spi_device_id *id = spi_get_device_id(spi); struct flash_platform_data *data; struct m25p *flash; struct flash_info *info; @@ -743,41 +751,44 @@ static int __devinit m25p_probe(struct spi_device *spi) */ data = spi->dev.platform_data; if (data && data->type) { + const struct spi_device_id *plat_id; + for (i = 0; i < ARRAY_SIZE(m25p_ids) - 1; i++) { - id = &m25p_ids[i]; - info = (void *)m25p_ids[i].driver_data; - if (strcmp(data->type, id->name)) + plat_id = &m25p_ids[i]; + if (strcmp(data->type, plat_id->name)) continue; break; } - /* unrecognized chip? */ - if (i == ARRAY_SIZE(m25p_ids) - 1) { - DEBUG(MTD_DEBUG_LEVEL0, "%s: unrecognized id %s\n", - dev_name(&spi->dev), data->type); - info = NULL; - - /* recognized; is that chip really what's there? */ - } else if (info->jedec_id) { - id = jedec_probe(spi); - - if (id != &m25p_ids[i]) { - dev_warn(&spi->dev, "found %s, expected %s\n", - id ? id->name : "UNKNOWN", - m25p_ids[i].name); - info = NULL; - } - } - } else { - id = jedec_probe(spi); - if (!id) - id = spi_get_device_id(spi); - - info = (void *)id->driver_data; + if (plat_id) + id = plat_id; + else + dev_warn(&spi->dev, "unrecognized id %s\n", data->type); } - if (!info) - return -ENODEV; + info = (void *)id->driver_data; + + if (info->jedec_id) { + const struct spi_device_id *jid; + + jid = jedec_probe(spi); + if (!jid) { + dev_info(&spi->dev, "non-JEDEC variant of %s\n", + id->name); + } else if (jid != id) { + /* + * JEDEC knows better, so overwrite platform ID. We + * can't trust partitions any longer, but we'll let + * mtd apply them anyway, since some partitions may be + * marked read-only, and we don't want to lose that + * information, even if it's not 100% accurate. + */ + dev_warn(&spi->dev, "found %s, expected %s\n", + jid->name, id->name); + id = jid; + info = (void *)jid->driver_data; + } + } flash = kzalloc(sizeof *flash, GFP_KERNEL); if (!flash) -- cgit v0.10.2 From 837479d25e221ba616de2c734f58e1decd8cdb95 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 12 Oct 2009 20:24:40 +0400 Subject: mtd: m25p80: Add support for CAT25xxx serial EEPROMs CAT25 chips (as manufactured by On Semiconductor, previously Catalyst Semiconductor) are similar to the original M25Px0 chips, except: - Address width can vary (1-2 bytes, in contrast to 3 bytes in M25P chips). So, implement convenient m25p_addr2cmd() and m25p_cmdsz() calls, and place address width information into flash_info struct; - Page size can vary, therefore we shouldn't hardcode it, so get rid of FLASH_PAGESIZE definition, and place the page size information into flash_info struct; - CAT25 EEPROMs don't need to be erased, so add NO_ERASE flag, and propagate it to the mtd subsystem. [dwmw2: Fix up for conflicts with DMA safety patch] Signed-off-by: Anton Vorontsov Signed-off-by: David Woodhouse diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index e689285..8f8c249 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -29,9 +29,6 @@ #include #include - -#define FLASH_PAGESIZE 256 - /* Flash opcodes. */ #define OPCODE_WREN 0x06 /* Write enable */ #define OPCODE_RDSR 0x05 /* Read status register */ @@ -61,7 +58,7 @@ /* Define max times to check status register before we give up. */ #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ -#define CMD_SIZE 4 +#define MAX_CMD_SIZE 4 #ifdef CONFIG_M25PXX_USE_FAST_READ #define OPCODE_READ OPCODE_FAST_READ @@ -78,6 +75,8 @@ struct m25p { struct mutex lock; struct mtd_info mtd; unsigned partitioned:1; + u16 page_size; + u16 addr_width; u8 erase_opcode; u8 *command; }; @@ -198,6 +197,19 @@ static int erase_chip(struct m25p *flash) return 0; } +static void m25p_addr2cmd(struct m25p *flash, unsigned int addr, u8 *cmd) +{ + /* opcode is in cmd[0] */ + cmd[1] = addr >> (flash->addr_width * 8 - 8); + cmd[2] = addr >> (flash->addr_width * 8 - 16); + cmd[3] = addr >> (flash->addr_width * 8 - 24); +} + +static int m25p_cmdsz(struct m25p *flash) +{ + return 1 + flash->addr_width; +} + /* * Erase one sector of flash memory at offset ``offset'' which is any * address within the sector which should be erased. @@ -219,11 +231,9 @@ static int erase_sector(struct m25p *flash, u32 offset) /* Set up command buffer. */ flash->command[0] = flash->erase_opcode; - flash->command[1] = offset >> 16; - flash->command[2] = offset >> 8; - flash->command[3] = offset; + m25p_addr2cmd(flash, offset, flash->command); - spi_write(flash->spi, flash->command, CMD_SIZE); + spi_write(flash->spi, flash->command, m25p_cmdsz(flash)); return 0; } @@ -325,7 +335,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, * Should add 1 byte DUMMY_BYTE. */ t[0].tx_buf = flash->command; - t[0].len = CMD_SIZE + FAST_READ_DUMMY_BYTE; + t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE; spi_message_add_tail(&t[0], &m); t[1].rx_buf = buf; @@ -352,13 +362,11 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, /* Set up the write data buffer. */ flash->command[0] = OPCODE_READ; - flash->command[1] = from >> 16; - flash->command[2] = from >> 8; - flash->command[3] = from; + m25p_addr2cmd(flash, from, flash->command); spi_sync(flash->spi, &m); - *retlen = m.actual_length - CMD_SIZE - FAST_READ_DUMMY_BYTE; + *retlen = m.actual_length - m25p_cmdsz(flash) - FAST_READ_DUMMY_BYTE; mutex_unlock(&flash->lock); @@ -396,7 +404,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, memset(t, 0, (sizeof t)); t[0].tx_buf = flash->command; - t[0].len = CMD_SIZE; + t[0].len = m25p_cmdsz(flash); spi_message_add_tail(&t[0], &m); t[1].tx_buf = buf; @@ -414,41 +422,36 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, /* Set up the opcode in the write buffer. */ flash->command[0] = OPCODE_PP; - flash->command[1] = to >> 16; - flash->command[2] = to >> 8; - flash->command[3] = to; + m25p_addr2cmd(flash, to, flash->command); - /* what page do we start with? */ - page_offset = to % FLASH_PAGESIZE; + page_offset = to & (flash->page_size - 1); /* do all the bytes fit onto one page? */ - if (page_offset + len <= FLASH_PAGESIZE) { + if (page_offset + len <= flash->page_size) { t[1].len = len; spi_sync(flash->spi, &m); - *retlen = m.actual_length - CMD_SIZE; + *retlen = m.actual_length - m25p_cmdsz(flash); } else { u32 i; /* the size of data remaining on the first page */ - page_size = FLASH_PAGESIZE - page_offset; + page_size = flash->page_size - page_offset; t[1].len = page_size; spi_sync(flash->spi, &m); - *retlen = m.actual_length - CMD_SIZE; + *retlen = m.actual_length - m25p_cmdsz(flash); - /* write everything in PAGESIZE chunks */ + /* write everything in flash->page_size chunks */ for (i = page_size; i < len; i += page_size) { page_size = len - i; - if (page_size > FLASH_PAGESIZE) - page_size = FLASH_PAGESIZE; + if (page_size > flash->page_size) + page_size = flash->page_size; /* write the next page to flash */ - flash->command[1] = (to + i) >> 16; - flash->command[2] = (to + i) >> 8; - flash->command[3] = (to + i); + m25p_addr2cmd(flash, to + i, flash->command); t[1].tx_buf = buf + i; t[1].len = page_size; @@ -460,7 +463,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, spi_sync(flash->spi, &m); if (retlen) - *retlen += m.actual_length - CMD_SIZE; + *retlen += m.actual_length - m25p_cmdsz(flash); } } @@ -492,7 +495,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, memset(t, 0, (sizeof t)); t[0].tx_buf = flash->command; - t[0].len = CMD_SIZE; + t[0].len = m25p_cmdsz(flash); spi_message_add_tail(&t[0], &m); t[1].tx_buf = buf; @@ -511,9 +514,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, /* Start write from odd address. */ if (actual) { flash->command[0] = OPCODE_BP; - flash->command[1] = to >> 16; - flash->command[2] = to >> 8; - flash->command[3] = to; + m25p_addr2cmd(flash, to, flash->command); /* write one byte. */ t[1].len = 1; @@ -521,17 +522,15 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, ret = wait_till_ready(flash); if (ret) goto time_out; - *retlen += m.actual_length - CMD_SIZE; + *retlen += m.actual_length - m25p_cmdsz(flash); } to += actual; flash->command[0] = OPCODE_AAI_WP; - flash->command[1] = to >> 16; - flash->command[2] = to >> 8; - flash->command[3] = to; + m25p_addr2cmd(flash, to, flash->command); /* Write out most of the data here. */ - cmd_sz = CMD_SIZE; + cmd_sz = m25p_cmdsz(flash); for (; actual < len - 1; actual += 2) { t[0].len = cmd_sz; /* write two bytes. */ @@ -555,10 +554,8 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, if (actual != len) { write_enable(flash); flash->command[0] = OPCODE_BP; - flash->command[1] = to >> 16; - flash->command[2] = to >> 8; - flash->command[3] = to; - t[0].len = CMD_SIZE; + m25p_addr2cmd(flash, to, flash->command); + t[0].len = m25p_cmdsz(flash); t[1].len = 1; t[1].tx_buf = buf + actual; @@ -566,7 +563,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, ret = wait_till_ready(flash); if (ret) goto time_out; - *retlen += m.actual_length - CMD_SIZE; + *retlen += m.actual_length - m25p_cmdsz(flash); write_disable(flash); } @@ -595,8 +592,12 @@ struct flash_info { unsigned sector_size; u16 n_sectors; + u16 page_size; + u16 addr_width; + u16 flags; #define SECT_4K 0x01 /* OPCODE_BE_4K works uniformly */ +#define M25P_NO_ERASE 0x02 /* No erase command needed */ }; #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ @@ -605,9 +606,20 @@ struct flash_info { .ext_id = (_ext_id), \ .sector_size = (_sector_size), \ .n_sectors = (_n_sectors), \ + .page_size = 256, \ + .addr_width = 3, \ .flags = (_flags), \ }) +#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width) \ + ((kernel_ulong_t)&(struct flash_info) { \ + .sector_size = (_sector_size), \ + .n_sectors = (_n_sectors), \ + .page_size = (_page_size), \ + .addr_width = (_addr_width), \ + .flags = M25P_NO_ERASE, \ + }) + /* NOTE: double check command sets and memory organization when you add * more flash chips. This current list focusses on newer chips, which * have been converging on command sets which including JEDEC ID. @@ -680,6 +692,13 @@ static const struct spi_device_id m25p_ids[] = { { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, + + /* Catalyst / On Semiconductor -- non-JEDEC */ + { "cat25c11", CAT25_INFO( 16, 8, 16, 1) }, + { "cat25c03", CAT25_INFO( 32, 8, 16, 2) }, + { "cat25c09", CAT25_INFO( 128, 8, 32, 2) }, + { "cat25c17", CAT25_INFO( 256, 8, 32, 2) }, + { "cat25128", CAT25_INFO(2048, 8, 64, 2) }, { }, }; MODULE_DEVICE_TABLE(spi, m25p_ids); @@ -793,7 +812,7 @@ static int __devinit m25p_probe(struct spi_device *spi) flash = kzalloc(sizeof *flash, GFP_KERNEL); if (!flash) return -ENOMEM; - flash->command = kmalloc(CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL); + flash->command = kmalloc(MAX_CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL); if (!flash->command) { kfree(flash); return -ENOMEM; @@ -841,7 +860,12 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd.erasesize = info->sector_size; } + if (info->flags & M25P_NO_ERASE) + flash->mtd.flags |= MTD_NO_ERASE; + flash->mtd.dev.parent = &spi->dev; + flash->page_size = info->page_size; + flash->addr_width = info->addr_width; dev_info(&spi->dev, "%s (%lld Kbytes)\n", id->name, (long long)flash->mtd.size >> 10); -- cgit v0.10.2 From f611a79fe9859a30f2a7ae94b4d24f8e2dd75c91 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Mon, 12 Oct 2009 16:16:37 -0700 Subject: mtd: Add bad block table overrides to Davinci NAND driver The existing NAND infrastructure allows the default main and mirror bad block tables to be overridden in nand_default_bbt(). However, the davinci_nand driver does not support this. Add that support by adding fields to the davinci driver's platform data so platform code can pass in their own bbt's and make the davinci_nand driver honor them. Signed-off-by: Mark A. Greer Signed-off-by: Kevin Hilman CC: Sudhakar Rajashekhara Signed-off-by: David Woodhouse diff --git a/arch/arm/mach-davinci/include/mach/nand.h b/arch/arm/mach-davinci/include/mach/nand.h index b520c4b..b2ad809 100644 --- a/arch/arm/mach-davinci/include/mach/nand.h +++ b/arch/arm/mach-davinci/include/mach/nand.h @@ -79,6 +79,10 @@ struct davinci_nand_pdata { /* platform_data */ /* e.g. NAND_BUSWIDTH_16 or NAND_USE_FLASH_BBT */ unsigned options; + + /* Main and mirror bbt descriptor overrides */ + struct nand_bbt_descr *bbt_td; + struct nand_bbt_descr *bbt_md; }; #endif /* __ARCH_ARM_DAVINCI_NAND_H */ diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 68cc924..fe3eba8 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -591,6 +591,8 @@ static int __init nand_davinci_probe(struct platform_device *pdev) /* options such as NAND_USE_FLASH_BBT or 16-bit widths */ info->chip.options = pdata->options; + info->chip.bbt_td = pdata->bbt_td; + info->chip.bbt_md = pdata->bbt_md; info->ioaddr = (uint32_t __force) vaddr; -- cgit v0.10.2 From d5ba1c8ffd0b7d38e1fac48184637e6d6c1197d3 Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 17 Nov 2009 16:18:41 +0900 Subject: mtd: don't use PF_MEMALLOC Non MM subsystem must not use PF_MEMALLOC. Memory reclaim need few memory, anyone must not prevent it. Otherwise the system cause mysterious hang-up and/or OOM Killer invokation. Signed-off-by: KOSAKI Motohiro Signed-off-by: David Woodhouse diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 955226d..fa83757 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -91,9 +91,6 @@ static int mtd_blktrans_thread(void *arg) struct request_queue *rq = tr->blkcore_priv->rq; struct request *req = NULL; - /* we might get involved when memory gets low, so use PF_MEMALLOC */ - current->flags |= PF_MEMALLOC; - spin_lock_irq(rq->queue_lock); while (!kthread_should_stop()) { -- cgit v0.10.2 From db5432db81b1775f145945b21428490583ab3e2b Mon Sep 17 00:00:00 2001 From: Ladislav Michl Date: Mon, 23 Nov 2009 00:06:50 +0100 Subject: mtd: fix M29W800D dev_id and uaddr This one sits in my tree for more than two years... Using device code found on page 12 (http://www.btdesigner.com/pdfs/M29W800D.pdf) and unlock address from page 15 MTD subsytem happily detects ST M29W800DB in 16-bit mode. I do believe original author used only 8-bit mode and thus didn't hit this bug. Signed-off-by: Ladislav Michl Signed-off-by: David Woodhouse diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index 736a3be..1bec5e1 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -142,8 +142,8 @@ /* ST - www.st.com */ #define M29F800AB 0x0058 -#define M29W800DT 0x00D7 -#define M29W800DB 0x005B +#define M29W800DT 0x22D7 +#define M29W800DB 0x225B #define M29W400DT 0x00EE #define M29W400DB 0x00EF #define M29W160DT 0x22C4 @@ -1575,7 +1575,7 @@ static const struct amd_flash_info jedec_table[] = { .dev_id = M29W800DT, .name = "ST M29W800DT", .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, - .uaddr = MTD_UADDR_0x5555_0x2AAA, /* ???? */ + .uaddr = MTD_UADDR_0x0AAA_0x0555, .dev_size = SIZE_1MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 4, @@ -1590,7 +1590,7 @@ static const struct amd_flash_info jedec_table[] = { .dev_id = M29W800DB, .name = "ST M29W800DB", .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, - .uaddr = MTD_UADDR_0x5555_0x2AAA, /* ???? */ + .uaddr = MTD_UADDR_0x0AAA_0x0555, .dev_size = SIZE_1MiB, .cmd_set = P_ID_AMD_STD, .nr_regions = 4, -- cgit v0.10.2 From 4a58948669702639db7acecfa2105c3172d85c93 Mon Sep 17 00:00:00 2001 From: Guillaume LECERF Date: Mon, 23 Nov 2009 02:10:49 +0100 Subject: mtd: add support for switching old SST chips into QRY mode SST 39VF160x/39VF320x and some old SST chips need a special command sequence to enter CFI QueRY mode [1]. This patch adds the relevant sequence to cfi_qry_mode_on(). Tested with 39VF3201. Signed-off-by: Guillaume LECERF Signed-off-by: David Woodhouse diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index c5a84fd..ca584d0 100755 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c @@ -71,6 +71,13 @@ int __xipram cfi_qry_mode_on(uint32_t base, struct map_info *map, cfi_send_gen_cmd(0x98, 0x555, base, map, cfi, cfi->device_type, NULL); if (cfi_qry_present(map, base, cfi)) return 1; + /* some old SST chips, e.g. 39VF160x/39VF320x */ + cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL); + if (cfi_qry_present(map, base, cfi)) + return 1; /* QRY not found */ return 0; } -- cgit v0.10.2 From 6b0d9a84124937f048bcb8b21313152b23063978 Mon Sep 17 00:00:00 2001 From: Li Yang Date: Tue, 17 Nov 2009 14:45:49 -0800 Subject: mtd: nand: fix multi-chip suspend problem Symptom: device_suspend(): mtd_cls_suspend+0x0/0x58 returns -11 PM: Device mtd14 failed to suspend: error -11 PM: Some devices failed to suspend This patch enables other chips to be suspended if the active chip of the controller has been suspended. Signed-off-by: Jin Qing Signed-off-by: Li Yang Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 724cb2c..8f2958f 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -740,8 +740,14 @@ nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state) return 0; } if (new_state == FL_PM_SUSPENDED) { - spin_unlock(lock); - return (chip->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN; + if (chip->controller->active->state == FL_PM_SUSPENDED) { + chip->state = FL_PM_SUSPENDED; + spin_unlock(lock); + return 0; + } else { + spin_unlock(lock); + return -EAGAIN; + } } set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(wq, &wait); -- cgit v0.10.2 From 98ecc914d0a48dbbcbb5fc866ab5b59a52afbd41 Mon Sep 17 00:00:00 2001 From: David Hunter Date: Mon, 23 Nov 2009 21:02:35 -0800 Subject: mtd: pxa3xx_nand: Fix PIO data transfer The shift operator used here to convert from bytes to 32-bit words is backwards. Signed-off-by: David Hunter Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 6ea520a..75aa871 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -489,7 +489,7 @@ static int handle_data_pio(struct pxa3xx_nand_info *info) switch (info->state) { case STATE_PIO_WRITING: __raw_writesl(info->mmio_base + NDDB, info->data_buff, - info->data_size << 2); + info->data_size >> 2); enable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD); @@ -501,7 +501,7 @@ static int handle_data_pio(struct pxa3xx_nand_info *info) break; case STATE_PIO_READING: __raw_readsl(info->mmio_base + NDDB, info->data_buff, - info->data_size << 2); + info->data_size >> 2); break; default: printk(KERN_ERR "%s: invalid state %d\n", __func__, -- cgit v0.10.2 From 7cb777a3d71f9d1f7eb149c7a504d21f24219ae8 Mon Sep 17 00:00:00 2001 From: Russell King - ARM Linux Date: Sun, 29 Nov 2009 15:23:51 +0000 Subject: mtd: add ARM pismo support The following patch adds support for PISMO modules found on ARM Ltd development platforms. These are MTD modules, and can have a selection of SRAM, flash or DOC devices as described by an on-board I2C EEPROM. We support SRAM and NOR flash devices only by registering appropriate conventional MTD platform devices as children of the 'pismo' device. Signed-off-by: Russell King Signed-off-by: David Woodhouse diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 34f3cdd..3078d6d 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_MTD_CEIVA) += ceiva.o obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o obj-$(CONFIG_MTD_PHYSMAP) += physmap.o obj-$(CONFIG_MTD_PHYSMAP_OF) += physmap_of.o +obj-$(CONFIG_MTD_PISMO) += pismo.o obj-$(CONFIG_MTD_PMC_MSP_EVM) += pmcmsp-flash.o obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o -- cgit v0.10.2 From 456b565cc52fbcdaa2e19ffdf40d9dd3b726d603 Mon Sep 17 00:00:00 2001 From: Simon Kagstrom Date: Fri, 16 Oct 2009 14:09:18 +0200 Subject: core: Add kernel message dumper to call on oopses and panics The core functionality is implemented as per Linus suggestion from http://lists.infradead.org/pipermail/linux-mtd/2009-October/027620.html (with the kmsg_dump implementation by Linus). A struct kmsg_dumper has been added which contains a callback to dump the kernel log buffers on crashes. The kmsg_dump function gets called from oops_exit() and panic() and invokes this callbacks with the crash reason. [dwmw2: Fix log_end handling] Signed-off-by: Simon Kagstrom Reviewed-by: Anders Grafstrom Reviewed-by: Linus Torvalds Acked-by: Ingo Molnar Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h new file mode 100644 index 0000000..7f089ec --- /dev/null +++ b/include/linux/kmsg_dump.h @@ -0,0 +1,44 @@ +/* + * linux/include/kmsg_dump.h + * + * Copyright (C) 2009 Net Insight AB + * + * Author: Simon Kagstrom + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ +#ifndef _LINUX_KMSG_DUMP_H +#define _LINUX_KMSG_DUMP_H + +#include + +enum kmsg_dump_reason { + KMSG_DUMP_OOPS, + KMSG_DUMP_PANIC, +}; + +/** + * struct kmsg_dumper - kernel crash message dumper structure + * @dump: The callback which gets called on crashes. The buffer is passed + * as two sections, where s1 (length l1) contains the older + * messages and s2 (length l2) contains the newer. + * @list: Entry in the dumper list (private) + * @registered: Flag that specifies if this is already registered + */ +struct kmsg_dumper { + void (*dump)(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason, + const char *s1, unsigned long l1, + const char *s2, unsigned long l2); + struct list_head list; + int registered; +}; + +void kmsg_dump(enum kmsg_dump_reason reason); + +int kmsg_dump_register(struct kmsg_dumper *dumper); + +int kmsg_dump_unregister(struct kmsg_dumper *dumper); + +#endif /* _LINUX_KMSG_DUMP_H */ diff --git a/kernel/panic.c b/kernel/panic.c index bcdef26..8c43226 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -10,6 +10,7 @@ */ #include #include +#include #include #include #include @@ -74,6 +75,7 @@ NORET_TYPE void panic(const char * fmt, ...) dump_stack(); #endif + kmsg_dump(KMSG_DUMP_PANIC); /* * If we have crashed and we have a crash kernel loaded let it handle * everything else. @@ -338,6 +340,7 @@ void oops_exit(void) { do_oops_enter_exit(); print_oops_end_marker(); + kmsg_dump(KMSG_DUMP_OOPS); } #ifdef WANT_WARN_ON_SLOWPATH diff --git a/kernel/printk.c b/kernel/printk.c index f38b07f..051d1f5 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -1405,3 +1406,121 @@ bool printk_timed_ratelimit(unsigned long *caller_jiffies, } EXPORT_SYMBOL(printk_timed_ratelimit); #endif + +static DEFINE_SPINLOCK(dump_list_lock); +static LIST_HEAD(dump_list); + +/** + * kmsg_dump_register - register a kernel log dumper. + * @dump: pointer to the kmsg_dumper structure + * + * Adds a kernel log dumper to the system. The dump callback in the + * structure will be called when the kernel oopses or panics and must be + * set. Returns zero on success and %-EINVAL or %-EBUSY otherwise. + */ +int kmsg_dump_register(struct kmsg_dumper *dumper) +{ + unsigned long flags; + int err = -EBUSY; + + /* The dump callback needs to be set */ + if (!dumper->dump) + return -EINVAL; + + spin_lock_irqsave(&dump_list_lock, flags); + /* Don't allow registering multiple times */ + if (!dumper->registered) { + dumper->registered = 1; + list_add_tail(&dumper->list, &dump_list); + err = 0; + } + spin_unlock_irqrestore(&dump_list_lock, flags); + + return err; +} +EXPORT_SYMBOL_GPL(kmsg_dump_register); + +/** + * kmsg_dump_unregister - unregister a kmsg dumper. + * @dump: pointer to the kmsg_dumper structure + * + * Removes a dump device from the system. Returns zero on success and + * %-EINVAL otherwise. + */ +int kmsg_dump_unregister(struct kmsg_dumper *dumper) +{ + unsigned long flags; + int err = -EINVAL; + + spin_lock_irqsave(&dump_list_lock, flags); + if (dumper->registered) { + dumper->registered = 0; + list_del(&dumper->list); + err = 0; + } + spin_unlock_irqrestore(&dump_list_lock, flags); + + return err; +} +EXPORT_SYMBOL_GPL(kmsg_dump_unregister); + +static const char const *kmsg_reasons[] = { + [KMSG_DUMP_OOPS] = "oops", + [KMSG_DUMP_PANIC] = "panic", +}; + +static const char *kmsg_to_str(enum kmsg_dump_reason reason) +{ + if (reason >= ARRAY_SIZE(kmsg_reasons) || reason < 0) + return "unknown"; + + return kmsg_reasons[reason]; +} + +/** + * kmsg_dump - dump kernel log to kernel message dumpers. + * @reason: the reason (oops, panic etc) for dumping + * + * Iterate through each of the dump devices and call the oops/panic + * callbacks with the log buffer. + */ +void kmsg_dump(enum kmsg_dump_reason reason) +{ + unsigned long end; + unsigned chars; + struct kmsg_dumper *dumper; + const char *s1, *s2; + unsigned long l1, l2; + unsigned long flags; + + /* Theoretically, the log could move on after we do this, but + there's not a lot we can do about that. The new messages + will overwrite the start of what we dump. */ + spin_lock_irqsave(&logbuf_lock, flags); + end = log_end & LOG_BUF_MASK; + chars = logged_chars; + spin_unlock_irqrestore(&logbuf_lock, flags); + + if (logged_chars > end) { + s1 = log_buf + log_buf_len - logged_chars + end; + l1 = logged_chars - end; + + s2 = log_buf; + l2 = end; + } else { + s1 = ""; + l1 = 0; + + s2 = log_buf + end - logged_chars; + l2 = logged_chars; + } + + if (!spin_trylock_irqsave(&dump_list_lock, flags)) { + printk(KERN_ERR "dump_kmsg: dump list lock is held during %s, skipping dump\n", + kmsg_to_str(reason)); + return; + } + list_for_each_entry(dumper, &dump_list, list) + dumper->dump(dumper, reason, s1, l1, s2, l2); + spin_unlock_irqrestore(&dump_list_lock, flags); +} -- cgit v0.10.2 From a15b124fc4f15b2c4fc51669c936a30ce179d1f7 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Sun, 11 Oct 2009 13:40:40 +0300 Subject: mtd: mtdoops: several minor cleanups While looking into the mtdoops module, I've spotted several minor imperfections. This patch addresses them. Namely: 1. Remove several trailing white-spaces and tabs 2. Check 'vmalloc()' return code straight away, not several lines below in the 'mtdoops_console_init()' function. 3. Clean up printks - make them more consistent and use the same code formatting style for them. 4. Remove silly style of putting brackets around everything in "if" operators. Signed-off-by: Artem Bityutskiy Cc: Simon Kagstrom Signed-off-by: David Woodhouse diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index 1060337..c383add 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -81,9 +81,9 @@ static int mtdoops_erase_block(struct mtd_info *mtd, int offset) if (ret) { set_current_state(TASK_RUNNING); remove_wait_queue(&wait_q, &wait); - printk (KERN_WARNING "mtdoops: erase of region [0x%llx, 0x%llx] " - "on \"%s\" failed\n", - (unsigned long long)erase.addr, (unsigned long long)erase.len, mtd->name); + printk(KERN_WARNING "mtdoops: erase of region [0x%llx, 0x%llx] on \"%s\" failed\n", + (unsigned long long)erase.addr, + (unsigned long long)erase.len, mtd->name); return ret; } @@ -109,10 +109,9 @@ static void mtdoops_inc_counter(struct mtdoops_context *cxt) ret = mtd->read(mtd, cxt->nextpage * OOPS_PAGE_SIZE, 4, &retlen, (u_char *) &count); - if ((retlen != 4) || ((ret < 0) && (ret != -EUCLEAN))) { - printk(KERN_ERR "mtdoops: Read failure at %d (%td of 4 read)" - ", err %d.\n", cxt->nextpage * OOPS_PAGE_SIZE, - retlen, ret); + if (retlen != 4 || (ret < 0 && ret != -EUCLEAN)) { + printk(KERN_ERR "mtdoops: read failure at %d (%td of 4 read), err %d\n", + cxt->nextpage * OOPS_PAGE_SIZE, retlen, ret); schedule_work(&cxt->work_erase); return; } @@ -123,8 +122,8 @@ static void mtdoops_inc_counter(struct mtdoops_context *cxt) return; } - printk(KERN_DEBUG "mtdoops: Ready %d, %d (no erase)\n", - cxt->nextpage, cxt->nextcount); + printk(KERN_DEBUG "mtdoops: ready %d, %d (no erase)\n", + cxt->nextpage, cxt->nextcount); cxt->ready = 1; } @@ -152,18 +151,18 @@ static void mtdoops_workfunc_erase(struct work_struct *work) if (!ret) break; if (ret < 0) { - printk(KERN_ERR "mtdoops: block_isbad failed, aborting.\n"); + printk(KERN_ERR "mtdoops: block_isbad failed, aborting\n"); return; } badblock: - printk(KERN_WARNING "mtdoops: Bad block at %08x\n", - cxt->nextpage * OOPS_PAGE_SIZE); + printk(KERN_WARNING "mtdoops: bad block at %08x\n", + cxt->nextpage * OOPS_PAGE_SIZE); i++; cxt->nextpage = cxt->nextpage + (mtd->erasesize / OOPS_PAGE_SIZE); if (cxt->nextpage >= cxt->oops_pages) cxt->nextpage = 0; - if (i == (cxt->oops_pages / (mtd->erasesize / OOPS_PAGE_SIZE))) { - printk(KERN_ERR "mtdoops: All blocks bad!\n"); + if (i == cxt->oops_pages / (mtd->erasesize / OOPS_PAGE_SIZE)) { + printk(KERN_ERR "mtdoops: all blocks bad!\n"); return; } } @@ -172,15 +171,16 @@ badblock: ret = mtdoops_erase_block(mtd, cxt->nextpage * OOPS_PAGE_SIZE); if (ret >= 0) { - printk(KERN_DEBUG "mtdoops: Ready %d, %d \n", cxt->nextpage, cxt->nextcount); + printk(KERN_DEBUG "mtdoops: ready %d, %d\n", + cxt->nextpage, cxt->nextcount); cxt->ready = 1; return; } - if (mtd->block_markbad && (ret == -EIO)) { + if (mtd->block_markbad && ret == -EIO) { ret = mtd->block_markbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE); if (ret < 0) { - printk(KERN_ERR "mtdoops: block_markbad failed, aborting.\n"); + printk(KERN_ERR "mtdoops: block_markbad failed, aborting\n"); return; } } @@ -206,9 +206,9 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic) cxt->writecount = 0; - if ((retlen != OOPS_PAGE_SIZE) || (ret < 0)) - printk(KERN_ERR "mtdoops: Write failure at %d (%td of %d written), err %d.\n", - cxt->nextpage * OOPS_PAGE_SIZE, retlen, OOPS_PAGE_SIZE, ret); + if (retlen != OOPS_PAGE_SIZE || ret < 0) + printk(KERN_ERR "mtdoops: write failure at %d (%td of %d written), error %d\n", + cxt->nextpage * OOPS_PAGE_SIZE, retlen, OOPS_PAGE_SIZE, ret); mtdoops_inc_counter(cxt); } @@ -220,7 +220,7 @@ static void mtdoops_workfunc_write(struct work_struct *work) container_of(work, struct mtdoops_context, work_write); mtdoops_write(cxt, 0); -} +} static void find_next_position(struct mtdoops_context *cxt) { @@ -231,9 +231,9 @@ static void find_next_position(struct mtdoops_context *cxt) for (page = 0; page < cxt->oops_pages; page++) { ret = mtd->read(mtd, page * OOPS_PAGE_SIZE, 8, &retlen, (u_char *) &count[0]); - if ((retlen != 8) || ((ret < 0) && (ret != -EUCLEAN))) { - printk(KERN_ERR "mtdoops: Read failure at %d (%td of 8 read)" - ", err %d.\n", page * OOPS_PAGE_SIZE, retlen, ret); + if (retlen != 8 || (ret < 0 && ret != -EUCLEAN)) { + printk(KERN_ERR "mtdoops: read failure at %d (%td of 8 read), err %d\n", + page * OOPS_PAGE_SIZE, retlen, ret); continue; } @@ -244,14 +244,14 @@ static void find_next_position(struct mtdoops_context *cxt) if (maxcount == 0xffffffff) { maxcount = count[0]; maxpos = page; - } else if ((count[0] < 0x40000000) && (maxcount > 0xc0000000)) { + } else if (count[0] < 0x40000000 && maxcount > 0xc0000000) { maxcount = count[0]; maxpos = page; - } else if ((count[0] > maxcount) && (count[0] < 0xc0000000)) { + } else if (count[0] > maxcount && count[0] < 0xc0000000) { maxcount = count[0]; maxpos = page; - } else if ((count[0] > maxcount) && (count[0] > 0xc0000000) - && (maxcount > 0x80000000)) { + } else if (count[0] > maxcount && count[0] > 0xc0000000 + && maxcount > 0x80000000) { maxcount = count[0]; maxpos = page; } @@ -277,18 +277,18 @@ static void mtdoops_notify_add(struct mtd_info *mtd) if (cxt->name && !strcmp(mtd->name, cxt->name)) cxt->mtd_index = mtd->index; - if ((mtd->index != cxt->mtd_index) || cxt->mtd_index < 0) + if (mtd->index != cxt->mtd_index || cxt->mtd_index < 0) return; - if (mtd->size < (mtd->erasesize * 2)) { - printk(KERN_ERR "MTD partition %d not big enough for mtdoops\n", - mtd->index); + if (mtd->size < mtd->erasesize * 2) { + printk(KERN_ERR "mtdoops: MTD partition %d not big enough for mtdoops\n", + mtd->index); return; } if (mtd->erasesize < OOPS_PAGE_SIZE) { - printk(KERN_ERR "Eraseblock size of MTD partition %d too small\n", - mtd->index); + printk(KERN_ERR "mtdoops: eraseblock size of MTD partition %d too small\n", + mtd->index); return; } @@ -307,7 +307,7 @@ static void mtdoops_notify_remove(struct mtd_info *mtd) { struct mtdoops_context *cxt = &oops_cxt; - if ((mtd->index != cxt->mtd_index) || cxt->mtd_index < 0) + if (mtd->index != cxt->mtd_index || cxt->mtd_index < 0) return; cxt->mtd = NULL; @@ -323,8 +323,8 @@ static void mtdoops_console_sync(void) if (!cxt->ready || !mtd || cxt->writecount == 0) return; - /* - * Once ready is 0 and we've held the lock no further writes to the + /* + * Once ready is 0 and we've held the lock no further writes to the * buffer will happen */ spin_lock_irqsave(&cxt->writecount_lock, flags); @@ -373,7 +373,7 @@ mtdoops_console_write(struct console *co, const char *s, unsigned int count) cxt->writecount = 8; } - if ((count + cxt->writecount) > OOPS_PAGE_SIZE) + if (count + cxt->writecount > OOPS_PAGE_SIZE) count = OOPS_PAGE_SIZE - cxt->writecount; memcpy(cxt->oops_buf + cxt->writecount, s, count); @@ -422,13 +422,12 @@ static int __init mtdoops_console_init(void) cxt->mtd_index = -1; cxt->oops_buf = vmalloc(OOPS_PAGE_SIZE); - spin_lock_init(&cxt->writecount_lock); - if (!cxt->oops_buf) { - printk(KERN_ERR "Failed to allocate mtdoops buffer workspace\n"); + printk(KERN_ERR "mtdoops: failed to allocate buffer workspace\n"); return -ENOMEM; } + spin_lock_init(&cxt->writecount_lock); INIT_WORK(&cxt->work_erase, mtdoops_workfunc_erase); INIT_WORK(&cxt->work_write, mtdoops_workfunc_write); -- cgit v0.10.2 From be95745f01677245a061a8f51473ef5ec8ad008e Mon Sep 17 00:00:00 2001 From: Simon Kagstrom Date: Thu, 29 Oct 2009 13:41:11 +0100 Subject: mtd: mtdoops: keep track of used/unused pages in an array This patch makes mtdoops keep track of used/unused pages in an array instead of scanning the flash after a write. The advantage with this approach is that it avoids calling mtd->read on a panic, which is not possible for all mtd drivers. Signed-off-by: Simon Kagstrom Reviewed-by: Anders Grafstrom Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index c383add..06c5382 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -44,6 +44,7 @@ static struct mtdoops_context { int oops_pages; int nextpage; int nextcount; + unsigned long *oops_page_used; char *name; void *oops_buf; @@ -54,18 +55,38 @@ static struct mtdoops_context { int writecount; } oops_cxt; +static void mark_page_used(struct mtdoops_context *cxt, int page) +{ + set_bit(page, cxt->oops_page_used); +} + +static void mark_page_unused(struct mtdoops_context *cxt, int page) +{ + clear_bit(page, cxt->oops_page_used); +} + +static int page_is_used(struct mtdoops_context *cxt, int page) +{ + return test_bit(page, cxt->oops_page_used); +} + static void mtdoops_erase_callback(struct erase_info *done) { wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv; wake_up(wait_q); } -static int mtdoops_erase_block(struct mtd_info *mtd, int offset) +static int mtdoops_erase_block(struct mtdoops_context *cxt, int offset) { + struct mtd_info *mtd = cxt->mtd; + u32 start_page_offset = mtd_div_by_eb(offset, mtd) * mtd->erasesize; + u32 start_page = start_page_offset / OOPS_PAGE_SIZE; + u32 erase_pages = mtd->erasesize / OOPS_PAGE_SIZE; struct erase_info erase; DECLARE_WAITQUEUE(wait, current); wait_queue_head_t wait_q; int ret; + int page; init_waitqueue_head(&wait_q); erase.mtd = mtd; @@ -90,16 +111,15 @@ static int mtdoops_erase_block(struct mtd_info *mtd, int offset) schedule(); /* Wait for erase to finish. */ remove_wait_queue(&wait_q, &wait); + /* Mark pages as unused */ + for (page = start_page; page < start_page + erase_pages; page++) + mark_page_unused(cxt, page); + return 0; } static void mtdoops_inc_counter(struct mtdoops_context *cxt) { - struct mtd_info *mtd = cxt->mtd; - size_t retlen; - u32 count; - int ret; - cxt->nextpage++; if (cxt->nextpage >= cxt->oops_pages) cxt->nextpage = 0; @@ -107,17 +127,7 @@ static void mtdoops_inc_counter(struct mtdoops_context *cxt) if (cxt->nextcount == 0xffffffff) cxt->nextcount = 0; - ret = mtd->read(mtd, cxt->nextpage * OOPS_PAGE_SIZE, 4, - &retlen, (u_char *) &count); - if (retlen != 4 || (ret < 0 && ret != -EUCLEAN)) { - printk(KERN_ERR "mtdoops: read failure at %d (%td of 4 read), err %d\n", - cxt->nextpage * OOPS_PAGE_SIZE, retlen, ret); - schedule_work(&cxt->work_erase); - return; - } - - /* See if we need to erase the next block */ - if (count != 0xffffffff) { + if (page_is_used(cxt, cxt->nextpage)) { schedule_work(&cxt->work_erase); return; } @@ -168,7 +178,7 @@ badblock: } for (j = 0, ret = -1; (j < 3) && (ret < 0); j++) - ret = mtdoops_erase_block(mtd, cxt->nextpage * OOPS_PAGE_SIZE); + ret = mtdoops_erase_block(cxt, cxt->nextpage * OOPS_PAGE_SIZE); if (ret >= 0) { printk(KERN_DEBUG "mtdoops: ready %d, %d\n", @@ -209,6 +219,7 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic) if (retlen != OOPS_PAGE_SIZE || ret < 0) printk(KERN_ERR "mtdoops: write failure at %d (%td of %d written), error %d\n", cxt->nextpage * OOPS_PAGE_SIZE, retlen, OOPS_PAGE_SIZE, ret); + mark_page_used(cxt, cxt->nextpage); mtdoops_inc_counter(cxt); } @@ -230,6 +241,8 @@ static void find_next_position(struct mtdoops_context *cxt) size_t retlen; for (page = 0; page < cxt->oops_pages; page++) { + /* Assume the page is used */ + mark_page_used(cxt, page); ret = mtd->read(mtd, page * OOPS_PAGE_SIZE, 8, &retlen, (u_char *) &count[0]); if (retlen != 8 || (ret < 0 && ret != -EUCLEAN)) { printk(KERN_ERR "mtdoops: read failure at %d (%td of 8 read), err %d\n", @@ -237,6 +250,8 @@ static void find_next_position(struct mtdoops_context *cxt) continue; } + if (count[0] == 0xffffffff && count[1] == 0xffffffff) + mark_page_unused(cxt, page); if (count[1] != MTDOOPS_KERNMSG_MAGIC) continue; if (count[0] == 0xffffffff) @@ -273,6 +288,9 @@ static void find_next_position(struct mtdoops_context *cxt) static void mtdoops_notify_add(struct mtd_info *mtd) { struct mtdoops_context *cxt = &oops_cxt; + u64 mtdoops_pages = mtd->size; + + do_div(mtdoops_pages, OOPS_PAGE_SIZE); if (cxt->name && !strcmp(mtd->name, cxt->name)) cxt->mtd_index = mtd->index; @@ -292,6 +310,13 @@ static void mtdoops_notify_add(struct mtd_info *mtd) return; } + /* oops_page_used is a bit field */ + cxt->oops_page_used = vmalloc(DIV_ROUND_UP(mtdoops_pages, + BITS_PER_LONG)); + if (!cxt->oops_page_used) { + printk(KERN_ERR "Could not allocate page array\n"); + return; + } cxt->mtd = mtd; if (mtd->size > INT_MAX) cxt->oops_pages = INT_MAX / OOPS_PAGE_SIZE; @@ -444,6 +469,7 @@ static void __exit mtdoops_console_exit(void) unregister_console(&mtdoops_console); kfree(cxt->name); vfree(cxt->oops_buf); + vfree(cxt->oops_page_used); } -- cgit v0.10.2 From 1114e3d00f539ecb7a8415663f2a47a80e00a537 Mon Sep 17 00:00:00 2001 From: Simon Kagstrom Date: Tue, 3 Nov 2009 08:08:41 +0200 Subject: mtd: mtdoops: limit the maximum mtd partition size Make the maximum mtdoops partition size to be 8MiB. Indeed, it does not make sense to use anything larger than that anyway. This limit makes it possible to catch stupid mistakes where the user gives e.g., a rootfs partition to mtdoops (which will happily erase it). Signed-off-by: Simon Kagstrom Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index 06c5382..b016eee 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -33,6 +33,9 @@ #include #include +/* Maximum MTD partition size */ +#define MTDOOPS_MAX_MTD_SIZE (8 * 1024 * 1024) + #define MTDOOPS_KERNMSG_MAGIC 0x5d005d00 #define OOPS_PAGE_SIZE 4096 @@ -310,6 +313,12 @@ static void mtdoops_notify_add(struct mtd_info *mtd) return; } + if (mtd->size > MTDOOPS_MAX_MTD_SIZE) { + printk(KERN_ERR "mtdoops: mtd%d is too large (limit is %d MiB)\n", + mtd->index, MTDOOPS_MAX_MTD_SIZE / 1024 / 1024); + return; + } + /* oops_page_used is a bit field */ cxt->oops_page_used = vmalloc(DIV_ROUND_UP(mtdoops_pages, BITS_PER_LONG)); @@ -317,14 +326,10 @@ static void mtdoops_notify_add(struct mtd_info *mtd) printk(KERN_ERR "Could not allocate page array\n"); return; } - cxt->mtd = mtd; - if (mtd->size > INT_MAX) - cxt->oops_pages = INT_MAX / OOPS_PAGE_SIZE; - else - cxt->oops_pages = (int)mtd->size / OOPS_PAGE_SIZE; + cxt->mtd = mtd; + cxt->oops_pages = (int)mtd->size / OOPS_PAGE_SIZE; find_next_position(cxt); - printk(KERN_INFO "mtdoops: Attached to MTD device %d\n", mtd->index); } -- cgit v0.10.2 From 9507b0c838e37651030d453b9cf3b136cfeefe89 Mon Sep 17 00:00:00 2001 From: Simon Kagstrom Date: Thu, 29 Oct 2009 13:41:19 +0100 Subject: mtd: mtdoops: make record size configurable The main justification for this is to allow catching long messages during a panic, where the top part might otherwise be lost since moving to the next block can require a flash erase. Signed-off-by: Simon Kagstrom Reviewed-by: Anders Grafstrom Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index b016eee..64772dc 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -37,7 +37,11 @@ #define MTDOOPS_MAX_MTD_SIZE (8 * 1024 * 1024) #define MTDOOPS_KERNMSG_MAGIC 0x5d005d00 -#define OOPS_PAGE_SIZE 4096 + +static unsigned long record_size = 4096; +module_param(record_size, ulong, 0400); +MODULE_PARM_DESC(record_size, + "record size for MTD OOPS pages in bytes (default 4096)"); static struct mtdoops_context { int mtd_index; @@ -83,8 +87,8 @@ static int mtdoops_erase_block(struct mtdoops_context *cxt, int offset) { struct mtd_info *mtd = cxt->mtd; u32 start_page_offset = mtd_div_by_eb(offset, mtd) * mtd->erasesize; - u32 start_page = start_page_offset / OOPS_PAGE_SIZE; - u32 erase_pages = mtd->erasesize / OOPS_PAGE_SIZE; + u32 start_page = start_page_offset / record_size; + u32 erase_pages = mtd->erasesize / record_size; struct erase_info erase; DECLARE_WAITQUEUE(wait, current); wait_queue_head_t wait_q; @@ -152,15 +156,15 @@ static void mtdoops_workfunc_erase(struct work_struct *work) if (!mtd) return; - mod = (cxt->nextpage * OOPS_PAGE_SIZE) % mtd->erasesize; + mod = (cxt->nextpage * record_size) % mtd->erasesize; if (mod != 0) { - cxt->nextpage = cxt->nextpage + ((mtd->erasesize - mod) / OOPS_PAGE_SIZE); + cxt->nextpage = cxt->nextpage + ((mtd->erasesize - mod) / record_size); if (cxt->nextpage >= cxt->oops_pages) cxt->nextpage = 0; } while (mtd->block_isbad) { - ret = mtd->block_isbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE); + ret = mtd->block_isbad(mtd, cxt->nextpage * record_size); if (!ret) break; if (ret < 0) { @@ -168,20 +172,20 @@ static void mtdoops_workfunc_erase(struct work_struct *work) return; } badblock: - printk(KERN_WARNING "mtdoops: bad block at %08x\n", - cxt->nextpage * OOPS_PAGE_SIZE); + printk(KERN_WARNING "mtdoops: bad block at %08lx\n", + cxt->nextpage * record_size); i++; - cxt->nextpage = cxt->nextpage + (mtd->erasesize / OOPS_PAGE_SIZE); + cxt->nextpage = cxt->nextpage + (mtd->erasesize / record_size); if (cxt->nextpage >= cxt->oops_pages) cxt->nextpage = 0; - if (i == cxt->oops_pages / (mtd->erasesize / OOPS_PAGE_SIZE)) { + if (i == cxt->oops_pages / (mtd->erasesize / record_size)) { printk(KERN_ERR "mtdoops: all blocks bad!\n"); return; } } for (j = 0, ret = -1; (j < 3) && (ret < 0); j++) - ret = mtdoops_erase_block(cxt, cxt->nextpage * OOPS_PAGE_SIZE); + ret = mtdoops_erase_block(cxt, cxt->nextpage * record_size); if (ret >= 0) { printk(KERN_DEBUG "mtdoops: ready %d, %d\n", @@ -191,7 +195,7 @@ badblock: } if (mtd->block_markbad && ret == -EIO) { - ret = mtd->block_markbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE); + ret = mtd->block_markbad(mtd, cxt->nextpage * record_size); if (ret < 0) { printk(KERN_ERR "mtdoops: block_markbad failed, aborting\n"); return; @@ -206,22 +210,22 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic) size_t retlen; int ret; - if (cxt->writecount < OOPS_PAGE_SIZE) + if (cxt->writecount < record_size) memset(cxt->oops_buf + cxt->writecount, 0xff, - OOPS_PAGE_SIZE - cxt->writecount); + record_size - cxt->writecount); if (panic) - ret = mtd->panic_write(mtd, cxt->nextpage * OOPS_PAGE_SIZE, - OOPS_PAGE_SIZE, &retlen, cxt->oops_buf); + ret = mtd->panic_write(mtd, cxt->nextpage * record_size, + record_size, &retlen, cxt->oops_buf); else - ret = mtd->write(mtd, cxt->nextpage * OOPS_PAGE_SIZE, - OOPS_PAGE_SIZE, &retlen, cxt->oops_buf); + ret = mtd->write(mtd, cxt->nextpage * record_size, + record_size, &retlen, cxt->oops_buf); cxt->writecount = 0; - if (retlen != OOPS_PAGE_SIZE || ret < 0) - printk(KERN_ERR "mtdoops: write failure at %d (%td of %d written), error %d\n", - cxt->nextpage * OOPS_PAGE_SIZE, retlen, OOPS_PAGE_SIZE, ret); + if (retlen != record_size || ret < 0) + printk(KERN_ERR "mtdoops: write failure at %ld (%td of %ld written), error %d\n", + cxt->nextpage * record_size, retlen, record_size, ret); mark_page_used(cxt, cxt->nextpage); mtdoops_inc_counter(cxt); @@ -246,10 +250,10 @@ static void find_next_position(struct mtdoops_context *cxt) for (page = 0; page < cxt->oops_pages; page++) { /* Assume the page is used */ mark_page_used(cxt, page); - ret = mtd->read(mtd, page * OOPS_PAGE_SIZE, 8, &retlen, (u_char *) &count[0]); + ret = mtd->read(mtd, page * record_size, 8, &retlen, (u_char *) &count[0]); if (retlen != 8 || (ret < 0 && ret != -EUCLEAN)) { - printk(KERN_ERR "mtdoops: read failure at %d (%td of 8 read), err %d\n", - page * OOPS_PAGE_SIZE, retlen, ret); + printk(KERN_ERR "mtdoops: read failure at %ld (%td of 8 read), err %d\n", + page * record_size, retlen, ret); continue; } @@ -293,7 +297,7 @@ static void mtdoops_notify_add(struct mtd_info *mtd) struct mtdoops_context *cxt = &oops_cxt; u64 mtdoops_pages = mtd->size; - do_div(mtdoops_pages, OOPS_PAGE_SIZE); + do_div(mtdoops_pages, record_size); if (cxt->name && !strcmp(mtd->name, cxt->name)) cxt->mtd_index = mtd->index; @@ -307,7 +311,7 @@ static void mtdoops_notify_add(struct mtd_info *mtd) return; } - if (mtd->erasesize < OOPS_PAGE_SIZE) { + if (mtd->erasesize < record_size) { printk(KERN_ERR "mtdoops: eraseblock size of MTD partition %d too small\n", mtd->index); return; @@ -328,7 +332,7 @@ static void mtdoops_notify_add(struct mtd_info *mtd) } cxt->mtd = mtd; - cxt->oops_pages = (int)mtd->size / OOPS_PAGE_SIZE; + cxt->oops_pages = (int)mtd->size / record_size; find_next_position(cxt); printk(KERN_INFO "mtdoops: Attached to MTD device %d\n", mtd->index); } @@ -403,15 +407,15 @@ mtdoops_console_write(struct console *co, const char *s, unsigned int count) cxt->writecount = 8; } - if (count + cxt->writecount > OOPS_PAGE_SIZE) - count = OOPS_PAGE_SIZE - cxt->writecount; + if (count + cxt->writecount > record_size) + count = record_size - cxt->writecount; memcpy(cxt->oops_buf + cxt->writecount, s, count); cxt->writecount += count; spin_unlock_irqrestore(&cxt->writecount_lock, flags); - if (cxt->writecount == OOPS_PAGE_SIZE) + if (cxt->writecount == record_size) mtdoops_console_sync(); } @@ -450,8 +454,16 @@ static int __init mtdoops_console_init(void) { struct mtdoops_context *cxt = &oops_cxt; + if ((record_size & 4095) != 0) { + printk(KERN_ERR "mtdoops: record_size must be a multiple of 4096\n"); + return -EINVAL; + } + if (record_size < 4096) { + printk(KERN_ERR "mtdoops: record_size must be over 4096 bytes\n"); + return -EINVAL; + } cxt->mtd_index = -1; - cxt->oops_buf = vmalloc(OOPS_PAGE_SIZE); + cxt->oops_buf = vmalloc(record_size); if (!cxt->oops_buf) { printk(KERN_ERR "mtdoops: failed to allocate buffer workspace\n"); return -ENOMEM; -- cgit v0.10.2 From 2e386e4bac90554887e73d6f342e845185b33fc3 Mon Sep 17 00:00:00 2001 From: Simon Kagstrom Date: Tue, 3 Nov 2009 14:19:03 +0100 Subject: mtd: mtdoops: refactor as a kmsg_dumper The last messages which happens before a crash might contain interesting information about the crash. This patch reworks mtdoops using the kmsg_dumper support instead of a console, which simplifies the code and also includes the messages before the oops started. On oops callbacks, the MTD device write is scheduled in a work queue (to be able to use the regular mtd->write call), while panics call mtd->panic_write directly. Thus, if panic_on_oops is set, the oops will be written out during the panic. A parameter to specify which mtd device to use (number or name), as well as a flag, writable at runtime, to toggle wheter to dump oopses or only panics (since oopses can often be handled by regular syslog). The patch was massaged and amended by Artem. Signed-off-by: Simon Kagstrom Reviewed-by: Anders Grafstrom Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index 64772dc..a714ec4 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -29,21 +29,34 @@ #include #include #include -#include #include #include +#include /* Maximum MTD partition size */ #define MTDOOPS_MAX_MTD_SIZE (8 * 1024 * 1024) #define MTDOOPS_KERNMSG_MAGIC 0x5d005d00 +#define MTDOOPS_HEADER_SIZE 8 static unsigned long record_size = 4096; module_param(record_size, ulong, 0400); MODULE_PARM_DESC(record_size, "record size for MTD OOPS pages in bytes (default 4096)"); +static char mtddev[80]; +module_param_string(mtddev, mtddev, 80, 0400); +MODULE_PARM_DESC(mtddev, + "name or index number of the MTD device to use"); + +static int dump_oops = 1; +module_param(dump_oops, int, 0600); +MODULE_PARM_DESC(dump_oops, + "set to 1 to dump oopses, 0 to only dump panics (default 1)"); + static struct mtdoops_context { + struct kmsg_dumper dump; + int mtd_index; struct work_struct work_erase; struct work_struct work_write; @@ -52,14 +65,8 @@ static struct mtdoops_context { int nextpage; int nextcount; unsigned long *oops_page_used; - char *name; void *oops_buf; - - /* writecount and disabling ready are spin lock protected */ - spinlock_t writecount_lock; - int ready; - int writecount; } oops_cxt; static void mark_page_used(struct mtdoops_context *cxt, int page) @@ -111,7 +118,7 @@ static int mtdoops_erase_block(struct mtdoops_context *cxt, int offset) remove_wait_queue(&wait_q, &wait); printk(KERN_WARNING "mtdoops: erase of region [0x%llx, 0x%llx] on \"%s\" failed\n", (unsigned long long)erase.addr, - (unsigned long long)erase.len, mtd->name); + (unsigned long long)erase.len, mtddev); return ret; } @@ -141,7 +148,6 @@ static void mtdoops_inc_counter(struct mtdoops_context *cxt) printk(KERN_DEBUG "mtdoops: ready %d, %d (no erase)\n", cxt->nextpage, cxt->nextcount); - cxt->ready = 1; } /* Scheduled work - when we can't proceed without erasing a block */ @@ -190,7 +196,6 @@ badblock: if (ret >= 0) { printk(KERN_DEBUG "mtdoops: ready %d, %d\n", cxt->nextpage, cxt->nextcount); - cxt->ready = 1; return; } @@ -208,11 +213,13 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic) { struct mtd_info *mtd = cxt->mtd; size_t retlen; + u32 *hdr; int ret; - if (cxt->writecount < record_size) - memset(cxt->oops_buf + cxt->writecount, 0xff, - record_size - cxt->writecount); + /* Add mtdoops header to the buffer */ + hdr = cxt->oops_buf; + hdr[0] = cxt->nextcount; + hdr[1] = MTDOOPS_KERNMSG_MAGIC; if (panic) ret = mtd->panic_write(mtd, cxt->nextpage * record_size, @@ -221,17 +228,15 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic) ret = mtd->write(mtd, cxt->nextpage * record_size, record_size, &retlen, cxt->oops_buf); - cxt->writecount = 0; - if (retlen != record_size || ret < 0) printk(KERN_ERR "mtdoops: write failure at %ld (%td of %ld written), error %d\n", cxt->nextpage * record_size, retlen, record_size, ret); mark_page_used(cxt, cxt->nextpage); + memset(cxt->oops_buf, 0xff, record_size); mtdoops_inc_counter(cxt); } - static void mtdoops_workfunc_write(struct work_struct *work) { struct mtdoops_context *cxt = @@ -250,17 +255,18 @@ static void find_next_position(struct mtdoops_context *cxt) for (page = 0; page < cxt->oops_pages; page++) { /* Assume the page is used */ mark_page_used(cxt, page); - ret = mtd->read(mtd, page * record_size, 8, &retlen, (u_char *) &count[0]); - if (retlen != 8 || (ret < 0 && ret != -EUCLEAN)) { - printk(KERN_ERR "mtdoops: read failure at %ld (%td of 8 read), err %d\n", - page * record_size, retlen, ret); + ret = mtd->read(mtd, page * record_size, MTDOOPS_HEADER_SIZE, + &retlen, (u_char *) &count[0]); + if (retlen != MTDOOPS_HEADER_SIZE || + (ret < 0 && ret != -EUCLEAN)) { + printk(KERN_ERR "mtdoops: read failure at %ld (%td of %d read), err %d\n", + page * record_size, retlen, + MTDOOPS_HEADER_SIZE, ret); continue; } if (count[0] == 0xffffffff && count[1] == 0xffffffff) mark_page_unused(cxt, page); - if (count[1] != MTDOOPS_KERNMSG_MAGIC) - continue; if (count[0] == 0xffffffff) continue; if (maxcount == 0xffffffff) { @@ -291,15 +297,50 @@ static void find_next_position(struct mtdoops_context *cxt) mtdoops_inc_counter(cxt); } +static void mtdoops_do_dump(struct kmsg_dumper *dumper, + enum kmsg_dump_reason reason, const char *s1, unsigned long l1, + const char *s2, unsigned long l2) +{ + struct mtdoops_context *cxt = container_of(dumper, + struct mtdoops_context, dump); + unsigned long s1_start, s2_start; + unsigned long l1_cpy, l2_cpy; + char *dst; + + /* Only dump oopses if dump_oops is set */ + if (reason == KMSG_DUMP_OOPS && !dump_oops) + return; + + dst = cxt->oops_buf + MTDOOPS_HEADER_SIZE; /* Skip the header */ + l2_cpy = min(l2, record_size - MTDOOPS_HEADER_SIZE); + l1_cpy = min(l1, record_size - MTDOOPS_HEADER_SIZE - l2_cpy); + + s2_start = l2 - l2_cpy; + s1_start = l1 - l1_cpy; + + memcpy(dst, s1 + s1_start, l1_cpy); + memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy); + + /* Panics must be written immediately */ + if (reason == KMSG_DUMP_PANIC) { + if (!cxt->mtd->panic_write) + printk(KERN_ERR "mtdoops: Cannot write from panic without panic_write\n"); + else + mtdoops_write(cxt, 1); + return; + } + + /* For other cases, schedule work to write it "nicely" */ + schedule_work(&cxt->work_write); +} static void mtdoops_notify_add(struct mtd_info *mtd) { struct mtdoops_context *cxt = &oops_cxt; - u64 mtdoops_pages = mtd->size; - - do_div(mtdoops_pages, record_size); + u64 mtdoops_pages = div_u64(mtd->size, record_size); + int err; - if (cxt->name && !strcmp(mtd->name, cxt->name)) + if (!strcmp(mtd->name, mtddev)) cxt->mtd_index = mtd->index; if (mtd->index != cxt->mtd_index || cxt->mtd_index < 0) @@ -310,13 +351,11 @@ static void mtdoops_notify_add(struct mtd_info *mtd) mtd->index); return; } - if (mtd->erasesize < record_size) { printk(KERN_ERR "mtdoops: eraseblock size of MTD partition %d too small\n", mtd->index); return; } - if (mtd->size > MTDOOPS_MAX_MTD_SIZE) { printk(KERN_ERR "mtdoops: mtd%d is too large (limit is %d MiB)\n", mtd->index, MTDOOPS_MAX_MTD_SIZE / 1024 / 1024); @@ -327,7 +366,16 @@ static void mtdoops_notify_add(struct mtd_info *mtd) cxt->oops_page_used = vmalloc(DIV_ROUND_UP(mtdoops_pages, BITS_PER_LONG)); if (!cxt->oops_page_used) { - printk(KERN_ERR "Could not allocate page array\n"); + printk(KERN_ERR "mtdoops: could not allocate page array\n"); + return; + } + + cxt->dump.dump = mtdoops_do_dump; + err = kmsg_dump_register(&cxt->dump); + if (err) { + printk(KERN_ERR "mtdoops: registering kmsg dumper failed, error %d\n", err); + vfree(cxt->oops_page_used); + cxt->oops_page_used = NULL; return; } @@ -344,116 +392,29 @@ static void mtdoops_notify_remove(struct mtd_info *mtd) if (mtd->index != cxt->mtd_index || cxt->mtd_index < 0) return; + if (kmsg_dump_unregister(&cxt->dump) < 0) + printk(KERN_WARNING "mtdoops: could not unregister kmsg_dumper\n"); + cxt->mtd = NULL; flush_scheduled_work(); } -static void mtdoops_console_sync(void) -{ - struct mtdoops_context *cxt = &oops_cxt; - struct mtd_info *mtd = cxt->mtd; - unsigned long flags; - - if (!cxt->ready || !mtd || cxt->writecount == 0) - return; - - /* - * Once ready is 0 and we've held the lock no further writes to the - * buffer will happen - */ - spin_lock_irqsave(&cxt->writecount_lock, flags); - if (!cxt->ready) { - spin_unlock_irqrestore(&cxt->writecount_lock, flags); - return; - } - cxt->ready = 0; - spin_unlock_irqrestore(&cxt->writecount_lock, flags); - - if (mtd->panic_write && in_interrupt()) - /* Interrupt context, we're going to panic so try and log */ - mtdoops_write(cxt, 1); - else - schedule_work(&cxt->work_write); -} - -static void -mtdoops_console_write(struct console *co, const char *s, unsigned int count) -{ - struct mtdoops_context *cxt = co->data; - struct mtd_info *mtd = cxt->mtd; - unsigned long flags; - - if (!oops_in_progress) { - mtdoops_console_sync(); - return; - } - - if (!cxt->ready || !mtd) - return; - - /* Locking on writecount ensures sequential writes to the buffer */ - spin_lock_irqsave(&cxt->writecount_lock, flags); - - /* Check ready status didn't change whilst waiting for the lock */ - if (!cxt->ready) { - spin_unlock_irqrestore(&cxt->writecount_lock, flags); - return; - } - - if (cxt->writecount == 0) { - u32 *stamp = cxt->oops_buf; - *stamp++ = cxt->nextcount; - *stamp = MTDOOPS_KERNMSG_MAGIC; - cxt->writecount = 8; - } - - if (count + cxt->writecount > record_size) - count = record_size - cxt->writecount; - - memcpy(cxt->oops_buf + cxt->writecount, s, count); - cxt->writecount += count; - - spin_unlock_irqrestore(&cxt->writecount_lock, flags); - - if (cxt->writecount == record_size) - mtdoops_console_sync(); -} - -static int __init mtdoops_console_setup(struct console *co, char *options) -{ - struct mtdoops_context *cxt = co->data; - - if (cxt->mtd_index != -1 || cxt->name) - return -EBUSY; - if (options) { - cxt->name = kstrdup(options, GFP_KERNEL); - return 0; - } - if (co->index == -1) - return -EINVAL; - - cxt->mtd_index = co->index; - return 0; -} static struct mtd_notifier mtdoops_notifier = { .add = mtdoops_notify_add, .remove = mtdoops_notify_remove, }; -static struct console mtdoops_console = { - .name = "ttyMTD", - .write = mtdoops_console_write, - .setup = mtdoops_console_setup, - .unblank = mtdoops_console_sync, - .index = -1, - .data = &oops_cxt, -}; - -static int __init mtdoops_console_init(void) +static int __init mtdoops_init(void) { struct mtdoops_context *cxt = &oops_cxt; + int mtd_index; + char *endp; + if (strlen(mtddev) == 0) { + printk(KERN_ERR "mtdoops: mtd device (mtddev=name/number) must be supplied\n"); + return -EINVAL; + } if ((record_size & 4095) != 0) { printk(KERN_ERR "mtdoops: record_size must be a multiple of 4096\n"); return -EINVAL; @@ -462,36 +423,44 @@ static int __init mtdoops_console_init(void) printk(KERN_ERR "mtdoops: record_size must be over 4096 bytes\n"); return -EINVAL; } + + /* Setup the MTD device to use */ cxt->mtd_index = -1; + mtd_index = simple_strtoul(mtddev, &endp, 0); + if (*endp == '\0') + cxt->mtd_index = mtd_index; + if (cxt->mtd_index > MAX_MTD_DEVICES) { + printk(KERN_ERR "mtdoops: invalid mtd device number (%u) given\n", + mtd_index); + return -EINVAL; + } + cxt->oops_buf = vmalloc(record_size); if (!cxt->oops_buf) { printk(KERN_ERR "mtdoops: failed to allocate buffer workspace\n"); return -ENOMEM; } + memset(cxt->oops_buf, 0xff, record_size); - spin_lock_init(&cxt->writecount_lock); INIT_WORK(&cxt->work_erase, mtdoops_workfunc_erase); INIT_WORK(&cxt->work_write, mtdoops_workfunc_write); - register_console(&mtdoops_console); register_mtd_user(&mtdoops_notifier); return 0; } -static void __exit mtdoops_console_exit(void) +static void __exit mtdoops_exit(void) { struct mtdoops_context *cxt = &oops_cxt; unregister_mtd_user(&mtdoops_notifier); - unregister_console(&mtdoops_console); - kfree(cxt->name); vfree(cxt->oops_buf); vfree(cxt->oops_page_used); } -subsys_initcall(mtdoops_console_init); -module_exit(mtdoops_console_exit); +module_init(mtdoops_init); +module_exit(mtdoops_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Richard Purdie "); -- cgit v0.10.2 From 75352662c54421b48ed58200565395b123952748 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sun, 29 Nov 2009 19:07:57 +0100 Subject: mtd: nandsim: add support for 4KiB pages I was going to play with a faulty nand image from real flash and noticed that nandsim does not work with: first_id_byte=0xec second_id_byte=0xd5 third_id_byte=0x51 fourth_id_byte=0xa6 This patch seems to fix it. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index cd0711b..7281000 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -161,7 +161,7 @@ MODULE_PARM_DESC(overridesize, "Specifies the NAND Flash size overriding the I MODULE_PARM_DESC(cache_file, "File to use to cache nand pages instead of memory"); /* The largest possible page size */ -#define NS_LARGEST_PAGE_SIZE 2048 +#define NS_LARGEST_PAGE_SIZE 4096 /* The prefix for simulator output */ #define NS_OUTPUT_PREFIX "[nandsim]" @@ -259,7 +259,8 @@ MODULE_PARM_DESC(cache_file, "File to use to cache nand pages instead of mem #define OPT_SMARTMEDIA 0x00000010 /* SmartMedia technology chips */ #define OPT_AUTOINCR 0x00000020 /* page number auto inctimentation is possible */ #define OPT_PAGE512_8BIT 0x00000040 /* 512-byte page chips with 8-bit bus width */ -#define OPT_LARGEPAGE (OPT_PAGE2048) /* 2048-byte page chips */ +#define OPT_PAGE4096 0x00000080 /* 4096-byte page chips */ +#define OPT_LARGEPAGE (OPT_PAGE2048 | OPT_PAGE4096) /* 2048 & 4096-byte page chips */ #define OPT_SMALLPAGE (OPT_PAGE256 | OPT_PAGE512) /* 256 and 512-byte page chips */ /* Remove action bits ftom state */ @@ -588,6 +589,8 @@ static int init_nandsim(struct mtd_info *mtd) ns->options |= OPT_PAGE512_8BIT; } else if (ns->geom.pgsz == 2048) { ns->options |= OPT_PAGE2048; + } else if (ns->geom.pgsz == 4096) { + ns->options |= OPT_PAGE4096; } else { NS_ERR("init_nandsim: unknown page size %u\n", ns->geom.pgsz); return -EIO; -- cgit v0.10.2 From 595dd3d8bf953254d8d2f30f99c54fe09c470040 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 1 Dec 2009 10:52:02 -0800 Subject: kmsg_dump: fix build for CONFIG_PRINTK=n kmsg_dump() fails to build when CONFIG_PRINTK=n; provide stubs for the kmsg_dump*() functions when CONFIG_PRINTK=n. kernel/printk.c: In function 'kmsg_dump': kernel/printk.c:1501: error: 'log_buf_len' undeclared (first use in this function) kernel/printk.c:1502: error: 'logged_chars' undeclared (first use in this function) kernel/printk.c:1506: error: 'log_buf' undeclared (first use in this function) Signed-off-by: Randy Dunlap Acked-by: Simon Kagstrom Signed-off-by: David Woodhouse diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h index 7f089ec..e32aa26 100644 --- a/include/linux/kmsg_dump.h +++ b/include/linux/kmsg_dump.h @@ -35,10 +35,26 @@ struct kmsg_dumper { int registered; }; +#ifdef CONFIG_PRINTK void kmsg_dump(enum kmsg_dump_reason reason); int kmsg_dump_register(struct kmsg_dumper *dumper); int kmsg_dump_unregister(struct kmsg_dumper *dumper); +#else +static inline void kmsg_dump(enum kmsg_dump_reason reason) +{ +} + +static inline int kmsg_dump_register(struct kmsg_dumper *dumper) +{ + return -EINVAL; +} + +static inline int kmsg_dump_unregister(struct kmsg_dumper *dumper) +{ + return -EINVAL; +} +#endif #endif /* _LINUX_KMSG_DUMP_H */ diff --git a/kernel/printk.c b/kernel/printk.c index 051d1f5..2a56457 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -1405,7 +1405,6 @@ bool printk_timed_ratelimit(unsigned long *caller_jiffies, return false; } EXPORT_SYMBOL(printk_timed_ratelimit); -#endif static DEFINE_SPINLOCK(dump_list_lock); static LIST_HEAD(dump_list); @@ -1524,3 +1523,4 @@ void kmsg_dump(enum kmsg_dump_reason reason) dumper->dump(dumper, reason, s1, l1, s2, l2); spin_unlock_irqrestore(&dump_list_lock, flags); } +#endif -- cgit v0.10.2 From 9d233e8bb92e355fd20b14745c1d9ff402e0e685 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 3 Dec 2009 00:24:51 +0300 Subject: power_supply_sysfs: Handle -ENODATA in a special way There are cases when some device can not report any meaningful value, e.g. TWL4030 charger can report voltage only when charging is active. In these cases drivers will return -ENODATA, and we shouldn't flood kernel log with error messages. Signed-off-by: Anton Vorontsov diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index 0814439..c790e0c 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -65,7 +65,10 @@ static ssize_t power_supply_show_property(struct device *dev, ret = psy->get_property(psy, off, &value); if (ret < 0) { - if (ret != -ENODEV) + if (ret == -ENODATA) + dev_dbg(dev, "driver has no data for `%s' property\n", + attr->attr.name); + else if (ret != -ENODEV) dev_err(dev, "driver failed to report `%s' property\n", attr->attr.name); return ret; -- cgit v0.10.2 From 38a04e432768ec0b016f3c687b4de31ac111ae59 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Mon, 30 Nov 2009 14:32:19 +0800 Subject: ocfs2: Find proper end cpos for a leaf refcount block. ocfs2 refcount tree is stored as an extent tree while the leaf ocfs2_refcount_rec points to a refcount block. The following step can trip a kernel panic. mkfs.ocfs2 -b 512 -C 1M --fs-features=refcount $DEVICE mount -t ocfs2 $DEVICE $MNT_DIR FILE_NAME=$RANDOM FILE_NAME_1=$RANDOM FILE_REF="${FILE_NAME}_ref" FILE_REF_1="${FILE_NAME}_ref_1" for((i=0;i<305;i++)) do # /mnt/1048576 is a file with 1048576 sizes. cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME_1 done for((i=0;i<3;i++)) do cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME done for((i=0;i<2;i++)) do cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME_1 done cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME for((i=0;i<11;i++)) do cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME cat /mnt/1048576 >> $MNT_DIR/$FILE_NAME_1 done reflink $MNT_DIR/$FILE_NAME $MNT_DIR/$FILE_REF # write_f is a program which will write some bytes to a file at offset. # write_f -f file_name -l offset -w write_bytes. ./write_f -f $MNT_DIR/$FILE_REF -l $[310*1048576] -w 4096 ./write_f -f $MNT_DIR/$FILE_REF -l $[306*1048576] -w 4096 ./write_f -f $MNT_DIR/$FILE_REF -l $[311*1048576] -w 4096 ./write_f -f $MNT_DIR/$FILE_NAME -l $[310*1048576] -w 4096 ./write_f -f $MNT_DIR/$FILE_NAME -l $[311*1048576] -w 4096 reflink $MNT_DIR/$FILE_NAME $MNT_DIR/$FILE_REF_1 ./write_f -f $MNT_DIR/$FILE_NAME -l $[311*1048576] -w 4096 #kernel panic here. The reason is that if the ocfs2_extent_rec is the last record in a leaf extent block, the old solution fails to find the suitable end cpos. So this patch try to walk through the b-tree, find the next sub root and get the c_pos the next sub-tree starts from. btw, I have runned tristan's test case against the patched kernel for several days and this type of kernel panic never happens again. Signed-off-by: Tao Ma Signed-off-by: Joel Becker diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 38a42f5..5661db1 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -1765,9 +1765,9 @@ set_and_inc: * * The array index of the subtree root is passed back. */ -static int ocfs2_find_subtree_root(struct ocfs2_extent_tree *et, - struct ocfs2_path *left, - struct ocfs2_path *right) +int ocfs2_find_subtree_root(struct ocfs2_extent_tree *et, + struct ocfs2_path *left, + struct ocfs2_path *right) { int i = 0; @@ -2872,8 +2872,8 @@ out: * This looks similar, but is subtly different to * ocfs2_find_cpos_for_left_leaf(). */ -static int ocfs2_find_cpos_for_right_leaf(struct super_block *sb, - struct ocfs2_path *path, u32 *cpos) +int ocfs2_find_cpos_for_right_leaf(struct super_block *sb, + struct ocfs2_path *path, u32 *cpos) { int i, j, ret = 0; u64 blkno; diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index 9c122d5..1db4359 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h @@ -317,4 +317,9 @@ int ocfs2_path_bh_journal_access(handle_t *handle, int ocfs2_journal_access_path(struct ocfs2_caching_info *ci, handle_t *handle, struct ocfs2_path *path); +int ocfs2_find_cpos_for_right_leaf(struct super_block *sb, + struct ocfs2_path *path, u32 *cpos); +int ocfs2_find_subtree_root(struct ocfs2_extent_tree *et, + struct ocfs2_path *left, + struct ocfs2_path *right); #endif /* OCFS2_ALLOC_H */ diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 3a0df7a..9c3956f 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c @@ -969,6 +969,103 @@ out: } /* + * Find the end range for a leaf refcount block indicated by + * el->l_recs[index].e_blkno. + */ +static int ocfs2_get_refcount_cpos_end(struct ocfs2_caching_info *ci, + struct buffer_head *ref_root_bh, + struct ocfs2_extent_block *eb, + struct ocfs2_extent_list *el, + int index, u32 *cpos_end) +{ + int ret, i, subtree_root; + u32 cpos; + u64 blkno; + struct super_block *sb = ocfs2_metadata_cache_get_super(ci); + struct ocfs2_path *left_path = NULL, *right_path = NULL; + struct ocfs2_extent_tree et; + struct ocfs2_extent_list *tmp_el; + + if (index < le16_to_cpu(el->l_next_free_rec) - 1) { + /* + * We have a extent rec after index, so just use the e_cpos + * of the next extent rec. + */ + *cpos_end = le32_to_cpu(el->l_recs[index+1].e_cpos); + return 0; + } + + if (!eb || (eb && !eb->h_next_leaf_blk)) { + /* + * We are the last extent rec, so any high cpos should + * be stored in this leaf refcount block. + */ + *cpos_end = UINT_MAX; + return 0; + } + + /* + * If the extent block isn't the last one, we have to find + * the subtree root between this extent block and the next + * leaf extent block and get the corresponding e_cpos from + * the subroot. Otherwise we may corrupt the b-tree. + */ + ocfs2_init_refcount_extent_tree(&et, ci, ref_root_bh); + + left_path = ocfs2_new_path_from_et(&et); + if (!left_path) { + ret = -ENOMEM; + mlog_errno(ret); + goto out; + } + + cpos = le32_to_cpu(eb->h_list.l_recs[index].e_cpos); + ret = ocfs2_find_path(ci, left_path, cpos); + if (ret) { + mlog_errno(ret); + goto out; + } + + right_path = ocfs2_new_path_from_path(left_path); + if (!right_path) { + ret = -ENOMEM; + mlog_errno(ret); + goto out; + } + + ret = ocfs2_find_cpos_for_right_leaf(sb, left_path, &cpos); + if (ret) { + mlog_errno(ret); + goto out; + } + + ret = ocfs2_find_path(ci, right_path, cpos); + if (ret) { + mlog_errno(ret); + goto out; + } + + subtree_root = ocfs2_find_subtree_root(&et, left_path, + right_path); + + tmp_el = left_path->p_node[subtree_root].el; + blkno = left_path->p_node[subtree_root+1].bh->b_blocknr; + for (i = 0; i < le32_to_cpu(tmp_el->l_next_free_rec); i++) { + if (le64_to_cpu(tmp_el->l_recs[i].e_blkno) == blkno) { + *cpos_end = le32_to_cpu(tmp_el->l_recs[i+1].e_cpos); + break; + } + } + + BUG_ON(i == le32_to_cpu(tmp_el->l_next_free_rec)); + +out: + ocfs2_free_path(left_path); + ocfs2_free_path(right_path); + return ret; +} + +/* * Given a cpos and len, try to find the refcount record which contains cpos. * 1. If cpos can be found in one refcount record, return the record. * 2. If cpos can't be found, return a fake record which start from cpos @@ -983,10 +1080,10 @@ static int ocfs2_get_refcount_rec(struct ocfs2_caching_info *ci, struct buffer_head **ret_bh) { int ret = 0, i, found; - u32 low_cpos; + u32 low_cpos, uninitialized_var(cpos_end); struct ocfs2_extent_list *el; - struct ocfs2_extent_rec *tmp, *rec = NULL; - struct ocfs2_extent_block *eb; + struct ocfs2_extent_rec *rec = NULL; + struct ocfs2_extent_block *eb = NULL; struct buffer_head *eb_bh = NULL, *ref_leaf_bh = NULL; struct super_block *sb = ocfs2_metadata_cache_get_super(ci); struct ocfs2_refcount_block *rb = @@ -1034,12 +1131,16 @@ static int ocfs2_get_refcount_rec(struct ocfs2_caching_info *ci, } } - /* adjust len when we have ocfs2_extent_rec after it. */ - if (found && i < le16_to_cpu(el->l_next_free_rec) - 1) { - tmp = &el->l_recs[i+1]; + if (found) { + ret = ocfs2_get_refcount_cpos_end(ci, ref_root_bh, + eb, el, i, &cpos_end); + if (ret) { + mlog_errno(ret); + goto out; + } - if (le32_to_cpu(tmp->e_cpos) < cpos + len) - len = le32_to_cpu(tmp->e_cpos) - cpos; + if (cpos_end < low_cpos + len) + len = cpos_end - low_cpos; } ret = ocfs2_read_refcount_block(ci, le64_to_cpu(rec->e_blkno), -- cgit v0.10.2 From 12d4cec988a8a20927a9795dbf2c6d9ef2f85baa Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Mon, 30 Nov 2009 15:08:40 +0800 Subject: ocfs2: refcounttree.c cleanup. sparse check finds some endian problem and some other minor issues. There is an obsolete function which should be removed. So this patch resolve all these. Signed-off-by: Tao Ma Signed-off-by: Joel Becker diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 9c3956f..c7ffba8 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c @@ -276,7 +276,7 @@ static void ocfs2_erase_refcount_tree_from_list(struct ocfs2_super *osb, spin_unlock(&osb->osb_lock); } -void ocfs2_kref_remove_refcount_tree(struct kref *kref) +static void ocfs2_kref_remove_refcount_tree(struct kref *kref) { struct ocfs2_refcount_tree *tree = container_of(kref, struct ocfs2_refcount_tree, rf_getcnt); @@ -524,23 +524,6 @@ out: return ret; } -int ocfs2_lock_refcount_tree_by_inode(struct inode *inode, int rw, - struct ocfs2_refcount_tree **ret_tree, - struct buffer_head **ref_bh) -{ - int ret; - u64 ref_blkno; - - ret = ocfs2_get_refcount_block(inode, &ref_blkno); - if (ret) { - mlog_errno(ret); - return ret; - } - - return ocfs2_lock_refcount_tree(OCFS2_SB(inode->i_sb), ref_blkno, - rw, ret_tree, ref_bh); -} - void ocfs2_unlock_refcount_tree(struct ocfs2_super *osb, struct ocfs2_refcount_tree *tree, int rw) { @@ -1519,7 +1502,7 @@ static int ocfs2_divide_leaf_refcount_block(struct buffer_head *ref_leaf_bh, /* change old and new rl_used accordingly. */ le16_add_cpu(&rl->rl_used, -num_moved); - new_rl->rl_used = cpu_to_le32(num_moved); + new_rl->rl_used = cpu_to_le16(num_moved); sort(&rl->rl_recs, le16_to_cpu(rl->rl_used), sizeof(struct ocfs2_refcount_rec), @@ -1898,7 +1881,8 @@ static int ocfs2_split_refcount_rec(handle_t *handle, recs_need++; /* If the leaf block don't have enough record, expand it. */ - if (le16_to_cpu(rf_list->rl_used) + recs_need > rf_list->rl_count) { + if (le16_to_cpu(rf_list->rl_used) + recs_need > + le16_to_cpu(rf_list->rl_count)) { struct ocfs2_refcount_rec tmp_rec; u64 cpos = le64_to_cpu(orig_rec->r_cpos); len = le32_to_cpu(orig_rec->r_clusters); @@ -1960,7 +1944,7 @@ static int ocfs2_split_refcount_rec(handle_t *handle, memcpy(tail_rec, orig_rec, sizeof(struct ocfs2_refcount_rec)); le64_add_cpu(&tail_rec->r_cpos, le32_to_cpu(tail_rec->r_clusters) - len); - tail_rec->r_clusters = le32_to_cpu(len); + tail_rec->r_clusters = cpu_to_le32(len); } /* @@ -3941,8 +3925,7 @@ static int ocfs2_add_refcounted_extent(struct inode *inode, } ret = ocfs2_insert_extent(handle, et, cpos, - cpu_to_le64(ocfs2_clusters_to_blocks(inode->i_sb, - p_cluster)), + ocfs2_clusters_to_blocks(inode->i_sb, p_cluster), num_clusters, ext_flags, meta_ac); if (ret) { mlog_errno(ret); @@ -4354,8 +4337,8 @@ static int ocfs2_user_path_parent(const char __user *path, * @new_dentry: target dentry * @preserve: if true, preserve all file attributes */ -int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir, - struct dentry *new_dentry, bool preserve) +static int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir, + struct dentry *new_dentry, bool preserve) { struct inode *inode = old_dentry->d_inode; int error; -- cgit v0.10.2 From f6656d26d17b2598f43cd41be088853fa2a03397 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 17 Nov 2009 16:29:19 -0800 Subject: ocfs2/cluster: Make fence method configurable - v2 By default, o2cb fences the box by calling emergency_restart(). While this scheme works well in production, it comes in the way during testing as it does not let the tester take stack/core dumps for analysis. This patch allows user to dynamically change the fence method to panic() by: # echo "panic" > /sys/kernel/config/cluster//fence_method Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c index 7ee6188..c81142e 100644 --- a/fs/ocfs2/cluster/nodemanager.c +++ b/fs/ocfs2/cluster/nodemanager.c @@ -35,6 +35,10 @@ * cluster references throughout where nodes are looked up */ struct o2nm_cluster *o2nm_single_cluster = NULL; +char *o2nm_fence_method_desc[O2NM_FENCE_METHODS] = { + "reset", /* O2NM_FENCE_RESET */ + "panic", /* O2NM_FENCE_PANIC */ +}; struct o2nm_node *o2nm_get_node_by_num(u8 node_num) { @@ -579,6 +583,43 @@ static ssize_t o2nm_cluster_attr_reconnect_delay_ms_write( return o2nm_cluster_attr_write(page, count, &cluster->cl_reconnect_delay_ms); } + +static ssize_t o2nm_cluster_attr_fence_method_read( + struct o2nm_cluster *cluster, char *page) +{ + ssize_t ret = 0; + + if (cluster) + ret = sprintf(page, "%s\n", + o2nm_fence_method_desc[cluster->cl_fence_method]); + return ret; +} + +static ssize_t o2nm_cluster_attr_fence_method_write( + struct o2nm_cluster *cluster, const char *page, size_t count) +{ + unsigned int i; + + if (page[count - 1] != '\n') + goto bail; + + for (i = 0; i < O2NM_FENCE_METHODS; ++i) { + if (count != strlen(o2nm_fence_method_desc[i]) + 1) + continue; + if (strncasecmp(page, o2nm_fence_method_desc[i], count - 1)) + continue; + if (cluster->cl_fence_method != i) { + printk(KERN_INFO "ocfs2: Changing fence method to %s\n", + o2nm_fence_method_desc[i]); + cluster->cl_fence_method = i; + } + return count; + } + +bail: + return -EINVAL; +} + static struct o2nm_cluster_attribute o2nm_cluster_attr_idle_timeout_ms = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "idle_timeout_ms", @@ -603,10 +644,19 @@ static struct o2nm_cluster_attribute o2nm_cluster_attr_reconnect_delay_ms = { .store = o2nm_cluster_attr_reconnect_delay_ms_write, }; +static struct o2nm_cluster_attribute o2nm_cluster_attr_fence_method = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "fence_method", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2nm_cluster_attr_fence_method_read, + .store = o2nm_cluster_attr_fence_method_write, +}; + static struct configfs_attribute *o2nm_cluster_attrs[] = { &o2nm_cluster_attr_idle_timeout_ms.attr, &o2nm_cluster_attr_keepalive_delay_ms.attr, &o2nm_cluster_attr_reconnect_delay_ms.attr, + &o2nm_cluster_attr_fence_method.attr, NULL, }; static ssize_t o2nm_cluster_show(struct config_item *item, @@ -778,6 +828,7 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g cluster->cl_reconnect_delay_ms = O2NET_RECONNECT_DELAY_MS_DEFAULT; cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT; cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT; + cluster->cl_fence_method = O2NM_FENCE_RESET; ret = &cluster->cl_group; o2nm_single_cluster = cluster; diff --git a/fs/ocfs2/cluster/nodemanager.h b/fs/ocfs2/cluster/nodemanager.h index c992ea0..09ea2d3 100644 --- a/fs/ocfs2/cluster/nodemanager.h +++ b/fs/ocfs2/cluster/nodemanager.h @@ -33,6 +33,12 @@ #include #include +enum o2nm_fence_method { + O2NM_FENCE_RESET = 0, + O2NM_FENCE_PANIC, + O2NM_FENCE_METHODS, /* Number of fence methods */ +}; + struct o2nm_node { spinlock_t nd_lock; struct config_item nd_item; @@ -58,6 +64,7 @@ struct o2nm_cluster { unsigned int cl_idle_timeout_ms; unsigned int cl_keepalive_delay_ms; unsigned int cl_reconnect_delay_ms; + enum o2nm_fence_method cl_fence_method; /* this bitmap is part of a hack for disk bitmap.. will go eventually. - zab */ unsigned long cl_nodes_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; diff --git a/fs/ocfs2/cluster/quorum.c b/fs/ocfs2/cluster/quorum.c index bbacf7d..6390240 100644 --- a/fs/ocfs2/cluster/quorum.c +++ b/fs/ocfs2/cluster/quorum.c @@ -74,8 +74,20 @@ static void o2quo_fence_self(void) * threads can still schedule, etc, etc */ o2hb_stop_all_regions(); - printk("ocfs2 is very sorry to be fencing this system by restarting\n"); - emergency_restart(); + switch (o2nm_single_cluster->cl_fence_method) { + case O2NM_FENCE_PANIC: + panic("*** ocfs2 is very sorry to be fencing this system by " + "panicing ***\n"); + break; + default: + WARN_ON(o2nm_single_cluster->cl_fence_method >= + O2NM_FENCE_METHODS); + case O2NM_FENCE_RESET: + printk(KERN_ERR "*** ocfs2 is very sorry to be fencing this " + "system by restarting ***\n"); + emergency_restart(); + break; + }; } /* Indicate that a timeout occured on a hearbeat region write. The -- cgit v0.10.2 From aad1b15310b9bcd59fa81ab8f2b1513b59553ea8 Mon Sep 17 00:00:00 2001 From: Tiger Yang Date: Thu, 19 Nov 2009 10:17:46 +0800 Subject: ocfs2: return -EAGAIN instead of EAGAIN in dlm We used to return positive EAGAIN to indicate a retry action is needed in dlm_begin_reco_handler(). Now we return negative -EAGAIN to erase the confusion caused by this error code. Signed-off-by: Tiger Yang Signed-off-by: Joel Becker diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index d9fa3d2..2f9e4e1 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -2589,6 +2589,14 @@ retry: "begin reco msg (%d)\n", dlm->name, nodenum, ret); ret = 0; } + if (ret == -EAGAIN) { + mlog(0, "%s: trying to start recovery of node " + "%u, but node %u is waiting for last recovery " + "to complete, backoff for a bit\n", dlm->name, + dead_node, nodenum); + msleep(100); + goto retry; + } if (ret < 0) { struct dlm_lock_resource *res; /* this is now a serious problem, possibly ENOMEM @@ -2608,14 +2616,6 @@ retry: * another ENOMEM */ msleep(100); goto retry; - } else if (ret == EAGAIN) { - mlog(0, "%s: trying to start recovery of node " - "%u, but node %u is waiting for last recovery " - "to complete, backoff for a bit\n", dlm->name, - dead_node, nodenum); - /* TODO Look into replacing msleep with cond_resched() */ - msleep(100); - goto retry; } } @@ -2639,7 +2639,7 @@ int dlm_begin_reco_handler(struct o2net_msg *msg, u32 len, void *data, dlm->name, br->node_idx, br->dead_node, dlm->reco.dead_node, dlm->reco.new_master); spin_unlock(&dlm->spinlock); - return EAGAIN; + return -EAGAIN; } spin_unlock(&dlm->spinlock); -- cgit v0.10.2 From a2934c7b363ddcc001964f2444649f909e583bef Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 3 Dec 2009 08:09:41 -0500 Subject: cifs: NULL out tcon, pSesInfo, and srvTcp pointers when chasing DFS referrals The scenario is this: The kernel gets EREMOTE and starts chasing a DFS referral at mount time. The tcon reference is put, which puts the session reference too, but neither pointer is zeroed out. The mount gets retried (goto try_mount_again) with new mount info. Session setup fails fails and rc ends up being non-zero. The code then falls through to the end and tries to put the previously freed tcon pointer again. Oops at: cifs_put_smb_ses+0x14/0xd0 Fix this by moving the initialization of the rc variable and the tcon, pSesInfo and srvTcp pointers below the try_mount_again label. Also, add a FreeXid() before the goto to prevent xid "leaks". Signed-off-by: Jeff Layton Reported-by: Gustavo Carvalho Homem CC: stable Signed-off-by: Steve French diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 63ea83f..3bbcaa7 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2287,12 +2287,12 @@ int cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, char *mount_data_global, const char *devname) { - int rc = 0; + int rc; int xid; struct smb_vol *volume_info; - struct cifsSesInfo *pSesInfo = NULL; - struct cifsTconInfo *tcon = NULL; - struct TCP_Server_Info *srvTcp = NULL; + struct cifsSesInfo *pSesInfo; + struct cifsTconInfo *tcon; + struct TCP_Server_Info *srvTcp; char *full_path; char *mount_data = mount_data_global; #ifdef CONFIG_CIFS_DFS_UPCALL @@ -2301,6 +2301,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, int referral_walks_count = 0; try_mount_again: #endif + rc = 0; + tcon = NULL; + pSesInfo = NULL; + srvTcp = NULL; full_path = NULL; xid = GetXid(); @@ -2597,6 +2601,7 @@ remote_path_check: cleanup_volume_info(&volume_info); referral_walks_count++; + FreeXid(xid); goto try_mount_again; } #else /* No DFS support, return error on mount */ -- cgit v0.10.2 From df0094d7f46d37944aa26b4f6e978b4b2ad252ea Mon Sep 17 00:00:00 2001 From: Simon Guinot Date: Sat, 5 Dec 2009 15:28:00 +0100 Subject: mtd: m25p80: add support for Macronix MX25L4005A Signed-off-by: Simon Guinot Signed-off-by: David Woodhouse diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 8f8c249..ae1bfb2 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -638,6 +638,7 @@ static const struct spi_device_id m25p_ids[] = { { "at26df321", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) }, /* Macronix */ + { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) }, { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) }, { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, -- cgit v0.10.2 From a994b8fa669f16c50728328c3735722a3f20652e Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 7 Dec 2009 05:44:46 +0000 Subject: [CIFS] Enable mmap on forcedirectio mounts openoffice and gedit failed with 'direct' options Signed-off-by: Pavel Shilovsky Signed-off-by: Steve French diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 094ea65..7b2600b 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -5,7 +5,9 @@ have duplicated data). Fix oops in cifs_lookup. Workaround problem mounting to OS/400 Netserve. Fix oops in cifs_get_tcp_session. Disable use of server inode numbers when server only partially supports them (e.g. for one server querying inode numbers on -FindFirst fails but QPathInfo queries works). +FindFirst fails but QPathInfo queries works). Fix oops with dfs in +cifs_put_smb_ses. Fix mmap to work on directio mounts (needed +for OpenOffice when on forcedirectio mount e.g.) Version 1.60 ------------- diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 29f1da7..8c6a036 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -758,7 +758,7 @@ const struct file_operations cifs_file_ops = { }; const struct file_operations cifs_file_direct_ops = { - /* no mmap, no aio, no readv - + /* no aio, no readv - BB reevaluate whether they can be done with directio, no cache */ .read = cifs_user_read, .write = cifs_user_write, @@ -767,6 +767,7 @@ const struct file_operations cifs_file_direct_ops = { .lock = cifs_lock, .fsync = cifs_fsync, .flush = cifs_flush, + .mmap = cifs_file_mmap, .splice_read = generic_file_splice_read, #ifdef CONFIG_CIFS_POSIX .unlocked_ioctl = cifs_ioctl, -- cgit v0.10.2 From 51eeb878155cdea73e7a1f0372b266018bd7a424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 7 Dec 2009 09:44:05 +0000 Subject: Revert "mtd: move mxcnd_remove to .exit.text" This reverts commit 82613b0da622efbd24cb7b23eb349966802310f1, because commit daa0f15 (mtd: don't use __exit_p to wrap mxcnd_remove) is a better solution. Not having a remove callback breaks rebinding because resources are not freed on remove. Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index f7366e9..45dec57 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -861,7 +861,7 @@ eclk: return err; } -static int __exit mxcnd_remove(struct platform_device *pdev) +static int __devexit mxcnd_remove(struct platform_device *pdev) { struct mxc_nand_host *host = platform_get_drvdata(pdev); -- cgit v0.10.2 From f0e5d2c959d5f14dd3bc879c8f9390aa2c049423 Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Sun, 6 Dec 2009 18:06:43 +0200 Subject: ARM: dove: fix the mm mmu flags of the pj4 procinfo ... to be the same as proc-v6 Signed-off-by: Saeed Bishara Signed-off-by: Nicolas Pitre diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 5485c82..395cc90 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -254,10 +254,9 @@ __pj4_v6_proc_info: .long 0x560f5810 .long 0xff0ffff0 .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ + PMD_SECT_AP_READ | \ + PMD_FLAGS .long PMD_TYPE_SECT | \ PMD_SECT_XN | \ PMD_SECT_AP_WRITE | \ -- cgit v0.10.2 From 2c99220810c1c79322034628b993573b088ff2da Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Wed, 2 Dec 2009 09:17:13 +0000 Subject: intel-iommu: Detect DMAR in hyperspace at probe time. Many BIOSes will lie to us about the existence of an IOMMU, and claim that there is one at an address which actually returns all 0xFF. We need to detect this early, so that we know we don't have a viable IOMMU and can set up swiotlb before it's too late. Cc: stable@kernel.org Signed-off-by: Chris Wright Signed-off-by: David Woodhouse diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 525a324..56883fc 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -632,6 +632,9 @@ int __init check_zero_address(void) } if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) { + void __iomem *addr; + u64 cap, ecap; + drhd = (void *)entry_header; if (!drhd->address) { /* Promote an attitude of violence to a BIOS engineer today */ @@ -640,17 +643,38 @@ int __init check_zero_address(void) dmi_get_system_info(DMI_BIOS_VENDOR), dmi_get_system_info(DMI_BIOS_VERSION), dmi_get_system_info(DMI_PRODUCT_VERSION)); -#ifdef CONFIG_DMAR - dmar_disabled = 1; -#endif - return 0; + goto failed; + } + + addr = early_ioremap(drhd->address, VTD_PAGE_SIZE); + if (!addr ) { + printk("IOMMU: can't validate: %llx\n", drhd->address); + goto failed; + } + cap = dmar_readq(addr + DMAR_CAP_REG); + ecap = dmar_readq(addr + DMAR_ECAP_REG); + early_iounmap(addr, VTD_PAGE_SIZE); + if (cap == (uint64_t)-1 && ecap == (uint64_t)-1) { + /* Promote an attitude of violence to a BIOS engineer today */ + WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + drhd->address, + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); + goto failed; } - break; } entry_header = ((void *)entry_header + entry_header->length); } return 1; + +failed: +#ifdef CONFIG_DMAR + dmar_disabled = 1; +#endif + return 0; } void __init detect_intel_iommu(void) -- cgit v0.10.2 From 6ecbf01c7ce4c0f4c3bdfa0e64ac6258328fda6c Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 2 Dec 2009 09:20:27 +0000 Subject: intel-iommu: Apply BIOS sanity checks for interrupt remapping too. The BIOS errors where an IOMMU is reported either at zero or a bogus address are causing problems even when the IOMMU is disabled -- because interrupt remapping uses the same hardware. Ensure that the checks get applied for the interrupt remapping initialisation too. Cc: stable@kernel.org Signed-off-by: David Woodhouse diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 56883fc..beeaef8 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -613,6 +613,8 @@ int __init dmar_table_init(void) return 0; } +static int bios_warned; + int __init check_zero_address(void) { struct acpi_table_dmar *dmar; @@ -643,6 +645,7 @@ int __init check_zero_address(void) dmi_get_system_info(DMI_BIOS_VENDOR), dmi_get_system_info(DMI_BIOS_VERSION), dmi_get_system_info(DMI_PRODUCT_VERSION)); + bios_warned = 1; goto failed; } @@ -662,6 +665,7 @@ int __init check_zero_address(void) dmi_get_system_info(DMI_BIOS_VENDOR), dmi_get_system_info(DMI_BIOS_VERSION), dmi_get_system_info(DMI_PRODUCT_VERSION)); + bios_warned = 1; goto failed; } } @@ -722,6 +726,18 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) int agaw = 0; int msagaw = 0; + if (!drhd->reg_base_addr) { + if (!bios_warned) { + WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); + bios_warned = 1; + } + return -EINVAL; + } + iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); if (!iommu) return -ENOMEM; @@ -738,13 +754,16 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) { - /* Promote an attitude of violence to a BIOS engineer today */ - WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n" - "BIOS vendor: %s; Ver: %s; Product Version: %s\n", - drhd->reg_base_addr, - dmi_get_system_info(DMI_BIOS_VENDOR), - dmi_get_system_info(DMI_BIOS_VERSION), - dmi_get_system_info(DMI_PRODUCT_VERSION)); + if (!bios_warned) { + /* Promote an attitude of violence to a BIOS engineer today */ + WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + drhd->reg_base_addr, + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); + bios_warned = 1; + } goto err_unmap; } -- cgit v0.10.2 From 5595b528b49a702c0428c0762bab60999648254c Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 2 Dec 2009 09:21:55 +0000 Subject: intel-iommu: Check for an RMRR which ends before it starts. Some HP BIOSes report an RMRR region (a region which needs a 1:1 mapping in the IOMMU for a given device) which has an end address lower than its start address. Detect that and warn, rather than triggering the BUG() in dma_pte_clear_range(). Cc: stable@kernel.org Signed-off-by: David Woodhouse diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index cb5cae3..83cabdc 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -2000,6 +2000,16 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev, "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n", pci_name(pdev), start, end); + if (end < start) { + WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); + ret = -EIO; + goto error; + } + if (end >> agaw_to_width(domain->agaw)) { WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n" "BIOS vendor: %s; Ver: %s; Product Version: %s\n", -- cgit v0.10.2 From 44cd613c0e4cd93079ea2a93aa06649d8ca0830a Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 2 Dec 2009 10:18:30 +0000 Subject: intel-iommu: Fix oops with intel_iommu=igfx_off The hotplug notifier will call find_domain() to see if the device in question has been assigned an IOMMU domain. However, this should never be called for devices with a "dummy" domain, such as graphics devices when intel_iommu=igfx_off is set and the corresponding IOMMU isn't even initialised. If you do that, it'll oops as it dereferences the (-1) pointer. The notifier function should check iommu_no_mapping() for the device before doing anything else. Cc: stable@kernel.org Signed-off-by: David Woodhouse diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 83cabdc..e3e84ca 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -3247,6 +3247,9 @@ static int device_notifier(struct notifier_block *nb, struct pci_dev *pdev = to_pci_dev(dev); struct dmar_domain *domain; + if (iommu_no_mapping(dev)) + return 0; + domain = find_domain(pdev); if (!domain) return 0; -- cgit v0.10.2 From 1672af1164d3d50ba8908014fd34cc0b58afdc1e Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Wed, 2 Dec 2009 12:06:34 -0800 Subject: intel-iommu: ignore page table validation in pass through mode We are seeing a bug when booting w/ iommu=pt with current upstream (bisect blames 19943b0e30b05d42e494ae6fef78156ebc8c637e "intel-iommu: Unify hardware and software passthrough support). The issue is specific to this loop during identity map initialization of each device: domain_context_mapping_one(si_domain, ..., CONTEXT_TT_PASS_THROUGH) ... /* Skip top levels of page tables for * iommu which has less agaw than default. */ for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) { pgd = phys_to_virt(dma_pte_addr(pgd)); if (!dma_pte_present(pgd)) { <------ failing here spin_unlock_irqrestore(&iommu->lock, flags); return -ENOMEM; } This box has 2 iommu's in it. The catchall iommu has MGAW == 48, and SAGAW == 4. The other iommu has MGAW == 39, SAGAW == 2. The device that's failing the above pgd test is the only device connected to the non-catchall iommu, which has a smaller address width than the domain default. This test is not necessary since the context is in PT mode and the ASR is ignored. Thanks to Don Dutile for discovering and debugging this one. Cc: stable@kernel.org Signed-off-by: Chris Wright Signed-off-by: David Woodhouse diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index e3e84ca..4660795 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -1530,12 +1530,15 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment, /* Skip top levels of page tables for * iommu which has less agaw than default. + * Unnecessary for PT mode. */ - for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) { - pgd = phys_to_virt(dma_pte_addr(pgd)); - if (!dma_pte_present(pgd)) { - spin_unlock_irqrestore(&iommu->lock, flags); - return -ENOMEM; + if (translation != CONTEXT_TT_PASS_THROUGH) { + for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) { + pgd = phys_to_virt(dma_pte_addr(pgd)); + if (!dma_pte_present(pgd)) { + spin_unlock_irqrestore(&iommu->lock, flags); + return -ENOMEM; + } } } } -- cgit v0.10.2 From 354bb65e6e0df0aaae0e5b1ea33948d8e0b61418 Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 17 Nov 2009 16:21:09 +0900 Subject: Revert "Intel IOMMU: Avoid memory allocation failures in dma map api calls" commit eb3fa7cb51 said Intel IOMMU Intel IOMMU driver needs memory during DMA map calls to setup its internal page tables and for other data structures. As we all know that these DMA map calls are mostly called in the interrupt context or with the spinlock held by the upper level drivers(network/storage drivers), so in order to avoid any memory allocation failure due to low memory issues, this patch makes memory allocation by temporarily setting PF_MEMALLOC flags for the current task before making memory allocation calls. We evaluated mempools as a backup when kmem_cache_alloc() fails and found that mempools are really not useful here because 1) We don't know for sure how much to reserve in advance 2) And mempools are not useful for GFP_ATOMIC case (as we call memory alloc functions with GFP_ATOMIC) (akpm: point 2 is wrong...) The above description doesn't justify to waste system emergency memory at all. Non MM subsystem must not use PF_MEMALLOC. Memory reclaim need few memory, anyone must not prevent it. Otherwise the system cause mysterious hang-up and/or OOM Killer invokation. Plus, akpm already pointed out what we should do. Then, this patch revert it. Cc: Keshavamurthy Anil S Signed-off-by: KOSAKI Motohiro Signed-off-by: David Woodhouse diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 4660795..4e1dd40 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -387,33 +387,14 @@ static struct kmem_cache *iommu_domain_cache; static struct kmem_cache *iommu_devinfo_cache; static struct kmem_cache *iommu_iova_cache; -static inline void *iommu_kmem_cache_alloc(struct kmem_cache *cachep) -{ - unsigned int flags; - void *vaddr; - - /* trying to avoid low memory issues */ - flags = current->flags & PF_MEMALLOC; - current->flags |= PF_MEMALLOC; - vaddr = kmem_cache_alloc(cachep, GFP_ATOMIC); - current->flags &= (~PF_MEMALLOC | flags); - return vaddr; -} - - static inline void *alloc_pgtable_page(int node) { - unsigned int flags; struct page *page; void *vaddr = NULL; - /* trying to avoid low memory issues */ - flags = current->flags & PF_MEMALLOC; - current->flags |= PF_MEMALLOC; page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0); if (page) vaddr = page_address(page); - current->flags &= (~PF_MEMALLOC | flags); return vaddr; } @@ -424,7 +405,7 @@ static inline void free_pgtable_page(void *vaddr) static inline void *alloc_domain_mem(void) { - return iommu_kmem_cache_alloc(iommu_domain_cache); + return kmem_cache_alloc(iommu_domain_cache, GFP_ATOMIC); } static void free_domain_mem(void *vaddr) @@ -434,7 +415,7 @@ static void free_domain_mem(void *vaddr) static inline void * alloc_devinfo_mem(void) { - return iommu_kmem_cache_alloc(iommu_devinfo_cache); + return kmem_cache_alloc(iommu_devinfo_cache, GFP_ATOMIC); } static inline void free_devinfo_mem(void *vaddr) @@ -444,7 +425,7 @@ static inline void free_devinfo_mem(void *vaddr) struct iova *alloc_iova_mem(void) { - return iommu_kmem_cache_alloc(iommu_iova_cache); + return kmem_cache_alloc(iommu_iova_cache, GFP_ATOMIC); } void free_iova_mem(struct iova *iova) -- cgit v0.10.2 From e717cc6c07f006be36e35189aacb28be4e30ad14 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Tue, 8 Dec 2009 14:23:11 +0000 Subject: sh: Can't compare physical and virtual addresses for aliases It does not make sense to compare virtual and physical addresses for aliasing, only virtual addresses can be compared for aliases. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index f36a08b..560ddb6 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -256,8 +256,7 @@ static void sh4_flush_cache_page(void *args) address = (unsigned long)vaddr; } - if (pages_do_alias(address, phys)) - flush_cache_one(CACHE_OC_ADDRESS_ARRAY | + flush_cache_one(CACHE_OC_ADDRESS_ARRAY | (address & shm_align_mask), phys); if (vma->vm_flags & VM_EXEC) -- cgit v0.10.2 From 87a705dde49d0c482fa818f0923af59ed0954d5d Mon Sep 17 00:00:00 2001 From: Francesco VIRLINZI Date: Fri, 4 Dec 2009 08:57:58 +0000 Subject: sh: intc: Fixed resume from hibernation This patch fixes the resume from hibernation in the intc sysdev device when it manages 'redirect' irq Signed-off-by: Francesco Virlinzi Signed-off-by: Paul Mundt diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c index a7e5c2e..88f5aaf 100644 --- a/drivers/sh/intc.c +++ b/drivers/sh/intc.c @@ -806,6 +806,8 @@ static int intc_suspend(struct sys_device *dev, pm_message_t state) if (d->state.event != PM_EVENT_FREEZE) break; for_each_irq_desc(irq, desc) { + if (desc->handle_irq == intc_redirect_irq) + continue if (desc->chip != &d->chip) continue; if (desc->status & IRQ_DISABLED) -- cgit v0.10.2 From f701b3999890b867f87733c146d4cdf9319ead05 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Mon, 7 Dec 2009 10:38:55 +0100 Subject: sh: Replace an explicit computation by the use of the container_of macro The macro container_of from kernel.h performs the same pointer arithmetic operation. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ type T; expression mptr; expression member; @@ - (void *)((char *)mptr - offsetof(T, member)) + container_of(mptr, T, member) // Signed-off-by: Nicolas Palix Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index c1508a9..9282d96 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c @@ -17,16 +17,17 @@ * for more details. */ #include +#include +#include #include +#include #include -#include -#include #include static inline struct ipr_desc *get_ipr_desc(unsigned int irq) { struct irq_chip *chip = get_irq_chip(irq); - return (void *)((char *)chip - offsetof(struct ipr_desc, chip)); + return container_of(chip, struct ipr_desc, chip); } static void disable_ipr_irq(unsigned int irq) -- cgit v0.10.2 From f3a4c00ad35a9f21db82516fdc600cb1be301c23 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 7 Dec 2009 14:11:59 +0000 Subject: sh: fix size calculation for NUMA node 0 Fix the NUMA size calculation for node 0. Do the same as the UMA version of setup_memory() and use address instead of pfn when calculating the size. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c index 6c52444..b44e835 100644 --- a/arch/sh/mm/numa.c +++ b/arch/sh/mm/numa.c @@ -28,7 +28,7 @@ void __init setup_memory(void) { unsigned long free_pfn = PFN_UP(__pa(_end)); u64 base = min_low_pfn << PAGE_SHIFT; - u64 size = (max_low_pfn << PAGE_SHIFT) - min_low_pfn; + u64 size = (max_low_pfn << PAGE_SHIFT) - base; lmb_add(base, size); -- cgit v0.10.2 From b25b9758466bb8bc837f1863389015820f7cb11d Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 7 Dec 2009 14:16:07 +0000 Subject: sh: NUMA lmb fixes This patch updates the NUMA version of setup_memory() with UMA code changes and also modifies the last argument to lmb_alloc_base() to use an address instead of pfn. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c index b44e835..422e927 100644 --- a/arch/sh/mm/numa.c +++ b/arch/sh/mm/numa.c @@ -38,6 +38,15 @@ void __init setup_memory(void) (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET)); /* + * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET. + */ + if (CONFIG_ZERO_PAGE_OFFSET != 0) + lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET); + + lmb_analyze(); + lmb_dump_all(); + + /* * Node 0 sets up its pgdat at the first available pfn, * and bumps it up before setting up the bootmem allocator. */ @@ -71,7 +80,7 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) /* Node-local pgdat */ NODE_DATA(nid) = __va(lmb_alloc_base(sizeof(struct pglist_data), - SMP_CACHE_BYTES, end_pfn)); + SMP_CACHE_BYTES, end)); memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); NODE_DATA(nid)->bdata = &bootmem_node_data[nid]; @@ -81,7 +90,7 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) /* Node-local bootmap */ bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); bootmem_paddr = lmb_alloc_base(bootmap_pages << PAGE_SHIFT, - PAGE_SIZE, end_pfn); + PAGE_SIZE, end); init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT, start_pfn, end_pfn); -- cgit v0.10.2 From ef61aae4ddf1dbd0e9b6ad21e2e57632a8fe76f6 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 7 Dec 2009 14:20:06 +0000 Subject: sh: add a start_transfer() callback to the LCDC driver This patch adds a ->start_transfer() callback to the driver sh_mobile_lcdcfb.c. The callback is used to program the LCDC panel in the case of one-shot mode. Needed by the LCD controller used on the KFR2R09 board. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index b4b5de9..d346bba 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -281,6 +281,7 @@ static void sh_mobile_lcdc_deferred_io(struct fb_info *info, struct list_head *pagelist) { struct sh_mobile_lcdc_chan *ch = info->par; + struct sh_mobile_lcdc_board_cfg *bcfg = &ch->cfg.board_cfg; /* enable clocks before accessing hardware */ sh_mobile_lcdc_clk_on(ch->lcdc); @@ -305,10 +306,17 @@ static void sh_mobile_lcdc_deferred_io(struct fb_info *info, /* trigger panel update */ dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); + if (bcfg->start_transfer) + bcfg->start_transfer(bcfg->board_data, ch, + &sh_mobile_lcdc_sys_bus_ops); lcdc_write_chan(ch, LDSM2R, 1); dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); - } else + } else { + if (bcfg->start_transfer) + bcfg->start_transfer(bcfg->board_data, ch, + &sh_mobile_lcdc_sys_bus_ops); lcdc_write_chan(ch, LDSM2R, 1); + } } static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info) diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h index 25144ab..2882054 100644 --- a/include/video/sh_mobile_lcdc.h +++ b/include/video/sh_mobile_lcdc.h @@ -50,6 +50,8 @@ struct sh_mobile_lcdc_board_cfg { void *board_data; int (*setup_sys)(void *board_data, void *sys_ops_handle, struct sh_mobile_lcdc_sys_bus_ops *sys_ops); + void (*start_transfer)(void *board_data, void *sys_ops_handle, + struct sh_mobile_lcdc_sys_bus_ops *sys_ops); void (*display_on)(void *board_data); void (*display_off)(void *board_data); }; -- cgit v0.10.2 From 657bf0bd068b2dc5244d553be66daac0a9e745d1 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 7 Dec 2009 14:26:05 +0000 Subject: sh: LCDC start_transfer() for the KFR2R09 board This patch adds a ->start_transfer() callback to the KFR2R09 lcd handling code. The callback is used to notify the lcd controller that a new frame of data is about to be transferred. The callback is only used in combination with deferred io, but the code has been tested both with and without deferred io enabled. Without this patch the display data on the KFR2R09 lcd panel becomes corrupted over time. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c index 8ccb1cc..e9b97084 100644 --- a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c +++ b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c @@ -273,6 +273,12 @@ int kfr2r09_lcd_setup(void *board_data, void *sohandle, return 0; } +void kfr2r09_lcd_start(void *board_data, void *sohandle, + struct sh_mobile_lcdc_sys_bus_ops *so) +{ + write_memory_start(sohandle, so); +} + #define CTRL_CKSW 0x10 #define CTRL_C10 0x20 #define CTRL_CPSW 0x80 diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index 87438d6..5cf7a6e 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -149,6 +149,7 @@ static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = { }, .board_cfg = { .setup_sys = kfr2r09_lcd_setup, + .start_transfer = kfr2r09_lcd_start, .display_on = kfr2r09_lcd_on, .display_off = kfr2r09_lcd_off, }, diff --git a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h index 174374e..484ef42 100644 --- a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h +++ b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h @@ -8,6 +8,8 @@ void kfr2r09_lcd_on(void *board_data); void kfr2r09_lcd_off(void *board_data); int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle, struct sh_mobile_lcdc_sys_bus_ops *sys_ops); +void kfr2r09_lcd_start(void *board_data, void *sys_ops_handle, + struct sh_mobile_lcdc_sys_bus_ops *sys_ops); #else static inline void kfr2r09_lcd_on(void *board_data) {} static inline void kfr2r09_lcd_off(void *board_data) {} @@ -16,6 +18,10 @@ static inline int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle, { return -ENODEV; } +static inline void kfr2r09_lcd_start(void *board_data, void *sys_ops_handle, + struct sh_mobile_lcdc_sys_bus_ops *sys_ops) +{ +} #endif #endif /* __ASM_SH_KFR2R09_H */ -- cgit v0.10.2 From fb2e9daffe32ba1bf8e777a841f7206acf567aac Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 8 Dec 2009 00:18:20 +0000 Subject: sh: mach-ap325rxa: Add SOCAM_DATA_ACTIVE_HIGH flags for soc-camera Current soc-camera needs SOCAM_DATA_ACTIVE_xxx flags for use. We can not open old ncm03j camera device without this patch. Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index cf9dc12..4b4320b 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c @@ -322,7 +322,8 @@ static struct soc_camera_platform_info camera_info = { .height = 480, }, .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | - SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8, + SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8 | + SOCAM_DATA_ACTIVE_HIGH, .set_capture = camera_set_capture, .link = { .bus_id = 0, -- cgit v0.10.2 From 0a753d58f901913e3e6416baeac437ee83eda90d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 9 Dec 2009 14:36:16 +0900 Subject: sh: intc: Fixup compile breakage. The resume from hibernation patch introduced build failure, fix it up.. Signed-off-by: Paul Mundt diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c index 88f5aaf..d5d7f23 100644 --- a/drivers/sh/intc.c +++ b/drivers/sh/intc.c @@ -807,7 +807,7 @@ static int intc_suspend(struct sys_device *dev, pm_message_t state) break; for_each_irq_desc(irq, desc) { if (desc->handle_irq == intc_redirect_irq) - continue + continue; if (desc->chip != &d->chip) continue; if (desc->status & IRQ_DISABLED) -- cgit v0.10.2 From d2d69a3ab2e62bcf8e5f5303bde024033face902 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 9 Dec 2009 05:21:42 +0000 Subject: sh: mach-ecovec24: MEMORY_SIZE fixup Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt diff --git a/arch/sh/configs/ecovec24-romimage_defconfig b/arch/sh/configs/ecovec24-romimage_defconfig index 0774924..4687470 100644 --- a/arch/sh/configs/ecovec24-romimage_defconfig +++ b/arch/sh/configs/ecovec24-romimage_defconfig @@ -203,7 +203,7 @@ CONFIG_MMU=y CONFIG_PAGE_OFFSET=0x80000000 CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 -CONFIG_MEMORY_SIZE=0x08000000 +CONFIG_MEMORY_SIZE=0x10000000 CONFIG_29BIT=y # CONFIG_X2TLB is not set CONFIG_VSYSCALL=y diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig index ac64697..cad9184 100644 --- a/arch/sh/configs/ecovec24_defconfig +++ b/arch/sh/configs/ecovec24_defconfig @@ -204,7 +204,7 @@ CONFIG_MMU=y CONFIG_PAGE_OFFSET=0x80000000 CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x08000000 -CONFIG_MEMORY_SIZE=0x08000000 +CONFIG_MEMORY_SIZE=0x10000000 CONFIG_29BIT=y # CONFIG_X2TLB is not set CONFIG_VSYSCALL=y -- cgit v0.10.2 From ca6f2d7fafd2d48b2f6943f5c6787beaec2014d0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 9 Dec 2009 15:51:27 +0900 Subject: sh: pfc: Fixup type mismatch in debug printks. !!value works out to an int while we were still using %ld, so fix this up and shut gcc up. Signed-off-by: Paul Mundt diff --git a/drivers/sh/pfc.c b/drivers/sh/pfc.c index 841ed50..082604e 100644 --- a/drivers/sh/pfc.c +++ b/drivers/sh/pfc.c @@ -71,7 +71,7 @@ static void gpio_write_bit(struct pinmux_data_reg *dr, pos = dr->reg_width - (in_pos + 1); - pr_debug("write_bit addr = %lx, value = %ld, pos = %ld, " + pr_debug("write_bit addr = %lx, value = %d, pos = %ld, " "r_width = %ld\n", dr->reg, !!value, pos, dr->reg_width); -- cgit v0.10.2 From 4230fa3b89ea1c413766bd411a8315a3d05aa6c7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 9 Dec 2009 01:39:09 -0800 Subject: sparc64: Fix overly strict range type matching for PCI devices. When we are trying to see if a range property entry applies to a given address, we are overly strict about the type. We should only allow I/O ranges for I/O addresses, and only allow CONFIG space ranges for CONFIG space address. However for MEM ranges, they come in 32-bit and 64-bit flavors. And a lack of an exact match is OK if the range is 32-bit and the address is 64-bit. We can assign a 64-bit address properly into a 32-bit parent range just fine. So allow it. Reported-by: Patrick Finnegan Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index 881947e..0a6f2d1 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -104,9 +104,19 @@ static int of_bus_pci_map(u32 *addr, const u32 *range, int i; /* Check address type match */ - if ((addr[0] ^ range[0]) & 0x03000000) - return -EINVAL; + if (!((addr[0] ^ range[0]) & 0x03000000)) + goto type_match; + + /* Special exception, we can map a 64-bit address into + * a 32-bit range. + */ + if ((addr[0] & 0x03000000) == 0x03000000 && + (range[0] & 0x03000000) == 0x02000000) + goto type_match; + + return -EINVAL; +type_match: if (of_out_of_range(addr + 1, range + 1, range + na + pna, na - 1, ns)) return -EINVAL; -- cgit v0.10.2 From 166e553a575f09485f6d0df8a1ef3c5991f7d953 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 9 Dec 2009 01:43:45 -0800 Subject: sparc64: Fix stack debugging IRQ stack regression. Commit 4f70f7a91bffdcc39f088748dc678953eb9a3fbd (sparc64: Implement IRQ stacks.) has two bugs. First, the softirq range check forgets to subtract STACK_BIAS before comparing with %sp. Next, on failure the wrong label is jumped to, resulting in a bogus stack being loaded. Reported-by: Igor Kovalenko Signed-off-by: David S. Miller diff --git a/arch/sparc/lib/mcount.S b/arch/sparc/lib/mcount.S index 7ce9c65..24b8b12 100644 --- a/arch/sparc/lib/mcount.S +++ b/arch/sparc/lib/mcount.S @@ -64,8 +64,9 @@ mcount: 2: sethi %hi(softirq_stack), %g3 or %g3, %lo(softirq_stack), %g3 ldx [%g3 + %g1], %g7 + sub %g7, STACK_BIAS, %g7 cmp %sp, %g7 - bleu,pt %xcc, 2f + bleu,pt %xcc, 3f sethi %hi(THREAD_SIZE), %g3 add %g7, %g3, %g7 cmp %sp, %g7 @@ -75,7 +76,7 @@ mcount: * again, we are already trying to output the stack overflow * message. */ - sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough +3: sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough or %g7, %lo(ovstack), %g7 add %g7, OVSTACKSIZE, %g3 sub %g3, STACK_BIAS + 192, %g3 -- cgit v0.10.2 From 573412b29586e58477adb70e022193a337763319 Mon Sep 17 00:00:00 2001 From: Corrado Zoccolo Date: Sun, 6 Dec 2009 11:48:52 +0100 Subject: cfq-iosched: reduce write depth only if sync was delayed The introduction of ramp-up formula for async queue depths has slowed down dirty page reclaim, by reducing async write performance. This patch makes sure the formula kicks in only when sync request was recently delayed. Signed-off-by: Corrado Zoccolo Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index cfb0b2f..5009af4 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -283,7 +283,7 @@ struct cfq_data { */ struct cfq_queue oom_cfqq; - unsigned long last_end_sync_rq; + unsigned long last_delayed_sync; /* List of cfq groups being managed on this device*/ struct hlist_head cfqg_list; @@ -2264,7 +2264,7 @@ static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq) * based on the last sync IO we serviced */ if (!cfq_cfqq_sync(cfqq) && cfqd->cfq_latency) { - unsigned long last_sync = jiffies - cfqd->last_end_sync_rq; + unsigned long last_sync = jiffies - cfqd->last_delayed_sync; unsigned int depth; depth = last_sync / cfqd->cfq_slice[1]; @@ -3273,7 +3273,8 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) if (sync) { RQ_CIC(rq)->last_end_request = now; - cfqd->last_end_sync_rq = now; + if (!time_after(rq->start_time + cfqd->cfq_fifo_expire[1], now)) + cfqd->last_delayed_sync = now; } /* @@ -3711,7 +3712,7 @@ static void *cfq_init_queue(struct request_queue *q) cfqd->cfq_latency = 1; cfqd->cfq_group_isolation = 0; cfqd->hw_tag = -1; - cfqd->last_end_sync_rq = jiffies; + cfqd->last_delayed_sync = jiffies - HZ; INIT_RCU_HEAD(&cfqd->rcu); return cfqd; } -- cgit v0.10.2 From 8b43aebdaa4fa3348dafd6f2f5f526bd3e8b84ac Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Sun, 6 Dec 2009 23:50:24 +0100 Subject: drbd: Following the hmac change to SHASH (see linux commit 8bd1209cfff) Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 436a090..4e0726a 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -1271,8 +1271,7 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, goto fail; } - if (crypto_tfm_alg_type(crypto_hash_tfm(tfm)) - != CRYPTO_ALG_TYPE_HASH) { + if (crypto_tfm_alg_type(crypto_hash_tfm(tfm)) != CRYPTO_ALG_TYPE_SHASH) { retcode = ERR_AUTH_ALG_ND; goto fail; } -- cgit v0.10.2 From a3b8d92d25212c5b6534ae9b347ed2858de78336 Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Mon, 7 Dec 2009 22:10:46 +0100 Subject: block,xd: Delay allocation of DMA buffers until device is known Loading the XD module triggers a warning like WARNING: at mm/page_alloc.c:1805 __alloc_pages_nodemask+0x127/0x48f() Hardware name: System Product Name Modules linked in: Pid: 1, comm: swapper Not tainted 2.6.32-rc8-git5 #1 Call Trace: [] warn_slowpath_common+0x65/0x95 [] warn_slowpath_null+0x12/0x15 [] __alloc_pages_nodemask+0x127/0x48f [] ? get_slab+0x8/0x50 [] alloc_page_interleave+0x2e/0x6e [] alloc_pages_current+0x57/0x99 [] ? xd_init+0x0/0x482 [] __get_free_pages+0xd/0x1e [] xd_init+0x4a/0x482 [] ? loop_init+0x104/0x16a [] ? loop_probe+0x0/0xaf [] ? xd_init+0x0/0x482 [] do_one_initcall+0x51/0x13f [] kernel_init+0x10b/0x15f [] ? kernel_init+0x0/0x15f [] kernel_thread_helper+0x7/0x10 ---[ end trace 686db6333ade6e7a ]--- xd: Out of memory. The warning is because the alloc_pages is called with an order >= MAX_ORDER. The simplistic reason is that get_order(0) returns garbage values when given 0 as a size. The more complex reason is that the XD driver initialisation is broken. It's not clear why this ever worked. XD allocates a buffer for DMA based on the value of xd_maxsectors. This value is determined by the exact type of controller in use but the value is determined *after* an attempt has been made to allocate the buffer. i.e. the requested size of the DMA buffer will always be 0. This patch alters how XD is initialised slightly by allocating the buffer when and if a device has actually been detected. The error paths are updated to suit the new logic. Signed-off-by: Mel Gorman Signed-off-by: Jens Axboe diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 0877d36..d1fd032 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -169,13 +169,6 @@ static int __init xd_init(void) init_timer (&xd_watchdog_int); xd_watchdog_int.function = xd_watchdog; - if (!xd_dma_buffer) - xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200); - if (!xd_dma_buffer) { - printk(KERN_ERR "xd: Out of memory.\n"); - return -ENOMEM; - } - err = -EBUSY; if (register_blkdev(XT_DISK_MAJOR, "xd")) goto out1; @@ -202,6 +195,19 @@ static int __init xd_init(void) xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma); } + /* + * With the drive detected, xd_maxsectors should now be known. + * If xd_maxsectors is 0, nothing was detected and we fall through + * to return -ENODEV + */ + if (!xd_dma_buffer && xd_maxsectors) { + xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200); + if (!xd_dma_buffer) { + printk(KERN_ERR "xd: Out of memory.\n"); + goto out3; + } + } + err = -ENODEV; if (!xd_drives) goto out3; @@ -249,15 +255,17 @@ out4: for (i = 0; i < xd_drives; i++) put_disk(xd_gendisk[i]); out3: - release_region(xd_iobase,4); + if (xd_maxsectors) + release_region(xd_iobase,4); + + if (xd_dma_buffer) + xd_dma_mem_free((unsigned long)xd_dma_buffer, + xd_maxsectors * 0x200); out2: blk_cleanup_queue(xd_queue); out1a: unregister_blkdev(XT_DISK_MAJOR, "xd"); out1: - if (xd_dma_buffer) - xd_dma_mem_free((unsigned long)xd_dma_buffer, - xd_maxsectors * 0x200); return err; Enomem: err = -ENOMEM; -- cgit v0.10.2 From b9d8f4c73b1af4cfd53f819bf84c2bce31232275 Mon Sep 17 00:00:00 2001 From: Gui Jianfeng Date: Tue, 8 Dec 2009 08:54:17 +0100 Subject: cfq: Optimization for close cooperating queue searching It doesn't make any sense to try to find out a close cooperating queue if current cfqq is the only one in the group. Signed-off-by: Gui Jianfeng Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 5009af4..b19cd68 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -1750,6 +1750,12 @@ static struct cfq_queue *cfq_close_cooperator(struct cfq_data *cfqd, return NULL; /* + * Don't search priority tree if it's the only queue in the group. + */ + if (cur_cfqq->cfqg->nr_cfqq == 1) + return NULL; + + /* * We should notice if some of the queues are cooperating, eg * working closely on the same area of the disk. In that case, * we can group them together and don't waste time idling. -- cgit v0.10.2 From c244bb50a9baa2ec47a458bbafb36b5e559ed5fa Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Tue, 8 Dec 2009 17:52:57 -0500 Subject: cfq-iosched: Get rid of cfqq wait_busy_done flag o Get rid of wait_busy_done flag. This flag only tells we were doing wait busy on a queue and that queue got request so expire it. That information can easily be obtained by (cfq_cfqq_wait_busy() && queue_is_not_empty). So remove this flag and keep code simple. Signed-off-by: Vivek Goyal Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index b19cd68..f41fdb5 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -319,7 +319,6 @@ enum cfqq_state_flags { CFQ_CFQQ_FLAG_coop, /* cfqq is shared */ CFQ_CFQQ_FLAG_deep, /* sync cfqq experienced large depth */ CFQ_CFQQ_FLAG_wait_busy, /* Waiting for next request */ - CFQ_CFQQ_FLAG_wait_busy_done, /* Got new request. Expire the queue */ }; #define CFQ_CFQQ_FNS(name) \ @@ -348,7 +347,6 @@ CFQ_CFQQ_FNS(sync); CFQ_CFQQ_FNS(coop); CFQ_CFQQ_FNS(deep); CFQ_CFQQ_FNS(wait_busy); -CFQ_CFQQ_FNS(wait_busy_done); #undef CFQ_CFQQ_FNS #ifdef CONFIG_DEBUG_CFQ_IOSCHED @@ -1574,7 +1572,6 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, cfq_clear_cfqq_wait_request(cfqq); cfq_clear_cfqq_wait_busy(cfqq); - cfq_clear_cfqq_wait_busy_done(cfqq); /* * store what was left of this slice, if the queue idled/timed out @@ -2134,11 +2131,17 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd) if (!cfqd->rq_queued) return NULL; + + /* + * We were waiting for group to get backlogged. Expire the queue + */ + if (cfq_cfqq_wait_busy(cfqq) && !RB_EMPTY_ROOT(&cfqq->sort_list)) + goto expire; + /* * The active queue has run out of time, expire it and select new. */ - if ((cfq_slice_used(cfqq) || cfq_cfqq_wait_busy_done(cfqq)) - && !cfq_cfqq_must_dispatch(cfqq)) + if (cfq_slice_used(cfqq) && !cfq_cfqq_must_dispatch(cfqq)) goto expire; /* @@ -3171,10 +3174,6 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, cfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq); if (cfqq == cfqd->active_queue) { - if (cfq_cfqq_wait_busy(cfqq)) { - cfq_clear_cfqq_wait_busy(cfqq); - cfq_mark_cfqq_wait_busy_done(cfqq); - } /* * Remember that we saw a request from this process, but * don't start queuing just yet. Otherwise we risk seeing lots -- cgit v0.10.2 From 7667aa0630407bc07dc38dcc79d29cc0a65553c1 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Tue, 8 Dec 2009 17:52:58 -0500 Subject: cfq-iosched: Take care of corner cases of group losing share due to deletion If there is a sequential reader running in a group, we wait for next request to come in that group after slice expiry and once new request is in, we expire the queue. Otherwise we delete the group from service tree and group looses its fair share. So far I was marking a queue as wait_busy if it had consumed its slice and it was last queue in the group. But this condition did not cover following two cases. 1.If a request completed and slice has not expired yet. Next request comes in and is dispatched to disk. Now select_queue() hits and slice has expired. This group will be deleted. Because request is still in the disk, this queue will never get a chance to wait_busy. 2.If request completed and slice has not expired yet. Before next request comes in (delay due to think time), select_queue() hits and expires the queue hence group. This queue never got a chance to wait busy. Gui was hitting the boundary condition 1 and not getting fairness numbers proportional to weight. This patch puts the checks for above two conditions and improves the fairness numbers for sequential workload on rotational media. Check in select_queue() takes care of case 1 and additional check in should_wait_busy() takes care of case 2. Reported-by: Gui Jianfeng Signed-off-by: Vivek Goyal Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index f41fdb5..98b15b9 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -2141,8 +2141,22 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd) /* * The active queue has run out of time, expire it and select new. */ - if (cfq_slice_used(cfqq) && !cfq_cfqq_must_dispatch(cfqq)) - goto expire; + if (cfq_slice_used(cfqq) && !cfq_cfqq_must_dispatch(cfqq)) { + /* + * If slice had not expired at the completion of last request + * we might not have turned on wait_busy flag. Don't expire + * the queue yet. Allow the group to get backlogged. + * + * The very fact that we have used the slice, that means we + * have been idling all along on this queue and it should be + * ok to wait for this request to complete. + */ + if (cfqq->cfqg->nr_cfqq == 1 && cfqq->dispatched + && cfq_should_idle(cfqd, cfqq)) + goto keep_queue; + else + goto expire; + } /* * The active queue has requests and isn't expired, allow it to @@ -3256,6 +3270,35 @@ static void cfq_update_hw_tag(struct cfq_data *cfqd) cfqd->hw_tag = 0; } +static bool cfq_should_wait_busy(struct cfq_data *cfqd, struct cfq_queue *cfqq) +{ + struct cfq_io_context *cic = cfqd->active_cic; + + /* If there are other queues in the group, don't wait */ + if (cfqq->cfqg->nr_cfqq > 1) + return false; + + if (cfq_slice_used(cfqq)) + return true; + + /* if slice left is less than think time, wait busy */ + if (cic && sample_valid(cic->ttime_samples) + && (cfqq->slice_end - jiffies < cic->ttime_mean)) + return true; + + /* + * If think times is less than a jiffy than ttime_mean=0 and above + * will not be true. It might happen that slice has not expired yet + * but will expire soon (4-5 ns) during select_queue(). To cover the + * case where think time is less than a jiffy, mark the queue wait + * busy if only 1 jiffy is left in the slice. + */ + if (cfqq->slice_end - jiffies == 1) + return true; + + return false; +} + static void cfq_completed_request(struct request_queue *q, struct request *rq) { struct cfq_queue *cfqq = RQ_CFQQ(rq); @@ -3295,11 +3338,10 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) } /* - * If this queue consumed its slice and this is last queue - * in the group, wait for next request before we expire - * the queue + * Should we wait for next request to come in before we expire + * the queue. */ - if (cfq_slice_used(cfqq) && cfqq->cfqg->nr_cfqq == 1) { + if (cfq_should_wait_busy(cfqd, cfqq)) { cfqq->slice_end = jiffies + cfqd->cfq_slice_idle; cfq_mark_cfqq_wait_busy(cfqq); } -- cgit v0.10.2 From 0cd4d0fd9b0a4e10c091fc6316d1bf92885dcd9c Mon Sep 17 00:00:00 2001 From: "David J. Wilder" Date: Wed, 9 Dec 2009 10:03:00 -0800 Subject: IPoIB: Clear ipoib_neigh.dgid in ipoib_neigh_alloc() IPoIB can miss a change in destination GID under some conditions. The problem is caused when ipoib_neigh->dgid contains a stale address. The fix is to set ipoib_neigh->dgid to zero in ipoib_neigh_alloc(). This can happen when a system using bonding on its IPoIB interfaces has switched its active interface from interface A to B and back to A. The system that fails over will not correctly processes the 2nd address change, as described below. When an address has changed neighbor->ha is updated with the new address. Each neighbor has an associated ipoib_neigh. ipoib_neigh->dgid also holds a copy of the remote node's hardware address. When an address changes neighbor->ha is updated by the network layer (arp code) with the new address. IPoIB detects this change in ipoib_start_xmit() by comparing neighbor->ha with ipoib_neigh->dgid. The bug is that ipoib_neigh->dgid may already contain the new address (A) thus the change from B to A is missed by ipoib. Here is the sequence of events: ipoib_neigh->dgid = A and neighbor->ha = A The address is switched to B (the first switch) neighbor->ha = B The change is seen in ipoib_start_xmit() -- neighbor->ha != ipoib_neigh->dgid so ipoib_neigh is released, and a new one is allocated. The allocator may return the same chunk of memory that was just released, therefore ipoib_neigh->dgid still contains A at this point. ipoib_neigh->dgid should be updated in neigh_add_path(), but if the following conditions are true dgid is not updated: 1) __path_find() returns a path 2) path->ah is NULL The remote system now switches from address B to A, neighbor->ha is updated to A. Now we have again : ipoib_neigh->dgid = A and neighbor->ha = A Since the addresses are the same ipoib won't process the change in address. Fix this by zeroing out the dgid field when allocating a new struct ipoib_neigh. Signed-off-by: David Wilder Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 2bf5116..df3eb8c 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -884,6 +884,7 @@ struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour, neigh->neighbour = neighbour; neigh->dev = dev; + memset(&neigh->dgid.raw, 0, sizeof (union ib_gid)); *to_ipoib_neigh(neighbour) = neigh; skb_queue_head_init(&neigh->queue); ipoib_cm_set(neigh, NULL); -- cgit v0.10.2 From 598cb6f327c99ceaf81c45c32504669b2028712b Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Wed, 9 Dec 2009 10:05:28 -0800 Subject: IB/ipath: Use bitmap_weight() Use bitmap_weight() instead of finding all set bits in bitmap by hand. Signed-off-by: Akinobu Mita Cc: Ralph Campbell Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index 013d138..d2787fe 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "ipath_kernel.h" #include "ipath_verbs.h" @@ -1697,7 +1698,7 @@ void ipath_chg_pioavailkernel(struct ipath_devdata *dd, unsigned start, unsigned len, int avail) { unsigned long flags; - unsigned end, cnt = 0, next; + unsigned end, cnt = 0; /* There are two bits per send buffer (busy and generation) */ start *= 2; @@ -1748,12 +1749,7 @@ void ipath_chg_pioavailkernel(struct ipath_devdata *dd, unsigned start, if (dd->ipath_pioupd_thresh) { end = 2 * (dd->ipath_piobcnt2k + dd->ipath_piobcnt4k); - next = find_first_bit(dd->ipath_pioavailkernel, end); - while (next < end) { - cnt++; - next = find_next_bit(dd->ipath_pioavailkernel, end, - next + 1); - } + cnt = bitmap_weight(dd->ipath_pioavailkernel, end); } spin_unlock_irqrestore(&ipath_pioavail_lock, flags); -- cgit v0.10.2 From 9420269428b3dc80c98e52beac60a3976fbef7d2 Mon Sep 17 00:00:00 2001 From: Alexander Schmidt Date: Wed, 9 Dec 2009 10:11:04 -0800 Subject: IB/ehca: Rework destroy_eq() The ibmebus_free_irq() function, which might sleep, was called with interrupts disabled. To fix this, make sure that no interrupts are running by killing the interrupt tasklet. Also lock the shca_list_lock to protect against the poll_eqs_timer running concurrently. Signed-off-by: Alexander Schmidt Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h index c825142..0136abd 100644 --- a/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/drivers/infiniband/hw/ehca/ehca_classes.h @@ -375,6 +375,7 @@ extern rwlock_t ehca_qp_idr_lock; extern rwlock_t ehca_cq_idr_lock; extern struct idr ehca_qp_idr; extern struct idr ehca_cq_idr; +extern spinlock_t shca_list_lock; extern int ehca_static_rate; extern int ehca_port_act_time; diff --git a/drivers/infiniband/hw/ehca/ehca_eq.c b/drivers/infiniband/hw/ehca/ehca_eq.c index 523e733..3b87589 100644 --- a/drivers/infiniband/hw/ehca/ehca_eq.c +++ b/drivers/infiniband/hw/ehca/ehca_eq.c @@ -169,12 +169,15 @@ int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq) unsigned long flags; u64 h_ret; - spin_lock_irqsave(&eq->spinlock, flags); ibmebus_free_irq(eq->ist, (void *)shca); - h_ret = hipz_h_destroy_eq(shca->ipz_hca_handle, eq); + spin_lock_irqsave(&shca_list_lock, flags); + eq->is_initialized = 0; + spin_unlock_irqrestore(&shca_list_lock, flags); - spin_unlock_irqrestore(&eq->spinlock, flags); + tasklet_kill(&eq->interrupt_task); + + h_ret = hipz_h_destroy_eq(shca->ipz_hca_handle, eq); if (h_ret != H_SUCCESS) { ehca_err(&shca->ib_device, "Can't free EQ resources."); diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index fb2d83c..129a6be 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c @@ -123,7 +123,7 @@ DEFINE_IDR(ehca_qp_idr); DEFINE_IDR(ehca_cq_idr); static LIST_HEAD(shca_list); /* list of all registered ehcas */ -static DEFINE_SPINLOCK(shca_list_lock); +DEFINE_SPINLOCK(shca_list_lock); static struct timer_list poll_eqs_timer; -- cgit v0.10.2 From 876fba43cc810e3c37ce26995933f9547b83cb0e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 11 Nov 2009 15:22:15 +0100 Subject: ACPI: add const to acpi_check_resource_conflict() acpi_check_resource_conflict() doesn't change the resource it operates on, so the res parameter can be marked const. Signed-off-by: Jean Delvare Signed-off-by: Len Brown diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 7c1c59e..02e8464 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1118,7 +1118,7 @@ __setup("acpi_enforce_resources=", acpi_enforce_resources_setup); /* Check for resource conflicts between ACPI OperationRegions and native * drivers */ -int acpi_check_resource_conflict(struct resource *res) +int acpi_check_resource_conflict(const struct resource *res) { struct acpi_res_list *res_list_elem; int ioport; diff --git a/include/linux/acpi.h b/include/linux/acpi.h index dfcd920..c920d2d 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -240,7 +240,7 @@ extern int pnpacpi_disabled; #define PXM_INVAL (-1) #define NID_INVAL (-1) -int acpi_check_resource_conflict(struct resource *res); +int acpi_check_resource_conflict(const struct resource *res); int acpi_check_region(resource_size_t start, resource_size_t n, const char *name); -- cgit v0.10.2 From edc71131c4dc6cc73e2a24aa0a7a79cfce738f12 Mon Sep 17 00:00:00 2001 From: Corrado Zoccolo Date: Wed, 9 Dec 2009 20:56:04 +0100 Subject: cfq-iosched: commenting non-obvious initialization Added a comment to explain the initialization of last_delayed_sync. Signed-off-by: Corrado Zoccolo Acked-by: Jeff Moyer Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 98b15b9..69ecee7 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -3759,6 +3759,10 @@ static void *cfq_init_queue(struct request_queue *q) cfqd->cfq_latency = 1; cfqd->cfq_group_isolation = 0; cfqd->hw_tag = -1; + /* + * we optimistically start assuming sync ops weren't delayed in last + * second, in order to have larger depth for async operations. + */ cfqd->last_delayed_sync = jiffies - HZ; INIT_RCU_HEAD(&cfqd->rcu); return cfqd; -- cgit v0.10.2 From a9f8eacca4e9e8693de9b896c1fa7aadaa9402e8 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Wed, 9 Dec 2009 01:36:21 +0000 Subject: thinkpad-acpi: fix default brightness_mode for R50e/R51 According to a report, the R50e wants EC-based brightness control, even if it uses an Intel GPU. The current driver default was reported to not work at all. This bug can be worked around by the "brightness_mode=3" module parameter. Change the default of the R50e and R51 2xxx models (which use the same EC firmware, 1V) to TPACPI_BRGHT_Q_EC, but keep TPACPI_BRGHT_Q_ASK set for now, as I'd like to get more reports. This fixes a regression caused by commit 59fe4fe34d7afdf63208124f313be9056feaa2f4, "thinkpad-acpi: fix incorrect use of TPACPI_BRGHT_MODE_ECNVRAM" Kernel 2.6.31 also needs this fix. Reported-by: Ferenc Wagner Tested-by: Ferenc Wagner Signed-off-by: Henrique de Moraes Holschuh Cc: stable@kernel.org Signed-off-by: Len Brown diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index a848c7e..9c6d5a9 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -6123,8 +6123,8 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = { /* Models with Intel Extreme Graphics 2 */ TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), - TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), - TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), + TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), + TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), /* Models with Intel GMA900 */ TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */ -- cgit v0.10.2 From 208b996b6c460285650d39b2330f8ef82c007d10 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Wed, 9 Dec 2009 01:36:22 +0000 Subject: thinkpad-acpi: preserve rfkill state across suspend/resume Since the rfkill rework in 2.6.31, the driver is always resuming with the radios disabled. Change thinkpad-acpi to ask the firmware to resume with the radios in the last state. This fixes the Bluetooth and WWAN rfkill switches. Note that it means we respect the firmware's oddities. Should the user toggle the hardware rfkill switch on and off, it might cause the radios to resume enabled. UWB is an unknown quantity since it has nowhere the same level of firmware support (no control over state storage in NVRAM, for example), and might need further fixing. Testers welcome. This change fixes a regression from 2.6.30. Reported-by: Jerone Young Reported-by: Ian Molton Signed-off-by: Henrique de Moraes Holschuh Tested-by: Ian Molton Cc: stable@kernel.org Signed-off-by: Len Brown diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 9c6d5a9..1ee734c 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -3866,15 +3866,6 @@ enum { #define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw" -static void bluetooth_suspend(pm_message_t state) -{ - /* Try to make sure radio will resume powered off */ - if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd", - TP_ACPI_BLTH_PWR_OFF_ON_RESUME)) - vdbg_printk(TPACPI_DBG_RFKILL, - "bluetooth power down on resume request failed\n"); -} - static int bluetooth_get_status(void) { int status; @@ -3908,10 +3899,9 @@ static int bluetooth_set_status(enum tpacpi_rfkill_state state) #endif /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */ + status = TP_ACPI_BLUETOOTH_RESUMECTRL; if (state == TPACPI_RFK_RADIO_ON) - status = TP_ACPI_BLUETOOTH_RADIOSSW; - else - status = 0; + status |= TP_ACPI_BLUETOOTH_RADIOSSW; if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) return -EIO; @@ -4050,7 +4040,6 @@ static struct ibm_struct bluetooth_driver_data = { .read = bluetooth_read, .write = bluetooth_write, .exit = bluetooth_exit, - .suspend = bluetooth_suspend, .shutdown = bluetooth_shutdown, }; @@ -4068,15 +4057,6 @@ enum { #define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" -static void wan_suspend(pm_message_t state) -{ - /* Try to make sure radio will resume powered off */ - if (!acpi_evalf(NULL, NULL, "\\WGSV", "qvd", - TP_ACPI_WGSV_PWR_OFF_ON_RESUME)) - vdbg_printk(TPACPI_DBG_RFKILL, - "WWAN power down on resume request failed\n"); -} - static int wan_get_status(void) { int status; @@ -4109,11 +4089,10 @@ static int wan_set_status(enum tpacpi_rfkill_state state) } #endif - /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */ + /* We make sure to set TP_ACPI_WANCARD_RESUMECTRL */ + status = TP_ACPI_WANCARD_RESUMECTRL; if (state == TPACPI_RFK_RADIO_ON) - status = TP_ACPI_WANCARD_RADIOSSW; - else - status = 0; + status |= TP_ACPI_WANCARD_RADIOSSW; if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) return -EIO; @@ -4251,7 +4230,6 @@ static struct ibm_struct wan_driver_data = { .read = wan_read, .write = wan_write, .exit = wan_exit, - .suspend = wan_suspend, .shutdown = wan_shutdown, }; -- cgit v0.10.2 From 90765c6aee568137521ba19347c744b5abde8161 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Wed, 9 Dec 2009 01:36:23 +0000 Subject: thinkpad-acpi: fix some version quirks Update some of the BIOS/EC version quirks. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 1ee734c..6160813 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -1779,7 +1779,7 @@ static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = { TPV_QL1('7', '9', 'E', '3', '5', '0'), /* T60/p */ TPV_QL1('7', 'C', 'D', '2', '2', '2'), /* R60, R60i */ - TPV_QL0('7', 'E', 'D', '0'), /* R60e, R60i */ + TPV_QL1('7', 'E', 'D', '0', '1', '5'), /* R60e, R60i */ /* BIOS FW BIOS VERS EC FW EC VERS */ TPV_QI2('1', 'W', '9', '0', '1', 'V', '2', '8'), /* R50e (1) */ @@ -1795,8 +1795,8 @@ static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = { TPV_QI1('7', '4', '6', '4', '2', '7'), /* X41 (0) */ TPV_QI1('7', '5', '6', '0', '2', '0'), /* X41t (0) */ - TPV_QL0('7', 'B', 'D', '7'), /* X60/s */ - TPV_QL0('7', 'J', '3', '0'), /* X60t */ + TPV_QL1('7', 'B', 'D', '7', '4', '0'), /* X60/s */ + TPV_QL1('7', 'J', '3', '0', '1', '3'), /* X60t */ /* (0) - older versions lack DMI EC fw string and functionality */ /* (1) - older versions known to lack functionality */ -- cgit v0.10.2 From 347a26860e2293b1347996876d3550499c7bb31f Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Wed, 9 Dec 2009 01:36:24 +0000 Subject: thinkpad-acpi: issue backlight class events Take advantage of the new events capabilities of the backlight class to notify userspace of backlight changes. This depends on "backlight: Allow drivers to update the core, and generate events on changes", by Matthew Garrett. Signed-off-by: Henrique de Moraes Holschuh Cc: Matthew Garrett Cc: Richard Purdie Signed-off-by: Len Brown diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index aafcaa6..f5056c7 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt @@ -460,6 +460,8 @@ event code Key Notes For Lenovo ThinkPads with a new BIOS, it has to be handled either by the ACPI OSI, or by userspace. + The driver does the right thing, + never mess with this. 0x1011 0x10 FN+END Brightness down. See brightness up for details. @@ -582,46 +584,15 @@ with hotkey_report_mode. Brightness hotkey notes: -These are the current sane choices for brightness key mapping in -thinkpad-acpi: +Don't mess with the brightness hotkeys in a Thinkpad. If you want +notifications for OSD, use the sysfs backlight class event support. -For IBM and Lenovo models *without* ACPI backlight control (the ones on -which thinkpad-acpi will autoload its backlight interface by default, -and on which ACPI video does not export a backlight interface): - -1. Don't enable or map the brightness hotkeys in thinkpad-acpi, as - these older firmware versions unfortunately won't respect the hotkey - mask for brightness keys anyway, and always reacts to them. This - usually work fine, unless X.org drivers are doing something to block - the BIOS. In that case, use (3) below. This is the default mode of - operation. - -2. Enable the hotkeys, but map them to something else that is NOT - KEY_BRIGHTNESS_UP/DOWN or any other keycode that would cause - userspace to try to change the backlight level, and use that as an - on-screen-display hint. - -3. IF AND ONLY IF X.org drivers find a way to block the firmware from - automatically changing the brightness, enable the hotkeys and map - them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN, and feed that to - something that calls xbacklight. thinkpad-acpi will not be able to - change brightness in that case either, so you should disable its - backlight interface. - -For Lenovo models *with* ACPI backlight control: - -1. Load up ACPI video and use that. ACPI video will report ACPI - events for brightness change keys. Do not mess with thinkpad-acpi - defaults in this case. thinkpad-acpi should not have anything to do - with backlight events in a scenario where ACPI video is loaded: - brightness hotkeys must be disabled, and the backlight interface is - to be kept disabled as well. This is the default mode of operation. - -2. Do *NOT* load up ACPI video, enable the hotkeys in thinkpad-acpi, - and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process - these keys on userspace somehow (e.g. by calling xbacklight). - The driver will do this automatically if it detects that ACPI video - has been disabled. +The driver will issue KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN events +automatically for the cases were userspace has to do something to +implement brightness changes. When you override these events, you will +either fail to handle properly the ThinkPads that require explicit +action to change backlight brightness, or the ThinkPads that require +that no action be taken to work properly. Bluetooth @@ -1465,3 +1436,5 @@ Sysfs interface changelog: and it is always able to disable hot keys. Very old thinkpads are properly supported. hotkey_bios_mask is deprecated and marked for removal. + +0x020600: Marker for backlight change event support. diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 6160813..4406136 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -22,7 +22,7 @@ */ #define TPACPI_VERSION "0.23" -#define TPACPI_SYSFS_VERSION 0x020500 +#define TPACPI_SYSFS_VERSION 0x020600 /* * Changelog: @@ -6073,6 +6073,12 @@ static int brightness_get(struct backlight_device *bd) return status & TP_EC_BACKLIGHT_LVLMSK; } +static void tpacpi_brightness_notify_change(void) +{ + backlight_force_update(ibm_backlight_device, + BACKLIGHT_UPDATE_HOTKEY); +} + static struct backlight_ops ibm_backlight_data = { .get_brightness = brightness_get, .update_status = brightness_update_status, @@ -6227,6 +6233,12 @@ static int __init brightness_init(struct ibm_init_struct *iibm) ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK; backlight_update_status(ibm_backlight_device); + vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, + "brightness: registering brightness hotkeys " + "as change notification\n"); + tpacpi_hotkey_driver_mask_set(hotkey_driver_mask + | TP_ACPI_HKEY_BRGHTUP_MASK + | TP_ACPI_HKEY_BRGHTDWN_MASK);; return 0; } @@ -6303,6 +6315,9 @@ static int brightness_write(char *buf) * Doing it this way makes the syscall restartable in case of EINTR */ rc = brightness_set(level); + if (!rc && ibm_backlight_device) + backlight_force_update(ibm_backlight_device, + BACKLIGHT_UPDATE_SYSFS); return (rc == -EINTR)? -ERESTARTSYS : rc; } @@ -7702,6 +7717,13 @@ static struct ibm_struct fan_driver_data = { */ static void tpacpi_driver_event(const unsigned int hkey_event) { + if (ibm_backlight_device) { + switch (hkey_event) { + case TP_HKEY_EV_BRGHT_UP: + case TP_HKEY_EV_BRGHT_DOWN: + tpacpi_brightness_notify_change(); + } + } } -- cgit v0.10.2 From 6b30eb7d211840ba1a03f855d9e7b80a921368f2 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Wed, 9 Dec 2009 01:36:25 +0000 Subject: thinkpad-acpi: silence bogus complain during rmmod Fix this bogus warning during module shutdown, when backlight event reporting is enabled: "thinkpad_acpi: required events 0x00018000 not enabled!" Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 4406136..86418cd 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -2189,7 +2189,8 @@ static int hotkey_mask_set(u32 mask) fwmask, hotkey_acpi_mask); } - hotkey_mask_warn_incomplete_mask(); + if (tpacpi_lifecycle != TPACPI_LIFE_EXITING) + hotkey_mask_warn_incomplete_mask(); return rc; } -- cgit v0.10.2 From d112ef95d4ec1ee7fe7123e3f21e4aac0d57570c Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Wed, 9 Dec 2009 01:36:26 +0000 Subject: thinkpad-acpi: adopt input device Properly init the parent field of the input device. Thanks to Alan Jenkins, who noted this problem in a different driver. Reported-by: Alan Jenkins Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 86418cd..dd8bd07 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -8375,6 +8375,7 @@ static int __init thinkpad_acpi_module_init(void) PCI_VENDOR_ID_IBM; tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT; tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION; + tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev; } for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { ret = ibm_init(&ibms_init[i]); -- cgit v0.10.2 From b09c72259e88cec3d602aef987a3209297f3a9c2 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Wed, 9 Dec 2009 01:36:27 +0000 Subject: thinkpad-acpi: expose module parameters Export the normal (non-command) module paramenters as mode 0444, so that they will show up in sysfs. These parameters must not be changed at runtime as a rule, with very few exceptions. Reported-by: Ferenc Wagner Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index dd8bd07..4b96a96 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -8116,32 +8116,32 @@ static int __init set_ibm_param(const char *val, struct kernel_param *kp) return -EINVAL; } -module_param(experimental, int, 0); +module_param(experimental, int, 0444); MODULE_PARM_DESC(experimental, "Enables experimental features when non-zero"); module_param_named(debug, dbg_level, uint, 0); MODULE_PARM_DESC(debug, "Sets debug level bit-mask"); -module_param(force_load, bool, 0); +module_param(force_load, bool, 0444); MODULE_PARM_DESC(force_load, "Attempts to load the driver even on a " "mis-identified ThinkPad when true"); -module_param_named(fan_control, fan_control_allowed, bool, 0); +module_param_named(fan_control, fan_control_allowed, bool, 0444); MODULE_PARM_DESC(fan_control, "Enables setting fan parameters features when true"); -module_param_named(brightness_mode, brightness_mode, uint, 0); +module_param_named(brightness_mode, brightness_mode, uint, 0444); MODULE_PARM_DESC(brightness_mode, "Selects brightness control strategy: " "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM"); -module_param(brightness_enable, uint, 0); +module_param(brightness_enable, uint, 0444); MODULE_PARM_DESC(brightness_enable, "Enables backlight control when 1, disables when 0"); -module_param(hotkey_report_mode, uint, 0); +module_param(hotkey_report_mode, uint, 0444); MODULE_PARM_DESC(hotkey_report_mode, "used for backwards compatibility with userspace, " "see documentation"); @@ -8164,25 +8164,25 @@ TPACPI_PARAM(volume); TPACPI_PARAM(fan); #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES -module_param(dbg_wlswemul, uint, 0); +module_param(dbg_wlswemul, uint, 0444); MODULE_PARM_DESC(dbg_wlswemul, "Enables WLSW emulation"); module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0); MODULE_PARM_DESC(wlsw_state, "Initial state of the emulated WLSW switch"); -module_param(dbg_bluetoothemul, uint, 0); +module_param(dbg_bluetoothemul, uint, 0444); MODULE_PARM_DESC(dbg_bluetoothemul, "Enables bluetooth switch emulation"); module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0); MODULE_PARM_DESC(bluetooth_state, "Initial state of the emulated bluetooth switch"); -module_param(dbg_wwanemul, uint, 0); +module_param(dbg_wwanemul, uint, 0444); MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation"); module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0); MODULE_PARM_DESC(wwan_state, "Initial state of the emulated WWAN switch"); -module_param(dbg_uwbemul, uint, 0); +module_param(dbg_uwbemul, uint, 0444); MODULE_PARM_DESC(dbg_uwbemul, "Enables UWB switch emulation"); module_param_named(uwb_state, tpacpi_uwb_emulstate, bool, 0); MODULE_PARM_DESC(uwb_state, -- cgit v0.10.2 From 9ebd9e833648745fa5ac6998b9e0153ccd3ba839 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Wed, 9 Dec 2009 01:36:28 +0000 Subject: thinkpad-acpi: log temperatures on termal alarm (v2) Log temperatures on any of the EC thermal alarms. It could be useful to help tracking down what is happening... Signed-off-by: Henrique de Moraes Holschuh Acked-by: Pavel Machek Signed-off-by: Len Brown diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 4b96a96..b3e256b 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -3546,49 +3546,57 @@ static bool hotkey_notify_usrevent(const u32 hkey, } } +static void thermal_dump_all_sensors(void); + static bool hotkey_notify_thermal(const u32 hkey, bool *send_acpi_ev, bool *ignore_acpi_ev) { + bool known = true; + /* 0x6000-0x6FFF: thermal alarms */ *send_acpi_ev = true; *ignore_acpi_ev = false; switch (hkey) { + case TP_HKEY_EV_THM_TABLE_CHANGED: + printk(TPACPI_INFO + "EC reports that Thermal Table has changed\n"); + /* recommended action: do nothing, we don't have + * Lenovo ATM information */ + return true; case TP_HKEY_EV_ALARM_BAT_HOT: printk(TPACPI_CRIT "THERMAL ALARM: battery is too hot!\n"); /* recommended action: warn user through gui */ - return true; + break; case TP_HKEY_EV_ALARM_BAT_XHOT: printk(TPACPI_ALERT "THERMAL EMERGENCY: battery is extremely hot!\n"); /* recommended action: immediate sleep/hibernate */ - return true; + break; case TP_HKEY_EV_ALARM_SENSOR_HOT: printk(TPACPI_CRIT "THERMAL ALARM: " "a sensor reports something is too hot!\n"); /* recommended action: warn user through gui, that */ /* some internal component is too hot */ - return true; + break; case TP_HKEY_EV_ALARM_SENSOR_XHOT: printk(TPACPI_ALERT "THERMAL EMERGENCY: " "a sensor reports something is extremely hot!\n"); /* recommended action: immediate sleep/hibernate */ - return true; - case TP_HKEY_EV_THM_TABLE_CHANGED: - printk(TPACPI_INFO - "EC reports that Thermal Table has changed\n"); - /* recommended action: do nothing, we don't have - * Lenovo ATM information */ - return true; + break; default: printk(TPACPI_ALERT "THERMAL ALERT: unknown thermal alarm received\n"); - return false; + known = false; } + + thermal_dump_all_sensors(); + + return known; } static void hotkey_notify(struct ibm_struct *ibm, u32 event) @@ -5462,8 +5470,11 @@ enum { /* TPACPI_THERMAL_TPEC_* */ TP_EC_THERMAL_TMP0 = 0x78, /* ACPI EC regs TMP 0..7 */ TP_EC_THERMAL_TMP8 = 0xC0, /* ACPI EC regs TMP 8..15 */ TP_EC_THERMAL_TMP_NA = -128, /* ACPI EC sensor not available */ + + TPACPI_THERMAL_SENSOR_NA = -128000, /* Sensor not available */ }; + #define TPACPI_MAX_THERMAL_SENSORS 16 /* Max thermal sensors supported */ struct ibm_thermal_sensors_struct { s32 temp[TPACPI_MAX_THERMAL_SENSORS]; @@ -5553,6 +5564,28 @@ static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s) return n; } +static void thermal_dump_all_sensors(void) +{ + int n, i; + struct ibm_thermal_sensors_struct t; + + n = thermal_get_sensors(&t); + if (n <= 0) + return; + + printk(TPACPI_NOTICE + "temperatures (Celsius):"); + + for (i = 0; i < n; i++) { + if (t.temp[i] != TPACPI_THERMAL_SENSOR_NA) + printk(KERN_CONT " %d", (int)(t.temp[i] / 1000)); + else + printk(KERN_CONT " N/A"); + } + + printk(KERN_CONT "\n"); +} + /* sysfs temp##_input -------------------------------------------------- */ static ssize_t thermal_temp_input_show(struct device *dev, @@ -5568,7 +5601,7 @@ static ssize_t thermal_temp_input_show(struct device *dev, res = thermal_get_sensor(idx, &value); if (res) return res; - if (value == TP_EC_THERMAL_TMP_NA * 1000) + if (value == TPACPI_THERMAL_SENSOR_NA) return -ENXIO; return snprintf(buf, PAGE_SIZE, "%d\n", value); -- cgit v0.10.2 From 792979c8032b8f5adb77ea986db7082fff04c8e7 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Wed, 9 Dec 2009 01:36:29 +0000 Subject: thinkpad-acpi: use input_set_capability Use input_set_capability() instead of set_bit. Signed-off-by: Henrique de Moraes Holschuh Cc: Dmitry Torokhov Signed-off-by: Len Brown diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index b3e256b..53d6c33 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -3348,16 +3348,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) TPACPI_HOTKEY_MAP_SIZE); } - set_bit(EV_KEY, tpacpi_inputdev->evbit); - set_bit(EV_MSC, tpacpi_inputdev->evbit); - set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); + input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN); tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; tpacpi_inputdev->keycode = hotkey_keycode_map; for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { if (hotkey_keycode_map[i] != KEY_RESERVED) { - set_bit(hotkey_keycode_map[i], - tpacpi_inputdev->keybit); + input_set_capability(tpacpi_inputdev, EV_KEY, + hotkey_keycode_map[i]); } else { if (i < sizeof(hotkey_reserved_mask)*8) hotkey_reserved_mask |= 1 << i; @@ -3365,12 +3363,10 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) } if (tp_features.hotkey_wlsw) { - set_bit(EV_SW, tpacpi_inputdev->evbit); - set_bit(SW_RFKILL_ALL, tpacpi_inputdev->swbit); + input_set_capability(tpacpi_inputdev, EV_SW, SW_RFKILL_ALL); } if (tp_features.hotkey_tablet) { - set_bit(EV_SW, tpacpi_inputdev->evbit); - set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); + input_set_capability(tpacpi_inputdev, EV_SW, SW_TABLET_MODE); } /* Do not issue duplicate brightness change events to -- cgit v0.10.2 From f93611fac7eed3aa175795fb8e452aa30af33b6a Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 8 Dec 2009 01:54:35 +0300 Subject: powerpc/fsl_pci: Fix P2P bridge handling for MPC83xx PCIe controllers It appears that we wrongly calculate dev_base for type1 config cycles. The thing is: we shouldn't subtract hose->first_busno because PCI core sets PCI primary, secondary and subordinate bus numbers, and PCIe controller actually takes the registers into account. So we should use just bus->number. Also, according to MPC8315 reference manual, primary bus number should always remain 0. We have PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS quirk in indirect_pci.c, but since 83xx is somewhat special, it doesn't use indirect_pci.c routines, so we have to implement the quirk specifically for 83xx PCIe controllers. Signed-off-by: Anton Vorontsov Signed-off-by: Kumar Gala diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 4e3a3e3..e1a028c 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -464,8 +464,7 @@ static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus, { struct pci_controller *hose = pci_bus_to_host(bus); struct mpc83xx_pcie_priv *pcie = hose->dn->data; - u8 bus_no = bus->number - hose->first_busno; - u32 dev_base = bus_no << 24 | devfn << 16; + u32 dev_base = bus->number << 24 | devfn << 16; int ret; ret = mpc83xx_pcie_exclude_device(bus, devfn); @@ -515,12 +514,17 @@ static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn, static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { + struct pci_controller *hose = pci_bus_to_host(bus); void __iomem *cfg_addr; cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset); if (!cfg_addr) return PCIBIOS_DEVICE_NOT_FOUND; + /* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */ + if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno) + val &= 0xffffff00; + switch (len) { case 1: out_8(cfg_addr, val); -- cgit v0.10.2 From 196f0082d8e77f647edd21ea27b5a9bba8116396 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sun, 6 Dec 2009 12:32:47 +0100 Subject: powerpc/fsl: try to explain why the interrupt numbers are off by 16 Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Kumar Gala diff --git a/Documentation/powerpc/dts-bindings/fsl/mpic.txt b/Documentation/powerpc/dts-bindings/fsl/mpic.txt new file mode 100644 index 0000000..71e39cf --- /dev/null +++ b/Documentation/powerpc/dts-bindings/fsl/mpic.txt @@ -0,0 +1,42 @@ +* OpenPIC and its interrupt numbers on Freescale's e500/e600 cores + +The OpenPIC specification does not specify which interrupt source has to +become which interrupt number. This is up to the software implementation +of the interrupt controller. The only requirement is that every +interrupt source has to have an unique interrupt number / vector number. +To accomplish this the current implementation assigns the number zero to +the first source, the number one to the second source and so on until +all interrupt sources have their unique number. +Usually the assigned vector number equals the interrupt number mentioned +in the documentation for a given core / CPU. This is however not true +for the e500 cores (MPC85XX CPUs) where the documentation distinguishes +between internal and external interrupt sources and starts counting at +zero for both of them. + +So what to write for external interrupt source X or internal interrupt +source Y into the device tree? Here is an example: + +The memory map for the interrupt controller in the MPC8544[0] shows, +that the first interrupt source starts at 0x5_0000 (PIC Register Address +Map-Interrupt Source Configuration Registers). This source becomes the +number zero therefore: + External interrupt 0 = interrupt number 0 + External interrupt 1 = interrupt number 1 + External interrupt 2 = interrupt number 2 + ... +Every interrupt number allocates 0x20 bytes register space. So to get +its number it is sufficient to shift the lower 16bits to right by five. +So for the external interrupt 10 we have: + 0x0140 >> 5 = 10 + +After the external sources, the internal sources follow. The in core I2C +controller on the MPC8544 for instance has the internal source number +27. Oo obtain its interrupt number we take the lower 16bits of its memory +address (0x5_0560) and shift it right: + 0x0560 >> 5 = 43 + +Therefore the I2C device node for the MPC8544 CPU has to have the +interrupt number 43 specified in the device tree. + +[0] MPC8544E PowerQUICCTM III, Integrated Host Processor Family Reference Manual + MPC8544ERM Rev. 1 10/2007 -- cgit v0.10.2 From 6dff29b63a5bf2eaf3313cb8a84f0b7520c43401 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:44:45 +0000 Subject: eeepc-laptop: disp attribute should be write-only Currently, reading from the disp attribute fails with "No such device", which is misleading. According to CMSG table on acpi4asus project site, no models have a getter method corresponding to SDSP. Change the file permission to disallow reads. If some joker changes the permission to permit reads, then return -EIO to be consistent with sysfs' behaviour when no show() method is provided. Signed-off-by: Alan Jenkins Signed-off-by: Corentin Chary Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 4226e53..2c65a37 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -380,7 +380,7 @@ static ssize_t store_sys_acpi(int cm, const char *buf, size_t count) if (rv > 0) value = set_acpi(cm, value); if (value < 0) - return value; + return -EIO; return rv; } @@ -389,11 +389,11 @@ static ssize_t show_sys_acpi(int cm, char *buf) int value = get_acpi(cm); if (value < 0) - return value; + return -EIO; return sprintf(buf, "%d\n", value); } -#define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \ +#define EEEPC_CREATE_DEVICE_ATTR(_name, _mode, _cm) \ static ssize_t show_##_name(struct device *dev, \ struct device_attribute *attr, \ char *buf) \ @@ -409,14 +409,14 @@ static ssize_t show_sys_acpi(int cm, char *buf) static struct device_attribute dev_attr_##_name = { \ .attr = { \ .name = __stringify(_name), \ - .mode = 0644 }, \ + .mode = _mode }, \ .show = show_##_name, \ .store = store_##_name, \ } -EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); -EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); -EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); +EEEPC_CREATE_DEVICE_ATTR(camera, 0644, CM_ASL_CAMERA); +EEEPC_CREATE_DEVICE_ATTR(cardr, 0644, CM_ASL_CARDREADER); +EEEPC_CREATE_DEVICE_ATTR(disp, 0200, CM_ASL_DISPLAYSWITCH); struct eeepc_cpufv { int num; -- cgit v0.10.2 From 1df8d8d4efb7bce0e44d2aa91c4c0fa7ffe613c0 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:44:46 +0000 Subject: asus-laptop: Remove redundant NULL checks The acpi device callbacks add, start, remove, suspend and resume can never be called with a NULL acpi_device. Each callsite in acpi/scan.c has to dereference the device in order to get the ops structure, e.g. struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_driver *acpi_drv = acpi_dev->driver; if (acpi_drv && acpi_drv->ops.suspend) return acpi_drv->ops.suspend(acpi_dev, state); Remove all checks for acpi_dev == NULL within these callbacks. Also remove the checks for acpi_driver_data(acpi_dev) == NULL. None of these checks could fail unless the driver does something strange (which none of them do), the acpi core did something terribly wrong, or we have a memory corruption issue. If this does happen then it's best to dereference the pointer and crash noisily. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index b39d2bb..8af43e9 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -1240,9 +1240,6 @@ static int asus_hotk_add(struct acpi_device *device) { int result; - if (!device) - return -EINVAL; - pr_notice("Asus Laptop Support version %s\n", ASUS_LAPTOP_VERSION); @@ -1306,9 +1303,6 @@ end: static int asus_hotk_remove(struct acpi_device *device, int type) { - if (!device || !acpi_driver_data(device)) - return -EINVAL; - kfree(hotk->name); kfree(hotk); -- cgit v0.10.2 From 2d5db0be4ce36b265f9ddd8debab40acd8580403 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:44:47 +0000 Subject: asus-acpi: Remove redundant NULL checks The acpi device callbacks add, start, remove, suspend and resume can never be called with a NULL acpi_device. Each callsite in acpi/scan.c has to dereference the device in order to get the ops structure, e.g. struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_driver *acpi_drv = acpi_dev->driver; if (acpi_drv && acpi_drv->ops.suspend) return acpi_drv->ops.suspend(acpi_dev, state); Remove all checks for acpi_dev == NULL within these callbacks. Also remove the checks for acpi_driver_data(acpi_dev) == NULL. None of these checks could fail unless the driver does something strange (which none of them do), the acpi core did something terribly wrong, or we have a memory corruption issue. If this does happen then it's best to dereference the pointer and crash noisily. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index ddf5240..25a7d57 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c @@ -1334,9 +1334,6 @@ static int asus_hotk_add(struct acpi_device *device) acpi_status status = AE_OK; int result; - if (!device) - return -EINVAL; - printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n", ASUS_ACPI_VERSION); @@ -1392,9 +1389,6 @@ end: static int asus_hotk_remove(struct acpi_device *device, int type) { - if (!device || !acpi_driver_data(device)) - return -EINVAL; - asus_hotk_remove_fs(device); kfree(hotk); -- cgit v0.10.2 From b7fab7a0703a9d3a3b4b59aa2f7b098b2b83b8fe Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:44:48 +0000 Subject: asus-laptop: Remove uneccesary acpi_disabled check acpi_bus_register_driver() already checks acpi_disabled, so acpi bus drivers don't need to. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 8af43e9..4234edb 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -1438,9 +1438,6 @@ static int __init asus_laptop_init(void) { int result; - if (acpi_disabled) - return -ENODEV; - result = acpi_bus_register_driver(&asus_hotk_driver); if (result < 0) return result; -- cgit v0.10.2 From 5a4a9f6fd3dedefe06aed0e35c76bb6e0177adb6 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:44:49 +0000 Subject: asus-acpi: Remove uneccesary acpi_disabled checks acpi_bus_register_driver() already checks acpi_disabled, so acpi bus drivers don't need to. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index 25a7d57..783243f 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c @@ -1416,21 +1416,17 @@ static int __init asus_acpi_init(void) { int result; - if (acpi_disabled) - return -ENODEV; + result = acpi_bus_register_driver(&asus_hotk_driver); + if (result < 0) + return result; asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir); if (!asus_proc_dir) { printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n"); + acpi_bus_unregister_driver(&asus_hotk_driver); return -ENODEV; } - result = acpi_bus_register_driver(&asus_hotk_driver); - if (result < 0) { - remove_proc_entry(PROC_ASUS, acpi_root_dir); - return result; - } - /* * This is a bit of a kludge. We only want this module loaded * for ASUS systems, but there's currently no way to probe the -- cgit v0.10.2 From db7c554afeee7e535a5476dedb1339cb30d0b5df Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:44:50 +0000 Subject: asus-acpi: set acpi_driver.owner The owner field provides the link between drivers and modules in sysfs, but no ACPI driver was setting it. After setting the owner field, we can see which module provides which driver and vice versa by looking at /sys/bus/acpi/driver/*/module and /sys/module/*/drivers/acpi:*. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index 783243f..0c9c531 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c @@ -466,6 +466,7 @@ MODULE_DEVICE_TABLE(acpi, asus_device_ids); static struct acpi_driver asus_hotk_driver = { .name = "asus_acpi", .class = ACPI_HOTK_CLASS, + .owner = THIS_MODULE, .ids = asus_device_ids, .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { -- cgit v0.10.2 From edf624522757adec8ceb83a4b97747eba645c454 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:44:51 +0000 Subject: asus-laptop: set acpi_driver.owner The owner field provides the link between drivers and modules in sysfs, but no ACPI driver was setting it. After setting the owner field, we can see which module provides which driver and vice versa by looking at /sys/bus/acpi/driver/*/module and /sys/module/*/drivers/acpi:*. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 4234edb..6c05172 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -232,6 +232,7 @@ static void asus_hotk_notify(struct acpi_device *device, u32 event); static struct acpi_driver asus_hotk_driver = { .name = ASUS_HOTK_NAME, .class = ASUS_HOTK_CLASS, + .owner = THIS_MODULE, .ids = asus_device_ids, .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { -- cgit v0.10.2 From 3c0eb510697dbbb53674c72544350624a04ab5b4 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Thu, 3 Dec 2009 07:44:52 +0000 Subject: eeepc-laptop: add touchpad led This led can be found on Eeepc 1005 series. Signed-off-by: Corentin Chary Signed-off-by: Len Brown diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 55ca39d..e5e4312 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -334,6 +334,8 @@ config EEEPC_LAPTOP depends on HOTPLUG_PCI select BACKLIGHT_CLASS_DEVICE select HWMON + select LEDS_CLASS + select NEW_LEDS ---help--- This driver supports the Fn-Fx keys on Eee PC laptops. diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 2c65a37..9130434 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -34,6 +34,7 @@ #include #include #include +#include #define EEEPC_LAPTOP_VERSION "0.1" @@ -507,6 +508,39 @@ static struct attribute_group platform_attribute_group = { }; /* + * LEDs + */ +/* + * These functions actually update the LED's, and are called from a + * workqueue. By doing this as separate work rather than when the LED + * subsystem asks, we avoid messing with the Asus ACPI stuff during a + * potentially bad time, such as a timer interrupt. + */ +static int tpd_led_wk; + +static void tpd_led_update(struct work_struct *ignored) +{ + int value = tpd_led_wk; + set_acpi(CM_ASL_TPD, value); +} + +static struct workqueue_struct *led_workqueue; +static DECLARE_WORK(tpd_led_work, tpd_led_update); + +static void tpd_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + tpd_led_wk = (value > 0) ? 1 : 0; + queue_work(led_workqueue, &tpd_led_work); +} + +static struct led_classdev tpd_led = { + .name = "eeepc::touchpad", + .brightness_set = tpd_led_set, + .max_brightness = 1 +}; + +/* * Hotkey functions */ static struct key_entry *eepc_get_entry_by_scancode(int code) @@ -1034,6 +1068,14 @@ static void eeepc_hwmon_exit(void) eeepc_hwmon_device = NULL; } +static void eeepc_led_exit(void) +{ + if (led_workqueue) + destroy_workqueue(led_workqueue); + if (tpd_led.dev) + led_classdev_unregister(&tpd_led); +} + static int eeepc_new_rfkill(struct rfkill **rfkill, const char *name, struct device *dev, enum rfkill_type type, int cm) @@ -1190,6 +1232,24 @@ static int eeepc_input_init(struct device *dev) return 0; } +static int eeepc_led_init(struct device *dev) +{ + int rv; + + if (get_acpi(CM_ASL_TPD) == -ENODEV) + return 0; + + rv = led_classdev_register(dev, &tpd_led); + if (rv) + return rv; + + led_workqueue = create_singlethread_workqueue("led_workqueue"); + if (!led_workqueue) + return -ENOMEM; + + return 0; +} + static int __devinit eeepc_hotk_add(struct acpi_device *device) { struct device *dev; @@ -1248,6 +1308,10 @@ static int __devinit eeepc_hotk_add(struct acpi_device *device) if (result) goto fail_hwmon; + result = eeepc_led_init(dev); + if (result) + goto fail_led; + result = eeepc_rfkill_init(dev); if (result) goto fail_rfkill; @@ -1255,6 +1319,8 @@ static int __devinit eeepc_hotk_add(struct acpi_device *device) return 0; fail_rfkill: + eeepc_led_exit(); +fail_led: eeepc_hwmon_exit(); fail_hwmon: eeepc_input_exit(); @@ -1284,6 +1350,7 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) eeepc_rfkill_exit(); eeepc_input_exit(); eeepc_hwmon_exit(); + eeepc_led_exit(); sysfs_remove_group(&platform_device->dev.kobj, &platform_attribute_group); platform_device_unregister(platform_device); -- cgit v0.10.2 From fbe3d8942e8fd1e947e4d11a3e9e15675a1cac7e Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:44:53 +0000 Subject: eeepc-laptop: Remove redundant NULL checks The acpi device callbacks add, start, remove, suspend and resume can never be called with a NULL acpi_device. Each callsite in acpi/scan.c has to dereference the device in order to get the ops structure, e.g. struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_driver *acpi_drv = acpi_dev->driver; if (acpi_drv && acpi_drv->ops.suspend) return acpi_drv->ops.suspend(acpi_dev, state); Remove all checks for acpi_dev == NULL within these callbacks. Also remove the checks for acpi_driver_data(acpi_dev) == NULL. None of these checks could fail unless the driver does something strange (which none of them do), the acpi core did something terribly wrong, or we have a memory corruption issue. If this does happen then it's best to dereference the pointer and crash noisily. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 9130434..7dde47a 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -1255,8 +1255,6 @@ static int __devinit eeepc_hotk_add(struct acpi_device *device) struct device *dev; int result; - if (!device) - return -EINVAL; pr_notice(EEEPC_HOTK_NAME "\n"); ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); if (!ehotk) @@ -1343,9 +1341,6 @@ fail_platform_driver: static int eeepc_hotk_remove(struct acpi_device *device, int type) { - if (!device || !acpi_driver_data(device)) - return -EINVAL; - eeepc_backlight_exit(); eeepc_rfkill_exit(); eeepc_input_exit(); -- cgit v0.10.2 From 2adb8bd380314feb8170d58b3852cad2c374d20f Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:44:54 +0000 Subject: eeepc-laptop: Remove uneccesary acpi_disabled check acpi_bus_register_driver() already checks acpi_disabled, so acpi bus drivers don't need to. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 7dde47a..f5efe8d 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -1359,8 +1359,6 @@ static int __init eeepc_laptop_init(void) { int result; - if (acpi_disabled) - return -ENODEV; result = acpi_bus_register_driver(&eeepc_hotk_driver); if (result < 0) return result; -- cgit v0.10.2 From eacec3031d1f444a618cf2d023d52f088cf82a7e Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:44:55 +0000 Subject: eeepc-laptop: set acpi_driver.owner The owner field provides the link between drivers and modules in sysfs, but no ACPI driver was setting it. After setting the owner field, we can see which module provides which driver and vice versa by looking at /sys/bus/acpi/driver/*/module and /sys/module/*/drivers/acpi:*. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index f5efe8d..1c04c87 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -214,6 +214,7 @@ MODULE_DEVICE_TABLE(acpi, eeepc_device_ids); static struct acpi_driver eeepc_hotk_driver = { .name = EEEPC_HOTK_NAME, .class = EEEPC_HOTK_CLASS, + .owner = THIS_MODULE, .ids = eeepc_device_ids, .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { -- cgit v0.10.2 From 487186880d31821eaaba0cc1f27d5a581c56981d Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:44:56 +0000 Subject: eeepc-laptop: fix value of pwm1_enable to match documentation Documentation/hwmon/sysfs-interface tells us that automatic fan speed control should be represented by a value of 2 or above for pwm1_enable. Fix eeepc_get_fan_ctrl() to return 2 for automatic fan control. Setting "1" for manual control is already consistent with the documentation, so this remains unchanged. Let's preserve the ABI for this specific driver, so that writing "0" will still invoke automatic control. (The documentation says setting "0" should leave the fan at full speed all the time. This mode is not directly supported by our hardware. Full speed is rather noisy on my 701 and the automatic control has never used it. If you really want this e.g. to prolong the life of an EeePC used as a server, you can always use manual mode. hwmon has always been fairly machine-specific, and you're in a tiny minority (or elite :-). I'm sure you're smart enough to notice that the fan doesn't turn on to full speed when you try this mode, either by ear or checking fan_input1. We could even claim to be honouring the spirit of the documentation. "0" really means "safe mode". EeePCs default to automatic mode, ie that is what Asus will actually test. Since we do not provide any way to tamper with the temperature threshold, automatic mode _is_ the safe option). Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 1c04c87..6c982d6 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -935,7 +935,10 @@ static int eeepc_get_fan_ctrl(void) int value = 0; read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value); - return ((value & 0x02 ? 1 : 0)); + if (value & 0x02) + return 1; /* manual */ + else + return 2; /* automatic */ } static void eeepc_set_fan_ctrl(int manual) @@ -943,7 +946,7 @@ static void eeepc_set_fan_ctrl(int manual) int value = 0; read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value); - if (manual) + if (manual == 1) value |= 0x02; else value &= ~0x02; -- cgit v0.10.2 From 2b56f1c170fc6338a7d907d6a7132669f9ccdf62 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:44:57 +0000 Subject: eeepc-laptop: fix led initialization order Create the workqueue thread used by tpd_led_set() *before* we register the led device. (And vice versa for unregistration). Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 6c982d6..ac45faf 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -1074,10 +1074,10 @@ static void eeepc_hwmon_exit(void) static void eeepc_led_exit(void) { - if (led_workqueue) - destroy_workqueue(led_workqueue); if (tpd_led.dev) led_classdev_unregister(&tpd_led); + if (led_workqueue) + destroy_workqueue(led_workqueue); } static int eeepc_new_rfkill(struct rfkill **rfkill, @@ -1243,14 +1243,14 @@ static int eeepc_led_init(struct device *dev) if (get_acpi(CM_ASL_TPD) == -ENODEV) return 0; - rv = led_classdev_register(dev, &tpd_led); - if (rv) - return rv; - led_workqueue = create_singlethread_workqueue("led_workqueue"); if (!led_workqueue) return -ENOMEM; + rv = led_classdev_register(dev, &tpd_led); + if (rv) + return rv; + return 0; } -- cgit v0.10.2 From dc56ad9b49d20e38bb9745bf3beca84291b21a51 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:44:58 +0000 Subject: eeepc-laptop: fix potential leak (led_init() failure) If we bail out because we can't create the led class device, we need to ensure the led workqueue is cleaned up. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index ac45faf..8b686b5 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -1248,8 +1248,10 @@ static int eeepc_led_init(struct device *dev) return -ENOMEM; rv = led_classdev_register(dev, &tpd_led); - if (rv) + if (rv) { + destroy_workqueue(led_workqueue); return rv; + } return 0; } -- cgit v0.10.2 From 13f70029daa3cd7f9983e4aec82f32939b1a6e6a Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:44:59 +0000 Subject: eeepc-laptop: fix set_acpi() to return non-zero on failure If the control method does not exist, return -ENODEV for consistency with get_acpi() Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 8b686b5..abd7389 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -289,26 +289,30 @@ static int read_acpi_int(acpi_handle handle, const char *method, int *val) static int set_acpi(int cm, int value) { - if (ehotk->cm_supported & (0x1 << cm)) { - const char *method = cm_setv[cm]; - if (method == NULL) - return -ENODEV; - if (write_acpi_int(ehotk->handle, method, value, NULL)) - pr_warning("Error writing %s\n", method); - } + const char *method = cm_setv[cm]; + + if (method == NULL) + return -ENODEV; + if ((ehotk->cm_supported & (0x1 << cm)) == 0) + return -ENODEV; + + if (write_acpi_int(ehotk->handle, method, value, NULL)) + pr_warning("Error writing %s\n", method); return 0; } static int get_acpi(int cm) { - int value = -ENODEV; - if ((ehotk->cm_supported & (0x1 << cm))) { - const char *method = cm_getv[cm]; - if (method == NULL) - return -ENODEV; - if (read_acpi_int(ehotk->handle, method, &value)) - pr_warning("Error reading %s\n", method); - } + const char *method = cm_getv[cm]; + int value; + + if (method == NULL) + return -ENODEV; + if ((ehotk->cm_supported & (0x1 << cm)) == 0) + return -ENODEV; + + if (read_acpi_int(ehotk->handle, method, &value)) + pr_warning("Error reading %s\n", method); return value; } -- cgit v0.10.2 From a2a1d36c78e90977e4ded9a20a7d8d27d84b13e4 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:45:00 +0000 Subject: eeepc-laptop: remove redundant NULL checks eeepc_hotk_notify() cannot be called with ehotk == NULL or bd == NULL. We check both variables for allocation failure and would bail out before the notifier is registered. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index abd7389..f6b7796 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -662,12 +662,11 @@ static int notify_brn(void) { /* returns the *previous* brightness, or -1 */ struct backlight_device *bd = eeepc_backlight_device; - if (bd) { - int old = bd->props.brightness; - backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY); - return old; - } - return -1; + int old = bd->props.brightness; + + backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY); + + return old; } static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, @@ -741,8 +740,6 @@ static void eeepc_hotk_notify(struct acpi_device *device, u32 event) u16 count; int brn = -ENODEV; - if (!ehotk) - return; if (event > ACPI_MAX_SYS_NOTIFY) return; if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) @@ -753,21 +750,20 @@ static void eeepc_hotk_notify(struct acpi_device *device, u32 event) dev_name(&ehotk->device->dev), event, count); if (ehotk->inputdev) { - if (brn != -ENODEV) { - /* brightness-change events need special - * handling for conversion to key events - */ - if (brn < 0) - brn = event; - else - brn += NOTIFY_BRN_MIN; - if (event < brn) - event = NOTIFY_BRN_MIN; /* brightness down */ - else if (event > brn) - event = NOTIFY_BRN_MIN + 2; /* ... up */ - else - event = NOTIFY_BRN_MIN + 1; /* ... unchanged */ - } + /* brightness-change events need special + * handling for conversion to key events + */ + if (brn < 0) + brn = event; + else + brn += NOTIFY_BRN_MIN; + if (event < brn) + event = NOTIFY_BRN_MIN; /* brightness down */ + else if (event > brn) + event = NOTIFY_BRN_MIN + 2; /* ... up */ + else + event = NOTIFY_BRN_MIN + 1; /* ... unchanged */ + key = eepc_get_entry_by_scancode(event); if (key) { switch (key->type) { -- cgit v0.10.2 From 951037ea1cf4dc323906fd45d55ff015fd295d0c Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:45:01 +0000 Subject: eeepc-laptop: no need to check argument of set_brightness() We already tell the backlight class our maximum brightness value; it will validate the user requested values for us. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index f6b7796..9f33e51 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -326,7 +326,6 @@ static int read_brightness(struct backlight_device *bd) static int set_brightness(struct backlight_device *bd, int value) { - value = max(0, min(15, value)); return set_acpi(CM_ASL_PANELBRIGHT, value); } -- cgit v0.10.2 From 6b188a7b218cb33d918e72f24995341f949297d2 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:45:02 +0000 Subject: eeepc-laptop: simplify acpi initialization We don't need to store init_flags after using them. And we don't use the result of INIT, so we don't need to allocate a buffer for it. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 9f33e51..50ceaaf 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -136,7 +136,6 @@ struct eeepc_hotk { acpi_handle handle; /* the handle of the hotk device */ u32 cm_supported; /* the control methods supported by this BIOS */ - uint init_flag; /* Init flags */ u16 event_count[128]; /* count for each event */ struct input_dev *inputdev; u16 *keycode_map; @@ -256,8 +255,7 @@ MODULE_LICENSE("GPL"); /* * ACPI Helpers */ -static int write_acpi_int(acpi_handle handle, const char *method, int val, - struct acpi_buffer *output) +static int write_acpi_int(acpi_handle handle, const char *method, int val) { struct acpi_object_list params; union acpi_object in_obj; @@ -268,7 +266,7 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val, in_obj.type = ACPI_TYPE_INTEGER; in_obj.integer.value = val; - status = acpi_evaluate_object(handle, (char *)method, ¶ms, output); + status = acpi_evaluate_object(handle, (char *)method, ¶ms, NULL); return (status == AE_OK ? 0 : -1); } @@ -296,7 +294,7 @@ static int set_acpi(int cm, int value) if ((ehotk->cm_supported & (0x1 << cm)) == 0) return -ENODEV; - if (write_acpi_int(ehotk->handle, method, value, NULL)) + if (write_acpi_int(ehotk->handle, method, value)) pr_warning("Error writing %s\n", method); return 0; } @@ -624,36 +622,36 @@ static void cmsg_quirks(void) cmsg_quirk(CM_ASL_TPD, "TPD"); } -static int eeepc_hotk_check(void) +static int eeepc_hotk_init(void) { - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + unsigned int init_flags; int result; result = acpi_bus_get_status(ehotk->device); if (result) return result; - if (ehotk->device->status.present) { - if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag, - &buffer)) { - pr_err("Hotkey initialization failed\n"); - return -ENODEV; - } else { - pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag); - } - /* get control methods supported */ - if (read_acpi_int(ehotk->handle, "CMSG" - , &ehotk->cm_supported)) { - pr_err("Get control methods supported failed\n"); - return -ENODEV; - } else { - cmsg_quirks(); - pr_info("Get control methods supported: 0x%x\n", - ehotk->cm_supported); - } - } else { + if (!ehotk->device->status.present) { pr_err("Hotkey device not present, aborting\n"); - return -EINVAL; + return -ENODEV; } + + init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH; + pr_notice("Hotkey init flags 0x%x\n", init_flags); + + if (write_acpi_int(ehotk->handle, "INIT", init_flags)) { + pr_err("Hotkey initialization failed\n"); + return -ENODEV; + } + + /* get control methods supported */ + if (read_acpi_int(ehotk->handle, "CMSG", + &ehotk->cm_supported)) { + pr_err("Get control methods supported failed\n"); + return -ENODEV; + } + cmsg_quirks(); + pr_info("Get control methods supported: 0x%x\n", ehotk->cm_supported); + return 0; } @@ -1264,14 +1262,13 @@ static int __devinit eeepc_hotk_add(struct acpi_device *device) ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); if (!ehotk) return -ENOMEM; - ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH; ehotk->handle = device->handle; strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME); strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS); device->driver_data = ehotk; ehotk->device = device; - result = eeepc_hotk_check(); + result = eeepc_hotk_init(); if (result) goto fail_platform_driver; eeepc_enable_camera(); -- cgit v0.10.2 From 463b4e474ed0905ffc27ee347648739dbfb03acc Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:45:03 +0000 Subject: eeepc-laptop: simplify how the hwmon device reads values from the EC The hwmon device uses ec_write() to write values to the EC. So for consistency it should use ec_read() to read values. The extra layers of indirection used did not add any value. This may mean we no longer take the ACPI global lock for such reads (if the EC operation region requires the lock and the EC does not). But there is no point locking each one-byte read individually, when write operations do not use the lock at all. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 50ceaaf..04a59d3 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -118,14 +118,14 @@ static const char *cm_setv[] = { NULL, NULL, "PBPS", "TPDS" }; -#define EEEPC_EC "\\_SB.PCI0.SBRG.EC0." +#define EEEPC_EC_SC00 0x61 +#define EEEPC_EC_FAN_PWM (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */ +#define EEEPC_EC_FAN_HRPM (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */ +#define EEEPC_EC_FAN_LRPM (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */ + +#define EEEPC_EC_SFB0 0xD0 +#define EEEPC_EC_FAN_CTRL (EEEPC_EC_SFB0 + 3) /* Byte containing SF25 */ -#define EEEPC_EC_FAN_PWM EEEPC_EC "SC02" /* Fan PWM duty cycle (%) */ -#define EEEPC_EC_SC02 0x63 -#define EEEPC_EC_FAN_HRPM EEEPC_EC "SC05" /* High byte, fan speed (RPM) */ -#define EEEPC_EC_FAN_LRPM EEEPC_EC "SC06" /* Low byte, fan speed (RPM) */ -#define EEEPC_EC_FAN_CTRL EEEPC_EC "SFB3" /* Byte containing SF25 */ -#define EEEPC_EC_SFB3 0xD3 /* * This is the main structure, we can use it to store useful information @@ -903,35 +903,34 @@ static int eeepc_hotk_restore(struct device *device) */ static int eeepc_get_fan_pwm(void) { - int value = 0; + u8 value = 0; - read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value); - value = value * 255 / 100; - return (value); + ec_read(EEEPC_EC_FAN_PWM, &value); + return value * 255 / 100; } static void eeepc_set_fan_pwm(int value) { value = SENSORS_LIMIT(value, 0, 255); value = value * 100 / 255; - ec_write(EEEPC_EC_SC02, value); + ec_write(EEEPC_EC_FAN_PWM, value); } static int eeepc_get_fan_rpm(void) { - int high = 0; - int low = 0; + u8 high = 0; + u8 low = 0; - read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high); - read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low); - return (high << 8 | low); + ec_read(EEEPC_EC_FAN_HRPM, &high); + ec_read(EEEPC_EC_FAN_LRPM, &low); + return high << 8 | low; } static int eeepc_get_fan_ctrl(void) { - int value = 0; + u8 value = 0; - read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value); + ec_read(EEEPC_EC_FAN_CTRL, &value); if (value & 0x02) return 1; /* manual */ else @@ -940,14 +939,14 @@ static int eeepc_get_fan_ctrl(void) static void eeepc_set_fan_ctrl(int manual) { - int value = 0; + u8 value = 0; - read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value); + ec_read(EEEPC_EC_FAN_CTRL, &value); if (manual == 1) value |= 0x02; else value &= ~0x02; - ec_write(EEEPC_EC_SFB3, value); + ec_write(EEEPC_EC_FAN_CTRL, value); } static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count) -- cgit v0.10.2 From bf9598bcd5a73385ced7880ea09998a545e03dd8 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:45:04 +0000 Subject: eeepc-laptop: refactor notifications Separate out input_notify(), in a similar way to how notify_brn() is already separated. This will allow all the functions which refer to the input device to be grouped together. This includes a small behaviour change - we now synthesize brightness up/down key events even if the brightness is already at the maximum/minimum value. This is consistent with the new uevent interface. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 04a59d3..b4eacb6 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -655,9 +655,8 @@ static int eeepc_hotk_init(void) return 0; } -static int notify_brn(void) +static int eeepc_backlight_notify(void) { - /* returns the *previous* brightness, or -1 */ struct backlight_device *bd = eeepc_backlight_device; int old = bd->props.brightness; @@ -731,50 +730,58 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) eeepc_rfkill_hotplug(); } -static void eeepc_hotk_notify(struct acpi_device *device, u32 event) +static void eeepc_input_notify(int event) { static struct key_entry *key; + + key = eepc_get_entry_by_scancode(event); + if (key) { + switch (key->type) { + case KE_KEY: + input_report_key(ehotk->inputdev, key->keycode, + 1); + input_sync(ehotk->inputdev); + input_report_key(ehotk->inputdev, key->keycode, + 0); + input_sync(ehotk->inputdev); + break; + } + } +} + +static void eeepc_hotk_notify(struct acpi_device *device, u32 event) +{ u16 count; - int brn = -ENODEV; if (event > ACPI_MAX_SYS_NOTIFY) return; - if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) - brn = notify_brn(); count = ehotk->event_count[event % 128]++; acpi_bus_generate_proc_event(ehotk->device, event, count); acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, dev_name(&ehotk->device->dev), event, count); - if (ehotk->inputdev) { - /* brightness-change events need special - * handling for conversion to key events - */ - if (brn < 0) - brn = event; - else - brn += NOTIFY_BRN_MIN; - if (event < brn) + + if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) { + int old_brightness, new_brightness; + + /* Update backlight device. */ + old_brightness = eeepc_backlight_notify(); + + /* Convert brightness event to keypress (obsolescent hack). */ + new_brightness = event - NOTIFY_BRN_MIN; + + if (new_brightness < old_brightness) { event = NOTIFY_BRN_MIN; /* brightness down */ - else if (event > brn) - event = NOTIFY_BRN_MIN + 2; /* ... up */ - else - event = NOTIFY_BRN_MIN + 1; /* ... unchanged */ - - key = eepc_get_entry_by_scancode(event); - if (key) { - switch (key->type) { - case KE_KEY: - input_report_key(ehotk->inputdev, key->keycode, - 1); - input_sync(ehotk->inputdev); - input_report_key(ehotk->inputdev, key->keycode, - 0); - input_sync(ehotk->inputdev); - break; - } + } else if (new_brightness > old_brightness) { + event = NOTIFY_BRN_MAX; /* brightness up */ + } else { + /* + * no change in brightness - already at min/max, + * event will be desired value (or else ignored). + */ } } + eeepc_input_notify(event); } static int eeepc_register_rfkill_notifier(char *node) -- cgit v0.10.2 From 22072e92a038d2ee5848b3e54499ecab730c722c Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:45:05 +0000 Subject: eeepc-laptop: move platform driver registration out of eeepc_hotk_add() Strictly speaking we should register the platform driver exactly once, whether there are zero, one, or multiple matching acpi devices. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index b4eacb6..3f9b286 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -1276,13 +1276,10 @@ static int __devinit eeepc_hotk_add(struct acpi_device *device) result = eeepc_hotk_init(); if (result) - goto fail_platform_driver; + goto fail_platform_device1; eeepc_enable_camera(); /* Register platform stuff */ - result = platform_driver_register(&platform_driver); - if (result) - goto fail_platform_driver; platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1); if (!platform_device) { result = -ENOMEM; @@ -1340,8 +1337,6 @@ fail_sysfs: fail_platform_device2: platform_device_put(platform_device); fail_platform_device1: - platform_driver_unregister(&platform_driver); -fail_platform_driver: kfree(ehotk); return result; @@ -1357,7 +1352,6 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) sysfs_remove_group(&platform_device->dev.kobj, &platform_attribute_group); platform_device_unregister(platform_device); - platform_driver_unregister(&platform_driver); kfree(ehotk); return 0; @@ -1367,19 +1361,30 @@ static int __init eeepc_laptop_init(void) { int result; - result = acpi_bus_register_driver(&eeepc_hotk_driver); + result = platform_driver_register(&platform_driver); if (result < 0) return result; + + result = acpi_bus_register_driver(&eeepc_hotk_driver); + if (result < 0) + goto fail_acpi_driver; if (!ehotk) { - acpi_bus_unregister_driver(&eeepc_hotk_driver); - return -ENODEV; + result = -ENODEV; + goto fail_no_device; } return 0; + +fail_no_device: + acpi_bus_unregister_driver(&eeepc_hotk_driver); +fail_acpi_driver: + platform_driver_unregister(&platform_driver); + return result; } static void __exit eeepc_laptop_exit(void) { acpi_bus_unregister_driver(&eeepc_hotk_driver); + platform_driver_unregister(&platform_driver); } module_init(eeepc_laptop_init); -- cgit v0.10.2 From 9db106be554288df5a0a7c56c20257a4391b9738 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:45:06 +0000 Subject: eeepc-laptop: move platform device initialisation to a separate function This moves the sysfs_create_group() call just after the declaration of the platform device attributes. It should make it easier to examine the implementation of the platform device attributes in isolation from the rest of the code. (The next commit will apply this pattern to all of the sub-devices as well). Signed-off-by: Alan Jenkins diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 3f9b286..f4f6796 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -509,6 +509,38 @@ static struct attribute_group platform_attribute_group = { .attrs = platform_attributes }; +static int eeepc_platform_init(void) +{ + int result; + + platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1); + if (!platform_device) + return -ENOMEM; + + result = platform_device_add(platform_device); + if (result) + goto fail_platform_device; + + result = sysfs_create_group(&platform_device->dev.kobj, + &platform_attribute_group); + if (result) + goto fail_sysfs; + return 0; + +fail_sysfs: + platform_device_del(platform_device); +fail_platform_device: + platform_device_put(platform_device); + return result; +} + +static void eeepc_platform_exit(void) +{ + sysfs_remove_group(&platform_device->dev.kobj, + &platform_attribute_group); + platform_device_unregister(platform_device); +} + /* * LEDs */ @@ -1276,22 +1308,12 @@ static int __devinit eeepc_hotk_add(struct acpi_device *device) result = eeepc_hotk_init(); if (result) - goto fail_platform_device1; + goto fail_platform; eeepc_enable_camera(); - /* Register platform stuff */ - platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1); - if (!platform_device) { - result = -ENOMEM; - goto fail_platform_device1; - } - result = platform_device_add(platform_device); + result = eeepc_platform_init(); if (result) - goto fail_platform_device2; - result = sysfs_create_group(&platform_device->dev.kobj, - &platform_attribute_group); - if (result) - goto fail_sysfs; + goto fail_platform; dev = &platform_device->dev; @@ -1300,8 +1322,7 @@ static int __devinit eeepc_hotk_add(struct acpi_device *device) if (result) goto fail_backlight; } else - pr_info("Backlight controlled by ACPI video " - "driver\n"); + pr_info("Backlight controlled by ACPI video driver\n"); result = eeepc_input_init(dev); if (result) @@ -1330,13 +1351,8 @@ fail_hwmon: fail_input: eeepc_backlight_exit(); fail_backlight: - sysfs_remove_group(&platform_device->dev.kobj, - &platform_attribute_group); -fail_sysfs: - platform_device_del(platform_device); -fail_platform_device2: - platform_device_put(platform_device); -fail_platform_device1: + eeepc_platform_exit(); +fail_platform: kfree(ehotk); return result; @@ -1349,9 +1365,7 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) eeepc_input_exit(); eeepc_hwmon_exit(); eeepc_led_exit(); - sysfs_remove_group(&platform_device->dev.kobj, - &platform_attribute_group); - platform_device_unregister(platform_device); + eeepc_platform_exit(); kfree(ehotk); return 0; -- cgit v0.10.2 From 52bbe3c7b413d656833686f9f08e5dcab3786eeb Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:45:07 +0000 Subject: eeepc-laptop: code movement Move e.g. backlight_init() and backlight_exit() together along with the other backlight functions, instead of grouping init() and exit() functions. Move e.g. backlight_ops to follow the functions it refers to, and remove the forward declarations. The code itself should remain unchanged. The eeepc-laptop driver implements a number of interfaces like the backlight class driver. This change makes it easier to examine the implementation of one interface at at a time, without having to search through the file to find init() and exit() functions etc. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index f4f6796..f457587 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -44,6 +44,9 @@ #define EEEPC_HOTK_DEVICE_NAME "Hotkey" #define EEEPC_HOTK_HID "ASUS010" +MODULE_AUTHOR("Corentin Chary, Eric Cooper"); +MODULE_DESCRIPTION(EEEPC_HOTK_NAME); +MODULE_LICENSE("GPL"); /* * Definitions for Asus EeePC @@ -118,57 +121,6 @@ static const char *cm_setv[] = { NULL, NULL, "PBPS", "TPDS" }; -#define EEEPC_EC_SC00 0x61 -#define EEEPC_EC_FAN_PWM (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */ -#define EEEPC_EC_FAN_HRPM (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */ -#define EEEPC_EC_FAN_LRPM (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */ - -#define EEEPC_EC_SFB0 0xD0 -#define EEEPC_EC_FAN_CTRL (EEEPC_EC_SFB0 + 3) /* Byte containing SF25 */ - - -/* - * This is the main structure, we can use it to store useful information - * about the hotk device - */ -struct eeepc_hotk { - struct acpi_device *device; /* the device we are in */ - acpi_handle handle; /* the handle of the hotk device */ - u32 cm_supported; /* the control methods supported - by this BIOS */ - u16 event_count[128]; /* count for each event */ - struct input_dev *inputdev; - u16 *keycode_map; - struct rfkill *wlan_rfkill; - struct rfkill *bluetooth_rfkill; - struct rfkill *wwan3g_rfkill; - struct rfkill *wimax_rfkill; - struct hotplug_slot *hotplug_slot; - struct mutex hotplug_lock; -}; - -/* The actual device the driver binds to */ -static struct eeepc_hotk *ehotk; - -/* Platform device/driver */ -static int eeepc_hotk_thaw(struct device *device); -static int eeepc_hotk_restore(struct device *device); - -static struct dev_pm_ops eeepc_pm_ops = { - .thaw = eeepc_hotk_thaw, - .restore = eeepc_hotk_restore, -}; - -static struct platform_driver platform_driver = { - .driver = { - .name = EEEPC_HOTK_FILE, - .owner = THIS_MODULE, - .pm = &eeepc_pm_ops, - } -}; - -static struct platform_device *platform_device; - struct key_entry { char type; u8 code; @@ -189,48 +141,40 @@ static struct key_entry eeepc_keymap[] = { {KE_KEY, 0x1b, KEY_ZOOM }, {KE_KEY, 0x1c, KEY_PROG2 }, {KE_KEY, 0x1d, KEY_PROG3 }, - {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN }, - {KE_KEY, NOTIFY_BRN_MIN + 2, KEY_BRIGHTNESSUP }, + {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN }, + {KE_KEY, NOTIFY_BRN_MAX, KEY_BRIGHTNESSUP }, {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, {KE_END, 0}, }; + /* - * The hotkey driver declaration + * This is the main structure, we can use it to store useful information + * about the hotk device */ -static int eeepc_hotk_add(struct acpi_device *device); -static int eeepc_hotk_remove(struct acpi_device *device, int type); -static void eeepc_hotk_notify(struct acpi_device *device, u32 event); - -static const struct acpi_device_id eeepc_device_ids[] = { - {EEEPC_HOTK_HID, 0}, - {"", 0}, -}; -MODULE_DEVICE_TABLE(acpi, eeepc_device_ids); - -static struct acpi_driver eeepc_hotk_driver = { - .name = EEEPC_HOTK_NAME, - .class = EEEPC_HOTK_CLASS, - .owner = THIS_MODULE, - .ids = eeepc_device_ids, - .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, - .ops = { - .add = eeepc_hotk_add, - .remove = eeepc_hotk_remove, - .notify = eeepc_hotk_notify, - }, +struct eeepc_hotk { + struct acpi_device *device; /* the device we are in */ + acpi_handle handle; /* the handle of the hotk device */ + u32 cm_supported; /* the control methods supported + by this BIOS */ + u16 event_count[128]; /* count for each event */ + struct input_dev *inputdev; + u16 *keycode_map; + struct rfkill *wlan_rfkill; + struct rfkill *bluetooth_rfkill; + struct rfkill *wwan3g_rfkill; + struct rfkill *wimax_rfkill; + struct hotplug_slot *hotplug_slot; + struct mutex hotplug_lock; }; -/* PCI hotplug ops */ -static int eeepc_get_adapter_status(struct hotplug_slot *slot, u8 *value); +/* The actual device the driver binds to */ +static struct eeepc_hotk *ehotk; -static struct hotplug_slot_ops eeepc_hotplug_slot_ops = { - .owner = THIS_MODULE, - .get_adapter_status = eeepc_get_adapter_status, - .get_power_status = eeepc_get_adapter_status, -}; +/* The platform device */ +static struct platform_device *platform_device; /* The backlight device /sys/class/backlight */ static struct backlight_device *eeepc_backlight_device; @@ -238,19 +182,6 @@ static struct backlight_device *eeepc_backlight_device; /* The hwmon device */ static struct device *eeepc_hwmon_device; -/* - * The backlight class declaration - */ -static int read_brightness(struct backlight_device *bd); -static int update_bl_status(struct backlight_device *bd); -static struct backlight_ops eeepcbl_ops = { - .get_brightness = read_brightness, - .update_status = update_bl_status, -}; - -MODULE_AUTHOR("Corentin Chary, Eric Cooper"); -MODULE_DESCRIPTION(EEEPC_HOTK_NAME); -MODULE_LICENSE("GPL"); /* * ACPI Helpers @@ -315,55 +246,6 @@ static int get_acpi(int cm) } /* - * Backlight - */ -static int read_brightness(struct backlight_device *bd) -{ - return get_acpi(CM_ASL_PANELBRIGHT); -} - -static int set_brightness(struct backlight_device *bd, int value) -{ - return set_acpi(CM_ASL_PANELBRIGHT, value); -} - -static int update_bl_status(struct backlight_device *bd) -{ - return set_brightness(bd, bd->props.brightness); -} - -/* - * Rfkill helpers - */ - -static bool eeepc_wlan_rfkill_blocked(void) -{ - if (get_acpi(CM_ASL_WLAN) == 1) - return false; - return true; -} - -static int eeepc_rfkill_set(void *data, bool blocked) -{ - unsigned long asl = (unsigned long)data; - return set_acpi(asl, !blocked); -} - -static const struct rfkill_ops eeepc_rfkill_ops = { - .set_block = eeepc_rfkill_set, -}; - -static void __devinit eeepc_enable_camera(void) -{ - /* - * If the following call to set_acpi() fails, it's because there's no - * camera so we can ignore the error. - */ - if (get_acpi(CM_ASL_CAMERA) == 0) - set_acpi(CM_ASL_CAMERA, 1); -} - -/* * Sys helpers */ static int parse_arg(const char *buf, unsigned long count, int *val) @@ -574,248 +456,97 @@ static struct led_classdev tpd_led = { .max_brightness = 1 }; -/* - * Hotkey functions - */ -static struct key_entry *eepc_get_entry_by_scancode(int code) +static int eeepc_led_init(struct device *dev) { - struct key_entry *key; - - for (key = eeepc_keymap; key->type != KE_END; key++) - if (code == key->code) - return key; + int rv; - return NULL; -} + if (get_acpi(CM_ASL_TPD) == -ENODEV) + return 0; -static struct key_entry *eepc_get_entry_by_keycode(int code) -{ - struct key_entry *key; + led_workqueue = create_singlethread_workqueue("led_workqueue"); + if (!led_workqueue) + return -ENOMEM; - for (key = eeepc_keymap; key->type != KE_END; key++) - if (code == key->keycode && key->type == KE_KEY) - return key; + rv = led_classdev_register(dev, &tpd_led); + if (rv) { + destroy_workqueue(led_workqueue); + return rv; + } - return NULL; + return 0; } -static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode) +static void eeepc_led_exit(void) { - struct key_entry *key = eepc_get_entry_by_scancode(scancode); + if (tpd_led.dev) + led_classdev_unregister(&tpd_led); + if (led_workqueue) + destroy_workqueue(led_workqueue); +} - if (key && key->type == KE_KEY) { - *keycode = key->keycode; - return 0; - } - return -EINVAL; +/* + * PCI hotplug (for wlan rfkill) + */ +static bool eeepc_wlan_rfkill_blocked(void) +{ + if (get_acpi(CM_ASL_WLAN) == 1) + return false; + return true; } -static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode) +static void eeepc_rfkill_hotplug(void) { - struct key_entry *key; - int old_keycode; + struct pci_dev *dev; + struct pci_bus *bus; + bool blocked = eeepc_wlan_rfkill_blocked(); - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; + if (ehotk->wlan_rfkill) + rfkill_set_sw_state(ehotk->wlan_rfkill, blocked); - key = eepc_get_entry_by_scancode(scancode); - if (key && key->type == KE_KEY) { - old_keycode = key->keycode; - key->keycode = keycode; - set_bit(keycode, dev->keybit); - if (!eepc_get_entry_by_keycode(old_keycode)) - clear_bit(old_keycode, dev->keybit); - return 0; + mutex_lock(&ehotk->hotplug_lock); + + if (ehotk->hotplug_slot) { + bus = pci_find_bus(0, 1); + if (!bus) { + pr_warning("Unable to find PCI bus 1?\n"); + goto out_unlock; + } + + if (!blocked) { + dev = pci_get_slot(bus, 0); + if (dev) { + /* Device already present */ + pci_dev_put(dev); + goto out_unlock; + } + dev = pci_scan_single_device(bus, 0); + if (dev) { + pci_bus_assign_resources(bus); + if (pci_bus_add_device(dev)) + pr_err("Unable to hotplug wifi\n"); + } + } else { + dev = pci_get_slot(bus, 0); + if (dev) { + pci_remove_bus_device(dev); + pci_dev_put(dev); + } + } } - return -EINVAL; +out_unlock: + mutex_unlock(&ehotk->hotplug_lock); } -static void cmsg_quirk(int cm, const char *name) +static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) { - int dummy; - - /* Some BIOSes do not report cm although it is avaliable. - Check if cm_getv[cm] works and, if yes, assume cm should be set. */ - if (!(ehotk->cm_supported & (1 << cm)) - && !read_acpi_int(ehotk->handle, cm_getv[cm], &dummy)) { - pr_info("%s (%x) not reported by BIOS," - " enabling anyway\n", name, 1 << cm); - ehotk->cm_supported |= 1 << cm; - } -} - -static void cmsg_quirks(void) -{ - cmsg_quirk(CM_ASL_LID, "LID"); - cmsg_quirk(CM_ASL_TYPE, "TYPE"); - cmsg_quirk(CM_ASL_PANELPOWER, "PANELPOWER"); - cmsg_quirk(CM_ASL_TPD, "TPD"); -} - -static int eeepc_hotk_init(void) -{ - unsigned int init_flags; - int result; - - result = acpi_bus_get_status(ehotk->device); - if (result) - return result; - if (!ehotk->device->status.present) { - pr_err("Hotkey device not present, aborting\n"); - return -ENODEV; - } - - init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH; - pr_notice("Hotkey init flags 0x%x\n", init_flags); - - if (write_acpi_int(ehotk->handle, "INIT", init_flags)) { - pr_err("Hotkey initialization failed\n"); - return -ENODEV; - } - - /* get control methods supported */ - if (read_acpi_int(ehotk->handle, "CMSG", - &ehotk->cm_supported)) { - pr_err("Get control methods supported failed\n"); - return -ENODEV; - } - cmsg_quirks(); - pr_info("Get control methods supported: 0x%x\n", ehotk->cm_supported); - - return 0; -} - -static int eeepc_backlight_notify(void) -{ - struct backlight_device *bd = eeepc_backlight_device; - int old = bd->props.brightness; - - backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY); - - return old; -} - -static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, - u8 *value) -{ - int val = get_acpi(CM_ASL_WLAN); - - if (val == 1 || val == 0) - *value = val; - else - return -EINVAL; - - return 0; -} - -static void eeepc_rfkill_hotplug(void) -{ - struct pci_dev *dev; - struct pci_bus *bus; - bool blocked = eeepc_wlan_rfkill_blocked(); - - if (ehotk->wlan_rfkill) - rfkill_set_sw_state(ehotk->wlan_rfkill, blocked); - - mutex_lock(&ehotk->hotplug_lock); - - if (ehotk->hotplug_slot) { - bus = pci_find_bus(0, 1); - if (!bus) { - pr_warning("Unable to find PCI bus 1?\n"); - goto out_unlock; - } - - if (!blocked) { - dev = pci_get_slot(bus, 0); - if (dev) { - /* Device already present */ - pci_dev_put(dev); - goto out_unlock; - } - dev = pci_scan_single_device(bus, 0); - if (dev) { - pci_bus_assign_resources(bus); - if (pci_bus_add_device(dev)) - pr_err("Unable to hotplug wifi\n"); - } - } else { - dev = pci_get_slot(bus, 0); - if (dev) { - pci_remove_bus_device(dev); - pci_dev_put(dev); - } - } - } - -out_unlock: - mutex_unlock(&ehotk->hotplug_lock); -} - -static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) -{ - if (event != ACPI_NOTIFY_BUS_CHECK) - return; + if (event != ACPI_NOTIFY_BUS_CHECK) + return; eeepc_rfkill_hotplug(); } -static void eeepc_input_notify(int event) -{ - static struct key_entry *key; - - key = eepc_get_entry_by_scancode(event); - if (key) { - switch (key->type) { - case KE_KEY: - input_report_key(ehotk->inputdev, key->keycode, - 1); - input_sync(ehotk->inputdev); - input_report_key(ehotk->inputdev, key->keycode, - 0); - input_sync(ehotk->inputdev); - break; - } - } -} - -static void eeepc_hotk_notify(struct acpi_device *device, u32 event) -{ - u16 count; - - if (event > ACPI_MAX_SYS_NOTIFY) - return; - count = ehotk->event_count[event % 128]++; - acpi_bus_generate_proc_event(ehotk->device, event, count); - acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, - dev_name(&ehotk->device->dev), event, - count); - - if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) { - int old_brightness, new_brightness; - - /* Update backlight device. */ - old_brightness = eeepc_backlight_notify(); - - /* Convert brightness event to keypress (obsolescent hack). */ - new_brightness = event - NOTIFY_BRN_MIN; - - if (new_brightness < old_brightness) { - event = NOTIFY_BRN_MIN; /* brightness down */ - } else if (new_brightness > old_brightness) { - event = NOTIFY_BRN_MAX; /* brightness up */ - } else { - /* - * no change in brightness - already at min/max, - * event will be desired value (or else ignored). - */ - } - } - eeepc_input_notify(event); -} - static int eeepc_register_rfkill_notifier(char *node) { acpi_status status = AE_OK; @@ -853,12 +584,31 @@ static void eeepc_unregister_rfkill_notifier(char *node) } } +static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, + u8 *value) +{ + int val = get_acpi(CM_ASL_WLAN); + + if (val == 1 || val == 0) + *value = val; + else + return -EINVAL; + + return 0; +} + static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot) { kfree(hotplug_slot->info); kfree(hotplug_slot); } +static struct hotplug_slot_ops eeepc_hotplug_slot_ops = { + .owner = THIS_MODULE, + .get_adapter_status = eeepc_get_adapter_status, + .get_power_status = eeepc_get_adapter_status, +}; + static int eeepc_setup_pci_hotplug(void) { int ret = -ENOMEM; @@ -901,6 +651,140 @@ error_slot: return ret; } +/* + * Rfkill devices + */ +static int eeepc_rfkill_set(void *data, bool blocked) +{ + unsigned long asl = (unsigned long)data; + return set_acpi(asl, !blocked); +} + +static const struct rfkill_ops eeepc_rfkill_ops = { + .set_block = eeepc_rfkill_set, +}; + +static int eeepc_new_rfkill(struct rfkill **rfkill, + const char *name, struct device *dev, + enum rfkill_type type, int cm) +{ + int result; + + result = get_acpi(cm); + if (result < 0) + return result; + + *rfkill = rfkill_alloc(name, dev, type, + &eeepc_rfkill_ops, (void *)(unsigned long)cm); + + if (!*rfkill) + return -EINVAL; + + rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1); + result = rfkill_register(*rfkill); + if (result) { + rfkill_destroy(*rfkill); + *rfkill = NULL; + return result; + } + return 0; +} + +static void eeepc_rfkill_exit(void) +{ + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P5"); + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); + if (ehotk->wlan_rfkill) { + rfkill_unregister(ehotk->wlan_rfkill); + rfkill_destroy(ehotk->wlan_rfkill); + ehotk->wlan_rfkill = NULL; + } + /* + * Refresh pci hotplug in case the rfkill state was changed after + * eeepc_unregister_rfkill_notifier() + */ + eeepc_rfkill_hotplug(); + if (ehotk->hotplug_slot) + pci_hp_deregister(ehotk->hotplug_slot); + + if (ehotk->bluetooth_rfkill) { + rfkill_unregister(ehotk->bluetooth_rfkill); + rfkill_destroy(ehotk->bluetooth_rfkill); + ehotk->bluetooth_rfkill = NULL; + } + if (ehotk->wwan3g_rfkill) { + rfkill_unregister(ehotk->wwan3g_rfkill); + rfkill_destroy(ehotk->wwan3g_rfkill); + ehotk->wwan3g_rfkill = NULL; + } + if (ehotk->wimax_rfkill) { + rfkill_unregister(ehotk->wimax_rfkill); + rfkill_destroy(ehotk->wimax_rfkill); + ehotk->wimax_rfkill = NULL; + } +} + +static int eeepc_rfkill_init(struct device *dev) +{ + int result = 0; + + mutex_init(&ehotk->hotplug_lock); + + result = eeepc_new_rfkill(&ehotk->wlan_rfkill, + "eeepc-wlan", dev, + RFKILL_TYPE_WLAN, CM_ASL_WLAN); + + if (result && result != -ENODEV) + goto exit; + + result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill, + "eeepc-bluetooth", dev, + RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH); + + if (result && result != -ENODEV) + goto exit; + + result = eeepc_new_rfkill(&ehotk->wwan3g_rfkill, + "eeepc-wwan3g", dev, + RFKILL_TYPE_WWAN, CM_ASL_3G); + + if (result && result != -ENODEV) + goto exit; + + result = eeepc_new_rfkill(&ehotk->wimax_rfkill, + "eeepc-wimax", dev, + RFKILL_TYPE_WIMAX, CM_ASL_WIMAX); + + if (result && result != -ENODEV) + goto exit; + + result = eeepc_setup_pci_hotplug(); + /* + * If we get -EBUSY then something else is handling the PCI hotplug - + * don't fail in this case + */ + if (result == -EBUSY) + result = 0; + + eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P5"); + eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); + eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); + /* + * Refresh pci hotplug in case the rfkill state was changed during + * setup. + */ + eeepc_rfkill_hotplug(); + +exit: + if (result && result != -ENODEV) + eeepc_rfkill_exit(); + return result; +} + +/* + * Platform driver - hibernate/resume callbacks + */ static int eeepc_hotk_thaw(struct device *device) { if (ehotk->wlan_rfkill) { @@ -937,9 +821,31 @@ static int eeepc_hotk_restore(struct device *device) return 0; } +static struct dev_pm_ops eeepc_pm_ops = { + .thaw = eeepc_hotk_thaw, + .restore = eeepc_hotk_restore, +}; + +static struct platform_driver platform_driver = { + .driver = { + .name = EEEPC_HOTK_FILE, + .owner = THIS_MODULE, + .pm = &eeepc_pm_ops, + } +}; + /* - * Hwmon + * Hwmon device */ + +#define EEEPC_EC_SC00 0x61 +#define EEEPC_EC_FAN_PWM (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */ +#define EEEPC_EC_FAN_HRPM (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */ +#define EEEPC_EC_FAN_LRPM (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */ + +#define EEEPC_EC_SFB0 0xD0 +#define EEEPC_EC_FAN_CTRL (EEEPC_EC_SFB0 + 3) /* Byte containing SF25 */ + static int eeepc_get_fan_pwm(void) { u8 value = 0; @@ -1043,57 +949,6 @@ static struct attribute_group hwmon_attribute_group = { .attrs = hwmon_attributes }; -/* - * exit/init - */ -static void eeepc_backlight_exit(void) -{ - if (eeepc_backlight_device) - backlight_device_unregister(eeepc_backlight_device); - eeepc_backlight_device = NULL; -} - -static void eeepc_rfkill_exit(void) -{ - eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P5"); - eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); - eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); - if (ehotk->wlan_rfkill) { - rfkill_unregister(ehotk->wlan_rfkill); - rfkill_destroy(ehotk->wlan_rfkill); - ehotk->wlan_rfkill = NULL; - } - /* - * Refresh pci hotplug in case the rfkill state was changed after - * eeepc_unregister_rfkill_notifier() - */ - eeepc_rfkill_hotplug(); - if (ehotk->hotplug_slot) - pci_hp_deregister(ehotk->hotplug_slot); - - if (ehotk->bluetooth_rfkill) { - rfkill_unregister(ehotk->bluetooth_rfkill); - rfkill_destroy(ehotk->bluetooth_rfkill); - ehotk->bluetooth_rfkill = NULL; - } - if (ehotk->wwan3g_rfkill) { - rfkill_unregister(ehotk->wwan3g_rfkill); - rfkill_destroy(ehotk->wwan3g_rfkill); - ehotk->wwan3g_rfkill = NULL; - } - if (ehotk->wimax_rfkill) { - rfkill_unregister(ehotk->wimax_rfkill); - rfkill_destroy(ehotk->wimax_rfkill); - ehotk->wimax_rfkill = NULL; - } -} - -static void eeepc_input_exit(void) -{ - if (ehotk->inputdev) - input_unregister_device(ehotk->inputdev); -} - static void eeepc_hwmon_exit(void) { struct device *hwmon; @@ -1107,96 +962,56 @@ static void eeepc_hwmon_exit(void) eeepc_hwmon_device = NULL; } -static void eeepc_led_exit(void) -{ - if (tpd_led.dev) - led_classdev_unregister(&tpd_led); - if (led_workqueue) - destroy_workqueue(led_workqueue); -} - -static int eeepc_new_rfkill(struct rfkill **rfkill, - const char *name, struct device *dev, - enum rfkill_type type, int cm) +static int eeepc_hwmon_init(struct device *dev) { + struct device *hwmon; int result; - result = get_acpi(cm); - if (result < 0) - return result; - - *rfkill = rfkill_alloc(name, dev, type, - &eeepc_rfkill_ops, (void *)(unsigned long)cm); - - if (!*rfkill) - return -EINVAL; - - rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1); - result = rfkill_register(*rfkill); - if (result) { - rfkill_destroy(*rfkill); - *rfkill = NULL; - return result; + hwmon = hwmon_device_register(dev); + if (IS_ERR(hwmon)) { + pr_err("Could not register eeepc hwmon device\n"); + eeepc_hwmon_device = NULL; + return PTR_ERR(hwmon); } - return 0; + eeepc_hwmon_device = hwmon; + result = sysfs_create_group(&hwmon->kobj, + &hwmon_attribute_group); + if (result) + eeepc_hwmon_exit(); + return result; } - -static int eeepc_rfkill_init(struct device *dev) +/* + * Backlight device + */ +static int read_brightness(struct backlight_device *bd) { - int result = 0; - - mutex_init(&ehotk->hotplug_lock); - - result = eeepc_new_rfkill(&ehotk->wlan_rfkill, - "eeepc-wlan", dev, - RFKILL_TYPE_WLAN, CM_ASL_WLAN); - - if (result && result != -ENODEV) - goto exit; - - result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill, - "eeepc-bluetooth", dev, - RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH); - - if (result && result != -ENODEV) - goto exit; - - result = eeepc_new_rfkill(&ehotk->wwan3g_rfkill, - "eeepc-wwan3g", dev, - RFKILL_TYPE_WWAN, CM_ASL_3G); + return get_acpi(CM_ASL_PANELBRIGHT); +} - if (result && result != -ENODEV) - goto exit; +static int set_brightness(struct backlight_device *bd, int value) +{ + return set_acpi(CM_ASL_PANELBRIGHT, value); +} - result = eeepc_new_rfkill(&ehotk->wimax_rfkill, - "eeepc-wimax", dev, - RFKILL_TYPE_WIMAX, CM_ASL_WIMAX); +static int update_bl_status(struct backlight_device *bd) +{ + return set_brightness(bd, bd->props.brightness); +} - if (result && result != -ENODEV) - goto exit; +static struct backlight_ops eeepcbl_ops = { + .get_brightness = read_brightness, + .update_status = update_bl_status, +}; - result = eeepc_setup_pci_hotplug(); - /* - * If we get -EBUSY then something else is handling the PCI hotplug - - * don't fail in this case - */ - if (result == -EBUSY) - result = 0; +static int eeepc_backlight_notify(void) +{ + struct backlight_device *bd = eeepc_backlight_device; + int old = bd->props.brightness; - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P5"); - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); - /* - * Refresh pci hotplug in case the rfkill state was changed during - * setup. - */ - eeepc_rfkill_hotplug(); + backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY); -exit: - if (result && result != -ENODEV) - eeepc_rfkill_exit(); - return result; + return old; } static int eeepc_backlight_init(struct device *dev) @@ -1218,23 +1033,89 @@ static int eeepc_backlight_init(struct device *dev) return 0; } -static int eeepc_hwmon_init(struct device *dev) +static void eeepc_backlight_exit(void) { - struct device *hwmon; - int result; + if (eeepc_backlight_device) + backlight_device_unregister(eeepc_backlight_device); + eeepc_backlight_device = NULL; +} - hwmon = hwmon_device_register(dev); - if (IS_ERR(hwmon)) { - pr_err("Could not register eeepc hwmon device\n"); - eeepc_hwmon_device = NULL; - return PTR_ERR(hwmon); + +/* + * Input device (i.e. hotkeys) + */ +static struct key_entry *eeepc_get_entry_by_scancode(int code) +{ + struct key_entry *key; + + for (key = eeepc_keymap; key->type != KE_END; key++) + if (code == key->code) + return key; + + return NULL; +} + +static void eeepc_input_notify(int event) +{ + static struct key_entry *key; + + key = eeepc_get_entry_by_scancode(event); + if (key) { + switch (key->type) { + case KE_KEY: + input_report_key(ehotk->inputdev, key->keycode, + 1); + input_sync(ehotk->inputdev); + input_report_key(ehotk->inputdev, key->keycode, + 0); + input_sync(ehotk->inputdev); + break; + } } - eeepc_hwmon_device = hwmon; - result = sysfs_create_group(&hwmon->kobj, - &hwmon_attribute_group); - if (result) - eeepc_hwmon_exit(); - return result; +} + +static struct key_entry *eepc_get_entry_by_keycode(int code) +{ + struct key_entry *key; + + for (key = eeepc_keymap; key->type != KE_END; key++) + if (code == key->keycode && key->type == KE_KEY) + return key; + + return NULL; +} + +static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode) +{ + struct key_entry *key = eeepc_get_entry_by_scancode(scancode); + + if (key && key->type == KE_KEY) { + *keycode = key->keycode; + return 0; + } + + return -EINVAL; +} + +static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode) +{ + struct key_entry *key; + int old_keycode; + + if (keycode < 0 || keycode > KEY_MAX) + return -EINVAL; + + key = eeepc_get_entry_by_scancode(scancode); + if (key && key->type == KE_KEY) { + old_keycode = key->keycode; + key->keycode = keycode; + set_bit(keycode, dev->keybit); + if (!eepc_get_entry_by_keycode(old_keycode)) + clear_bit(old_keycode, dev->keybit); + return 0; + } + + return -EINVAL; } static int eeepc_input_init(struct device *dev) @@ -1271,26 +1152,114 @@ static int eeepc_input_init(struct device *dev) return 0; } -static int eeepc_led_init(struct device *dev) +static void eeepc_input_exit(void) { - int rv; + if (ehotk->inputdev) + input_unregister_device(ehotk->inputdev); +} - if (get_acpi(CM_ASL_TPD) == -ENODEV) - return 0; +/* + * ACPI driver + */ +static void eeepc_hotk_notify(struct acpi_device *device, u32 event) +{ + u16 count; - led_workqueue = create_singlethread_workqueue("led_workqueue"); - if (!led_workqueue) - return -ENOMEM; + if (event > ACPI_MAX_SYS_NOTIFY) + return; + count = ehotk->event_count[event % 128]++; + acpi_bus_generate_proc_event(ehotk->device, event, count); + acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, + dev_name(&ehotk->device->dev), event, + count); - rv = led_classdev_register(dev, &tpd_led); - if (rv) { - destroy_workqueue(led_workqueue); - return rv; + if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) { + int old_brightness, new_brightness; + + /* Update backlight device. */ + old_brightness = eeepc_backlight_notify(); + + /* Convert brightness event to keypress (obsolescent hack). */ + new_brightness = event - NOTIFY_BRN_MIN; + + if (new_brightness < old_brightness) { + event = NOTIFY_BRN_MIN; /* brightness down */ + } else if (new_brightness > old_brightness) { + event = NOTIFY_BRN_MAX; /* brightness up */ + } else { + /* + * no change in brightness - already at min/max, + * event will be desired value (or else ignored). + */ + } + } + eeepc_input_notify(event); +} + +static void cmsg_quirk(int cm, const char *name) +{ + int dummy; + + /* Some BIOSes do not report cm although it is avaliable. + Check if cm_getv[cm] works and, if yes, assume cm should be set. */ + if (!(ehotk->cm_supported & (1 << cm)) + && !read_acpi_int(ehotk->handle, cm_getv[cm], &dummy)) { + pr_info("%s (%x) not reported by BIOS," + " enabling anyway\n", name, 1 << cm); + ehotk->cm_supported |= 1 << cm; + } +} + +static void cmsg_quirks(void) +{ + cmsg_quirk(CM_ASL_LID, "LID"); + cmsg_quirk(CM_ASL_TYPE, "TYPE"); + cmsg_quirk(CM_ASL_PANELPOWER, "PANELPOWER"); + cmsg_quirk(CM_ASL_TPD, "TPD"); +} + +static int eeepc_hotk_init(void) +{ + unsigned int init_flags; + int result; + + result = acpi_bus_get_status(ehotk->device); + if (result) + return result; + if (!ehotk->device->status.present) { + pr_err("Hotkey device not present, aborting\n"); + return -ENODEV; + } + + init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH; + pr_notice("Hotkey init flags 0x%x\n", init_flags); + + if (write_acpi_int(ehotk->handle, "INIT", init_flags)) { + pr_err("Hotkey initialization failed\n"); + return -ENODEV; + } + + /* get control methods supported */ + if (read_acpi_int(ehotk->handle, "CMSG", &ehotk->cm_supported)) { + pr_err("Get control methods supported failed\n"); + return -ENODEV; } + cmsg_quirks(); + pr_info("Get control methods supported: 0x%x\n", ehotk->cm_supported); return 0; } +static void __devinit eeepc_enable_camera(void) +{ + /* + * If the following call to set_acpi() fails, it's because there's no + * camera so we can ignore the error. + */ + if (get_acpi(CM_ASL_CAMERA) == 0) + set_acpi(CM_ASL_CAMERA, 1); +} + static int __devinit eeepc_hotk_add(struct acpi_device *device) { struct device *dev; @@ -1371,6 +1340,27 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) return 0; } + +static const struct acpi_device_id eeepc_device_ids[] = { + {EEEPC_HOTK_HID, 0}, + {"", 0}, +}; +MODULE_DEVICE_TABLE(acpi, eeepc_device_ids); + +static struct acpi_driver eeepc_hotk_driver = { + .name = EEEPC_HOTK_NAME, + .class = EEEPC_HOTK_CLASS, + .owner = THIS_MODULE, + .ids = eeepc_device_ids, + .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, + .ops = { + .add = eeepc_hotk_add, + .remove = eeepc_hotk_remove, + .notify = eeepc_hotk_notify, + }, +}; + + static int __init eeepc_laptop_init(void) { int result; -- cgit v0.10.2 From a7624b63fdf50d7f460170891a49397280f08758 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:45:08 +0000 Subject: eeepc-laptop: revise names eeepc-laptop now does a lot more than just hotkeys. Replace the "hotk" names used throughout the driver with some slightly more appropriate names. The actual strings used in kernel messages and sysfs are left unchanged. e.g. EEEPC_HOTK_FILE -> EEEPC_LAPTOP_FILE EEEPC_HOTK_HID -> EEEPC_ACPI_HID eeepc_hotk_notify -> eeepc_acpi_notify struct eeepc_hotk -> struct eeepc_laptop ehotk -> eeepc I'm about to refactor the entire driver to remove the global "ehotk" variable, and I don't wish to add "struct eeepc_hotk *ehotk" to functions which have nothing to do with hotkeys. Also - fix the name of "eepc_get_entry_by_keycode()" - remove the unused definition of NOTIFY_WLAN_ON. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index f457587..b9b5aeb 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -1,5 +1,5 @@ /* - * eepc-laptop.c - Asus Eee PC extras + * eeepc-laptop.c - Asus Eee PC extras * * Based on asus_acpi.c as patched for the Eee PC by Asus: * ftp://ftp.asus.com/pub/ASUS/EeePC/701/ASUS_ACPI_071126.rar @@ -37,21 +37,20 @@ #include #define EEEPC_LAPTOP_VERSION "0.1" +#define EEEPC_LAPTOP_NAME "Eee PC Hotkey Driver" +#define EEEPC_LAPTOP_FILE "eeepc" -#define EEEPC_HOTK_NAME "Eee PC Hotkey Driver" -#define EEEPC_HOTK_FILE "eeepc" -#define EEEPC_HOTK_CLASS "hotkey" -#define EEEPC_HOTK_DEVICE_NAME "Hotkey" -#define EEEPC_HOTK_HID "ASUS010" +#define EEEPC_ACPI_CLASS "hotkey" +#define EEEPC_ACPI_DEVICE_NAME "Hotkey" +#define EEEPC_ACPI_HID "ASUS010" MODULE_AUTHOR("Corentin Chary, Eric Cooper"); -MODULE_DESCRIPTION(EEEPC_HOTK_NAME); +MODULE_DESCRIPTION(EEEPC_LAPTOP_NAME); MODULE_LICENSE("GPL"); /* * Definitions for Asus EeePC */ -#define NOTIFY_WLAN_ON 0x10 #define NOTIFY_BRN_MIN 0x20 #define NOTIFY_BRN_MAX 0x2f @@ -152,9 +151,8 @@ static struct key_entry eeepc_keymap[] = { /* * This is the main structure, we can use it to store useful information - * about the hotk device */ -struct eeepc_hotk { +struct eeepc_laptop { struct acpi_device *device; /* the device we are in */ acpi_handle handle; /* the handle of the hotk device */ u32 cm_supported; /* the control methods supported @@ -171,7 +169,7 @@ struct eeepc_hotk { }; /* The actual device the driver binds to */ -static struct eeepc_hotk *ehotk; +static struct eeepc_laptop *eeepc; /* The platform device */ static struct platform_device *platform_device; @@ -222,10 +220,10 @@ static int set_acpi(int cm, int value) if (method == NULL) return -ENODEV; - if ((ehotk->cm_supported & (0x1 << cm)) == 0) + if ((eeepc->cm_supported & (0x1 << cm)) == 0) return -ENODEV; - if (write_acpi_int(ehotk->handle, method, value)) + if (write_acpi_int(eeepc->handle, method, value)) pr_warning("Error writing %s\n", method); return 0; } @@ -237,10 +235,10 @@ static int get_acpi(int cm) if (method == NULL) return -ENODEV; - if ((ehotk->cm_supported & (0x1 << cm)) == 0) + if ((eeepc->cm_supported & (0x1 << cm)) == 0) return -ENODEV; - if (read_acpi_int(ehotk->handle, method, &value)) + if (read_acpi_int(eeepc->handle, method, &value)) pr_warning("Error reading %s\n", method); return value; } @@ -395,7 +393,7 @@ static int eeepc_platform_init(void) { int result; - platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1); + platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, -1); if (!platform_device) return -ENOMEM; @@ -501,12 +499,12 @@ static void eeepc_rfkill_hotplug(void) struct pci_bus *bus; bool blocked = eeepc_wlan_rfkill_blocked(); - if (ehotk->wlan_rfkill) - rfkill_set_sw_state(ehotk->wlan_rfkill, blocked); + if (eeepc->wlan_rfkill) + rfkill_set_sw_state(eeepc->wlan_rfkill, blocked); - mutex_lock(&ehotk->hotplug_lock); + mutex_lock(&eeepc->hotplug_lock); - if (ehotk->hotplug_slot) { + if (eeepc->hotplug_slot) { bus = pci_find_bus(0, 1); if (!bus) { pr_warning("Unable to find PCI bus 1?\n"); @@ -536,7 +534,7 @@ static void eeepc_rfkill_hotplug(void) } out_unlock: - mutex_unlock(&ehotk->hotplug_lock); + mutex_unlock(&eeepc->hotplug_lock); } static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) @@ -619,22 +617,22 @@ static int eeepc_setup_pci_hotplug(void) return -ENODEV; } - ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); - if (!ehotk->hotplug_slot) + eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); + if (!eeepc->hotplug_slot) goto error_slot; - ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info), + eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); - if (!ehotk->hotplug_slot->info) + if (!eeepc->hotplug_slot->info) goto error_info; - ehotk->hotplug_slot->private = ehotk; - ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug; - ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops; - eeepc_get_adapter_status(ehotk->hotplug_slot, - &ehotk->hotplug_slot->info->adapter_status); + eeepc->hotplug_slot->private = eeepc; + eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug; + eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops; + eeepc_get_adapter_status(eeepc->hotplug_slot, + &eeepc->hotplug_slot->info->adapter_status); - ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi"); + ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi"); if (ret) { pr_err("Unable to register hotplug slot - %d\n", ret); goto error_register; @@ -643,10 +641,10 @@ static int eeepc_setup_pci_hotplug(void) return 0; error_register: - kfree(ehotk->hotplug_slot->info); + kfree(eeepc->hotplug_slot->info); error_info: - kfree(ehotk->hotplug_slot); - ehotk->hotplug_slot = NULL; + kfree(eeepc->hotplug_slot); + eeepc->hotplug_slot = NULL; error_slot: return ret; } @@ -695,33 +693,33 @@ static void eeepc_rfkill_exit(void) eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P5"); eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); - if (ehotk->wlan_rfkill) { - rfkill_unregister(ehotk->wlan_rfkill); - rfkill_destroy(ehotk->wlan_rfkill); - ehotk->wlan_rfkill = NULL; + if (eeepc->wlan_rfkill) { + rfkill_unregister(eeepc->wlan_rfkill); + rfkill_destroy(eeepc->wlan_rfkill); + eeepc->wlan_rfkill = NULL; } /* * Refresh pci hotplug in case the rfkill state was changed after * eeepc_unregister_rfkill_notifier() */ eeepc_rfkill_hotplug(); - if (ehotk->hotplug_slot) - pci_hp_deregister(ehotk->hotplug_slot); + if (eeepc->hotplug_slot) + pci_hp_deregister(eeepc->hotplug_slot); - if (ehotk->bluetooth_rfkill) { - rfkill_unregister(ehotk->bluetooth_rfkill); - rfkill_destroy(ehotk->bluetooth_rfkill); - ehotk->bluetooth_rfkill = NULL; + if (eeepc->bluetooth_rfkill) { + rfkill_unregister(eeepc->bluetooth_rfkill); + rfkill_destroy(eeepc->bluetooth_rfkill); + eeepc->bluetooth_rfkill = NULL; } - if (ehotk->wwan3g_rfkill) { - rfkill_unregister(ehotk->wwan3g_rfkill); - rfkill_destroy(ehotk->wwan3g_rfkill); - ehotk->wwan3g_rfkill = NULL; + if (eeepc->wwan3g_rfkill) { + rfkill_unregister(eeepc->wwan3g_rfkill); + rfkill_destroy(eeepc->wwan3g_rfkill); + eeepc->wwan3g_rfkill = NULL; } - if (ehotk->wimax_rfkill) { - rfkill_unregister(ehotk->wimax_rfkill); - rfkill_destroy(ehotk->wimax_rfkill); - ehotk->wimax_rfkill = NULL; + if (eeepc->wimax_rfkill) { + rfkill_unregister(eeepc->wimax_rfkill); + rfkill_destroy(eeepc->wimax_rfkill); + eeepc->wimax_rfkill = NULL; } } @@ -729,30 +727,30 @@ static int eeepc_rfkill_init(struct device *dev) { int result = 0; - mutex_init(&ehotk->hotplug_lock); + mutex_init(&eeepc->hotplug_lock); - result = eeepc_new_rfkill(&ehotk->wlan_rfkill, + result = eeepc_new_rfkill(&eeepc->wlan_rfkill, "eeepc-wlan", dev, RFKILL_TYPE_WLAN, CM_ASL_WLAN); if (result && result != -ENODEV) goto exit; - result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill, + result = eeepc_new_rfkill(&eeepc->bluetooth_rfkill, "eeepc-bluetooth", dev, RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH); if (result && result != -ENODEV) goto exit; - result = eeepc_new_rfkill(&ehotk->wwan3g_rfkill, + result = eeepc_new_rfkill(&eeepc->wwan3g_rfkill, "eeepc-wwan3g", dev, RFKILL_TYPE_WWAN, CM_ASL_3G); if (result && result != -ENODEV) goto exit; - result = eeepc_new_rfkill(&ehotk->wimax_rfkill, + result = eeepc_new_rfkill(&eeepc->wimax_rfkill, "eeepc-wimax", dev, RFKILL_TYPE_WIMAX, CM_ASL_WIMAX); @@ -785,9 +783,9 @@ exit: /* * Platform driver - hibernate/resume callbacks */ -static int eeepc_hotk_thaw(struct device *device) +static int eeepc_thaw(struct device *device) { - if (ehotk->wlan_rfkill) { + if (eeepc->wlan_rfkill) { bool wlan; /* @@ -802,33 +800,33 @@ static int eeepc_hotk_thaw(struct device *device) return 0; } -static int eeepc_hotk_restore(struct device *device) +static int eeepc_restore(struct device *device) { /* Refresh both wlan rfkill state and pci hotplug */ - if (ehotk->wlan_rfkill) + if (eeepc->wlan_rfkill) eeepc_rfkill_hotplug(); - if (ehotk->bluetooth_rfkill) - rfkill_set_sw_state(ehotk->bluetooth_rfkill, + if (eeepc->bluetooth_rfkill) + rfkill_set_sw_state(eeepc->bluetooth_rfkill, get_acpi(CM_ASL_BLUETOOTH) != 1); - if (ehotk->wwan3g_rfkill) - rfkill_set_sw_state(ehotk->wwan3g_rfkill, + if (eeepc->wwan3g_rfkill) + rfkill_set_sw_state(eeepc->wwan3g_rfkill, get_acpi(CM_ASL_3G) != 1); - if (ehotk->wimax_rfkill) - rfkill_set_sw_state(ehotk->wimax_rfkill, + if (eeepc->wimax_rfkill) + rfkill_set_sw_state(eeepc->wimax_rfkill, get_acpi(CM_ASL_WIMAX) != 1); return 0; } static struct dev_pm_ops eeepc_pm_ops = { - .thaw = eeepc_hotk_thaw, - .restore = eeepc_hotk_restore, + .thaw = eeepc_thaw, + .restore = eeepc_restore, }; static struct platform_driver platform_driver = { .driver = { - .name = EEEPC_HOTK_FILE, + .name = EEEPC_LAPTOP_FILE, .owner = THIS_MODULE, .pm = &eeepc_pm_ops, } @@ -1018,7 +1016,7 @@ static int eeepc_backlight_init(struct device *dev) { struct backlight_device *bd; - bd = backlight_device_register(EEEPC_HOTK_FILE, dev, + bd = backlight_device_register(EEEPC_LAPTOP_FILE, dev, NULL, &eeepcbl_ops); if (IS_ERR(bd)) { pr_err("Could not register eeepc backlight device\n"); @@ -1063,12 +1061,12 @@ static void eeepc_input_notify(int event) if (key) { switch (key->type) { case KE_KEY: - input_report_key(ehotk->inputdev, key->keycode, + input_report_key(eeepc->inputdev, key->keycode, 1); - input_sync(ehotk->inputdev); - input_report_key(ehotk->inputdev, key->keycode, + input_sync(eeepc->inputdev); + input_report_key(eeepc->inputdev, key->keycode, 0); - input_sync(ehotk->inputdev); + input_sync(eeepc->inputdev); break; } } @@ -1123,30 +1121,30 @@ static int eeepc_input_init(struct device *dev) const struct key_entry *key; int result; - ehotk->inputdev = input_allocate_device(); - if (!ehotk->inputdev) { + eeepc->inputdev = input_allocate_device(); + if (!eeepc->inputdev) { pr_info("Unable to allocate input device\n"); return -ENOMEM; } - ehotk->inputdev->name = "Asus EeePC extra buttons"; - ehotk->inputdev->dev.parent = dev; - ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0"; - ehotk->inputdev->id.bustype = BUS_HOST; - ehotk->inputdev->getkeycode = eeepc_getkeycode; - ehotk->inputdev->setkeycode = eeepc_setkeycode; + eeepc->inputdev->name = "Asus EeePC extra buttons"; + eeepc->inputdev->dev.parent = dev; + eeepc->inputdev->phys = EEEPC_LAPTOP_FILE "/input0"; + eeepc->inputdev->id.bustype = BUS_HOST; + eeepc->inputdev->getkeycode = eeepc_getkeycode; + eeepc->inputdev->setkeycode = eeepc_setkeycode; for (key = eeepc_keymap; key->type != KE_END; key++) { switch (key->type) { case KE_KEY: - set_bit(EV_KEY, ehotk->inputdev->evbit); - set_bit(key->keycode, ehotk->inputdev->keybit); + set_bit(EV_KEY, eeepc->inputdev->evbit); + set_bit(key->keycode, eeepc->inputdev->keybit); break; } } - result = input_register_device(ehotk->inputdev); + result = input_register_device(eeepc->inputdev); if (result) { pr_info("Unable to register input device\n"); - input_free_device(ehotk->inputdev); + input_free_device(eeepc->inputdev); return result; } return 0; @@ -1154,23 +1152,23 @@ static int eeepc_input_init(struct device *dev) static void eeepc_input_exit(void) { - if (ehotk->inputdev) - input_unregister_device(ehotk->inputdev); + if (eeepc->inputdev) + input_unregister_device(eeepc->inputdev); } /* * ACPI driver */ -static void eeepc_hotk_notify(struct acpi_device *device, u32 event) +static void eeepc_acpi_notify(struct acpi_device *device, u32 event) { u16 count; if (event > ACPI_MAX_SYS_NOTIFY) return; - count = ehotk->event_count[event % 128]++; - acpi_bus_generate_proc_event(ehotk->device, event, count); - acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, - dev_name(&ehotk->device->dev), event, + count = eeepc->event_count[event % 128]++; + acpi_bus_generate_proc_event(eeepc->device, event, count); + acpi_bus_generate_netlink_event(eeepc->device->pnp.device_class, + dev_name(&eeepc->device->dev), event, count); if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) { @@ -1202,11 +1200,11 @@ static void cmsg_quirk(int cm, const char *name) /* Some BIOSes do not report cm although it is avaliable. Check if cm_getv[cm] works and, if yes, assume cm should be set. */ - if (!(ehotk->cm_supported & (1 << cm)) - && !read_acpi_int(ehotk->handle, cm_getv[cm], &dummy)) { + if (!(eeepc->cm_supported & (1 << cm)) + && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) { pr_info("%s (%x) not reported by BIOS," " enabling anyway\n", name, 1 << cm); - ehotk->cm_supported |= 1 << cm; + eeepc->cm_supported |= 1 << cm; } } @@ -1218,15 +1216,15 @@ static void cmsg_quirks(void) cmsg_quirk(CM_ASL_TPD, "TPD"); } -static int eeepc_hotk_init(void) +static int eeepc_acpi_init(void) { unsigned int init_flags; int result; - result = acpi_bus_get_status(ehotk->device); + result = acpi_bus_get_status(eeepc->device); if (result) return result; - if (!ehotk->device->status.present) { + if (!eeepc->device->status.present) { pr_err("Hotkey device not present, aborting\n"); return -ENODEV; } @@ -1234,18 +1232,18 @@ static int eeepc_hotk_init(void) init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH; pr_notice("Hotkey init flags 0x%x\n", init_flags); - if (write_acpi_int(ehotk->handle, "INIT", init_flags)) { + if (write_acpi_int(eeepc->handle, "INIT", init_flags)) { pr_err("Hotkey initialization failed\n"); return -ENODEV; } /* get control methods supported */ - if (read_acpi_int(ehotk->handle, "CMSG", &ehotk->cm_supported)) { + if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) { pr_err("Get control methods supported failed\n"); return -ENODEV; } cmsg_quirks(); - pr_info("Get control methods supported: 0x%x\n", ehotk->cm_supported); + pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported); return 0; } @@ -1260,22 +1258,22 @@ static void __devinit eeepc_enable_camera(void) set_acpi(CM_ASL_CAMERA, 1); } -static int __devinit eeepc_hotk_add(struct acpi_device *device) +static int __devinit eeepc_acpi_add(struct acpi_device *device) { struct device *dev; int result; - pr_notice(EEEPC_HOTK_NAME "\n"); - ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); - if (!ehotk) + pr_notice(EEEPC_LAPTOP_NAME "\n"); + eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL); + if (!eeepc) return -ENOMEM; - ehotk->handle = device->handle; - strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME); - strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS); - device->driver_data = ehotk; - ehotk->device = device; + eeepc->handle = device->handle; + strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME); + strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS); + device->driver_data = eeepc; + eeepc->device = device; - result = eeepc_hotk_init(); + result = eeepc_acpi_init(); if (result) goto fail_platform; eeepc_enable_camera(); @@ -1283,7 +1281,6 @@ static int __devinit eeepc_hotk_add(struct acpi_device *device) result = eeepc_platform_init(); if (result) goto fail_platform; - dev = &platform_device->dev; if (!acpi_video_backlight_support()) { @@ -1322,12 +1319,12 @@ fail_input: fail_backlight: eeepc_platform_exit(); fail_platform: - kfree(ehotk); + kfree(eeepc); return result; } -static int eeepc_hotk_remove(struct acpi_device *device, int type) +static int eeepc_acpi_remove(struct acpi_device *device, int type) { eeepc_backlight_exit(); eeepc_rfkill_exit(); @@ -1336,27 +1333,27 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) eeepc_led_exit(); eeepc_platform_exit(); - kfree(ehotk); + kfree(eeepc); return 0; } static const struct acpi_device_id eeepc_device_ids[] = { - {EEEPC_HOTK_HID, 0}, + {EEEPC_ACPI_HID, 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, eeepc_device_ids); -static struct acpi_driver eeepc_hotk_driver = { - .name = EEEPC_HOTK_NAME, - .class = EEEPC_HOTK_CLASS, +static struct acpi_driver eeepc_acpi_driver = { + .name = EEEPC_LAPTOP_NAME, + .class = EEEPC_ACPI_CLASS, .owner = THIS_MODULE, .ids = eeepc_device_ids, .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { - .add = eeepc_hotk_add, - .remove = eeepc_hotk_remove, - .notify = eeepc_hotk_notify, + .add = eeepc_acpi_add, + .remove = eeepc_acpi_remove, + .notify = eeepc_acpi_notify, }, }; @@ -1369,17 +1366,17 @@ static int __init eeepc_laptop_init(void) if (result < 0) return result; - result = acpi_bus_register_driver(&eeepc_hotk_driver); + result = acpi_bus_register_driver(&eeepc_acpi_driver); if (result < 0) goto fail_acpi_driver; - if (!ehotk) { + if (!eeepc) { result = -ENODEV; goto fail_no_device; } return 0; fail_no_device: - acpi_bus_unregister_driver(&eeepc_hotk_driver); + acpi_bus_unregister_driver(&eeepc_acpi_driver); fail_acpi_driver: platform_driver_unregister(&platform_driver); return result; @@ -1387,7 +1384,7 @@ fail_acpi_driver: static void __exit eeepc_laptop_exit(void) { - acpi_bus_unregister_driver(&eeepc_hotk_driver); + acpi_bus_unregister_driver(&eeepc_acpi_driver); platform_driver_unregister(&platform_driver); } -- cgit v0.10.2 From 854c78363f37f03e30e2856ef17d7eefc62e0d06 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:45:09 +0000 Subject: eeepc-laptop: callbacks should use "driver data" parameter or field Callback methods should not refer to a variable like "eeepc" (formally "ehotk"). Instead, they should extract the data they need either from a "driver data" parameter, or the "driver data" field of the object which they operate on. The "eeepc" variable can then be removed. In practice, drivers under "drivers/platform" can get away without using driver data, because it doesn't make sense to have more than one instance of them. However this makes it harder to review them for correctness. This is especially true for core ACPI developers who have not previously been exposed to this anti-pattern :-). This will serve as an example of best practice for new driver writers (whether they find it themselves, or have it pointed out during review :-). The hwmon sub-device is a special case. It uses ec_{read,write} which are defined to communicate with the (first) EC, so it does not require any driver data. It should still only be instantiated in the context of an ASUS010 device because we don't have a safe way to probe for it. Signed-off-by: Alan Jenkins CC: Bjorn Helgaas Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index b9b5aeb..935ec44 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -128,7 +128,7 @@ struct key_entry { enum { KE_KEY, KE_END }; -static struct key_entry eeepc_keymap[] = { +static const struct key_entry eeepc_keymap[] = { /* Sleep already handled via generic ACPI code */ {KE_KEY, 0x10, KEY_WLAN }, {KE_KEY, 0x11, KEY_WLAN }, @@ -153,33 +153,31 @@ static struct key_entry eeepc_keymap[] = { * This is the main structure, we can use it to store useful information */ struct eeepc_laptop { - struct acpi_device *device; /* the device we are in */ - acpi_handle handle; /* the handle of the hotk device */ + acpi_handle handle; /* the handle of the acpi device */ u32 cm_supported; /* the control methods supported by this BIOS */ u16 event_count[128]; /* count for each event */ + + struct platform_device *platform_device; + struct device *hwmon_device; + struct backlight_device *backlight_device; + struct input_dev *inputdev; - u16 *keycode_map; + struct key_entry *keymap; + struct rfkill *wlan_rfkill; struct rfkill *bluetooth_rfkill; struct rfkill *wwan3g_rfkill; struct rfkill *wimax_rfkill; + struct hotplug_slot *hotplug_slot; struct mutex hotplug_lock; -}; - -/* The actual device the driver binds to */ -static struct eeepc_laptop *eeepc; - -/* The platform device */ -static struct platform_device *platform_device; - -/* The backlight device /sys/class/backlight */ -static struct backlight_device *eeepc_backlight_device; - -/* The hwmon device */ -static struct device *eeepc_hwmon_device; + struct led_classdev tpd_led; + int tpd_led_wk; + struct workqueue_struct *led_workqueue; + struct work_struct tpd_led_work; +}; /* * ACPI Helpers @@ -214,7 +212,7 @@ static int read_acpi_int(acpi_handle handle, const char *method, int *val) } } -static int set_acpi(int cm, int value) +static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value) { const char *method = cm_setv[cm]; @@ -228,7 +226,7 @@ static int set_acpi(int cm, int value) return 0; } -static int get_acpi(int cm) +static int get_acpi(struct eeepc_laptop *eeepc, int cm) { const char *method = cm_getv[cm]; int value; @@ -243,6 +241,26 @@ static int get_acpi(int cm) return value; } +static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm, acpi_handle *handle) +{ + const char *method = cm_setv[cm]; + acpi_status status; + + if (method == NULL) + return -ENODEV; + if ((eeepc->cm_supported & (0x1 << cm)) == 0) + return -ENODEV; + + status = acpi_get_handle(eeepc->handle, (char *)method, + handle); + if (status != AE_OK) { + pr_warning("Error finding %s\n", method); + return -ENODEV; + } + return 0; +} + + /* * Sys helpers */ @@ -255,21 +273,24 @@ static int parse_arg(const char *buf, unsigned long count, int *val) return count; } -static ssize_t store_sys_acpi(int cm, const char *buf, size_t count) +static ssize_t store_sys_acpi(struct device *dev, int cm, + const char *buf, size_t count) { + struct eeepc_laptop *eeepc = dev_get_drvdata(dev); int rv, value; rv = parse_arg(buf, count, &value); if (rv > 0) - value = set_acpi(cm, value); + value = set_acpi(eeepc, cm, value); if (value < 0) return -EIO; return rv; } -static ssize_t show_sys_acpi(int cm, char *buf) +static ssize_t show_sys_acpi(struct device *dev, int cm, char *buf) { - int value = get_acpi(cm); + struct eeepc_laptop *eeepc = dev_get_drvdata(dev); + int value = get_acpi(eeepc, cm); if (value < 0) return -EIO; @@ -281,13 +302,13 @@ static ssize_t show_sys_acpi(int cm, char *buf) struct device_attribute *attr, \ char *buf) \ { \ - return show_sys_acpi(_cm, buf); \ + return show_sys_acpi(dev, _cm, buf); \ } \ static ssize_t store_##_name(struct device *dev, \ struct device_attribute *attr, \ const char *buf, size_t count) \ { \ - return store_sys_acpi(_cm, buf, count); \ + return store_sys_acpi(dev, _cm, buf, count); \ } \ static struct device_attribute dev_attr_##_name = { \ .attr = { \ @@ -306,9 +327,9 @@ struct eeepc_cpufv { int cur; }; -static int get_cpufv(struct eeepc_cpufv *c) +static int get_cpufv(struct eeepc_laptop *eeepc, struct eeepc_cpufv *c) { - c->cur = get_acpi(CM_ASL_CPUFV); + c->cur = get_acpi(eeepc, CM_ASL_CPUFV); c->num = (c->cur >> 8) & 0xff; c->cur &= 0xff; if (c->cur < 0 || c->num <= 0 || c->num > 12) @@ -320,11 +341,12 @@ static ssize_t show_available_cpufv(struct device *dev, struct device_attribute *attr, char *buf) { + struct eeepc_laptop *eeepc = dev_get_drvdata(dev); struct eeepc_cpufv c; int i; ssize_t len = 0; - if (get_cpufv(&c)) + if (get_cpufv(eeepc, &c)) return -ENODEV; for (i = 0; i < c.num; i++) len += sprintf(buf + len, "%d ", i); @@ -336,9 +358,10 @@ static ssize_t show_cpufv(struct device *dev, struct device_attribute *attr, char *buf) { + struct eeepc_laptop *eeepc = dev_get_drvdata(dev); struct eeepc_cpufv c; - if (get_cpufv(&c)) + if (get_cpufv(eeepc, &c)) return -ENODEV; return sprintf(buf, "%#x\n", (c.num << 8) | c.cur); } @@ -347,17 +370,18 @@ static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { + struct eeepc_laptop *eeepc = dev_get_drvdata(dev); struct eeepc_cpufv c; int rv, value; - if (get_cpufv(&c)) + if (get_cpufv(eeepc, &c)) return -ENODEV; rv = parse_arg(buf, count, &value); if (rv < 0) return rv; if (!rv || value < 0 || value >= c.num) return -EINVAL; - set_acpi(CM_ASL_CPUFV, value); + set_acpi(eeepc, CM_ASL_CPUFV, value); return rv; } @@ -389,36 +413,37 @@ static struct attribute_group platform_attribute_group = { .attrs = platform_attributes }; -static int eeepc_platform_init(void) +static int eeepc_platform_init(struct eeepc_laptop *eeepc) { int result; - platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, -1); - if (!platform_device) + eeepc->platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, -1); + if (!eeepc->platform_device) return -ENOMEM; + platform_set_drvdata(eeepc->platform_device, eeepc); - result = platform_device_add(platform_device); + result = platform_device_add(eeepc->platform_device); if (result) goto fail_platform_device; - result = sysfs_create_group(&platform_device->dev.kobj, + result = sysfs_create_group(&eeepc->platform_device->dev.kobj, &platform_attribute_group); if (result) goto fail_sysfs; return 0; fail_sysfs: - platform_device_del(platform_device); + platform_device_del(eeepc->platform_device); fail_platform_device: - platform_device_put(platform_device); + platform_device_put(eeepc->platform_device); return result; } -static void eeepc_platform_exit(void) +static void eeepc_platform_exit(struct eeepc_laptop *eeepc) { - sysfs_remove_group(&platform_device->dev.kobj, + sysfs_remove_group(&eeepc->platform_device->dev.kobj, &platform_attribute_group); - platform_device_unregister(platform_device); + platform_device_unregister(eeepc->platform_device); } /* @@ -430,74 +455,76 @@ static void eeepc_platform_exit(void) * subsystem asks, we avoid messing with the Asus ACPI stuff during a * potentially bad time, such as a timer interrupt. */ -static int tpd_led_wk; +static void tpd_led_update(struct work_struct *work) + { + struct eeepc_laptop *eeepc; -static void tpd_led_update(struct work_struct *ignored) -{ - int value = tpd_led_wk; - set_acpi(CM_ASL_TPD, value); -} + eeepc = container_of(work, struct eeepc_laptop, tpd_led_work); -static struct workqueue_struct *led_workqueue; -static DECLARE_WORK(tpd_led_work, tpd_led_update); + set_acpi(eeepc, CM_ASL_TPD, eeepc->tpd_led_wk); +} static void tpd_led_set(struct led_classdev *led_cdev, enum led_brightness value) { - tpd_led_wk = (value > 0) ? 1 : 0; - queue_work(led_workqueue, &tpd_led_work); -} + struct eeepc_laptop *eeepc; -static struct led_classdev tpd_led = { - .name = "eeepc::touchpad", - .brightness_set = tpd_led_set, - .max_brightness = 1 -}; + eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led); -static int eeepc_led_init(struct device *dev) + eeepc->tpd_led_wk = (value > 0) ? 1 : 0; + queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work); +} + +static int eeepc_led_init(struct eeepc_laptop *eeepc) { int rv; - if (get_acpi(CM_ASL_TPD) == -ENODEV) + if (get_acpi(eeepc, CM_ASL_TPD) == -ENODEV) return 0; - led_workqueue = create_singlethread_workqueue("led_workqueue"); - if (!led_workqueue) + eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue"); + if (!eeepc->led_workqueue) return -ENOMEM; + INIT_WORK(&eeepc->tpd_led_work, tpd_led_update); + + eeepc->tpd_led.name = "eeepc::touchpad"; + eeepc->tpd_led.brightness_set = tpd_led_set; + eeepc->tpd_led.max_brightness = 1; - rv = led_classdev_register(dev, &tpd_led); + rv = led_classdev_register(&eeepc->platform_device->dev, + &eeepc->tpd_led); if (rv) { - destroy_workqueue(led_workqueue); + destroy_workqueue(eeepc->led_workqueue); return rv; } return 0; } -static void eeepc_led_exit(void) +static void eeepc_led_exit(struct eeepc_laptop *eeepc) { - if (tpd_led.dev) - led_classdev_unregister(&tpd_led); - if (led_workqueue) - destroy_workqueue(led_workqueue); + if (eeepc->tpd_led.dev) + led_classdev_unregister(&eeepc->tpd_led); + if (eeepc->led_workqueue) + destroy_workqueue(eeepc->led_workqueue); } /* * PCI hotplug (for wlan rfkill) */ -static bool eeepc_wlan_rfkill_blocked(void) +static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc) { - if (get_acpi(CM_ASL_WLAN) == 1) + if (get_acpi(eeepc, CM_ASL_WLAN) == 1) return false; return true; } -static void eeepc_rfkill_hotplug(void) +static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc) { struct pci_dev *dev; struct pci_bus *bus; - bool blocked = eeepc_wlan_rfkill_blocked(); + bool blocked = eeepc_wlan_rfkill_blocked(eeepc); if (eeepc->wlan_rfkill) rfkill_set_sw_state(eeepc->wlan_rfkill, blocked); @@ -539,15 +566,18 @@ out_unlock: static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) { + struct eeepc_laptop *eeepc = data; + if (event != ACPI_NOTIFY_BUS_CHECK) return; - eeepc_rfkill_hotplug(); + eeepc_rfkill_hotplug(eeepc); } -static int eeepc_register_rfkill_notifier(char *node) +static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc, + char *node) { - acpi_status status = AE_OK; + acpi_status status; acpi_handle handle; status = acpi_get_handle(NULL, node, &handle); @@ -556,7 +586,7 @@ static int eeepc_register_rfkill_notifier(char *node) status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, eeepc_rfkill_notify, - NULL); + eeepc); if (ACPI_FAILURE(status)) pr_warning("Failed to register notify on %s\n", node); } else @@ -565,7 +595,8 @@ static int eeepc_register_rfkill_notifier(char *node) return 0; } -static void eeepc_unregister_rfkill_notifier(char *node) +static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc, + char *node) { acpi_status status = AE_OK; acpi_handle handle; @@ -585,7 +616,8 @@ static void eeepc_unregister_rfkill_notifier(char *node) static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) { - int val = get_acpi(CM_ASL_WLAN); + struct eeepc_laptop *eeepc = hotplug_slot->private; + int val = get_acpi(eeepc, CM_ASL_WLAN); if (val == 1 || val == 0) *value = val; @@ -607,7 +639,7 @@ static struct hotplug_slot_ops eeepc_hotplug_slot_ops = { .get_power_status = eeepc_get_adapter_status, }; -static int eeepc_setup_pci_hotplug(void) +static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc) { int ret = -ENOMEM; struct pci_bus *bus = pci_find_bus(0, 1); @@ -654,31 +686,34 @@ error_slot: */ static int eeepc_rfkill_set(void *data, bool blocked) { - unsigned long asl = (unsigned long)data; - return set_acpi(asl, !blocked); + acpi_handle handle = data; + + return write_acpi_int(handle, NULL, !blocked); } static const struct rfkill_ops eeepc_rfkill_ops = { .set_block = eeepc_rfkill_set, }; -static int eeepc_new_rfkill(struct rfkill **rfkill, - const char *name, struct device *dev, +static int eeepc_new_rfkill(struct eeepc_laptop *eeepc, + struct rfkill **rfkill, + const char *name, enum rfkill_type type, int cm) { + acpi_handle handle; int result; - result = get_acpi(cm); + result = acpi_setter_handle(eeepc, cm, &handle); if (result < 0) return result; - *rfkill = rfkill_alloc(name, dev, type, - &eeepc_rfkill_ops, (void *)(unsigned long)cm); + *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type, + &eeepc_rfkill_ops, handle); if (!*rfkill) return -EINVAL; - rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1); + rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1); result = rfkill_register(*rfkill); if (result) { rfkill_destroy(*rfkill); @@ -688,11 +723,11 @@ static int eeepc_new_rfkill(struct rfkill **rfkill, return 0; } -static void eeepc_rfkill_exit(void) +static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc) { - eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P5"); - eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); - eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); + eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5"); + eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6"); + eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7"); if (eeepc->wlan_rfkill) { rfkill_unregister(eeepc->wlan_rfkill); rfkill_destroy(eeepc->wlan_rfkill); @@ -702,7 +737,7 @@ static void eeepc_rfkill_exit(void) * Refresh pci hotplug in case the rfkill state was changed after * eeepc_unregister_rfkill_notifier() */ - eeepc_rfkill_hotplug(); + eeepc_rfkill_hotplug(eeepc); if (eeepc->hotplug_slot) pci_hp_deregister(eeepc->hotplug_slot); @@ -723,41 +758,41 @@ static void eeepc_rfkill_exit(void) } } -static int eeepc_rfkill_init(struct device *dev) +static int eeepc_rfkill_init(struct eeepc_laptop *eeepc) { int result = 0; mutex_init(&eeepc->hotplug_lock); - result = eeepc_new_rfkill(&eeepc->wlan_rfkill, - "eeepc-wlan", dev, - RFKILL_TYPE_WLAN, CM_ASL_WLAN); + result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill, + "eeepc-wlan", RFKILL_TYPE_WLAN, + CM_ASL_WLAN); if (result && result != -ENODEV) goto exit; - result = eeepc_new_rfkill(&eeepc->bluetooth_rfkill, - "eeepc-bluetooth", dev, - RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH); + result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill, + "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH, + CM_ASL_BLUETOOTH); if (result && result != -ENODEV) goto exit; - result = eeepc_new_rfkill(&eeepc->wwan3g_rfkill, - "eeepc-wwan3g", dev, - RFKILL_TYPE_WWAN, CM_ASL_3G); + result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill, + "eeepc-wwan3g", RFKILL_TYPE_WWAN, + CM_ASL_3G); if (result && result != -ENODEV) goto exit; - result = eeepc_new_rfkill(&eeepc->wimax_rfkill, - "eeepc-wimax", dev, - RFKILL_TYPE_WIMAX, CM_ASL_WIMAX); + result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill, + "eeepc-wimax", RFKILL_TYPE_WIMAX, + CM_ASL_WIMAX); if (result && result != -ENODEV) goto exit; - result = eeepc_setup_pci_hotplug(); + result = eeepc_setup_pci_hotplug(eeepc); /* * If we get -EBUSY then something else is handling the PCI hotplug - * don't fail in this case @@ -765,26 +800,28 @@ static int eeepc_rfkill_init(struct device *dev) if (result == -EBUSY) result = 0; - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P5"); - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); + eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5"); + eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6"); + eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7"); /* * Refresh pci hotplug in case the rfkill state was changed during * setup. */ - eeepc_rfkill_hotplug(); + eeepc_rfkill_hotplug(eeepc); exit: if (result && result != -ENODEV) - eeepc_rfkill_exit(); + eeepc_rfkill_exit(eeepc); return result; } /* * Platform driver - hibernate/resume callbacks */ -static int eeepc_thaw(struct device *device) +static int eeepc_hotk_thaw(struct device *device) { + struct eeepc_laptop *eeepc = dev_get_drvdata(device); + if (eeepc->wlan_rfkill) { bool wlan; @@ -793,35 +830,37 @@ static int eeepc_thaw(struct device *device) * during suspend. Normally it restores it on resume, but * we should kick it ourselves in case hibernation is aborted. */ - wlan = get_acpi(CM_ASL_WLAN); - set_acpi(CM_ASL_WLAN, wlan); + wlan = get_acpi(eeepc, CM_ASL_WLAN); + set_acpi(eeepc, CM_ASL_WLAN, wlan); } return 0; } -static int eeepc_restore(struct device *device) +static int eeepc_hotk_restore(struct device *device) { + struct eeepc_laptop *eeepc = dev_get_drvdata(device); + /* Refresh both wlan rfkill state and pci hotplug */ if (eeepc->wlan_rfkill) - eeepc_rfkill_hotplug(); + eeepc_rfkill_hotplug(eeepc); if (eeepc->bluetooth_rfkill) rfkill_set_sw_state(eeepc->bluetooth_rfkill, - get_acpi(CM_ASL_BLUETOOTH) != 1); + get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1); if (eeepc->wwan3g_rfkill) rfkill_set_sw_state(eeepc->wwan3g_rfkill, - get_acpi(CM_ASL_3G) != 1); + get_acpi(eeepc, CM_ASL_3G) != 1); if (eeepc->wimax_rfkill) rfkill_set_sw_state(eeepc->wimax_rfkill, - get_acpi(CM_ASL_WIMAX) != 1); + get_acpi(eeepc, CM_ASL_WIMAX) != 1); return 0; } static struct dev_pm_ops eeepc_pm_ops = { - .thaw = eeepc_thaw, - .restore = eeepc_restore, + .thaw = eeepc_hotk_thaw, + .restore = eeepc_hotk_restore, }; static struct platform_driver platform_driver = { @@ -947,35 +986,35 @@ static struct attribute_group hwmon_attribute_group = { .attrs = hwmon_attributes }; -static void eeepc_hwmon_exit(void) +static void eeepc_hwmon_exit(struct eeepc_laptop *eeepc) { struct device *hwmon; - hwmon = eeepc_hwmon_device; + hwmon = eeepc->hwmon_device; if (!hwmon) - return ; + return; sysfs_remove_group(&hwmon->kobj, &hwmon_attribute_group); hwmon_device_unregister(hwmon); - eeepc_hwmon_device = NULL; + eeepc->hwmon_device = NULL; } -static int eeepc_hwmon_init(struct device *dev) +static int eeepc_hwmon_init(struct eeepc_laptop *eeepc) { struct device *hwmon; int result; - hwmon = hwmon_device_register(dev); + hwmon = hwmon_device_register(&eeepc->platform_device->dev); if (IS_ERR(hwmon)) { pr_err("Could not register eeepc hwmon device\n"); - eeepc_hwmon_device = NULL; + eeepc->hwmon_device = NULL; return PTR_ERR(hwmon); } - eeepc_hwmon_device = hwmon; + eeepc->hwmon_device = hwmon; result = sysfs_create_group(&hwmon->kobj, &hwmon_attribute_group); if (result) - eeepc_hwmon_exit(); + eeepc_hwmon_exit(eeepc); return result; } @@ -984,12 +1023,16 @@ static int eeepc_hwmon_init(struct device *dev) */ static int read_brightness(struct backlight_device *bd) { - return get_acpi(CM_ASL_PANELBRIGHT); + struct eeepc_laptop *eeepc = bl_get_data(bd); + + return get_acpi(eeepc, CM_ASL_PANELBRIGHT); } static int set_brightness(struct backlight_device *bd, int value) { - return set_acpi(CM_ASL_PANELBRIGHT, value); + struct eeepc_laptop *eeepc = bl_get_data(bd); + + return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value); } static int update_bl_status(struct backlight_device *bd) @@ -1002,9 +1045,9 @@ static struct backlight_ops eeepcbl_ops = { .update_status = update_bl_status, }; -static int eeepc_backlight_notify(void) +static int eeepc_backlight_notify(struct eeepc_laptop *eeepc) { - struct backlight_device *bd = eeepc_backlight_device; + struct backlight_device *bd = eeepc->backlight_device; int old = bd->props.brightness; backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY); @@ -1012,52 +1055,55 @@ static int eeepc_backlight_notify(void) return old; } -static int eeepc_backlight_init(struct device *dev) +static int eeepc_backlight_init(struct eeepc_laptop *eeepc) { struct backlight_device *bd; - bd = backlight_device_register(EEEPC_LAPTOP_FILE, dev, - NULL, &eeepcbl_ops); + bd = backlight_device_register(EEEPC_LAPTOP_FILE, + &eeepc->platform_device->dev, + eeepc, &eeepcbl_ops); if (IS_ERR(bd)) { pr_err("Could not register eeepc backlight device\n"); - eeepc_backlight_device = NULL; + eeepc->backlight_device = NULL; return PTR_ERR(bd); } - eeepc_backlight_device = bd; + eeepc->backlight_device = bd; bd->props.max_brightness = 15; - bd->props.brightness = read_brightness(NULL); + bd->props.brightness = read_brightness(bd); bd->props.power = FB_BLANK_UNBLANK; backlight_update_status(bd); return 0; } -static void eeepc_backlight_exit(void) +static void eeepc_backlight_exit(struct eeepc_laptop *eeepc) { - if (eeepc_backlight_device) - backlight_device_unregister(eeepc_backlight_device); - eeepc_backlight_device = NULL; + if (eeepc->backlight_device) + backlight_device_unregister(eeepc->backlight_device); + eeepc->backlight_device = NULL; } /* * Input device (i.e. hotkeys) */ -static struct key_entry *eeepc_get_entry_by_scancode(int code) +static struct key_entry *eeepc_get_entry_by_scancode( + struct eeepc_laptop *eeepc, + int code) { struct key_entry *key; - for (key = eeepc_keymap; key->type != KE_END; key++) + for (key = eeepc->keymap; key->type != KE_END; key++) if (code == key->code) return key; return NULL; } -static void eeepc_input_notify(int event) +static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event) { static struct key_entry *key; - key = eeepc_get_entry_by_scancode(event); + key = eeepc_get_entry_by_scancode(eeepc, event); if (key) { switch (key->type) { case KE_KEY: @@ -1072,11 +1118,12 @@ static void eeepc_input_notify(int event) } } -static struct key_entry *eepc_get_entry_by_keycode(int code) +static struct key_entry *eeepc_get_entry_by_keycode( + struct eeepc_laptop *eeepc, int code) { struct key_entry *key; - for (key = eeepc_keymap; key->type != KE_END; key++) + for (key = eeepc->keymap; key->type != KE_END; key++) if (code == key->keycode && key->type == KE_KEY) return key; @@ -1085,7 +1132,8 @@ static struct key_entry *eepc_get_entry_by_keycode(int code) static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode) { - struct key_entry *key = eeepc_get_entry_by_scancode(scancode); + struct eeepc_laptop *eeepc = input_get_drvdata(dev); + struct key_entry *key = eeepc_get_entry_by_scancode(eeepc, scancode); if (key && key->type == KE_KEY) { *keycode = key->keycode; @@ -1097,18 +1145,19 @@ static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode) static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode) { + struct eeepc_laptop *eeepc = input_get_drvdata(dev); struct key_entry *key; int old_keycode; if (keycode < 0 || keycode > KEY_MAX) return -EINVAL; - key = eeepc_get_entry_by_scancode(scancode); + key = eeepc_get_entry_by_scancode(eeepc, scancode); if (key && key->type == KE_KEY) { old_keycode = key->keycode; key->keycode = keycode; set_bit(keycode, dev->keybit); - if (!eepc_get_entry_by_keycode(old_keycode)) + if (!eeepc_get_entry_by_keycode(eeepc, old_keycode)) clear_bit(old_keycode, dev->keybit); return 0; } @@ -1116,7 +1165,7 @@ static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode) return -EINVAL; } -static int eeepc_input_init(struct device *dev) +static int eeepc_input_init(struct eeepc_laptop *eeepc) { const struct key_entry *key; int result; @@ -1127,12 +1176,15 @@ static int eeepc_input_init(struct device *dev) return -ENOMEM; } eeepc->inputdev->name = "Asus EeePC extra buttons"; - eeepc->inputdev->dev.parent = dev; + eeepc->inputdev->dev.parent = &eeepc->platform_device->dev; eeepc->inputdev->phys = EEEPC_LAPTOP_FILE "/input0"; eeepc->inputdev->id.bustype = BUS_HOST; eeepc->inputdev->getkeycode = eeepc_getkeycode; eeepc->inputdev->setkeycode = eeepc_setkeycode; + input_set_drvdata(eeepc->inputdev, eeepc); + eeepc->keymap = kmemdup(eeepc_keymap, sizeof(eeepc_keymap), + GFP_KERNEL); for (key = eeepc_keymap; key->type != KE_END; key++) { switch (key->type) { case KE_KEY: @@ -1150,10 +1202,12 @@ static int eeepc_input_init(struct device *dev) return 0; } -static void eeepc_input_exit(void) +static void eeepc_input_exit(struct eeepc_laptop *eeepc) { - if (eeepc->inputdev) + if (eeepc->inputdev) { input_unregister_device(eeepc->inputdev); + kfree(eeepc->keymap); + } } /* @@ -1161,21 +1215,22 @@ static void eeepc_input_exit(void) */ static void eeepc_acpi_notify(struct acpi_device *device, u32 event) { + struct eeepc_laptop *eeepc = acpi_driver_data(device); u16 count; if (event > ACPI_MAX_SYS_NOTIFY) return; count = eeepc->event_count[event % 128]++; - acpi_bus_generate_proc_event(eeepc->device, event, count); - acpi_bus_generate_netlink_event(eeepc->device->pnp.device_class, - dev_name(&eeepc->device->dev), event, + acpi_bus_generate_proc_event(device, event, count); + acpi_bus_generate_netlink_event(device->pnp.device_class, + dev_name(&device->dev), event, count); if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) { int old_brightness, new_brightness; /* Update backlight device. */ - old_brightness = eeepc_backlight_notify(); + old_brightness = eeepc_backlight_notify(eeepc); /* Convert brightness event to keypress (obsolescent hack). */ new_brightness = event - NOTIFY_BRN_MIN; @@ -1191,10 +1246,10 @@ static void eeepc_acpi_notify(struct acpi_device *device, u32 event) */ } } - eeepc_input_notify(event); + eeepc_input_notify(eeepc, event); } -static void cmsg_quirk(int cm, const char *name) +static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name) { int dummy; @@ -1208,23 +1263,23 @@ static void cmsg_quirk(int cm, const char *name) } } -static void cmsg_quirks(void) +static void cmsg_quirks(struct eeepc_laptop *eeepc) { - cmsg_quirk(CM_ASL_LID, "LID"); - cmsg_quirk(CM_ASL_TYPE, "TYPE"); - cmsg_quirk(CM_ASL_PANELPOWER, "PANELPOWER"); - cmsg_quirk(CM_ASL_TPD, "TPD"); + cmsg_quirk(eeepc, CM_ASL_LID, "LID"); + cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE"); + cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER"); + cmsg_quirk(eeepc, CM_ASL_TPD, "TPD"); } -static int eeepc_acpi_init(void) +static int eeepc_acpi_init(struct eeepc_laptop *eeepc, struct acpi_device *device) { unsigned int init_flags; int result; - result = acpi_bus_get_status(eeepc->device); + result = acpi_bus_get_status(device); if (result) return result; - if (!eeepc->device->status.present) { + if (!device->status.present) { pr_err("Hotkey device not present, aborting\n"); return -ENODEV; } @@ -1242,25 +1297,27 @@ static int eeepc_acpi_init(void) pr_err("Get control methods supported failed\n"); return -ENODEV; } - cmsg_quirks(); + cmsg_quirks(eeepc); pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported); return 0; } -static void __devinit eeepc_enable_camera(void) +static void __devinit eeepc_enable_camera(struct eeepc_laptop *eeepc) { /* * If the following call to set_acpi() fails, it's because there's no * camera so we can ignore the error. */ - if (get_acpi(CM_ASL_CAMERA) == 0) - set_acpi(CM_ASL_CAMERA, 1); + if (get_acpi(eeepc, CM_ASL_CAMERA) == 0) + set_acpi(eeepc, CM_ASL_CAMERA, 1); } +static bool eeepc_device_present; + static int __devinit eeepc_acpi_add(struct acpi_device *device) { - struct device *dev; + struct eeepc_laptop *eeepc; int result; pr_notice(EEEPC_LAPTOP_NAME "\n"); @@ -1271,53 +1328,64 @@ static int __devinit eeepc_acpi_add(struct acpi_device *device) strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME); strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS); device->driver_data = eeepc; - eeepc->device = device; - result = eeepc_acpi_init(); + result = eeepc_acpi_init(eeepc, device); if (result) goto fail_platform; - eeepc_enable_camera(); + eeepc_enable_camera(eeepc); - result = eeepc_platform_init(); + /* + * Register the platform device first. It is used as a parent for the + * sub-devices below. + * + * Note that if there are multiple instances of this ACPI device it + * will bail out, because the platform device is registered with a + * fixed name. Of course it doesn't make sense to have more than one, + * and machine-specific scripts find the fixed name convenient. But + * It's also good for us to exclude multiple instances because both + * our hwmon and our wlan rfkill subdevice use global ACPI objects + * (the EC and the wlan PCI slot respectively). + */ + result = eeepc_platform_init(eeepc); if (result) goto fail_platform; - dev = &platform_device->dev; if (!acpi_video_backlight_support()) { - result = eeepc_backlight_init(dev); + result = eeepc_backlight_init(eeepc); if (result) goto fail_backlight; } else pr_info("Backlight controlled by ACPI video driver\n"); - result = eeepc_input_init(dev); + result = eeepc_input_init(eeepc); if (result) goto fail_input; - result = eeepc_hwmon_init(dev); + result = eeepc_hwmon_init(eeepc); if (result) goto fail_hwmon; - result = eeepc_led_init(dev); + result = eeepc_led_init(eeepc); if (result) goto fail_led; - result = eeepc_rfkill_init(dev); + result = eeepc_rfkill_init(eeepc); if (result) goto fail_rfkill; + eeepc_device_present = true; return 0; fail_rfkill: - eeepc_led_exit(); + eeepc_led_exit(eeepc); fail_led: - eeepc_hwmon_exit(); + eeepc_hwmon_exit(eeepc); fail_hwmon: - eeepc_input_exit(); + eeepc_input_exit(eeepc); fail_input: - eeepc_backlight_exit(); + eeepc_backlight_exit(eeepc); fail_backlight: - eeepc_platform_exit(); + eeepc_platform_exit(eeepc); fail_platform: kfree(eeepc); @@ -1326,12 +1394,14 @@ fail_platform: static int eeepc_acpi_remove(struct acpi_device *device, int type) { - eeepc_backlight_exit(); - eeepc_rfkill_exit(); - eeepc_input_exit(); - eeepc_hwmon_exit(); - eeepc_led_exit(); - eeepc_platform_exit(); + struct eeepc_laptop *eeepc = acpi_driver_data(device); + + eeepc_backlight_exit(eeepc); + eeepc_rfkill_exit(eeepc); + eeepc_input_exit(eeepc); + eeepc_hwmon_exit(eeepc); + eeepc_led_exit(eeepc); + eeepc_platform_exit(eeepc); kfree(eeepc); return 0; @@ -1369,7 +1439,7 @@ static int __init eeepc_laptop_init(void) result = acpi_bus_register_driver(&eeepc_acpi_driver); if (result < 0) goto fail_acpi_driver; - if (!eeepc) { + if (!eeepc_device_present) { result = -ENODEV; goto fail_no_device; } -- cgit v0.10.2 From 16851f92a5998bf8880a7401898ecfe351913854 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Thu, 3 Dec 2009 07:45:10 +0000 Subject: asus-laptop: use KEY_F13 to map "Disable Touchpad" event The same key is used in toshiba-laptop, and there is no reserved key for that. Signed-off-by: Corentin Chary Signed-off-by: Len Brown diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 6c05172..e931e80 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -313,7 +313,7 @@ static struct key_entry asus_keymap[] = { {KE_KEY, 0x5F, KEY_WLAN}, {KE_KEY, 0x60, KEY_SWITCHVIDEOMODE}, {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE}, - {KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */ + {KE_KEY, 0x6B, KEY_F13}, /* Lock Touchpad */ {KE_KEY, 0x82, KEY_CAMERA}, {KE_KEY, 0x8A, KEY_PROG1}, {KE_KEY, 0x95, KEY_MEDIA}, -- cgit v0.10.2 From 14f8af311e7d3e4198cbaade84a34f86505dcb37 Mon Sep 17 00:00:00 2001 From: Ike Panhc Date: Thu, 3 Dec 2009 07:45:11 +0000 Subject: asus-laptop: add Lenovo SL hotkey support Lenovo SL series laptop has a very similar DSDT with Asus laptops. We can easily have the extra ACPI function support with little modification in asus-laptop.c Here is the hotkey enablement for Lenovo SL series laptop. This patch will enable the following hotkey: - Volumn Up - Volumn Down - Mute - Screen Lock (Fn+F2) - Battery Status (Fn+F3) - WLAN switch (Fn+F5) - Video output switch (Fn+F7) - Touchpad switch (Fn+F8) - Screen Magnifier (Fn+Space) The following function of Lenovo SL laptop is still need to be enabled: - Hotkey: KEY_SUSPEND (Fn+F4), KEY_SLEEP (Fn+F12), Dock Eject (Fn+F9) - Rfkill for bluetooth and wlan - LenovoCare LED - Hwmon for fan speed - Fingerprint scanner - Active Protection System Signed-off-by: Ike Panhc Signed-off-by: Len Brown diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index e931e80..83948df 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -221,6 +221,7 @@ static struct asus_hotk *hotk; */ static const struct acpi_device_id asus_device_ids[] = { {"ATK0100", 0}, + {"ATK0101", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, asus_device_ids); @@ -294,6 +295,11 @@ struct key_entry { enum { KE_KEY, KE_END }; static struct key_entry asus_keymap[] = { + {KE_KEY, 0x02, KEY_SCREENLOCK}, + {KE_KEY, 0x05, KEY_WLAN}, + {KE_KEY, 0x08, KEY_F13}, + {KE_KEY, 0x17, KEY_ZOOM}, + {KE_KEY, 0x1f, KEY_BATTERY}, {KE_KEY, 0x30, KEY_VOLUMEUP}, {KE_KEY, 0x31, KEY_VOLUMEDOWN}, {KE_KEY, 0x32, KEY_MUTE}, @@ -313,6 +319,8 @@ static struct key_entry asus_keymap[] = { {KE_KEY, 0x5F, KEY_WLAN}, {KE_KEY, 0x60, KEY_SWITCHVIDEOMODE}, {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE}, + {KE_KEY, 0x62, KEY_SWITCHVIDEOMODE}, + {KE_KEY, 0x63, KEY_SWITCHVIDEOMODE}, {KE_KEY, 0x6B, KEY_F13}, /* Lock Touchpad */ {KE_KEY, 0x82, KEY_CAMERA}, {KE_KEY, 0x8A, KEY_PROG1}, -- cgit v0.10.2 From 1f0233eee9b385d78fda78626136c43e045082f7 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Thu, 3 Dec 2009 07:45:12 +0000 Subject: asus-laptop: Add wlan switch found on V6V Signed-off-by: Corentin Chary Signed-off-by: Len Brown diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 83948df..3348cc6 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -323,6 +323,7 @@ static struct key_entry asus_keymap[] = { {KE_KEY, 0x63, KEY_SWITCHVIDEOMODE}, {KE_KEY, 0x6B, KEY_F13}, /* Lock Touchpad */ {KE_KEY, 0x82, KEY_CAMERA}, + {KE_KEY, 0x88, KEY_WLAN }, {KE_KEY, 0x8A, KEY_PROG1}, {KE_KEY, 0x95, KEY_MEDIA}, {KE_KEY, 0x99, KEY_PHONE}, -- cgit v0.10.2 From b39b85e74acfd62a22afc33a88a7bda36beb3367 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Thu, 3 Dec 2009 07:45:13 +0000 Subject: eeepc-laptop: map keys found on newer eeepc Signed-off-by: Corentin Chary Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 935ec44..920d9d9 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -136,6 +136,7 @@ static const struct key_entry eeepc_keymap[] = { {KE_KEY, 0x13, KEY_MUTE }, {KE_KEY, 0x14, KEY_VOLUMEDOWN }, {KE_KEY, 0x15, KEY_VOLUMEUP }, + {KE_KEY, 0x16, KEY_DISPLAY_OFF }, {KE_KEY, 0x1a, KEY_COFFEE }, {KE_KEY, 0x1b, KEY_ZOOM }, {KE_KEY, 0x1c, KEY_PROG2 }, @@ -145,6 +146,8 @@ static const struct key_entry eeepc_keymap[] = { {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, + {KE_KEY, 0x37, KEY_F13 }, /* Disable Touchpad */ + {KE_KEY, 0x38, KEY_F14 }, {KE_END, 0}, }; -- cgit v0.10.2 From f90be874303eddc53c199083a37bc44d65ab8351 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Thu, 3 Dec 2009 07:45:14 +0000 Subject: eeepc-laptop: fix coding style fix styles problems introduced by commit e86bda235a08b6a8e64c1e8bb9d175f6961554e3 Signed-off-by: Corentin Chary Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 920d9d9..5f0eb76 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -244,7 +244,8 @@ static int get_acpi(struct eeepc_laptop *eeepc, int cm) return value; } -static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm, acpi_handle *handle) +static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm, + acpi_handle *handle) { const char *method = cm_setv[cm]; acpi_status status; @@ -255,7 +256,7 @@ static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm, acpi_handle *h return -ENODEV; status = acpi_get_handle(eeepc->handle, (char *)method, - handle); + handle); if (status != AE_OK) { pr_warning("Error finding %s\n", method); return -ENODEV; @@ -1274,7 +1275,8 @@ static void cmsg_quirks(struct eeepc_laptop *eeepc) cmsg_quirk(eeepc, CM_ASL_TPD, "TPD"); } -static int eeepc_acpi_init(struct eeepc_laptop *eeepc, struct acpi_device *device) +static int eeepc_acpi_init(struct eeepc_laptop *eeepc, + struct acpi_device *device) { unsigned int init_flags; int result; -- cgit v0.10.2 From 325fb8e9aeddf7bf8a7a892869dca00e7305c41e Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Thu, 3 Dec 2009 07:45:15 +0000 Subject: eeepc-laptop: re-add check for eeepc->backlight == NULL As Corentin points out, we do not create a backlight device if the ACPI video driver is able to provide equivalent functionality. So we do need to check before we try to update the backlight device. We now ignore brightness events completely if we have not created a backlight device. This is slightly more cautious than the original check. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 5f0eb76..d07a4c0 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -1230,27 +1230,35 @@ static void eeepc_acpi_notify(struct acpi_device *device, u32 event) dev_name(&device->dev), event, count); + /* Brightness events are special */ if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) { - int old_brightness, new_brightness; - /* Update backlight device. */ - old_brightness = eeepc_backlight_notify(eeepc); - - /* Convert brightness event to keypress (obsolescent hack). */ - new_brightness = event - NOTIFY_BRN_MIN; - - if (new_brightness < old_brightness) { - event = NOTIFY_BRN_MIN; /* brightness down */ - } else if (new_brightness > old_brightness) { - event = NOTIFY_BRN_MAX; /* brightness up */ - } else { - /* - * no change in brightness - already at min/max, - * event will be desired value (or else ignored). - */ + /* Ignore them completely if the acpi video driver is used */ + if (eeepc->backlight_device != NULL) { + int old_brightness, new_brightness; + + /* Update the backlight device. */ + old_brightness = eeepc_backlight_notify(eeepc); + + /* Convert event to keypress (obsolescent hack) */ + new_brightness = event - NOTIFY_BRN_MIN; + + if (new_brightness < old_brightness) { + event = NOTIFY_BRN_MIN; /* brightness down */ + } else if (new_brightness > old_brightness) { + event = NOTIFY_BRN_MAX; /* brightness up */ + } else { + /* + * no change in brightness - already at min/max, + * event will be desired value (or else ignored) + */ + } + eeepc_input_notify(eeepc, event); } + } else { + /* Everything else is a bona-fide keypress event */ + eeepc_input_notify(eeepc, event); } - eeepc_input_notify(eeepc, event); } static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name) -- cgit v0.10.2 From 728900f6fa7142e07a67d10d862bcb774d7a3493 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Thu, 3 Dec 2009 07:45:17 +0000 Subject: asus-laptop: schedule display_get and lcd_switch for removal Signed-off-by: Corentin Chary Signed-off-by: Len Brown diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index bc693ff..d1c9e17 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -489,3 +489,23 @@ Why: With the recent innovations in CPU hardware acceleration technologies Who: Alok N Kataria ---------------------------- + +What: Support for lcd_switch and display_get in asus-laptop driver +When: March 2010 +Why: These two features use non-standard interfaces. There are the + only features that really need multiple path to guess what's + the right method name on a specific laptop. + + Removing them will allow to remove a lot of code an significantly + clean the drivers. + + This will affect the backlight code which won't be able to know + if the backlight is on or off. The platform display file will also be + write only (like the one in eeepc-laptop). + + This should'nt affect a lot of user because they usually know + when their display is on or off. + +Who: Corentin Chary + +---------------------------- -- cgit v0.10.2 From 9174e4989ecf53eca69767229deb9ad85efd55fe Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 16 Nov 2009 16:58:51 +0300 Subject: powerpc/83xx: mpc8349emitx - add gpio controller declarations mpc8349 bears two GPIO controllers. Enable support for them. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Kumar Gala diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index feeeb7f..16872c9 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -63,6 +63,24 @@ reg = <0x200 0x100>; }; + gpio1: gpio-controller@c00 { + #gpio-cells = <2>; + compatible = "fsl,mpc8349-gpio"; + reg = <0xc00 0x100>; + interrupts = <74 0x8>; + interrupt-parent = <&ipic>; + gpio-controller; + }; + + gpio2: gpio-controller@d00 { + #gpio-cells = <2>; + compatible = "fsl,mpc8349-gpio"; + reg = <0xd00 0x100>; + interrupts = <75 0x8>; + interrupt-parent = <&ipic>; + gpio-controller; + }; + i2c@3000 { #address-cells = <1>; #size-cells = <0>; -- cgit v0.10.2 From 3320cf844f3183870e66059174ce73f9662e523b Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 16 Nov 2009 16:58:52 +0300 Subject: powerpc/83xx: mpc8349emitx - populate I2C busses in device tree Add OF descriptions of EEPROM, two GPIO extenders and SPD hanging on I2C on this board. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Kumar Gala diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index 16872c9..0fb78b2 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -90,6 +90,12 @@ interrupts = <14 0x8>; interrupt-parent = <&ipic>; dfsrr; + + eeprom: at24@50 { + compatible = "st-micro,24c256"; + reg = <0x50>; + }; + }; i2c@3100 { @@ -109,6 +115,25 @@ interrupt-parent = <&ipic>; }; + pcf1: iexp@38 { + #gpio-cells = <2>; + compatible = "ti,pcf8574a"; + reg = <0x38>; + gpio-controller; + }; + + pcf2: iexp@39 { + #gpio-cells = <2>; + compatible = "ti,pcf8574a"; + reg = <0x39>; + gpio-controller; + }; + + spd: at24@51 { + compatible = "at24,spd"; + reg = <0x51>; + }; + mcu_pio: mcu@a { #gpio-cells = <2>; compatible = "fsl,mc9s08qg8-mpc8349emitx", -- cgit v0.10.2 From 1d88fd11a2484b1bc0a36010781dc410446bef29 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 16 Nov 2009 23:51:20 +0300 Subject: powerpc/83xx: mpc8349emitx - add OF descriptions of LocalBus devices Describe all LocalBus chipselects on MPC8349E-MITX board. Also add flash bindings. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Kumar Gala diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index 0fb78b2..346d1ba 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -374,7 +374,26 @@ compatible = "fsl,mpc8349e-localbus", "fsl,pq2pro-localbus"; reg = <0xe0005000 0xd8>; - ranges = <0x3 0x0 0xf0000000 0x210>; + ranges = <0x0 0x0 0xfe000000 0x1000000 /* flash */ + 0x1 0x0 0xf8000000 0x20000 /* VSC 7385 */ + 0x2 0x0 0xf9000000 0x200000 /* exp slot */ + 0x3 0x0 0xf0000000 0x210>; /* CF slot */ + + flash@0,0 { + compatible = "cfi-flash"; + reg = <0x0 0x0 0x800000>; + bank-width = <2>; + device-width = <1>; + }; + + flash@0,800000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0x0 0x800000 0x800000>; + bank-width = <2>; + device-width = <1>; + }; pata@3,0 { compatible = "fsl,mpc8349emitx-pata", "ata-generic"; -- cgit v0.10.2 From b387dfe902c352d5be4690a135412ece4868b531 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 16 Nov 2009 16:58:54 +0300 Subject: powerpc/83xx: mpc8349emitx - add leds-gpio binding Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Kumar Gala diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index 346d1ba..b53d1df 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -318,6 +318,24 @@ reg = <0x700 0x100>; device_type = "ipic"; }; + + gpio-leds { + compatible = "gpio-leds"; + + green { + label = "Green"; + gpios = <&pcf1 0 1>; + linux,default-trigger = "heartbeat"; + }; + + yellow { + label = "Yellow"; + gpios = <&pcf1 1 1>; + /* linux,default-trigger = "heartbeat"; */ + default-state = "on"; + }; + }; + }; pci0: pci@e0008500 { -- cgit v0.10.2 From e5dec39474fac3458ad6a649eab8cabfc977ae87 Mon Sep 17 00:00:00 2001 From: Frank Zago Date: Wed, 9 Dec 2009 13:51:36 -0800 Subject: RDMA/nes: In nes_post_send() always set bad_wr on error On error, set bad_wr in nes_post_send(). Stop processing ib_wr queue when an error is detected. Signed-off-by: Frank Zago Signed-off-by: Chien Tung Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index a680c42..25b52d2 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -3386,8 +3386,10 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, wqe_count = 0; total_payload_length = 0; - if (nesqp->ibqp_state > IB_QPS_RTS) - return -EINVAL; + if (nesqp->ibqp_state > IB_QPS_RTS) { + err = -EINVAL; + goto out; + } spin_lock_irqsave(&nesqp->lock, flags); @@ -3498,6 +3500,9 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, break; } + if (err) + break; + if (ib_wr->send_flags & IB_SEND_SIGNALED) { wqe_misc |= NES_IWARP_SQ_WQE_SIGNALED_COMPL; } @@ -3522,6 +3527,7 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, spin_unlock_irqrestore(&nesqp->lock, flags); +out: if (err) *bad_wr = ib_wr; return err; -- cgit v0.10.2 From 4293fdc115e1e4f83dcb9ec6cbd3a54c563835f0 Mon Sep 17 00:00:00 2001 From: Frank Zago Date: Wed, 9 Dec 2009 13:51:36 -0800 Subject: RDMA/nes: In nes_post_recv() always set bad_wr on error On error, set bad_wr in nes_post_recv(). Stop processing ib_wr queue when an error is detected. Signed-off-by: Frank Zago Signed-off-by: Chien Tung Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 25b52d2..0b17c01 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -3554,8 +3554,10 @@ static int nes_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, u32 counter; u32 total_payload_length; - if (nesqp->ibqp_state > IB_QPS_RTS) - return -EINVAL; + if (nesqp->ibqp_state > IB_QPS_RTS) { + err = -EINVAL; + goto out; + } spin_lock_irqsave(&nesqp->lock, flags); @@ -3618,6 +3620,7 @@ static int nes_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, spin_unlock_irqrestore(&nesqp->lock, flags); +out: if (err) *bad_wr = ib_wr; return err; -- cgit v0.10.2 From 649fe4aeab8c9b90eb31c899791534add0c78e04 Mon Sep 17 00:00:00 2001 From: Chien Tung Date: Wed, 9 Dec 2009 13:51:37 -0800 Subject: RDMA/nes: Add support for IB_WR_*INV Add support for IB_WR_SEND_WITH_INV, IB_WR_RDMA_READ_WITH_INV and IB_WR_LOCAL_INV. Signed-off-by: Chien Tung Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 0b17c01..499dd78 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -3373,18 +3373,12 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, struct nes_device *nesdev = nesvnic->nesdev; struct nes_qp *nesqp = to_nesqp(ibqp); struct nes_hw_qp_wqe *wqe; - int err; + int err = 0; u32 qsize = nesqp->hwqp.sq_size; u32 head; - u32 wqe_misc; - u32 wqe_count; + u32 wqe_misc = 0; + u32 wqe_count = 0; u32 counter; - u32 total_payload_length; - - err = 0; - wqe_misc = 0; - wqe_count = 0; - total_payload_length = 0; if (nesqp->ibqp_state > IB_QPS_RTS) { err = -EINVAL; @@ -3415,91 +3409,117 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, u64temp = (u64)(ib_wr->wr_id); set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX, u64temp); - switch (ib_wr->opcode) { - case IB_WR_SEND: - if (ib_wr->send_flags & IB_SEND_SOLICITED) { - wqe_misc = NES_IWARP_SQ_OP_SENDSE; - } else { - wqe_misc = NES_IWARP_SQ_OP_SEND; - } - if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { - err = -EINVAL; - break; - } - if (ib_wr->send_flags & IB_SEND_FENCE) { - wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; - } - if ((ib_wr->send_flags & IB_SEND_INLINE) && - ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) && - (ib_wr->sg_list[0].length <= 64)) { - memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX], - (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length); - set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX, - ib_wr->sg_list[0].length); - wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA; - } else { - fill_wqe_sg_send(wqe, ib_wr, 1); - } + switch (ib_wr->opcode) { + case IB_WR_SEND: + case IB_WR_SEND_WITH_INV: + if (IB_WR_SEND == ib_wr->opcode) { + if (ib_wr->send_flags & IB_SEND_SOLICITED) + wqe_misc = NES_IWARP_SQ_OP_SENDSE; + else + wqe_misc = NES_IWARP_SQ_OP_SEND; + } else { + if (ib_wr->send_flags & IB_SEND_SOLICITED) + wqe_misc = NES_IWARP_SQ_OP_SENDSEINV; + else + wqe_misc = NES_IWARP_SQ_OP_SENDINV; - break; - case IB_WR_RDMA_WRITE: - wqe_misc = NES_IWARP_SQ_OP_RDMAW; - if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { - nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=%u\n", - ib_wr->num_sge, - nesdev->nesadapter->max_sge); - err = -EINVAL; - break; - } - if (ib_wr->send_flags & IB_SEND_FENCE) { - wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; - } + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_INV_STAG_LOW_IDX, + ib_wr->ex.invalidate_rkey); + } - set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, - ib_wr->wr.rdma.rkey); - set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, - ib_wr->wr.rdma.remote_addr); - - if ((ib_wr->send_flags & IB_SEND_INLINE) && - ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) && - (ib_wr->sg_list[0].length <= 64)) { - memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX], - (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length); - set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX, - ib_wr->sg_list[0].length); - wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA; - } else { - fill_wqe_sg_send(wqe, ib_wr, 1); - } - wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX] = - wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]; - break; - case IB_WR_RDMA_READ: - /* iWARP only supports 1 sge for RDMA reads */ - if (ib_wr->num_sge > 1) { - nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=1\n", - ib_wr->num_sge); - err = -EINVAL; - break; - } - wqe_misc = NES_IWARP_SQ_OP_RDMAR; - set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, - ib_wr->wr.rdma.remote_addr); - set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, - ib_wr->wr.rdma.rkey); - set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX, - ib_wr->sg_list->length); - set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_FRAG0_LOW_IDX, - ib_wr->sg_list->addr); - set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_STAG0_IDX, - ib_wr->sg_list->lkey); - break; - default: - /* error */ - err = -EINVAL; - break; + if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { + err = -EINVAL; + break; } + if (ib_wr->send_flags & IB_SEND_FENCE) + wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; + + if ((ib_wr->send_flags & IB_SEND_INLINE) && + ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) && + (ib_wr->sg_list[0].length <= 64)) { + memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX], + (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length); + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX, + ib_wr->sg_list[0].length); + wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA; + } else { + fill_wqe_sg_send(wqe, ib_wr, 1); + } + + break; + case IB_WR_RDMA_WRITE: + wqe_misc = NES_IWARP_SQ_OP_RDMAW; + if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { + nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=%u\n", + ib_wr->num_sge, nesdev->nesadapter->max_sge); + err = -EINVAL; + break; + } + + if (ib_wr->send_flags & IB_SEND_FENCE) + wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; + + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, + ib_wr->wr.rdma.rkey); + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, + ib_wr->wr.rdma.remote_addr); + + if ((ib_wr->send_flags & IB_SEND_INLINE) && + ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) && + (ib_wr->sg_list[0].length <= 64)) { + memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX], + (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length); + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX, + ib_wr->sg_list[0].length); + wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA; + } else { + fill_wqe_sg_send(wqe, ib_wr, 1); + } + + wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX] = + wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]; + break; + case IB_WR_RDMA_READ: + case IB_WR_RDMA_READ_WITH_INV: + /* iWARP only supports 1 sge for RDMA reads */ + if (ib_wr->num_sge > 1) { + nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=1\n", + ib_wr->num_sge); + err = -EINVAL; + break; + } + if (ib_wr->opcode == IB_WR_RDMA_READ) { + wqe_misc = NES_IWARP_SQ_OP_RDMAR; + } else { + wqe_misc = NES_IWARP_SQ_OP_RDMAR_LOCINV; + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_INV_STAG_LOW_IDX, + ib_wr->ex.invalidate_rkey); + } + + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, + ib_wr->wr.rdma.remote_addr); + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, + ib_wr->wr.rdma.rkey); + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX, + ib_wr->sg_list->length); + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_FRAG0_LOW_IDX, + ib_wr->sg_list->addr); + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_STAG0_IDX, + ib_wr->sg_list->lkey); + break; + case IB_WR_LOCAL_INV: + wqe_misc = NES_IWARP_SQ_OP_LOCINV; + set_wqe_32bit_value(wqe->wqe_words, + NES_IWARP_SQ_LOCINV_WQE_INV_STAG_IDX, + ib_wr->ex.invalidate_rkey); + break; + default: + /* error */ + err = -EINVAL; + break; + } + if (err) break; @@ -3729,6 +3749,9 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) nes_debug(NES_DBG_CQ, "Operation = Send.\n"); entry->opcode = IB_WC_SEND; break; + case NES_IWARP_SQ_OP_LOCINV: + entry->opcode = IB_WR_LOCAL_INV; + break; } nesqp->hwqp.sq_tail = (wqe_index+1)&(nesqp->hwqp.sq_size - 1); -- cgit v0.10.2 From 55464d461bdcffc4422aebfb750eacf99e3c0f27 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 9 Dec 2009 14:20:04 -0800 Subject: IB: Clarify the documentation of ib_post_send() Clarify the behavior of ib_post_send() when a list of work requests is passed in and an immediate error is returned. Signed-off-by: Bart Van Assche Signed-off-by: Roland Dreier diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index c179318..09509ed 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -1425,6 +1425,11 @@ int ib_destroy_qp(struct ib_qp *qp); * @send_wr: A list of work requests to post on the send queue. * @bad_send_wr: On an immediate failure, this parameter will reference * the work request that failed to be posted on the QP. + * + * While IBA Vol. 1 section 11.4.1.1 specifies that if an immediate + * error is returned, the QP state shall not be affected, + * ib_post_send() will return an immediate error after queueing any + * earlier work requests in the list. */ static inline int ib_post_send(struct ib_qp *qp, struct ib_send_wr *send_wr, -- cgit v0.10.2 From f7111821e51a58ee0f548f256743121ce1b365ae Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 9 Dec 2009 14:21:36 -0800 Subject: IB: Fix typo in ipoib.txt Delete extra words in "is to takes advantage of". Signed-off-by: Bart Van Assche Signed-off-by: Roland Dreier diff --git a/Documentation/infiniband/ipoib.txt b/Documentation/infiniband/ipoib.txt index 6d40f00..64eeb55 100644 --- a/Documentation/infiniband/ipoib.txt +++ b/Documentation/infiniband/ipoib.txt @@ -36,11 +36,11 @@ Datagram vs Connected modes fabric with a 2K MTU, the IPoIB MTU will be 2048 - 4 = 2044 bytes. In connected mode, the IB RC (Reliable Connected) transport is used. - Connected mode is to takes advantage of the connected nature of the - IB transport and allows an MTU up to the maximal IP packet size of - 64K, which reduces the number of IP packets needed for handling - large UDP datagrams, TCP segments, etc and increases the performance - for large messages. + Connected mode takes advantage of the connected nature of the IB + transport and allows an MTU up to the maximal IP packet size of 64K, + which reduces the number of IP packets needed for handling large UDP + datagrams, TCP segments, etc and increases the performance for large + messages. In connected mode, the interface's UD QP is still used for multicast and communication with peers that don't support connected mode. In -- cgit v0.10.2 From df42245a3c246ec1eeeedbc3e5edbcc17f081c79 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Wed, 9 Dec 2009 14:30:44 -0800 Subject: IB/uverbs: Fix return of PTR_ERR() of wrong pointer in ib_uverbs_get_context() Signed-off-by: Roel Kluin Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 56feab6..112d397 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -285,7 +285,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, ucontext = ibdev->alloc_ucontext(ibdev, &udata); if (IS_ERR(ucontext)) { - ret = PTR_ERR(file->ucontext); + ret = PTR_ERR(ucontext); goto err; } -- cgit v0.10.2 From c597b0240b686427248b6d4fc8adbe22f9a04c11 Mon Sep 17 00:00:00 2001 From: Frank Zago Date: Wed, 9 Dec 2009 14:56:11 -0800 Subject: RDMA/amso1100: Fix error paths in post_send and post_recv Always set bad_wr when an immediate error is detected. Signed-off-by: Frank Zago Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/amso1100/c2_qp.c b/drivers/infiniband/hw/amso1100/c2_qp.c index a6d8944..ad51886 100644 --- a/drivers/infiniband/hw/amso1100/c2_qp.c +++ b/drivers/infiniband/hw/amso1100/c2_qp.c @@ -798,8 +798,10 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, u8 actual_sge_count; u32 msg_size; - if (qp->state > IB_QPS_RTS) - return -EINVAL; + if (qp->state > IB_QPS_RTS) { + err = -EINVAL; + goto out; + } while (ib_wr) { @@ -930,6 +932,7 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, ib_wr = ib_wr->next; } +out: if (err) *bad_wr = ib_wr; return err; @@ -944,8 +947,10 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, unsigned long lock_flags; int err = 0; - if (qp->state > IB_QPS_RTS) - return -EINVAL; + if (qp->state > IB_QPS_RTS) { + err = -EINVAL; + goto out; + } /* * Try and post each work request @@ -998,6 +1003,7 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, ib_wr = ib_wr->next; } +out: if (err) *bad_wr = ib_wr; return err; -- cgit v0.10.2 From e147de03610fab7781c09aaed078a932e549ed4a Mon Sep 17 00:00:00 2001 From: Frank Zago Date: Wed, 9 Dec 2009 15:07:25 -0800 Subject: IB/ehca: Fix error paths in post_send and post_recv Always set bad_wr when an immediate error is detected. Do not report success if an error occurred. Signed-off-by: Frank Zago Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c index 8fd88cd..e3ec7fd 100644 --- a/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/drivers/infiniband/hw/ehca/ehca_reqs.c @@ -400,7 +400,6 @@ static inline void map_ib_wc_status(u32 cqe_status, static inline int post_one_send(struct ehca_qp *my_qp, struct ib_send_wr *cur_send_wr, - struct ib_send_wr **bad_send_wr, int hidden) { struct ehca_wqe *wqe_p; @@ -412,8 +411,6 @@ static inline int post_one_send(struct ehca_qp *my_qp, wqe_p = ipz_qeit_get_inc(&my_qp->ipz_squeue); if (unlikely(!wqe_p)) { /* too many posted work requests: queue overflow */ - if (bad_send_wr) - *bad_send_wr = cur_send_wr; ehca_err(my_qp->ib_qp.device, "Too many posted WQEs " "qp_num=%x", my_qp->ib_qp.qp_num); return -ENOMEM; @@ -433,8 +430,6 @@ static inline int post_one_send(struct ehca_qp *my_qp, */ if (unlikely(ret)) { my_qp->ipz_squeue.current_q_offset = start_offset; - if (bad_send_wr) - *bad_send_wr = cur_send_wr; ehca_err(my_qp->ib_qp.device, "Could not write WQE " "qp_num=%x", my_qp->ib_qp.qp_num); return -EINVAL; @@ -448,7 +443,6 @@ int ehca_post_send(struct ib_qp *qp, struct ib_send_wr **bad_send_wr) { struct ehca_qp *my_qp = container_of(qp, struct ehca_qp, ib_qp); - struct ib_send_wr *cur_send_wr; int wqe_cnt = 0; int ret = 0; unsigned long flags; @@ -457,7 +451,8 @@ int ehca_post_send(struct ib_qp *qp, if (unlikely(my_qp->state < IB_QPS_RTS)) { ehca_err(qp->device, "Invalid QP state qp_state=%d qpn=%x", my_qp->state, qp->qp_num); - return -EINVAL; + ret = -EINVAL; + goto out; } /* LOCK the QUEUE */ @@ -476,24 +471,21 @@ int ehca_post_send(struct ib_qp *qp, struct ib_send_wr circ_wr; memset(&circ_wr, 0, sizeof(circ_wr)); circ_wr.opcode = IB_WR_RDMA_READ; - post_one_send(my_qp, &circ_wr, NULL, 1); /* ignore retcode */ + post_one_send(my_qp, &circ_wr, 1); /* ignore retcode */ wqe_cnt++; ehca_dbg(qp->device, "posted circ wr qp_num=%x", qp->qp_num); my_qp->message_count = my_qp->packet_count = 0; } /* loop processes list of send reqs */ - for (cur_send_wr = send_wr; cur_send_wr != NULL; - cur_send_wr = cur_send_wr->next) { - ret = post_one_send(my_qp, cur_send_wr, bad_send_wr, 0); + while (send_wr) { + ret = post_one_send(my_qp, send_wr, 0); if (unlikely(ret)) { - /* if one or more WQEs were successful, don't fail */ - if (wqe_cnt) - ret = 0; goto post_send_exit0; } wqe_cnt++; - } /* eof for cur_send_wr */ + send_wr = send_wr->next; + } post_send_exit0: iosync(); /* serialize GAL register access */ @@ -503,6 +495,10 @@ post_send_exit0: my_qp, qp->qp_num, wqe_cnt, ret); my_qp->message_count += wqe_cnt; spin_unlock_irqrestore(&my_qp->spinlock_s, flags); + +out: + if (ret) + *bad_send_wr = send_wr; return ret; } @@ -511,7 +507,6 @@ static int internal_post_recv(struct ehca_qp *my_qp, struct ib_recv_wr *recv_wr, struct ib_recv_wr **bad_recv_wr) { - struct ib_recv_wr *cur_recv_wr; struct ehca_wqe *wqe_p; int wqe_cnt = 0; int ret = 0; @@ -522,27 +517,23 @@ static int internal_post_recv(struct ehca_qp *my_qp, if (unlikely(!HAS_RQ(my_qp))) { ehca_err(dev, "QP has no RQ ehca_qp=%p qp_num=%x ext_type=%d", my_qp, my_qp->real_qp_num, my_qp->ext_type); - return -ENODEV; + ret = -ENODEV; + goto out; } /* LOCK the QUEUE */ spin_lock_irqsave(&my_qp->spinlock_r, flags); - /* loop processes list of send reqs */ - for (cur_recv_wr = recv_wr; cur_recv_wr != NULL; - cur_recv_wr = cur_recv_wr->next) { + /* loop processes list of recv reqs */ + while (recv_wr) { u64 start_offset = my_qp->ipz_rqueue.current_q_offset; /* get pointer next to free WQE */ wqe_p = ipz_qeit_get_inc(&my_qp->ipz_rqueue); if (unlikely(!wqe_p)) { /* too many posted work requests: queue overflow */ - if (bad_recv_wr) - *bad_recv_wr = cur_recv_wr; - if (wqe_cnt == 0) { - ret = -ENOMEM; - ehca_err(dev, "Too many posted WQEs " - "qp_num=%x", my_qp->real_qp_num); - } + ret = -ENOMEM; + ehca_err(dev, "Too many posted WQEs " + "qp_num=%x", my_qp->real_qp_num); goto post_recv_exit0; } /* @@ -552,7 +543,7 @@ static int internal_post_recv(struct ehca_qp *my_qp, rq_map_idx = start_offset / my_qp->ipz_rqueue.qe_size; /* write a RECV WQE into the QUEUE */ - ret = ehca_write_rwqe(&my_qp->ipz_rqueue, wqe_p, cur_recv_wr, + ret = ehca_write_rwqe(&my_qp->ipz_rqueue, wqe_p, recv_wr, rq_map_idx); /* * if something failed, @@ -560,22 +551,20 @@ static int internal_post_recv(struct ehca_qp *my_qp, */ if (unlikely(ret)) { my_qp->ipz_rqueue.current_q_offset = start_offset; - *bad_recv_wr = cur_recv_wr; - if (wqe_cnt == 0) { - ret = -EINVAL; - ehca_err(dev, "Could not write WQE " - "qp_num=%x", my_qp->real_qp_num); - } + ret = -EINVAL; + ehca_err(dev, "Could not write WQE " + "qp_num=%x", my_qp->real_qp_num); goto post_recv_exit0; } qmap_entry = &my_qp->rq_map.map[rq_map_idx]; - qmap_entry->app_wr_id = get_app_wr_id(cur_recv_wr->wr_id); + qmap_entry->app_wr_id = get_app_wr_id(recv_wr->wr_id); qmap_entry->reported = 0; qmap_entry->cqe_req = 1; wqe_cnt++; - } /* eof for cur_recv_wr */ + recv_wr = recv_wr->next; + } /* eof for recv_wr */ post_recv_exit0: iosync(); /* serialize GAL register access */ @@ -584,6 +573,11 @@ post_recv_exit0: ehca_dbg(dev, "ehca_qp=%p qp_num=%x wqe_cnt=%d ret=%i", my_qp, my_qp->real_qp_num, wqe_cnt, ret); spin_unlock_irqrestore(&my_qp->spinlock_r, flags); + +out: + if (ret) + *bad_recv_wr = recv_wr; + return ret; } @@ -597,6 +591,7 @@ int ehca_post_recv(struct ib_qp *qp, if (unlikely(my_qp->state == IB_QPS_RESET)) { ehca_err(qp->device, "Invalid QP state qp_state=%d qpn=%x", my_qp->state, qp->qp_num); + *bad_recv_wr = recv_wr; return -EINVAL; } -- cgit v0.10.2 From e293a26fe97c8598a96562c1c9376d9ae6cb96dd Mon Sep 17 00:00:00 2001 From: Chien Tung Date: Wed, 9 Dec 2009 15:21:54 -0800 Subject: RDMA/nes: Correct fast memory registration implementation Replace alloc_fmr, unmap_fmr, dealloc_fmr and map_phys_fmr with alloc_fast_reg_mr, alloc_fast_reg_page_list, free_fast_reg_page_list. Signed-off-by: Chien Tung Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 3512d6d..3d9bbff 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -424,8 +424,9 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { nesadapter->base_pd = 1; - nesadapter->device_cap_flags = - IB_DEVICE_LOCAL_DMA_LKEY | IB_DEVICE_MEM_WINDOW; + nesadapter->device_cap_flags = IB_DEVICE_LOCAL_DMA_LKEY | + IB_DEVICE_MEM_WINDOW | + IB_DEVICE_MEM_MGT_EXTENSIONS; nesadapter->allocated_qps = (unsigned long *)&(((unsigned char *)nesadapter) [(sizeof(struct nes_adapter)+(sizeof(unsigned long)-1))&(~(sizeof(unsigned long)-1))]); diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index f28a41b..8a4c738 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h @@ -546,11 +546,23 @@ enum nes_iwarp_sq_fmr_wqe_word_idx { NES_IWARP_SQ_FMR_WQE_PBL_LENGTH_IDX = 14, }; +enum nes_iwarp_sq_fmr_opcodes { + NES_IWARP_SQ_FMR_WQE_ZERO_BASED = (1<<6), + NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_4K = (0<<7), + NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_2M = (1<<7), + NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_LOCAL_READ = (1<<16), + NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_LOCAL_WRITE = (1<<17), + NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_REMOTE_READ = (1<<18), + NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_REMOTE_WRITE = (1<<19), + NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_WINDOW_BIND = (1<<20), +}; + +#define NES_IWARP_SQ_FMR_WQE_MR_LENGTH_HIGH_MASK 0xFF; + enum nes_iwarp_sq_locinv_wqe_word_idx { NES_IWARP_SQ_LOCINV_WQE_INV_STAG_IDX = 6, }; - enum nes_iwarp_rq_wqe_word_idx { NES_IWARP_RQ_WQE_TOTAL_PAYLOAD_IDX = 1, NES_IWARP_RQ_WQE_COMP_CTX_LOW_IDX = 2, @@ -1153,6 +1165,19 @@ struct nes_pbl { /* TODO: need to add list for two level tables */ }; +#define NES_4K_PBL_CHUNK_SIZE 4096 + +struct nes_fast_mr_wqe_pbl { + u64 *kva; + dma_addr_t paddr; +}; + +struct nes_ib_fast_reg_page_list { + struct ib_fast_reg_page_list ibfrpl; + struct nes_fast_mr_wqe_pbl nes_wqe_pbl; + u64 pbl; +}; + struct nes_listener { struct work_struct work; struct workqueue_struct *wq; diff --git a/drivers/infiniband/hw/nes/nes_user.h b/drivers/infiniband/hw/nes/nes_user.h index cc90c14..ce62f3c 100644 --- a/drivers/infiniband/hw/nes/nes_user.h +++ b/drivers/infiniband/hw/nes/nes_user.h @@ -86,6 +86,7 @@ enum iwnes_memreg_type { IWNES_MEMREG_TYPE_CQ = 0x0002, IWNES_MEMREG_TYPE_MW = 0x0003, IWNES_MEMREG_TYPE_FMR = 0x0004, + IWNES_MEMREG_TYPE_FMEM = 0x0005, }; struct nes_mem_reg_req { diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 499dd78..0a2b18b 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -275,342 +275,236 @@ static int nes_bind_mw(struct ib_qp *ibqp, struct ib_mw *ibmw, } -/** - * nes_alloc_fmr +/* + * nes_alloc_fast_mr */ -static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd, - int ibmr_access_flags, - struct ib_fmr_attr *ibfmr_attr) +static int alloc_fast_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd, + u32 stag, u32 page_count) { - unsigned long flags; - struct nes_pd *nespd = to_nespd(ibpd); - struct nes_vnic *nesvnic = to_nesvnic(ibpd->device); - struct nes_device *nesdev = nesvnic->nesdev; - struct nes_adapter *nesadapter = nesdev->nesadapter; - struct nes_fmr *nesfmr; - struct nes_cqp_request *cqp_request; struct nes_hw_cqp_wqe *cqp_wqe; + struct nes_cqp_request *cqp_request; + unsigned long flags; int ret; - u32 stag; - u32 stag_index = 0; - u32 next_stag_index = 0; - u32 driver_key = 0; + struct nes_adapter *nesadapter = nesdev->nesadapter; u32 opcode = 0; - u8 stag_key = 0; - int i=0; - struct nes_vpbl vpbl; - - get_random_bytes(&next_stag_index, sizeof(next_stag_index)); - stag_key = (u8)next_stag_index; - - driver_key = 0; - - next_stag_index >>= 8; - next_stag_index %= nesadapter->max_mr; - - ret = nes_alloc_resource(nesadapter, nesadapter->allocated_mrs, - nesadapter->max_mr, &stag_index, &next_stag_index); - if (ret) { - goto failed_resource_alloc; - } - - nesfmr = kzalloc(sizeof(*nesfmr), GFP_KERNEL); - if (!nesfmr) { - ret = -ENOMEM; - goto failed_fmr_alloc; - } - - nesfmr->nesmr.mode = IWNES_MEMREG_TYPE_FMR; - if (ibfmr_attr->max_pages == 1) { - /* use zero length PBL */ - nesfmr->nesmr.pbl_4k = 0; - nesfmr->nesmr.pbls_used = 0; - } else if (ibfmr_attr->max_pages <= 32) { - /* use PBL 256 */ - nesfmr->nesmr.pbl_4k = 0; - nesfmr->nesmr.pbls_used = 1; - } else if (ibfmr_attr->max_pages <= 512) { - /* use 4K PBLs */ - nesfmr->nesmr.pbl_4k = 1; - nesfmr->nesmr.pbls_used = 1; - } else { - /* use two level 4K PBLs */ - /* add support for two level 256B PBLs */ - nesfmr->nesmr.pbl_4k = 1; - nesfmr->nesmr.pbls_used = 1 + (ibfmr_attr->max_pages >> 9) + - ((ibfmr_attr->max_pages & 511) ? 1 : 0); - } - /* Register the region with the adapter */ - spin_lock_irqsave(&nesadapter->pbl_lock, flags); - - /* track PBL resources */ - if (nesfmr->nesmr.pbls_used != 0) { - if (nesfmr->nesmr.pbl_4k) { - if (nesfmr->nesmr.pbls_used > nesadapter->free_4kpbl) { - spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); - ret = -ENOMEM; - goto failed_vpbl_avail; - } else { - nesadapter->free_4kpbl -= nesfmr->nesmr.pbls_used; - } - } else { - if (nesfmr->nesmr.pbls_used > nesadapter->free_256pbl) { - spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); - ret = -ENOMEM; - goto failed_vpbl_avail; - } else { - nesadapter->free_256pbl -= nesfmr->nesmr.pbls_used; - } - } - } - - /* one level pbl */ - if (nesfmr->nesmr.pbls_used == 0) { - nesfmr->root_vpbl.pbl_vbase = NULL; - nes_debug(NES_DBG_MR, "zero level pbl \n"); - } else if (nesfmr->nesmr.pbls_used == 1) { - /* can change it to kmalloc & dma_map_single */ - nesfmr->root_vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096, - &nesfmr->root_vpbl.pbl_pbase); - if (!nesfmr->root_vpbl.pbl_vbase) { - spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); - ret = -ENOMEM; - goto failed_vpbl_alloc; - } - nesfmr->leaf_pbl_cnt = 0; - nes_debug(NES_DBG_MR, "one level pbl, root_vpbl.pbl_vbase=%p \n", - nesfmr->root_vpbl.pbl_vbase); - } - /* two level pbl */ - else { - nesfmr->root_vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 8192, - &nesfmr->root_vpbl.pbl_pbase); - if (!nesfmr->root_vpbl.pbl_vbase) { - spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); - ret = -ENOMEM; - goto failed_vpbl_alloc; - } - - nesfmr->leaf_pbl_cnt = nesfmr->nesmr.pbls_used-1; - nesfmr->root_vpbl.leaf_vpbl = kzalloc(sizeof(*nesfmr->root_vpbl.leaf_vpbl)*1024, GFP_ATOMIC); - if (!nesfmr->root_vpbl.leaf_vpbl) { - spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); - ret = -ENOMEM; - goto failed_leaf_vpbl_alloc; - } - - nes_debug(NES_DBG_MR, "two level pbl, root_vpbl.pbl_vbase=%p" - " leaf_pbl_cnt=%d root_vpbl.leaf_vpbl=%p\n", - nesfmr->root_vpbl.pbl_vbase, nesfmr->leaf_pbl_cnt, nesfmr->root_vpbl.leaf_vpbl); - - for (i=0; ileaf_pbl_cnt; i++) - nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase = NULL; - - for (i=0; ileaf_pbl_cnt; i++) { - vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096, - &vpbl.pbl_pbase); - - if (!vpbl.pbl_vbase) { - ret = -ENOMEM; - spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); - goto failed_leaf_vpbl_pages_alloc; - } - - nesfmr->root_vpbl.pbl_vbase[i].pa_low = cpu_to_le32((u32)vpbl.pbl_pbase); - nesfmr->root_vpbl.pbl_vbase[i].pa_high = cpu_to_le32((u32)((((u64)vpbl.pbl_pbase)>>32))); - nesfmr->root_vpbl.leaf_vpbl[i] = vpbl; - - nes_debug(NES_DBG_MR, "pbase_low=0x%x, pbase_high=0x%x, vpbl=%p\n", - nesfmr->root_vpbl.pbl_vbase[i].pa_low, - nesfmr->root_vpbl.pbl_vbase[i].pa_high, - &nesfmr->root_vpbl.leaf_vpbl[i]); - } - } - nesfmr->ib_qp = NULL; - nesfmr->access_rights =0; + u16 major_code; + u64 region_length = page_count * PAGE_SIZE; - stag = stag_index << 8; - stag |= driver_key; - stag += (u32)stag_key; - spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); cqp_request = nes_get_cqp_request(nesdev); if (cqp_request == NULL) { nes_debug(NES_DBG_MR, "Failed to get a cqp_request.\n"); - ret = -ENOMEM; - goto failed_leaf_vpbl_pages_alloc; + return -ENOMEM; } + nes_debug(NES_DBG_MR, "alloc_fast_reg_mr: page_count = %d, " + "region_length = %llu\n", + page_count, region_length); cqp_request->waiting = 1; cqp_wqe = &cqp_request->cqp_wqe; - nes_debug(NES_DBG_MR, "Registering STag 0x%08X, index = 0x%08X\n", - stag, stag_index); - - opcode = NES_CQP_ALLOCATE_STAG | NES_CQP_STAG_VA_TO | NES_CQP_STAG_MR; - - if (nesfmr->nesmr.pbl_4k == 1) - opcode |= NES_CQP_STAG_PBL_BLK_SIZE; - - if (ibmr_access_flags & IB_ACCESS_REMOTE_WRITE) { - opcode |= NES_CQP_STAG_RIGHTS_REMOTE_WRITE | - NES_CQP_STAG_RIGHTS_LOCAL_WRITE | NES_CQP_STAG_REM_ACC_EN; - nesfmr->access_rights |= - NES_CQP_STAG_RIGHTS_REMOTE_WRITE | NES_CQP_STAG_RIGHTS_LOCAL_WRITE | - NES_CQP_STAG_REM_ACC_EN; + spin_lock_irqsave(&nesadapter->pbl_lock, flags); + if (nesadapter->free_4kpbl > 0) { + nesadapter->free_4kpbl--; + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); + } else { + /* No 4kpbl's available: */ + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); + nes_debug(NES_DBG_MR, "Out of Pbls\n"); + nes_free_cqp_request(nesdev, cqp_request); + return -ENOMEM; } - if (ibmr_access_flags & IB_ACCESS_REMOTE_READ) { - opcode |= NES_CQP_STAG_RIGHTS_REMOTE_READ | - NES_CQP_STAG_RIGHTS_LOCAL_READ | NES_CQP_STAG_REM_ACC_EN; - nesfmr->access_rights |= - NES_CQP_STAG_RIGHTS_REMOTE_READ | NES_CQP_STAG_RIGHTS_LOCAL_READ | - NES_CQP_STAG_REM_ACC_EN; - } + opcode = NES_CQP_ALLOCATE_STAG | NES_CQP_STAG_MR | + NES_CQP_STAG_PBL_BLK_SIZE | NES_CQP_STAG_VA_TO | + NES_CQP_STAG_REM_ACC_EN; + /* + * The current OFED API does not support the zero based TO option. + * If added then need to changed the NES_CQP_STAG_VA* option. Also, + * the API does not support that ability to have the MR set for local + * access only when created and not allow the SQ op to override. Given + * this the remote enable must be set here. + */ nes_fill_init_cqp_wqe(cqp_wqe, nesdev); set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, opcode); - set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_LEN_HIGH_PD_IDX, (nespd->pd_id & 0x00007fff)); - set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_STAG_IDX, stag); + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_BLK_COUNT_IDX, 1); - cqp_wqe->wqe_words[NES_CQP_STAG_WQE_PBL_BLK_COUNT_IDX] = - cpu_to_le32((nesfmr->nesmr.pbls_used>1) ? - (nesfmr->nesmr.pbls_used-1) : nesfmr->nesmr.pbls_used); + cqp_wqe->wqe_words[NES_CQP_STAG_WQE_LEN_HIGH_PD_IDX] = + cpu_to_le32((u32)(region_length >> 8) & 0xff000000); + cqp_wqe->wqe_words[NES_CQP_STAG_WQE_LEN_HIGH_PD_IDX] |= + cpu_to_le32(nespd->pd_id & 0x00007fff); + + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_STAG_IDX, stag); + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_VA_LOW_IDX, 0); + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_LEN_LOW_IDX, 0); + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PA_LOW_IDX, 0); + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_LEN_IDX, (page_count * 8)); + cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_STAG_PBL_BLK_SIZE); + barrier(); atomic_set(&cqp_request->refcount, 2); nes_post_cqp_request(nesdev, cqp_request); /* Wait for CQP */ - ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0), - NES_EVENT_TIMEOUT); - nes_debug(NES_DBG_MR, "Register STag 0x%08X completed, wait_event_timeout ret = %u," - " CQP Major:Minor codes = 0x%04X:0x%04X.\n", - stag, ret, cqp_request->major_code, cqp_request->minor_code); - - if ((!ret) || (cqp_request->major_code)) { - nes_put_cqp_request(nesdev, cqp_request); - ret = (!ret) ? -ETIME : -EIO; - goto failed_leaf_vpbl_pages_alloc; - } + ret = wait_event_timeout(cqp_request->waitq, + (0 != cqp_request->request_done), + NES_EVENT_TIMEOUT); + + nes_debug(NES_DBG_MR, "Allocate STag 0x%08X completed, " + "wait_event_timeout ret = %u, CQP Major:Minor codes = " + "0x%04X:0x%04X.\n", stag, ret, cqp_request->major_code, + cqp_request->minor_code); + major_code = cqp_request->major_code; nes_put_cqp_request(nesdev, cqp_request); - nesfmr->nesmr.ibfmr.lkey = stag; - nesfmr->nesmr.ibfmr.rkey = stag; - nesfmr->attr = *ibfmr_attr; - - return &nesfmr->nesmr.ibfmr; - - failed_leaf_vpbl_pages_alloc: - /* unroll all allocated pages */ - for (i=0; ileaf_pbl_cnt; i++) { - if (nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase) { - pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase, - nesfmr->root_vpbl.leaf_vpbl[i].pbl_pbase); - } - } - if (nesfmr->root_vpbl.leaf_vpbl) - kfree(nesfmr->root_vpbl.leaf_vpbl); - - failed_leaf_vpbl_alloc: - if (nesfmr->leaf_pbl_cnt == 0) { - if (nesfmr->root_vpbl.pbl_vbase) - pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.pbl_vbase, - nesfmr->root_vpbl.pbl_pbase); - } else - pci_free_consistent(nesdev->pcidev, 8192, nesfmr->root_vpbl.pbl_vbase, - nesfmr->root_vpbl.pbl_pbase); - failed_vpbl_alloc: - if (nesfmr->nesmr.pbls_used != 0) { + if (!ret || major_code) { spin_lock_irqsave(&nesadapter->pbl_lock, flags); - if (nesfmr->nesmr.pbl_4k) - nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used; - else - nesadapter->free_256pbl += nesfmr->nesmr.pbls_used; + nesadapter->free_4kpbl++; spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); } -failed_vpbl_avail: - kfree(nesfmr); - - failed_fmr_alloc: - nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); - - failed_resource_alloc: - return ERR_PTR(ret); + if (!ret) + return -ETIME; + else if (major_code) + return -EIO; + return 0; } - -/** - * nes_dealloc_fmr +/* + * nes_alloc_fast_reg_mr */ -static int nes_dealloc_fmr(struct ib_fmr *ibfmr) +struct ib_mr *nes_alloc_fast_reg_mr(struct ib_pd *ibpd, int max_page_list_len) { - unsigned long flags; - struct nes_mr *nesmr = to_nesmr_from_ibfmr(ibfmr); - struct nes_fmr *nesfmr = to_nesfmr(nesmr); - struct nes_vnic *nesvnic = to_nesvnic(ibfmr->device); + struct nes_pd *nespd = to_nespd(ibpd); + struct nes_vnic *nesvnic = to_nesvnic(ibpd->device); struct nes_device *nesdev = nesvnic->nesdev; struct nes_adapter *nesadapter = nesdev->nesadapter; - int i = 0; - int rc; - /* free the resources */ - if (nesfmr->leaf_pbl_cnt == 0) { - /* single PBL case */ - if (nesfmr->root_vpbl.pbl_vbase) - pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.pbl_vbase, - nesfmr->root_vpbl.pbl_pbase); - } else { - for (i = 0; i < nesfmr->leaf_pbl_cnt; i++) { - pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase, - nesfmr->root_vpbl.leaf_vpbl[i].pbl_pbase); - } - kfree(nesfmr->root_vpbl.leaf_vpbl); - pci_free_consistent(nesdev->pcidev, 8192, nesfmr->root_vpbl.pbl_vbase, - nesfmr->root_vpbl.pbl_pbase); - } - nesmr->ibmw.device = ibfmr->device; - nesmr->ibmw.pd = ibfmr->pd; - nesmr->ibmw.rkey = ibfmr->rkey; - nesmr->ibmw.uobject = NULL; + u32 next_stag_index; + u8 stag_key = 0; + u32 driver_key = 0; + int err = 0; + u32 stag_index = 0; + struct nes_mr *nesmr; + u32 stag; + int ret; + struct ib_mr *ibmr; +/* + * Note: Set to always use a fixed length single page entry PBL. This is to allow + * for the fast_reg_mr operation to always know the size of the PBL. + */ + if (max_page_list_len > (NES_4K_PBL_CHUNK_SIZE / sizeof(u64))) + return ERR_PTR(-E2BIG); - rc = nes_dealloc_mw(&nesmr->ibmw); + get_random_bytes(&next_stag_index, sizeof(next_stag_index)); + stag_key = (u8)next_stag_index; + next_stag_index >>= 8; + next_stag_index %= nesadapter->max_mr; - if ((rc == 0) && (nesfmr->nesmr.pbls_used != 0)) { - spin_lock_irqsave(&nesadapter->pbl_lock, flags); - if (nesfmr->nesmr.pbl_4k) { - nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used; - WARN_ON(nesadapter->free_4kpbl > nesadapter->max_4kpbl); - } else { - nesadapter->free_256pbl += nesfmr->nesmr.pbls_used; - WARN_ON(nesadapter->free_256pbl > nesadapter->max_256pbl); - } - spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); + err = nes_alloc_resource(nesadapter, nesadapter->allocated_mrs, + nesadapter->max_mr, &stag_index, + &next_stag_index); + if (err) + return ERR_PTR(err); + + nesmr = kzalloc(sizeof(*nesmr), GFP_KERNEL); + if (!nesmr) { + nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); + return ERR_PTR(-ENOMEM); } - return rc; -} + stag = stag_index << 8; + stag |= driver_key; + stag += (u32)stag_key; + nes_debug(NES_DBG_MR, "Allocating STag 0x%08X index = 0x%08X\n", + stag, stag_index); -/** - * nes_map_phys_fmr + ret = alloc_fast_reg_mr(nesdev, nespd, stag, max_page_list_len); + + if (ret == 0) { + nesmr->ibmr.rkey = stag; + nesmr->ibmr.lkey = stag; + nesmr->mode = IWNES_MEMREG_TYPE_FMEM; + ibmr = &nesmr->ibmr; + } else { + kfree(nesmr); + nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); + ibmr = ERR_PTR(-ENOMEM); + } + return ibmr; +} + +/* + * nes_alloc_fast_reg_page_list */ -static int nes_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list, - int list_len, u64 iova) +static struct ib_fast_reg_page_list *nes_alloc_fast_reg_page_list( + struct ib_device *ibdev, + int page_list_len) { - return 0; -} + struct nes_vnic *nesvnic = to_nesvnic(ibdev); + struct nes_device *nesdev = nesvnic->nesdev; + struct ib_fast_reg_page_list *pifrpl; + struct nes_ib_fast_reg_page_list *pnesfrpl; + if (page_list_len > (NES_4K_PBL_CHUNK_SIZE / sizeof(u64))) + return ERR_PTR(-E2BIG); + /* + * Allocate the ib_fast_reg_page_list structure, the + * nes_fast_bpl structure, and the PLB table. + */ + pnesfrpl = kmalloc(sizeof(struct nes_ib_fast_reg_page_list) + + page_list_len * sizeof(u64), GFP_KERNEL); + + if (!pnesfrpl) + return ERR_PTR(-ENOMEM); -/** - * nes_unmap_frm + pifrpl = &pnesfrpl->ibfrpl; + pifrpl->page_list = &pnesfrpl->pbl; + pifrpl->max_page_list_len = page_list_len; + /* + * Allocate the WQE PBL + */ + pnesfrpl->nes_wqe_pbl.kva = pci_alloc_consistent(nesdev->pcidev, + page_list_len * sizeof(u64), + &pnesfrpl->nes_wqe_pbl.paddr); + + if (!pnesfrpl->nes_wqe_pbl.kva) { + kfree(pnesfrpl); + return ERR_PTR(-ENOMEM); + } + nes_debug(NES_DBG_MR, "nes_alloc_fast_reg_pbl: nes_frpl = %p, " + "ibfrpl = %p, ibfrpl.page_list = %p, pbl.kva = %p, " + "pbl.paddr= %p\n", pnesfrpl, &pnesfrpl->ibfrpl, + pnesfrpl->ibfrpl.page_list, pnesfrpl->nes_wqe_pbl.kva, + (void *)pnesfrpl->nes_wqe_pbl.paddr); + + return pifrpl; +} + +/* + * nes_free_fast_reg_page_list */ -static int nes_unmap_fmr(struct list_head *ibfmr_list) +static void nes_free_fast_reg_page_list(struct ib_fast_reg_page_list *pifrpl) { - return 0; + struct nes_vnic *nesvnic = to_nesvnic(pifrpl->device); + struct nes_device *nesdev = nesvnic->nesdev; + struct nes_ib_fast_reg_page_list *pnesfrpl; + + pnesfrpl = container_of(pifrpl, struct nes_ib_fast_reg_page_list, ibfrpl); + /* + * Free the WQE PBL. + */ + pci_free_consistent(nesdev->pcidev, + pifrpl->max_page_list_len * sizeof(u64), + pnesfrpl->nes_wqe_pbl.kva, + pnesfrpl->nes_wqe_pbl.paddr); + /* + * Free the PBL structure + */ + kfree(pnesfrpl); } - - /** * nes_query_device */ @@ -3514,6 +3408,91 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, NES_IWARP_SQ_LOCINV_WQE_INV_STAG_IDX, ib_wr->ex.invalidate_rkey); break; + case IB_WR_FAST_REG_MR: + { + int i; + int flags = ib_wr->wr.fast_reg.access_flags; + struct nes_ib_fast_reg_page_list *pnesfrpl = + container_of(ib_wr->wr.fast_reg.page_list, + struct nes_ib_fast_reg_page_list, + ibfrpl); + u64 *src_page_list = pnesfrpl->ibfrpl.page_list; + u64 *dst_page_list = pnesfrpl->nes_wqe_pbl.kva; + + if (ib_wr->wr.fast_reg.page_list_len > + (NES_4K_PBL_CHUNK_SIZE / sizeof(u64))) { + nes_debug(NES_DBG_IW_TX, "SQ_FMR: bad page_list_len\n"); + err = -EINVAL; + break; + } + wqe_misc = NES_IWARP_SQ_OP_FAST_REG; + set_wqe_64bit_value(wqe->wqe_words, + NES_IWARP_SQ_FMR_WQE_VA_FBO_LOW_IDX, + ib_wr->wr.fast_reg.iova_start); + set_wqe_32bit_value(wqe->wqe_words, + NES_IWARP_SQ_FMR_WQE_LENGTH_LOW_IDX, + ib_wr->wr.fast_reg.length); + set_wqe_32bit_value(wqe->wqe_words, + NES_IWARP_SQ_FMR_WQE_MR_STAG_IDX, + ib_wr->wr.fast_reg.rkey); + /* Set page size: */ + if (ib_wr->wr.fast_reg.page_shift == 12) { + wqe_misc |= NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_4K; + } else if (ib_wr->wr.fast_reg.page_shift == 21) { + wqe_misc |= NES_IWARP_SQ_FMR_WQE_PAGE_SIZE_2M; + } else { + nes_debug(NES_DBG_IW_TX, "Invalid page shift," + " ib_wr=%u, max=1\n", ib_wr->num_sge); + err = -EINVAL; + break; + } + /* Set access_flags */ + wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_LOCAL_READ; + if (flags & IB_ACCESS_LOCAL_WRITE) + wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_LOCAL_WRITE; + + if (flags & IB_ACCESS_REMOTE_WRITE) + wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_REMOTE_WRITE; + + if (flags & IB_ACCESS_REMOTE_READ) + wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_REMOTE_READ; + + if (flags & IB_ACCESS_MW_BIND) + wqe_misc |= NES_IWARP_SQ_FMR_WQE_RIGHTS_ENABLE_WINDOW_BIND; + + /* Fill in PBL info: */ + if (ib_wr->wr.fast_reg.page_list_len > + pnesfrpl->ibfrpl.max_page_list_len) { + nes_debug(NES_DBG_IW_TX, "Invalid page list length," + " ib_wr=%p, value=%u, max=%u\n", + ib_wr, ib_wr->wr.fast_reg.page_list_len, + pnesfrpl->ibfrpl.max_page_list_len); + err = -EINVAL; + break; + } + + set_wqe_64bit_value(wqe->wqe_words, + NES_IWARP_SQ_FMR_WQE_PBL_ADDR_LOW_IDX, + pnesfrpl->nes_wqe_pbl.paddr); + + set_wqe_32bit_value(wqe->wqe_words, + NES_IWARP_SQ_FMR_WQE_PBL_LENGTH_IDX, + ib_wr->wr.fast_reg.page_list_len * 8); + + for (i = 0; i < ib_wr->wr.fast_reg.page_list_len; i++) + dst_page_list[i] = cpu_to_le64(src_page_list[i]); + + nes_debug(NES_DBG_IW_TX, "SQ_FMR: iova_start: %p, " + "length: %d, rkey: %0x, pgl_paddr: %p, " + "page_list_len: %u, wqe_misc: %x\n", + (void *)ib_wr->wr.fast_reg.iova_start, + ib_wr->wr.fast_reg.length, + ib_wr->wr.fast_reg.rkey, + (void *)pnesfrpl->nes_wqe_pbl.paddr, + ib_wr->wr.fast_reg.page_list_len, + wqe_misc); + break; + } default: /* error */ err = -EINVAL; @@ -3752,6 +3731,9 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) case NES_IWARP_SQ_OP_LOCINV: entry->opcode = IB_WR_LOCAL_INV; break; + case NES_IWARP_SQ_OP_FAST_REG: + entry->opcode = IB_WC_FAST_REG_MR; + break; } nesqp->hwqp.sq_tail = (wqe_index+1)&(nesqp->hwqp.sq_size - 1); @@ -3922,10 +3904,9 @@ struct nes_ib_device *nes_init_ofa_device(struct net_device *netdev) nesibdev->ibdev.dealloc_mw = nes_dealloc_mw; nesibdev->ibdev.bind_mw = nes_bind_mw; - nesibdev->ibdev.alloc_fmr = nes_alloc_fmr; - nesibdev->ibdev.unmap_fmr = nes_unmap_fmr; - nesibdev->ibdev.dealloc_fmr = nes_dealloc_fmr; - nesibdev->ibdev.map_phys_fmr = nes_map_phys_fmr; + nesibdev->ibdev.alloc_fast_reg_mr = nes_alloc_fast_reg_mr; + nesibdev->ibdev.alloc_fast_reg_page_list = nes_alloc_fast_reg_page_list; + nesibdev->ibdev.free_fast_reg_page_list = nes_free_fast_reg_page_list; nesibdev->ibdev.attach_mcast = nes_multicast_attach; nesibdev->ibdev.detach_mcast = nes_multicast_detach; -- cgit v0.10.2 From a276510328d0721c252b37044c51e2fb4efe0364 Mon Sep 17 00:00:00 2001 From: Chien Tung Date: Wed, 9 Dec 2009 15:21:56 -0800 Subject: RDMA/nes: Add additional SFP+ PHY uC status check and PHY reset Add additional PHY uC status check in case PHY firmware is not running properly with heartbeat. Add a hard PHY reset if uC status is 0x0 after initial reset. Signed-off-by: Chien Tung Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 3d9bbff..b59ca56 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -1356,6 +1356,8 @@ int nes_init_phy(struct nes_device *nesdev) } if ((phy_type == NES_PHY_TYPE_ARGUS) || (phy_type == NES_PHY_TYPE_SFP_D)) { + u32 first_time = 1; + /* Check firmware heartbeat */ nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); @@ -1363,8 +1365,13 @@ int nes_init_phy(struct nes_device *nesdev) nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); - if (temp_phy_data != temp_phy_data2) - return 0; + if (temp_phy_data != temp_phy_data2) { + nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd); + temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); + if ((temp_phy_data & 0xff) > 0x20) + return 0; + printk(PFX "Reinitializing PHY\n"); + } /* no heartbeat, configure the PHY */ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000); @@ -1400,7 +1407,7 @@ int nes_init_phy(struct nes_device *nesdev) temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); do { if (counter++ > 150) { - nes_debug(NES_DBG_PHY, "No PHY heartbeat\n"); + printk(PFX "No PHY heartbeat\n"); break; } mdelay(1); @@ -1414,11 +1421,20 @@ int nes_init_phy(struct nes_device *nesdev) nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd); temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); if (counter++ > 300) { - nes_debug(NES_DBG_PHY, "PHY did not track\n"); - break; + if (((temp_phy_data & 0xff) == 0x0) && first_time) { + first_time = 0; + counter = 0; + /* reset AMCC PHY and try again */ + nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x00c0); + nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x0040); + continue; + } else { + printk(PFX "PHY did not track\n"); + break; + } } mdelay(10); - } while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70)); + } while ((temp_phy_data & 0xff) < 0x30); /* setup signal integrity */ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000); -- cgit v0.10.2 From d14152da13dc29aa70cddd8ca214a13e3597eb7f Mon Sep 17 00:00:00 2001 From: Chien Tung Date: Wed, 9 Dec 2009 15:21:56 -0800 Subject: RDMA/nes: Implement IB_SIGNAL_ALL_WR as an iWARP extension Add IB_SINGAL_ALL_WR support as an iWARP extension. If set, make sure all WR for the QP are signalled. Consolidate flags used in nesqp structure. Signed-off-by: Chien Tung Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 0a2b18b..8ea7561 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -1407,6 +1407,8 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, return ERR_PTR(-EINVAL); } + nesqp->sig_all = (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR); + /* update the QP table */ nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp; nes_debug(NES_DBG_QP, "netdev refcnt=%u\n", @@ -3502,9 +3504,9 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, if (err) break; - if (ib_wr->send_flags & IB_SEND_SIGNALED) { + if ((ib_wr->send_flags & IB_SEND_SIGNALED) || nesqp->sig_all) wqe_misc |= NES_IWARP_SQ_WQE_SIGNALED_COMPL; - } + wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = cpu_to_le32(wqe_misc); ib_wr = ib_wr->next; diff --git a/drivers/infiniband/hw/nes/nes_verbs.h b/drivers/infiniband/hw/nes/nes_verbs.h index 89822d7..ac8b86b 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.h +++ b/drivers/infiniband/hw/nes/nes_verbs.h @@ -167,17 +167,20 @@ struct nes_qp { enum ib_event_type terminate_eventtype; wait_queue_head_t kick_waitq; u16 in_disconnect; + u16 active_conn:1; + u16 skip_lsmm:1; + u16 user_mode:1; + u16 hte_added:1; + u16 flush_issued:1; + u16 destroyed:1; + u16 sq_kmapped:1; + u16 sig_all:1; + u16 rsvd:8; u16 private_data_len; u16 term_sq_flush_code; u16 term_rq_flush_code; - u8 active_conn; - u8 skip_lsmm; - u8 user_mode; - u8 hte_added; u8 hw_iwarp_state; - u8 flush_issued; u8 hw_tcp_state; u8 term_flags; - u8 destroyed; }; #endif /* NES_VERBS_H */ -- cgit v0.10.2 From 75742c630ed552ad963948c9f3e596e96eed7a9f Mon Sep 17 00:00:00 2001 From: Chien Tung Date: Wed, 9 Dec 2009 15:21:56 -0800 Subject: RDMA/nes: Clean up struct nes_qp Remove unused and not really used variables. Signed-off-by: Chien Tung Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 8ea7561..ea4e22e 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -1398,8 +1398,6 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, nes_debug(NES_DBG_QP, "QP%u structure located @%p.Size = %u.\n", nesqp->hwqp.qp_id, nesqp, (u32)sizeof(*nesqp)); spin_lock_init(&nesqp->lock); - init_waitqueue_head(&nesqp->state_waitq); - init_waitqueue_head(&nesqp->kick_waitq); nes_add_ref(&nesqp->ibqp); break; default: @@ -3005,7 +3003,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, " already done based on hw state.\n", nesqp->hwqp.qp_id); issue_modify_qp = 0; - nesqp->in_disconnect = 0; } switch (nesqp->hw_iwarp_state) { case NES_AEQE_IWARP_STATE_CLOSING: @@ -3018,7 +3015,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, break; default: next_iwarp_state = NES_CQP_QP_IWARP_STATE_CLOSING; - nesqp->in_disconnect = 1; nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING; break; } @@ -3035,7 +3031,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, next_iwarp_state = NES_CQP_QP_IWARP_STATE_TERMINATE; nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_TERMINATE; issue_modify_qp = 1; - nesqp->in_disconnect = 1; break; case IB_QPS_ERR: case IB_QPS_RESET: @@ -3058,7 +3053,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, if ((nesqp->hw_tcp_state > NES_AEQE_TCP_STATE_CLOSED) && (nesqp->hw_tcp_state != NES_AEQE_TCP_STATE_TIME_WAIT)) { next_iwarp_state |= NES_CQP_QP_RESET; - nesqp->in_disconnect = 1; } else { nes_debug(NES_DBG_MOD_QP, "QP%u NOT setting NES_CQP_QP_RESET since TCP state = %u\n", nesqp->hwqp.qp_id, nesqp->hw_tcp_state); diff --git a/drivers/infiniband/hw/nes/nes_verbs.h b/drivers/infiniband/hw/nes/nes_verbs.h index ac8b86b..795aa4f 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.h +++ b/drivers/infiniband/hw/nes/nes_verbs.h @@ -135,19 +135,15 @@ struct nes_qp { struct ib_qp ibqp; void *allocated_buffer; struct iw_cm_id *cm_id; - struct workqueue_struct *wq; struct nes_cq *nesscq; struct nes_cq *nesrcq; struct nes_pd *nespd; void *cm_node; /* handle of the node this QP is associated with */ struct ietf_mpa_frame *ietf_frame; dma_addr_t ietf_frame_pbase; - wait_queue_head_t state_waitq; struct ib_mr *lsmm_mr; - unsigned long socket; struct nes_hw_qp hwqp; struct work_struct work; - struct work_struct ae_work; enum ib_qp_state ibqp_state; u32 iwarp_state; u32 hte_index; @@ -165,17 +161,14 @@ struct nes_qp { struct page *page; struct timer_list terminate_timer; enum ib_event_type terminate_eventtype; - wait_queue_head_t kick_waitq; - u16 in_disconnect; u16 active_conn:1; u16 skip_lsmm:1; u16 user_mode:1; u16 hte_added:1; u16 flush_issued:1; u16 destroyed:1; - u16 sq_kmapped:1; u16 sig_all:1; - u16 rsvd:8; + u16 rsvd:9; u16 private_data_len; u16 term_sq_flush_code; u16 term_rq_flush_code; -- cgit v0.10.2 From 5924aea6e26712cd372aa23ed432d4cefbb050d2 Mon Sep 17 00:00:00 2001 From: Chien Tung Date: Wed, 9 Dec 2009 15:21:56 -0800 Subject: RDMA/nes: Add max_cqe check to nes_create_cq() Add a check to nes_create_cq() to return -EINVAL if creating a CQ with depth > max_cqe (32766). Signed-off-by: Chien Tung Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index b59ca56..6f625a9 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -482,7 +482,7 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { nesadapter->max_irrq_wr = (u32temp >> 16) & 3; nesadapter->max_sge = 4; - nesadapter->max_cqe = 32767; + nesadapter->max_cqe = 32766; if (nes_read_eeprom_values(nesdev, nesadapter)) { printk(KERN_ERR PFX "Unable to read EEPROM data.\n"); diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index ea4e22e..155286b 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -527,7 +527,7 @@ static int nes_query_device(struct ib_device *ibdev, struct ib_device_attr *prop props->max_qp_wr = nesdev->nesadapter->max_qp_wr - 2; props->max_sge = nesdev->nesadapter->max_sge; props->max_cq = nesibdev->max_cq; - props->max_cqe = nesdev->nesadapter->max_cqe - 1; + props->max_cqe = nesdev->nesadapter->max_cqe; props->max_mr = nesibdev->max_mr; props->max_mw = nesibdev->max_mr; props->max_pd = nesibdev->max_pd; @@ -1543,6 +1543,9 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, unsigned long flags; int ret; + if (entries > nesadapter->max_cqe) + return ERR_PTR(-EINVAL); + err = nes_alloc_resource(nesadapter, nesadapter->allocated_cqs, nesadapter->max_cq, &cq_num, &nesadapter->next_cq); if (err) { -- cgit v0.10.2 From fa6c87d5104512bf73cf62162cec9ef6eba707c7 Mon Sep 17 00:00:00 2001 From: Chien Tung Date: Wed, 9 Dec 2009 15:21:56 -0800 Subject: RDMA/nes: Update copyright and branding string Update copyright from Intel-NE, Inc. to Intel Corporation. Use proper branding string in Kconfig and simplify description. Signed-off-by: Chien Tung Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/Kconfig b/drivers/infiniband/hw/nes/Kconfig index d449eb6..846dc97 100644 --- a/drivers/infiniband/hw/nes/Kconfig +++ b/drivers/infiniband/hw/nes/Kconfig @@ -4,14 +4,13 @@ config INFINIBAND_NES select LIBCRC32C select INET_LRO ---help--- - This is a low-level driver for NetEffect RDMA enabled - Network Interface Cards (RNIC). + This is the RDMA Network Interface Card (RNIC) driver for + NetEffect Ethernet Cluster Server Adapters. config INFINIBAND_NES_DEBUG bool "Verbose debugging output" depends on INFINIBAND_NES default n ---help--- - This option causes the NetEffect RNIC driver to produce debug - messages. Select this if you are developing the driver - or trying to diagnose a problem. + This option enables debug messages from the NetEffect RNIC + driver. Select this if you are diagnosing a problem. diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index cbde0cf..88d3114 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h index bcc6abc..9884056 100644 --- a/drivers/infiniband/hw/nes/nes.h +++ b/drivers/infiniband/hw/nes/nes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 73473db..dbe5455 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h index 90e8e4d..5e4808c 100644 --- a/drivers/infiniband/hw/nes/nes_cm.h +++ b/drivers/infiniband/hw/nes/nes_cm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/drivers/infiniband/hw/nes/nes_context.h b/drivers/infiniband/hw/nes/nes_context.h index 0fb8d81..b4393a1 100644 --- a/drivers/infiniband/hw/nes/nes_context.h +++ b/drivers/infiniband/hw/nes/nes_context.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 6f625a9..9fc0273 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 8a4c738..084be0e 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. +* Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index e593af3..5a7b554 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/drivers/infiniband/hw/nes/nes_user.h b/drivers/infiniband/hw/nes/nes_user.h index ce62f3c..71e133a 100644 --- a/drivers/infiniband/hw/nes/nes_user.h +++ b/drivers/infiniband/hw/nes/nes_user.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * Copyright (c) 2005 Topspin Communications. All rights reserved. * Copyright (c) 2005 Cisco Systems. All rights reserved. * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c index 9687c39..729d525 100644 --- a/drivers/infiniband/hw/nes/nes_utils.c +++ b/drivers/infiniband/hw/nes/nes_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 155286b..0868652 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/drivers/infiniband/hw/nes/nes_verbs.h b/drivers/infiniband/hw/nes/nes_verbs.h index 795aa4f..cc7a604 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.h +++ b/drivers/infiniband/hw/nes/nes_verbs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. * * This software is available to you under a choice of one of two -- cgit v0.10.2 From d85ddd835b33a9a0f2276ce068318da3fd1ad76a Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 9 Dec 2009 15:21:57 -0800 Subject: RDMA/nes: Pass correct size to ioremap_nocache() The size argument to ioremap_nocache should be the size of desired information, not the pointer to it. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @expression@ expression *x; @@ x = <+... *sizeof(x) ...+>// Signed-off-by: Julia Lawall Acked-by: Chien Tung Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index 88d3114..b9d09ba 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c @@ -521,7 +521,8 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i spin_lock_init(&nesdev->indexed_regs_lock); /* Remap the PCI registers in adapter BAR0 to kernel VA space */ - mmio_regs = ioremap_nocache(pci_resource_start(pcidev, BAR_0), sizeof(mmio_regs)); + mmio_regs = ioremap_nocache(pci_resource_start(pcidev, BAR_0), + pci_resource_len(pcidev, BAR_0)); if (mmio_regs == NULL) { printk(KERN_ERR PFX "Unable to remap BAR0\n"); ret = -EIO; -- cgit v0.10.2 From 9b84dbe7f479a5a5fa53d689c2adf214ce7760e5 Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Wed, 9 Dec 2009 15:53:36 -0800 Subject: RDMA/nes: Fix MAX_CM_BUFFER define Change MAX_CM_BUFFER for MPA frames to be conformant to RFC 5044: we need 512 + 20 instead of 512. Signed-off-by: Faisal Latif Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h index 5e4808c..911846a 100644 --- a/drivers/infiniband/hw/nes/nes_cm.h +++ b/drivers/infiniband/hw/nes/nes_cm.h @@ -47,6 +47,8 @@ #define IEFT_MPA_KEY_REP "MPA ID Rep Frame" #define IETF_MPA_KEY_SIZE 16 #define IETF_MPA_VERSION 1 +#define IETF_MAX_PRIV_DATA_LEN 512 +#define IETF_MPA_FRAME_SIZE 20 enum ietf_mpa_flags { IETF_MPA_FLAGS_MARKERS = 0x80, /* receive Markers */ @@ -169,7 +171,7 @@ struct nes_timer_entry { #define NES_CM_DEF_SEQ2 0x18ed5740 #define NES_CM_DEF_LOCAL_ID2 0xb807 -#define MAX_CM_BUFFER 512 +#define MAX_CM_BUFFER (IETF_MPA_FRAME_SIZE + IETF_MAX_PRIV_DATA_LEN) typedef u32 nes_addr_t; -- cgit v0.10.2 From 8ac7f6e1af5309d4fdf6805fb64ef48c1c820d85 Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Wed, 9 Dec 2009 15:53:46 -0800 Subject: RDMA/nes: Fix query of ORD values The ORD size needs updating as we are supporting more inbound READ resources per connection. Signed-off-by: Faisal Latif Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 0868652..67a87cb 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -534,16 +534,16 @@ static int nes_query_device(struct ib_device *ibdev, struct ib_device_attr *prop props->max_sge_rd = 1; switch (nesdev->nesadapter->max_irrq_wr) { case 0: - props->max_qp_rd_atom = 1; + props->max_qp_rd_atom = 2; break; case 1: - props->max_qp_rd_atom = 4; + props->max_qp_rd_atom = 8; break; case 2: - props->max_qp_rd_atom = 16; + props->max_qp_rd_atom = 32; break; case 3: - props->max_qp_rd_atom = 32; + props->max_qp_rd_atom = 64; break; default: props->max_qp_rd_atom = 0; -- cgit v0.10.2 From 1cf078c9951b531bc222a5195306a3a927c24fc9 Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Wed, 9 Dec 2009 15:53:54 -0800 Subject: RDMA/nes: MPA request/response error checking During Xansation testing, we saw that error handling of MPA frame msg/response is not handled properly. Signed-off-by: Faisal Latif Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index dbe5455..ae09463 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -251,6 +251,33 @@ static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 *type, mpa_frame = (struct ietf_mpa_frame *)buffer; cm_node->mpa_frame_size = ntohs(mpa_frame->priv_data_len); + /* make sure mpa private data len is less than 512 bytes */ + if (cm_node->mpa_frame_size > IETF_MAX_PRIV_DATA_LEN) { + nes_debug(NES_DBG_CM, "The received Length of Private" + " Data field exceeds 512 octets\n"); + return -EINVAL; + } + /* + * make sure MPA receiver interoperate with the + * received MPA version and MPA key information + * + */ + if (mpa_frame->rev != mpa_version) { + nes_debug(NES_DBG_CM, "The received mpa version" + " can not be interoperated\n"); + return -EINVAL; + } + if (cm_node->state != NES_CM_STATE_MPAREQ_SENT) { + if (memcmp(mpa_frame->key, IEFT_MPA_KEY_REQ, IETF_MPA_KEY_SIZE)) { + nes_debug(NES_DBG_CM, "Unexpected MPA Key received \n"); + return -EINVAL; + } + } else { + if (memcmp(mpa_frame->key, IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE)) { + nes_debug(NES_DBG_CM, "Unexpected MPA Key received \n"); + return -EINVAL; + } + } if (cm_node->mpa_frame_size + sizeof(struct ietf_mpa_frame) != len) { nes_debug(NES_DBG_CM, "The received ietf buffer was not right" @@ -1974,7 +2001,7 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, if (!cm_node) return NULL; mpa_frame = &cm_node->mpa_frame; - strcpy(mpa_frame->key, IEFT_MPA_KEY_REQ); + memcpy(mpa_frame->key, IEFT_MPA_KEY_REQ, IETF_MPA_KEY_SIZE); mpa_frame->flags = IETF_MPA_FLAGS_CRC; mpa_frame->rev = IETF_MPA_VERSION; mpa_frame->priv_data_len = htons(private_data_len); @@ -2929,7 +2956,7 @@ int nes_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len) if (cm_node->mpa_frame_size > MAX_CM_BUFFER) return -EINVAL; - strcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP); + memcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE); if (loopback) { memcpy(&loopback->mpa_frame.priv_data, pdata, pdata_len); loopback->mpa_frame.priv_data_len = pdata_len; -- cgit v0.10.2 From 69524e1aff75e4ed8efcb7d699c97d55c317a950 Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Wed, 9 Dec 2009 15:54:03 -0800 Subject: RDMA/nes: Resource not freed for REJECTed connections During testing of REJECT connection error handling, we saw that the cm_id resources are not released. When the retransmit timer expires, we need to send a reset message to remote node before issuing the ABORTED event. Signed-off-by: Faisal Latif Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index ae09463..08fcd25 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -513,6 +513,8 @@ static void nes_retrans_expired(struct nes_cm_node *cm_node) send_reset(cm_node, NULL); break; default: + add_ref_cm_node(cm_node); + send_reset(cm_node, NULL); create_event(cm_node, NES_CM_EVENT_ABORTED); } } -- cgit v0.10.2 From c5a7d4897156667a58fd8479f6227143573fe82d Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Wed, 9 Dec 2009 15:54:08 -0800 Subject: RDMA/nes: Fix crash in nes_accept() While running IMP_EXT's window test, we saw a crash in nes_accept(). Here is the sequence of what happened: (1) In MVAPICH2, connect request is received for port #0. FIX: Add a nes_connect() check to make sure local or remote tcp port is not 0. (2) Remote node's (passive) TCP stack sends a reset when it gets a connect request because of port = 0. Active side set the connect error to IW_CM_EVENT_STATUS_REJECTED when it received the RST from remote node. FIX: The corect error code is -ECONNRESET. (3) Wrong error code of IW_CM_EVENT_STATUS_REJECTED causes the core to destroy its listener ports. Here there are connections that may have sent an MPA request up and waiting for accept or reject. But the listener and its cm_nodes have been freed already causing the crash noticed. FIX: The cm_node is freed only if its state is not NES_CM_STATE_MPAREQ_RCVD. If cm_node's state is NES_CM_STATE_MPAREQ_RCVD then its new state is set to NES_CM_STATE_LISTENER_DESTROYED and it is not freed. When nes_accept() or nes_reject() is received, its state is checked for NES_CM_STATE_LISTENER_DESTROYED and in this case the cm_node is freed and error is returned. Signed-off-by: Faisal Latif Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 08fcd25..ec04786 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -978,6 +978,7 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, reset_entry); { struct nes_cm_node *loopback = cm_node->loopbackpartner; + enum nes_cm_node_state old_state; if (NES_CM_STATE_FIN_WAIT1 <= cm_node->state) { rem_ref_cm_node(cm_node->cm_core, cm_node); } else { @@ -989,11 +990,12 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, NES_CM_STATE_CLOSED; WARN_ON(1); } else { - cm_node->state = - NES_CM_STATE_CLOSED; - rem_ref_cm_node( - cm_node->cm_core, - cm_node); + old_state = cm_node->state; + cm_node->state = NES_CM_STATE_LISTENER_DESTROYED; + if (old_state != NES_CM_STATE_MPAREQ_RCVD) + rem_ref_cm_node( + cm_node->cm_core, + cm_node); } } else { struct nes_cm_event event; @@ -1009,6 +1011,7 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, loopback->loc_port; event.cm_info.cm_id = loopback->cm_id; cm_event_connect_error(&event); + cm_node->state = NES_CM_STATE_LISTENER_DESTROYED; loopback->state = NES_CM_STATE_CLOSED; event.cm_node = cm_node; @@ -2131,30 +2134,39 @@ static int mini_cm_reject(struct nes_cm_core *cm_core, cm_node->state = NES_CM_STATE_CLOSED; rem_ref_cm_node(cm_core, cm_node); } else { - ret = send_mpa_reject(cm_node); - if (ret) { - cm_node->state = NES_CM_STATE_CLOSED; - err = send_reset(cm_node, NULL); - if (err) - WARN_ON(1); - } else - cm_id->add_ref(cm_id); + if (cm_node->state == NES_CM_STATE_LISTENER_DESTROYED) { + rem_ref_cm_node(cm_core, cm_node); + } else { + ret = send_mpa_reject(cm_node); + if (ret) { + cm_node->state = NES_CM_STATE_CLOSED; + err = send_reset(cm_node, NULL); + if (err) + WARN_ON(1); + } else + cm_id->add_ref(cm_id); + } } } else { cm_node->cm_id = NULL; - event.cm_node = loopback; - event.cm_info.rem_addr = loopback->rem_addr; - event.cm_info.loc_addr = loopback->loc_addr; - event.cm_info.rem_port = loopback->rem_port; - event.cm_info.loc_port = loopback->loc_port; - event.cm_info.cm_id = loopback->cm_id; - cm_event_mpa_reject(&event); - rem_ref_cm_node(cm_core, cm_node); - loopback->state = NES_CM_STATE_CLOSING; + if (cm_node->state == NES_CM_STATE_LISTENER_DESTROYED) { + rem_ref_cm_node(cm_core, cm_node); + rem_ref_cm_node(cm_core, loopback); + } else { + event.cm_node = loopback; + event.cm_info.rem_addr = loopback->rem_addr; + event.cm_info.loc_addr = loopback->loc_addr; + event.cm_info.rem_port = loopback->rem_port; + event.cm_info.loc_port = loopback->loc_port; + event.cm_info.cm_id = loopback->cm_id; + cm_event_mpa_reject(&event); + rem_ref_cm_node(cm_core, cm_node); + loopback->state = NES_CM_STATE_CLOSING; - cm_id = loopback->cm_id; - rem_ref_cm_node(cm_core, loopback); - cm_id->rem_ref(cm_id); + cm_id = loopback->cm_id; + rem_ref_cm_node(cm_core, loopback); + cm_id->rem_ref(cm_id); + } } return ret; @@ -2198,6 +2210,7 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod case NES_CM_STATE_UNKNOWN: case NES_CM_STATE_INITED: case NES_CM_STATE_CLOSED: + case NES_CM_STATE_LISTENER_DESTROYED: ret = rem_ref_cm_node(cm_core, cm_node); break; case NES_CM_STATE_TSA: @@ -2716,8 +2729,6 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) struct nes_pd *nespd; u64 tagged_offset; - - ibqp = nes_get_qp(cm_id->device, conn_param->qpn); if (!ibqp) return -EINVAL; @@ -2733,6 +2744,13 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) "%s\n", cm_node, nesvnic, nesvnic->netdev, nesvnic->netdev->name); + if (NES_CM_STATE_LISTENER_DESTROYED == cm_node->state) { + if (cm_node->loopbackpartner) + rem_ref_cm_node(cm_node->cm_core, cm_node->loopbackpartner); + rem_ref_cm_node(cm_node->cm_core, cm_node); + return -EINVAL; + } + /* associate the node with the QP */ nesqp->cm_node = (void *)cm_node; cm_node->nesqp = nesqp; @@ -3003,6 +3021,9 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) if (!nesdev) return -EINVAL; + if (!(cm_id->local_addr.sin_port) || !(cm_id->remote_addr.sin_port)) + return -EINVAL; + nes_debug(NES_DBG_CM, "QP%u, current IP = 0x%08X, Destination IP = " "0x%08X:0x%04X, local = 0x%08X:0x%04X.\n", nesqp->hwqp.qp_id, ntohl(nesvnic->local_ipaddr), @@ -3375,7 +3396,7 @@ static void cm_event_connect_error(struct nes_cm_event *event) nesqp->cm_id = NULL; cm_id->provider_data = NULL; cm_event.event = IW_CM_EVENT_CONNECT_REPLY; - cm_event.status = IW_CM_EVENT_STATUS_REJECTED; + cm_event.status = -ECONNRESET; cm_event.provider_data = cm_id->provider_data; cm_event.local_addr = cm_id->local_addr; cm_event.remote_addr = cm_id->remote_addr; diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h index 911846a..d9825fd 100644 --- a/drivers/infiniband/hw/nes/nes_cm.h +++ b/drivers/infiniband/hw/nes/nes_cm.h @@ -200,6 +200,7 @@ enum nes_cm_node_state { NES_CM_STATE_TIME_WAIT, NES_CM_STATE_LAST_ACK, NES_CM_STATE_CLOSING, + NES_CM_STATE_LISTENER_DESTROYED, NES_CM_STATE_CLOSED }; -- cgit v0.10.2 From f9f3f1e08b4d66bfda2a0c2d49a26c80489a0725 Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Wed, 9 Dec 2009 15:54:14 -0800 Subject: RDMA/nes: Abnormal listener exit causes loopback node crash When the listener is destroyed for a loopback connection, the listener node gets a reset event. This causes a crash as the listener is not expecting a reset event. Code review of cm_event_reset() during debugging showed the cm_id ref count is incremented after calling its event handler and not before. Signed-off-by: Faisal Latif Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index ec04786..20e21f1 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1014,18 +1014,6 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, cm_node->state = NES_CM_STATE_LISTENER_DESTROYED; loopback->state = NES_CM_STATE_CLOSED; - event.cm_node = cm_node; - event.cm_info.rem_addr = - cm_node->rem_addr; - event.cm_info.loc_addr = - cm_node->loc_addr; - event.cm_info.rem_port = - cm_node->rem_port; - event.cm_info.loc_port = - cm_node->loc_port; - event.cm_info.cm_id = cm_node->cm_id; - cm_event_reset(&event); - rem_ref_cm_node(cm_node->cm_core, cm_node); @@ -3440,6 +3428,8 @@ static void cm_event_reset(struct nes_cm_event *event) nes_debug(NES_DBG_CM, "%p - cm_id = %p\n", event->cm_node, cm_id); nesqp = cm_id->provider_data; + if (!nesqp) + return; nesqp->cm_id = NULL; /* cm_id->provider_data = NULL; */ @@ -3451,8 +3441,8 @@ static void cm_event_reset(struct nes_cm_event *event) cm_event.private_data = NULL; cm_event.private_data_len = 0; - ret = cm_id->event_handler(cm_id, &cm_event); cm_id->add_ref(cm_id); + ret = cm_id->event_handler(cm_id, &cm_event); atomic_inc(&cm_closes); cm_event.event = IW_CM_EVENT_CLOSE; cm_event.status = IW_CM_EVENT_STATUS_OK; -- cgit v0.10.2 From 886f98a31586fd560fe83c44ad72e3ebe62f8e2e Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Wed, 9 Dec 2009 15:54:18 -0800 Subject: RDMA/nes: Fix Xansation test crash on cm_node ref_count While running a Xansation test, an active side node crashed. The problem started on the passive side, which generated an STtag that was 0. The passive side sent a TERMINATE instead of an MPA REJECT msg. The active side, receives TERMINATE and sends connect_err() and set the cm_node state to CLOSED. The passive side sends FIN + ACK after TERMINATE. Active side ends up in handle_ack_pkt() and send_reset(). send_reset() consumes 1 cm_node's ref_count. Because the cm_node is in CLOSED state, which means that cm_node will be destroyed after completion of the connect_err() indication, CM will crash after send_reset(). Signed-off-by: Faisal Latif Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 20e21f1..a258168 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1610,6 +1610,7 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, break; case NES_CM_STATE_CLOSED: cleanup_retrans_entry(cm_node); + add_ref_cm_node(cm_node); send_reset(cm_node, skb); break; case NES_CM_STATE_TSA: @@ -1661,9 +1662,15 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, passive_open_err(cm_node, skb, 1); break; case NES_CM_STATE_LISTENING: + cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq); + cleanup_retrans_entry(cm_node); + cm_node->state = NES_CM_STATE_CLOSED; + send_reset(cm_node, skb); + break; case NES_CM_STATE_CLOSED: cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq); cleanup_retrans_entry(cm_node); + add_ref_cm_node(cm_node); send_reset(cm_node, skb); break; case NES_CM_STATE_ESTABLISHED: @@ -1732,8 +1739,13 @@ static int handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, dev_kfree_skb_any(skb); break; case NES_CM_STATE_LISTENING: + cleanup_retrans_entry(cm_node); + cm_node->state = NES_CM_STATE_CLOSED; + send_reset(cm_node, skb); + break; case NES_CM_STATE_CLOSED: cleanup_retrans_entry(cm_node); + add_ref_cm_node(cm_node); send_reset(cm_node, skb); break; case NES_CM_STATE_LAST_ACK: @@ -2193,8 +2205,11 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod case NES_CM_STATE_CLOSING: ret = -1; break; - case NES_CM_STATE_MPAREJ_RCVD: case NES_CM_STATE_LISTENING: + cleanup_retrans_entry(cm_node); + send_reset(cm_node, NULL); + break; + case NES_CM_STATE_MPAREJ_RCVD: case NES_CM_STATE_UNKNOWN: case NES_CM_STATE_INITED: case NES_CM_STATE_CLOSED: -- cgit v0.10.2 From fd000e12a564bdeaec5e5a438d341d9132409f26 Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Wed, 9 Dec 2009 15:54:23 -0800 Subject: RDMA/nes: Check for zero STag STags are generated randomly but the driver does not correctly prevent a zero STag. Using STag zero is privileged and causes a user space application to fail. This change prevents the driver from trying to allocate a zero STag. Signed-off-by: Faisal Latif Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 9fc0273..b1c2cbb 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -437,11 +437,12 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { nesadapter->qp_table = (struct nes_qp **)(&nesadapter->allocated_arps[BITS_TO_LONGS(arp_table_size)]); - /* mark the usual suspect QPs and CQs as in use */ + /* mark the usual suspect QPs, MR and CQs as in use */ for (u32temp = 0; u32temp < NES_FIRST_QPN; u32temp++) { set_bit(u32temp, nesadapter->allocated_qps); set_bit(u32temp, nesadapter->allocated_cqs); } + set_bit(0, nesadapter->allocated_mrs); for (u32temp = 0; u32temp < 20; u32temp++) set_bit(u32temp, nesadapter->allocated_pds); diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 67a87cb..53dc39f 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -2503,9 +2503,6 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, stag = stag_index << 8; stag |= driver_key; stag += (u32)stag_key; - if (stag == 0) { - stag = 1; - } iova_start = virt; /* Make the leaf PBL the root if only one PBL */ -- cgit v0.10.2 From d2fa9b26e181d1e3c3df06a57fa13b04afee0e16 Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Wed, 9 Dec 2009 15:54:28 -0800 Subject: RDMA/nes: Free kmap() resources We fail when creating many qps as kmap() fails for sq_vbase. Fix this by doing kunmap() as soon as we are done with sq_vbase. We do kunmap() in one of the locations below: (1) nes_destroy_qp() (2) nes_accept() (3) nes_connect_event We keep a flag to avoid multiple calls to kunmap(). Signed-off-by: Faisal Latif Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index a258168..b139806 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -2836,6 +2837,10 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) cpu_to_le32(conn_param->private_data_len + sizeof(struct ietf_mpa_frame)); wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = ibmr->lkey; + if (nesqp->sq_kmapped) { + nesqp->sq_kmapped = 0; + kunmap(nesqp->page); + } nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | @@ -3304,6 +3309,11 @@ static void cm_event_connected(struct nes_cm_event *event) wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0; wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0; + if (nesqp->sq_kmapped) { + nesqp->sq_kmapped = 0; + kunmap(nesqp->page); + } + /* use the reserved spot on the WQ for the extra first WQE */ nesqp->nesqp_context->ird_ord_sizes &= cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 53dc39f..64d3136 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -1015,6 +1015,7 @@ static int nes_setup_virt_qp(struct nes_qp *nesqp, struct nes_pbl *nespbl, kunmap(nesqp->page); return -ENOMEM; } + nesqp->sq_kmapped = 1; nesqp->hwqp.q2_vbase = mem; mem += 256; memset(nesqp->hwqp.q2_vbase, 0, 256); @@ -1092,7 +1093,10 @@ static inline void nes_free_qp_mem(struct nes_device *nesdev, pci_free_consistent(nesdev->pcidev, nesqp->qp_mem_size, nesqp->hwqp.q2_vbase, nesqp->hwqp.q2_pbase); pci_free_consistent(nesdev->pcidev, 256, nesqp->pbl_vbase, nesqp->pbl_pbase ); nesqp->pbl_vbase = NULL; - kunmap(nesqp->page); + if (nesqp->sq_kmapped) { + nesqp->sq_kmapped = 0; + kunmap(nesqp->page); + } } } @@ -1501,8 +1505,10 @@ static int nes_destroy_qp(struct ib_qp *ibqp) nes_ucontext->first_free_wq = nesqp->mmap_sq_db_index; } } - if (nesqp->pbl_pbase) + if (nesqp->pbl_pbase && nesqp->sq_kmapped) { + nesqp->sq_kmapped = 0; kunmap(nesqp->page); + } } else { /* Clean any pending completions from the cq(s) */ if (nesqp->nesscq) diff --git a/drivers/infiniband/hw/nes/nes_verbs.h b/drivers/infiniband/hw/nes/nes_verbs.h index cc7a604..2df9993e 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.h +++ b/drivers/infiniband/hw/nes/nes_verbs.h @@ -175,5 +175,6 @@ struct nes_qp { u8 hw_iwarp_state; u8 hw_tcp_state; u8 term_flags; + u8 sq_kmapped; }; #endif /* NES_VERBS_H */ -- cgit v0.10.2 From b1190d3e0d548615ee7c38c10b5fc376a76b7afd Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Wed, 9 Dec 2009 15:54:32 -0800 Subject: RDMA/nes: FIN during MPA startup causes timeout A FIN that is received during an MPA start up sequence causes a timeout in iwcm.c. The connection has not been completely closed so the iwcm code is waiting for resources to be cleaned up. This closes the connection so everything cleans up correctly. Signed-off-by: Don Wood Signed-off-by: Faisal Latif Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index b139806..4acf04a 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1354,13 +1354,20 @@ static void handle_fin_pkt(struct nes_cm_node *cm_node) case NES_CM_STATE_SYN_RCVD: case NES_CM_STATE_SYN_SENT: case NES_CM_STATE_ESTABLISHED: - case NES_CM_STATE_MPAREQ_SENT: case NES_CM_STATE_MPAREJ_RCVD: cm_node->tcp_cntxt.rcv_nxt++; cleanup_retrans_entry(cm_node); cm_node->state = NES_CM_STATE_LAST_ACK; send_fin(cm_node, NULL); break; + case NES_CM_STATE_MPAREQ_SENT: + create_event(cm_node, NES_CM_EVENT_ABORTED); + cm_node->tcp_cntxt.rcv_nxt++; + cleanup_retrans_entry(cm_node); + cm_node->state = NES_CM_STATE_CLOSED; + add_ref_cm_node(cm_node); + send_reset(cm_node, NULL); + break; case NES_CM_STATE_FIN_WAIT1: cm_node->tcp_cntxt.rcv_nxt++; cleanup_retrans_entry(cm_node); -- cgit v0.10.2 From 7a576dfd9ed4fd0f32bb838ce4f644af201ac7df Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Wed, 9 Dec 2009 15:54:33 -0800 Subject: RDMA/nes: Fix stale ARP issue When the remote node's ethernet address changes, the connection keeps trying to connect using the old address. The connection wil continue failing until the driver is unloaded and loaded again (eiter reboot or rmmod). Fix this by checking that the NIC has the correct address before starting a connection. Signed-off-by: Faisal Latif Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 4acf04a..39468c2 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1098,12 +1098,13 @@ static inline int mini_cm_accelerated(struct nes_cm_core *cm_core, /** * nes_addr_resolve_neigh */ -static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip) +static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpindex) { struct rtable *rt; struct flowi fl; struct neighbour *neigh; - int rc = -1; + int rc = arpindex; + struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter; memset(&fl, 0, sizeof fl); fl.nl_u.ip4_u.daddr = htonl(dst_ip); @@ -1119,6 +1120,21 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip) nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X" " is %pM, Gateway is 0x%08X \n", dst_ip, neigh->ha, ntohl(rt->rt_gateway)); + + if (arpindex >= 0) { + if (!memcmp(nesadapter->arp_table[arpindex].mac_addr, + neigh->ha, ETH_ALEN)){ + /* Mac address same as in nes_arp_table */ + neigh_release(neigh); + ip_rt_put(rt); + return rc; + } + + nes_manage_arp_cache(nesvnic->netdev, + nesadapter->arp_table[arpindex].mac_addr, + dst_ip, NES_ARP_DELETE); + } + nes_manage_arp_cache(nesvnic->netdev, neigh->ha, dst_ip, NES_ARP_ADD); rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL, @@ -1134,7 +1150,6 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip) return rc; } - /** * make_cm_node - create a new instance of a cm node */ @@ -1144,6 +1159,7 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core, { struct nes_cm_node *cm_node; struct timespec ts; + int oldarpindex = 0; int arpindex = 0; struct nes_device *nesdev; struct nes_adapter *nesadapter; @@ -1197,17 +1213,18 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core, nesadapter = nesdev->nesadapter; cm_node->loopbackpartner = NULL; + /* get the mac addr for the remote node */ if (ipv4_is_loopback(htonl(cm_node->rem_addr))) arpindex = nes_arp_table(nesdev, ntohl(nesvnic->local_ipaddr), NULL, NES_ARP_RESOLVE); - else - arpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE); + else { + oldarpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE); + arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr, oldarpindex); + + } if (arpindex < 0) { - arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr); - if (arpindex < 0) { - kfree(cm_node); - return NULL; - } + kfree(cm_node); + return NULL; } /* copy the mac addr to node context */ -- cgit v0.10.2 From e258e4e0b495e6ecbd073d6bef1eafb62a58919a Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 9 Dec 2009 19:01:51 -0500 Subject: x86-32: Add new pt_regs stubs Add new stubs which add the pt_regs pointer as the last arg, matching 64-bit. This will allow these syscalls to be easily merged. Signed-off-by: Brian Gerst LKML-Reference: <1260403316-5679-2-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 50b9c22..34dbfa9 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -725,22 +725,49 @@ END(syscall_badsys) /* * System calls that need a pt_regs pointer. */ -#define PTREGSCALL(name) \ +#define PTREGSCALL0(name) \ ALIGN; \ ptregs_##name: \ leal 4(%esp),%eax; \ jmp sys_##name; -PTREGSCALL(iopl) -PTREGSCALL(fork) -PTREGSCALL(clone) -PTREGSCALL(vfork) -PTREGSCALL(execve) -PTREGSCALL(sigaltstack) -PTREGSCALL(sigreturn) -PTREGSCALL(rt_sigreturn) -PTREGSCALL(vm86) -PTREGSCALL(vm86old) +#define PTREGSCALL1(name) \ + ALIGN; \ +ptregs_##name: \ + leal 4(%esp),%edx; \ + movl PT_EBX(%edx),%eax; \ + jmp sys_##name; + +#define PTREGSCALL2(name) \ + ALIGN; \ +ptregs_##name: \ + leal 4(%esp),%ecx; \ + movl PT_ECX(%ecx),%edx; \ + movl PT_EBX(%ecx),%eax; \ + jmp sys_##name; + +#define PTREGSCALL3(name) \ + ALIGN; \ +ptregs_##name: \ + leal 4(%esp),%eax; \ + pushl %eax; \ + movl PT_EDX(%eax),%ecx; \ + movl PT_ECX(%eax),%edx; \ + movl PT_EBX(%eax),%eax; \ + call sys_##name; \ + addl $4,%esp; \ + ret + +PTREGSCALL0(iopl) +PTREGSCALL0(fork) +PTREGSCALL0(clone) +PTREGSCALL0(vfork) +PTREGSCALL0(execve) +PTREGSCALL0(sigaltstack) +PTREGSCALL0(sigreturn) +PTREGSCALL0(rt_sigreturn) +PTREGSCALL0(vm86) +PTREGSCALL0(vm86old) .macro FIXUP_ESPFIX_STACK /* -- cgit v0.10.2 From 27f59559d63375a4d59e7c720a439d9f0b47edad Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 9 Dec 2009 19:01:52 -0500 Subject: x86: Merge sys_iopl Change 32-bit sys_iopl to PTREGSCALL1, and merge with 64-bit. Signed-off-by: Brian Gerst LKML-Reference: <1260403316-5679-3-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h index 372b76e..4b694cd 100644 --- a/arch/x86/include/asm/syscalls.h +++ b/arch/x86/include/asm/syscalls.h @@ -18,6 +18,7 @@ /* Common in X86_32 and X86_64 */ /* kernel/ioport.c */ asmlinkage long sys_ioperm(unsigned long, unsigned long, int); +long sys_iopl(unsigned int, struct pt_regs *); /* kernel/process.c */ int sys_fork(struct pt_regs *); @@ -35,8 +36,6 @@ asmlinkage int sys_get_thread_area(struct user_desc __user *); /* X86_32 only */ #ifdef CONFIG_X86_32 -/* kernel/ioport.c */ -long sys_iopl(struct pt_regs *); /* kernel/process_32.c */ int sys_clone(struct pt_regs *); @@ -70,9 +69,6 @@ int sys_vm86(struct pt_regs *); #else /* CONFIG_X86_32 */ /* X86_64 only */ -/* kernel/ioport.c */ -asmlinkage long sys_iopl(unsigned int, struct pt_regs *); - /* kernel/process_64.c */ asmlinkage long sys_clone(unsigned long, unsigned long, void __user *, void __user *, diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 34dbfa9..ab7fcef 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -758,7 +758,7 @@ ptregs_##name: \ addl $4,%esp; \ ret -PTREGSCALL0(iopl) +PTREGSCALL1(iopl) PTREGSCALL0(fork) PTREGSCALL0(clone) PTREGSCALL0(vfork) diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c index 99c4d30..85ecc7c 100644 --- a/arch/x86/kernel/ioport.c +++ b/arch/x86/kernel/ioport.c @@ -103,9 +103,10 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) * on system-call entry - see also fork() and the signal handling * code. */ -static int do_iopl(unsigned int level, struct pt_regs *regs) +long sys_iopl(unsigned int level, struct pt_regs *regs) { unsigned int old = (regs->flags >> 12) & 3; + struct thread_struct *t = ¤t->thread; if (level > 3) return -EINVAL; @@ -115,29 +116,10 @@ static int do_iopl(unsigned int level, struct pt_regs *regs) return -EPERM; } regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12); - - return 0; -} - #ifdef CONFIG_X86_32 -long sys_iopl(struct pt_regs *regs) -{ - unsigned int level = regs->bx; - struct thread_struct *t = ¤t->thread; - int rc; - - rc = do_iopl(level, regs); - if (rc < 0) - goto out; - t->iopl = level << 12; set_iopl_mask(t->iopl); -out: - return rc; -} -#else -asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs) -{ - return do_iopl(level, regs); -} #endif + + return 0; +} -- cgit v0.10.2 From 11cf88bd0b8165b65aaabaee0977e9a3ad474ab7 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 9 Dec 2009 19:01:53 -0500 Subject: x86: Merge sys_execve Change 32-bit sys_execve to PTREGSCALL3, and merge with 64-bit. Signed-off-by: Brian Gerst LKML-Reference: <1260403316-5679-4-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h index 4b694cd..48c48e5 100644 --- a/arch/x86/include/asm/syscalls.h +++ b/arch/x86/include/asm/syscalls.h @@ -23,6 +23,8 @@ long sys_iopl(unsigned int, struct pt_regs *); /* kernel/process.c */ int sys_fork(struct pt_regs *); int sys_vfork(struct pt_regs *); +long sys_execve(char __user *, char __user * __user *, + char __user * __user *, struct pt_regs *); /* kernel/ldt.c */ asmlinkage int sys_modify_ldt(int, void __user *, unsigned long); @@ -39,7 +41,6 @@ asmlinkage int sys_get_thread_area(struct user_desc __user *); /* kernel/process_32.c */ int sys_clone(struct pt_regs *); -int sys_execve(struct pt_regs *); /* kernel/signal.c */ asmlinkage int sys_sigsuspend(int, int, old_sigset_t); @@ -73,9 +74,6 @@ int sys_vm86(struct pt_regs *); asmlinkage long sys_clone(unsigned long, unsigned long, void __user *, void __user *, struct pt_regs *); -asmlinkage long sys_execve(char __user *, char __user * __user *, - char __user * __user *, - struct pt_regs *); long sys_arch_prctl(int, unsigned long); /* kernel/signal.c */ diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index ab7fcef..a96a0d8 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -762,7 +762,7 @@ PTREGSCALL1(iopl) PTREGSCALL0(fork) PTREGSCALL0(clone) PTREGSCALL0(vfork) -PTREGSCALL0(execve) +PTREGSCALL3(execve) PTREGSCALL0(sigaltstack) PTREGSCALL0(sigreturn) PTREGSCALL0(rt_sigreturn) diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 5e2ba63..bb17bd9 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -236,6 +236,32 @@ int sys_vfork(struct pt_regs *regs) /* + * sys_execve() executes a new program. + */ +long sys_execve(char __user *name, char __user * __user *argv, + char __user * __user *envp, struct pt_regs *regs) +{ + long error; + char *filename; + + filename = getname(name); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + return error; + error = do_execve(filename, argv, envp, regs); + +#ifdef CONFIG_X86_32 + if (error == 0) { + /* Make sure we don't return using sysenter.. */ + set_thread_flag(TIF_IRET); + } +#endif + + putname(filename); + return error; +} + +/* * Idle related variables and functions */ unsigned long boot_option_idle_override = 0; diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 075580b..486e38e 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -451,31 +451,6 @@ int sys_clone(struct pt_regs *regs) return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr); } -/* - * sys_execve() executes a new program. - */ -int sys_execve(struct pt_regs *regs) -{ - int error; - char *filename; - - filename = getname((char __user *) regs->bx); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - error = do_execve(filename, - (char __user * __user *) regs->cx, - (char __user * __user *) regs->dx, - regs); - if (error == 0) { - /* Make sure we don't return using sysenter.. */ - set_thread_flag(TIF_IRET); - } - putname(filename); -out: - return error; -} - #define top_esp (THREAD_SIZE - sizeof(unsigned long)) #define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long)) diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index c95c8f4..671960d 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -520,25 +520,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) return prev_p; } -/* - * sys_execve() executes a new program. - */ -asmlinkage -long sys_execve(char __user *name, char __user * __user *argv, - char __user * __user *envp, struct pt_regs *regs) -{ - long error; - char *filename; - - filename = getname(name); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - return error; - error = do_execve(filename, argv, envp, regs); - putname(filename); - return error; -} - void set_personality_64bit(void) { /* inherit personality from parent */ -- cgit v0.10.2 From 052acad48a566a6dbcccb95e5d22e5e1b7cac8dd Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 9 Dec 2009 19:01:54 -0500 Subject: x86: Merge sys_sigaltstack Change 32-bit sys_sigaltstack to PTREGSCALL2, and merge with 64-bit. Signed-off-by: Brian Gerst LKML-Reference: <1260403316-5679-5-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h index 48c48e5..94e0b61 100644 --- a/arch/x86/include/asm/syscalls.h +++ b/arch/x86/include/asm/syscalls.h @@ -31,6 +31,9 @@ asmlinkage int sys_modify_ldt(int, void __user *, unsigned long); /* kernel/signal.c */ long sys_rt_sigreturn(struct pt_regs *); +long sys_sigaltstack(const stack_t __user *, stack_t __user *, + struct pt_regs *); + /* kernel/tls.c */ asmlinkage int sys_set_thread_area(struct user_desc __user *); @@ -46,7 +49,6 @@ int sys_clone(struct pt_regs *); asmlinkage int sys_sigsuspend(int, int, old_sigset_t); asmlinkage int sys_sigaction(int, const struct old_sigaction __user *, struct old_sigaction __user *); -int sys_sigaltstack(struct pt_regs *); unsigned long sys_sigreturn(struct pt_regs *); /* kernel/sys_i386_32.c */ @@ -76,10 +78,6 @@ asmlinkage long sys_clone(unsigned long, unsigned long, struct pt_regs *); long sys_arch_prctl(int, unsigned long); -/* kernel/signal.c */ -asmlinkage long sys_sigaltstack(const stack_t __user *, stack_t __user *, - struct pt_regs *); - /* kernel/sys_x86_64.c */ struct new_utsname; diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index a96a0d8..621ef45 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -763,7 +763,7 @@ PTREGSCALL0(fork) PTREGSCALL0(clone) PTREGSCALL0(vfork) PTREGSCALL3(execve) -PTREGSCALL0(sigaltstack) +PTREGSCALL2(sigaltstack) PTREGSCALL0(sigreturn) PTREGSCALL0(rt_sigreturn) PTREGSCALL0(vm86) diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 74fe6d8..4fd173c 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -545,22 +545,12 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, } #endif /* CONFIG_X86_32 */ -#ifdef CONFIG_X86_32 -int sys_sigaltstack(struct pt_regs *regs) -{ - const stack_t __user *uss = (const stack_t __user *)regs->bx; - stack_t __user *uoss = (stack_t __user *)regs->cx; - - return do_sigaltstack(uss, uoss, regs->sp); -} -#else /* !CONFIG_X86_32 */ -asmlinkage long +long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, struct pt_regs *regs) { return do_sigaltstack(uss, uoss, regs->sp); } -#endif /* CONFIG_X86_32 */ /* * Do a signal return; undo the signal stack. -- cgit v0.10.2 From f1382f157fb1175bba008abad0907310a1e459ce Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 9 Dec 2009 19:01:55 -0500 Subject: x86, 32-bit: Convert sys_vm86 & sys_vm86old Convert these to new PTREGSCALL stubs. Signed-off-by: Brian Gerst LKML-Reference: <1260403316-5679-6-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h index 94e0b61..df2c511 100644 --- a/arch/x86/include/asm/syscalls.h +++ b/arch/x86/include/asm/syscalls.h @@ -66,8 +66,8 @@ asmlinkage int sys_uname(struct old_utsname __user *); asmlinkage int sys_olduname(struct oldold_utsname __user *); /* kernel/vm86_32.c */ -int sys_vm86old(struct pt_regs *); -int sys_vm86(struct pt_regs *); +int sys_vm86old(struct vm86_struct __user *, struct pt_regs *); +int sys_vm86(unsigned long, unsigned long, struct pt_regs *); #else /* CONFIG_X86_32 */ diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 621ef45..6c2f25d 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -766,8 +766,8 @@ PTREGSCALL3(execve) PTREGSCALL2(sigaltstack) PTREGSCALL0(sigreturn) PTREGSCALL0(rt_sigreturn) -PTREGSCALL0(vm86) -PTREGSCALL0(vm86old) +PTREGSCALL2(vm86) +PTREGSCALL1(vm86old) .macro FIXUP_ESPFIX_STACK /* diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index 9c4e625..5ffb5622 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c @@ -197,9 +197,8 @@ out: static int do_vm86_irq_handling(int subfunction, int irqnumber); static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk); -int sys_vm86old(struct pt_regs *regs) +int sys_vm86old(struct vm86_struct __user *v86, struct pt_regs *regs) { - struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs->bx; struct kernel_vm86_struct info; /* declare this _on top_, * this avoids wasting of stack space. * This remains on the stack until we @@ -227,7 +226,7 @@ out: } -int sys_vm86(struct pt_regs *regs) +int sys_vm86(unsigned long cmd, unsigned long arg, struct pt_regs *regs) { struct kernel_vm86_struct info; /* declare this _on top_, * this avoids wasting of stack space. @@ -239,12 +238,12 @@ int sys_vm86(struct pt_regs *regs) struct vm86plus_struct __user *v86; tsk = current; - switch (regs->bx) { + switch (cmd) { case VM86_REQUEST_IRQ: case VM86_FREE_IRQ: case VM86_GET_IRQ_BITS: case VM86_GET_AND_RESET_IRQ: - ret = do_vm86_irq_handling(regs->bx, (int)regs->cx); + ret = do_vm86_irq_handling(cmd, (int)arg); goto out; case VM86_PLUS_INSTALL_CHECK: /* @@ -261,7 +260,7 @@ int sys_vm86(struct pt_regs *regs) ret = -EPERM; if (tsk->thread.saved_sp0) goto out; - v86 = (struct vm86plus_struct __user *)regs->cx; + v86 = (struct vm86plus_struct __user *)arg; tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs, offsetof(struct kernel_vm86_struct, regs32) - sizeof(info.regs)); -- cgit v0.10.2 From f839bbc5c81b1c92ff8e81c360e9564f7b961b2e Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 9 Dec 2009 19:01:56 -0500 Subject: x86: Merge sys_clone Change 32-bit sys_clone to new PTREGSCALL stub, and merge with 64-bit. Signed-off-by: Brian Gerst LKML-Reference: <1260403316-5679-7-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h index df2c511..b0ce780 100644 --- a/arch/x86/include/asm/syscalls.h +++ b/arch/x86/include/asm/syscalls.h @@ -25,6 +25,8 @@ int sys_fork(struct pt_regs *); int sys_vfork(struct pt_regs *); long sys_execve(char __user *, char __user * __user *, char __user * __user *, struct pt_regs *); +long sys_clone(unsigned long, unsigned long, void __user *, + void __user *, struct pt_regs *); /* kernel/ldt.c */ asmlinkage int sys_modify_ldt(int, void __user *, unsigned long); @@ -42,9 +44,6 @@ asmlinkage int sys_get_thread_area(struct user_desc __user *); /* X86_32 only */ #ifdef CONFIG_X86_32 -/* kernel/process_32.c */ -int sys_clone(struct pt_regs *); - /* kernel/signal.c */ asmlinkage int sys_sigsuspend(int, int, old_sigset_t); asmlinkage int sys_sigaction(int, const struct old_sigaction __user *, @@ -73,9 +72,6 @@ int sys_vm86(unsigned long, unsigned long, struct pt_regs *); /* X86_64 only */ /* kernel/process_64.c */ -asmlinkage long sys_clone(unsigned long, unsigned long, - void __user *, void __user *, - struct pt_regs *); long sys_arch_prctl(int, unsigned long); /* kernel/sys_x86_64.c */ diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 6c2f25d..6492555 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -760,7 +760,6 @@ ptregs_##name: \ PTREGSCALL1(iopl) PTREGSCALL0(fork) -PTREGSCALL0(clone) PTREGSCALL0(vfork) PTREGSCALL3(execve) PTREGSCALL2(sigaltstack) @@ -769,6 +768,19 @@ PTREGSCALL0(rt_sigreturn) PTREGSCALL2(vm86) PTREGSCALL1(vm86old) +/* Clone is an oddball. The 4th arg is in %edi */ + ALIGN; +ptregs_clone: + leal 4(%esp),%eax + pushl %eax + pushl PT_EDI(%eax) + movl PT_EDX(%eax),%ecx + movl PT_ECX(%eax),%edx + movl PT_EBX(%eax),%eax + call sys_clone + addl $8,%esp + ret + .macro FIXUP_ESPFIX_STACK /* * Switch back for ESPFIX stack to the normal zerobased stack diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index bb17bd9..f3c1a6b 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -234,6 +234,15 @@ int sys_vfork(struct pt_regs *regs) NULL, NULL); } +long +sys_clone(unsigned long clone_flags, unsigned long newsp, + void __user *parent_tid, void __user *child_tid, struct pt_regs *regs) +{ + if (!newsp) + newsp = regs->sp; + return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); +} + /* * sys_execve() executes a new program. diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 486e38e..506d5a7 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -436,21 +436,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) return prev_p; } -int sys_clone(struct pt_regs *regs) -{ - unsigned long clone_flags; - unsigned long newsp; - int __user *parent_tidptr, *child_tidptr; - - clone_flags = regs->bx; - newsp = regs->cx; - parent_tidptr = (int __user *)regs->dx; - child_tidptr = (int __user *)regs->di; - if (!newsp) - newsp = regs->sp; - return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr); -} - #define top_esp (THREAD_SIZE - sizeof(unsigned long)) #define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long)) diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 671960d..83019f9 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -534,15 +534,6 @@ void set_personality_64bit(void) current->personality &= ~READ_IMPLIES_EXEC; } -asmlinkage long -sys_clone(unsigned long clone_flags, unsigned long newsp, - void __user *parent_tid, void __user *child_tid, struct pt_regs *regs) -{ - if (!newsp) - newsp = regs->sp; - return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); -} - unsigned long get_wchan(struct task_struct *p) { unsigned long stack; -- cgit v0.10.2 From ce9119ad90b1caba550447bfcc0a21850558ca49 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 9 Dec 2009 16:33:44 -0800 Subject: x86-32: Avoid pipeline serialization in PTREGSCALL1 and 2 In the PTREGSCALL1 and 2 macros, we can trivially avoid an unnecessary pipeline serialization, so do so. In PTREGSCALLS3 this is much less clear-cut since we have to push a new value to the stack. Leave it alone for now assuming it is as good as it is going to be; may want to check on Atom or another in-order x86 to see if we can do better. Signed-off-by: H. Peter Anvin Cc: Brian Gerst LKML-Reference: <1260403316-5679-2-git-send-email-brgerst@gmail.com> diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 6492555..cb12b9b 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -735,15 +735,15 @@ ptregs_##name: \ ALIGN; \ ptregs_##name: \ leal 4(%esp),%edx; \ - movl PT_EBX(%edx),%eax; \ + movl (PT_EBX+4)(%esp),%eax; \ jmp sys_##name; #define PTREGSCALL2(name) \ ALIGN; \ ptregs_##name: \ leal 4(%esp),%ecx; \ - movl PT_ECX(%ecx),%edx; \ - movl PT_EBX(%ecx),%eax; \ + movl (PT_ECX+4)(%esp),%edx; \ + movl (PT_EBX+4)(%esp),%eax; \ jmp sys_##name; #define PTREGSCALL3(name) \ -- cgit v0.10.2 From fc380ceed7fe469728ea4acdbda4495ea943ee1c Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 9 Dec 2009 16:54:08 -0800 Subject: x86-64, paravirt: Call set_iopl_mask() on 64 bits set_iopl_mask() is a no-op on 64 bits, but it is also a paravirt hook, so call it even on 64 bits. Signed-off-by: H. Peter Anvin Cc: Jeremy Fitzhardinge Cc: Brian Gerst LKML-Reference: <1260403316-5679-3-git-send-email-brgerst@gmail.com> diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c index 85ecc7c..8eec0ec 100644 --- a/arch/x86/kernel/ioport.c +++ b/arch/x86/kernel/ioport.c @@ -116,10 +116,8 @@ long sys_iopl(unsigned int level, struct pt_regs *regs) return -EPERM; } regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12); -#ifdef CONFIG_X86_32 t->iopl = level << 12; set_iopl_mask(t->iopl); -#endif return 0; } -- cgit v0.10.2 From e5fbba85a7acc2626d4fe14501816811d702f3e9 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Tue, 21 Jul 2009 12:14:01 +0100 Subject: hp-wmi: improve rfkill support 1) Add support for reading the hardware blocked state. Previously we read a combination of the hardware and software blocked states, reporting it as the software blocked state. This caused some confusing behaviour. 2) The software state is persistent, mark it as such. 3) Check rfkill in the resume handler. Both the hard and soft blocked states may change over hibernation. Signed-off-by: Alan Jenkins Acked-by: Matthew Garrett Tested-by: Maciej Rutecki Signed-off-by: Len Brown diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index c284217..804cfdb 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -51,6 +51,12 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4"); #define HPWMI_WIRELESS_QUERY 0x5 #define HPWMI_HOTKEY_QUERY 0xc +enum hp_wmi_radio { + HPWMI_WIFI = 0, + HPWMI_BLUETOOTH = 1, + HPWMI_WWAN = 2, +}; + static int __init hp_wmi_bios_setup(struct platform_device *device); static int __exit hp_wmi_bios_remove(struct platform_device *device); static int hp_wmi_resume_handler(struct device *device); @@ -175,8 +181,8 @@ static int hp_wmi_tablet_state(void) static int hp_wmi_set_block(void *data, bool blocked) { - unsigned long b = (unsigned long) data; - int query = BIT(b + 8) | ((!blocked) << b); + enum hp_wmi_radio r = (enum hp_wmi_radio) data; + int query = BIT(r + 8) | ((!blocked) << r); return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query); } @@ -185,31 +191,23 @@ static const struct rfkill_ops hp_wmi_rfkill_ops = { .set_block = hp_wmi_set_block, }; -static bool hp_wmi_wifi_state(void) -{ - int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); - - if (wireless & 0x100) - return false; - else - return true; -} - -static bool hp_wmi_bluetooth_state(void) +static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) { int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); + int mask = 0x200 << (r * 8); - if (wireless & 0x10000) + if (wireless & mask) return false; else return true; } -static bool hp_wmi_wwan_state(void) +static bool hp_wmi_get_hw_state(enum hp_wmi_radio r) { int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); + int mask = 0x800 << (r * 8); - if (wireless & 0x1000000) + if (wireless & mask) return false; else return true; @@ -334,49 +332,55 @@ static void hp_wmi_notify(u32 value, void *context) struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; static struct key_entry *key; union acpi_object *obj; + int eventcode; wmi_get_event_data(value, &response); obj = (union acpi_object *)response.pointer; - if (obj && obj->type == ACPI_TYPE_BUFFER && obj->buffer.length == 8) { - int eventcode = *((u8 *) obj->buffer.pointer); - if (eventcode == 0x4) - eventcode = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, - 0); - key = hp_wmi_get_entry_by_scancode(eventcode); - if (key) { - switch (key->type) { - case KE_KEY: - input_report_key(hp_wmi_input_dev, - key->keycode, 1); - input_sync(hp_wmi_input_dev); - input_report_key(hp_wmi_input_dev, - key->keycode, 0); - input_sync(hp_wmi_input_dev); - break; - } - } else if (eventcode == 0x1) { - input_report_switch(hp_wmi_input_dev, SW_DOCK, - hp_wmi_dock_state()); - input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, - hp_wmi_tablet_state()); + if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) { + printk(KERN_INFO "HP WMI: Unknown response received\n"); + return; + } + + eventcode = *((u8 *) obj->buffer.pointer); + if (eventcode == 0x4) + eventcode = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, + 0); + key = hp_wmi_get_entry_by_scancode(eventcode); + if (key) { + switch (key->type) { + case KE_KEY: + input_report_key(hp_wmi_input_dev, + key->keycode, 1); + input_sync(hp_wmi_input_dev); + input_report_key(hp_wmi_input_dev, + key->keycode, 0); input_sync(hp_wmi_input_dev); - } else if (eventcode == 0x5) { - if (wifi_rfkill) - rfkill_set_sw_state(wifi_rfkill, - hp_wmi_wifi_state()); - if (bluetooth_rfkill) - rfkill_set_sw_state(bluetooth_rfkill, - hp_wmi_bluetooth_state()); - if (wwan_rfkill) - rfkill_set_sw_state(wwan_rfkill, - hp_wmi_wwan_state()); - } else - printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n", - eventcode); + break; + } + } else if (eventcode == 0x1) { + input_report_switch(hp_wmi_input_dev, SW_DOCK, + hp_wmi_dock_state()); + input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, + hp_wmi_tablet_state()); + input_sync(hp_wmi_input_dev); + } else if (eventcode == 0x5) { + if (wifi_rfkill) + rfkill_set_states(wifi_rfkill, + hp_wmi_get_sw_state(HPWMI_WIFI), + hp_wmi_get_hw_state(HPWMI_WIFI)); + if (bluetooth_rfkill) + rfkill_set_states(bluetooth_rfkill, + hp_wmi_get_sw_state(HPWMI_BLUETOOTH), + hp_wmi_get_hw_state(HPWMI_BLUETOOTH)); + if (wwan_rfkill) + rfkill_set_states(wwan_rfkill, + hp_wmi_get_sw_state(HPWMI_WWAN), + hp_wmi_get_hw_state(HPWMI_WWAN)); } else - printk(KERN_INFO "HP WMI: Unknown response received\n"); + printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n", + eventcode); } static int __init hp_wmi_input_setup(void) @@ -455,7 +459,11 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev, RFKILL_TYPE_WLAN, &hp_wmi_rfkill_ops, - (void *) 0); + (void *) HPWMI_WIFI); + rfkill_init_sw_state(wifi_rfkill, + hp_wmi_get_sw_state(HPWMI_WIFI)); + rfkill_set_hw_state(wifi_rfkill, + hp_wmi_get_hw_state(HPWMI_WIFI)); err = rfkill_register(wifi_rfkill); if (err) goto register_wifi_error; @@ -465,7 +473,11 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev, RFKILL_TYPE_BLUETOOTH, &hp_wmi_rfkill_ops, - (void *) 1); + (void *) HPWMI_BLUETOOTH); + rfkill_init_sw_state(bluetooth_rfkill, + hp_wmi_get_sw_state(HPWMI_BLUETOOTH)); + rfkill_set_hw_state(bluetooth_rfkill, + hp_wmi_get_hw_state(HPWMI_BLUETOOTH)); err = rfkill_register(bluetooth_rfkill); if (err) goto register_bluetooth_error; @@ -475,7 +487,11 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev, RFKILL_TYPE_WWAN, &hp_wmi_rfkill_ops, - (void *) 2); + (void *) HPWMI_WWAN); + rfkill_init_sw_state(wwan_rfkill, + hp_wmi_get_sw_state(HPWMI_WWAN)); + rfkill_set_hw_state(wwan_rfkill, + hp_wmi_get_hw_state(HPWMI_WWAN)); err = rfkill_register(wwan_rfkill); if (err) goto register_wwan_err; @@ -533,6 +549,19 @@ static int hp_wmi_resume_handler(struct device *device) input_sync(hp_wmi_input_dev); } + if (wifi_rfkill) + rfkill_set_states(wifi_rfkill, + hp_wmi_get_sw_state(HPWMI_WIFI), + hp_wmi_get_hw_state(HPWMI_WIFI)); + if (bluetooth_rfkill) + rfkill_set_states(bluetooth_rfkill, + hp_wmi_get_sw_state(HPWMI_BLUETOOTH), + hp_wmi_get_hw_state(HPWMI_BLUETOOTH)); + if (wwan_rfkill) + rfkill_set_states(wwan_rfkill, + hp_wmi_get_sw_state(HPWMI_WWAN), + hp_wmi_get_hw_state(HPWMI_WWAN)); + return 0; } -- cgit v0.10.2 From e1fbf346c7c56d6b2f9d835d297bcb088baaff3a Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Fri, 31 Jul 2009 03:25:38 +0100 Subject: dell-laptop: Fix rfkill state queries The current code in dell-laptop is confused about the hardware rfkill state. Fix it up such that it's always reported correctly. Signed-off-by: Matthew Garrett Tested-by: Tim Gardner Signed-off-by: Len Brown diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 74909c4..9061111 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -197,8 +197,8 @@ static void dell_rfkill_query(struct rfkill *rfkill, void *data) dell_send_request(&buffer, 17, 11); status = buffer.output[1]; - if (status & BIT(bit)) - rfkill_set_hw_state(rfkill, !!(status & BIT(16))); + rfkill_set_sw_state(rfkill, !!(status & BIT(bit))); + rfkill_set_hw_state(rfkill, !(status & BIT(16))); } static const struct rfkill_ops dell_rfkill_ops = { -- cgit v0.10.2 From 71e9dc73cb6b1351bdd5f732cef5dbef411b3219 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Wed, 19 Aug 2009 15:06:47 +0100 Subject: dell-laptop: fix a use-after-free error on the failure path dell_setup_rfkill() already cleans up the rfkill devices on failure. So if it returns an error, we should not try to unregister the rfkill devices. Signed-off-by: Alan Jenkins Acked-by: Matthew Garrett Signed-off-by: Len Brown diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 9061111..d791ef9 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -330,7 +330,7 @@ static int __init dell_init(void) if (ret) { printk(KERN_WARNING "dell-laptop: Unable to setup rfkill\n"); - goto out; + goto fail_rfkill; } #ifdef CONFIG_ACPI @@ -358,7 +358,7 @@ static int __init dell_init(void) if (IS_ERR(dell_backlight_device)) { ret = PTR_ERR(dell_backlight_device); dell_backlight_device = NULL; - goto out; + goto fail_backlight; } dell_backlight_device->props.max_brightness = max_intensity; @@ -368,13 +368,15 @@ static int __init dell_init(void) } return 0; -out: + +fail_backlight: if (wifi_rfkill) rfkill_unregister(wifi_rfkill); if (bluetooth_rfkill) rfkill_unregister(bluetooth_rfkill); if (wwan_rfkill) rfkill_unregister(wwan_rfkill); +fail_rfkill: kfree(da_tokens); return ret; } -- cgit v0.10.2 From 4311bb230e0f7e4daa5fd5bc0cc536e2bd1eff20 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Wed, 19 Aug 2009 15:06:48 +0100 Subject: dell-laptop: fix rfkill memory leak on unload and failure paths rfkill_unregister() should always be followed by rfkill_destroy(). Signed-off-by: Alan Jenkins Acked-by: Matthew Garrett Signed-off-by: Len Brown diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index d791ef9..94139d5 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -268,6 +268,22 @@ err_wifi: return ret; } +static void dell_cleanup_rfkill(void) +{ + if (wifi_rfkill) { + rfkill_unregister(wifi_rfkill); + rfkill_destroy(wifi_rfkill); + } + if (bluetooth_rfkill) { + rfkill_unregister(bluetooth_rfkill); + rfkill_destroy(bluetooth_rfkill); + } + if (wwan_rfkill) { + rfkill_unregister(wwan_rfkill); + rfkill_destroy(wwan_rfkill); + } +} + static int dell_send_intensity(struct backlight_device *bd) { struct calling_interface_buffer buffer; @@ -370,12 +386,7 @@ static int __init dell_init(void) return 0; fail_backlight: - if (wifi_rfkill) - rfkill_unregister(wifi_rfkill); - if (bluetooth_rfkill) - rfkill_unregister(bluetooth_rfkill); - if (wwan_rfkill) - rfkill_unregister(wwan_rfkill); + dell_cleanup_rfkill(); fail_rfkill: kfree(da_tokens); return ret; @@ -384,12 +395,7 @@ fail_rfkill: static void __exit dell_exit(void) { backlight_device_unregister(dell_backlight_device); - if (wifi_rfkill) - rfkill_unregister(wifi_rfkill); - if (bluetooth_rfkill) - rfkill_unregister(bluetooth_rfkill); - if (wwan_rfkill) - rfkill_unregister(wwan_rfkill); + dell_cleanup_rfkill(); } module_init(dell_init); -- cgit v0.10.2 From ada3248a5d38654b33b0ae2eabe1d7e3d9a9ffce Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Wed, 19 Aug 2009 15:06:49 +0100 Subject: dell-laptop: create a platform device as a parent for the rfkill devices etc. dell-laptop may not need to export any sysfs files, but it should still create a platform device as a parent for the rfkill and backlight devices. Otherwise sysfs will display these as "virtual" devices, with no connection to either physical hardware or the dell-laptop module. Apparently this is useful for hardware detection. Signed-off-by: Alan Jenkins Acked-by: Matthew Garrett Signed-off-by: Len Brown diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 94139d5..a4ce642 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -58,6 +58,14 @@ static int da_command_code; static int da_num_tokens; static struct calling_interface_token *da_tokens; +static struct platform_driver platform_driver = { + .driver = { + .name = "dell-laptop", + .owner = THIS_MODULE, + } +}; + +static struct platform_device *platform_device; static struct backlight_device *dell_backlight_device; static struct rfkill *wifi_rfkill; static struct rfkill *bluetooth_rfkill; @@ -217,7 +225,8 @@ static int dell_setup_rfkill(void) status = buffer.output[1]; if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { - wifi_rfkill = rfkill_alloc("dell-wifi", NULL, RFKILL_TYPE_WLAN, + wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev, + RFKILL_TYPE_WLAN, &dell_rfkill_ops, (void *) 1); if (!wifi_rfkill) { ret = -ENOMEM; @@ -229,7 +238,8 @@ static int dell_setup_rfkill(void) } if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) { - bluetooth_rfkill = rfkill_alloc("dell-bluetooth", NULL, + bluetooth_rfkill = rfkill_alloc("dell-bluetooth", + &platform_device->dev, RFKILL_TYPE_BLUETOOTH, &dell_rfkill_ops, (void *) 2); if (!bluetooth_rfkill) { @@ -242,7 +252,9 @@ static int dell_setup_rfkill(void) } if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) { - wwan_rfkill = rfkill_alloc("dell-wwan", NULL, RFKILL_TYPE_WWAN, + wwan_rfkill = rfkill_alloc("dell-wwan", + &platform_device->dev, + RFKILL_TYPE_WWAN, &dell_rfkill_ops, (void *) 3); if (!wwan_rfkill) { ret = -ENOMEM; @@ -342,6 +354,18 @@ static int __init dell_init(void) return -ENODEV; } + ret = platform_driver_register(&platform_driver); + if (ret) + goto fail_platform_driver; + platform_device = platform_device_alloc("dell-laptop", -1); + if (!platform_device) { + ret = -ENOMEM; + goto fail_platform_device1; + } + ret = platform_device_add(platform_device); + if (ret) + goto fail_platform_device2; + ret = dell_setup_rfkill(); if (ret) { @@ -368,7 +392,7 @@ static int __init dell_init(void) if (max_intensity) { dell_backlight_device = backlight_device_register( "dell_backlight", - NULL, NULL, + &platform_device->dev, NULL, &dell_ops); if (IS_ERR(dell_backlight_device)) { @@ -388,6 +412,12 @@ static int __init dell_init(void) fail_backlight: dell_cleanup_rfkill(); fail_rfkill: + platform_device_del(platform_device); +fail_platform_device2: + platform_device_put(platform_device); +fail_platform_device1: + platform_driver_unregister(&platform_driver); +fail_platform_driver: kfree(da_tokens); return ret; } -- cgit v0.10.2 From 4788df4cf44fd14847d37f88daea649f01c01017 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Wed, 19 Aug 2009 15:06:50 +0100 Subject: dell-laptop: add __init to init functions Signed-off-by: Alan Jenkins Acked-by: Matthew Garrett Signed-off-by: Len Brown diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index a4ce642..3780994 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -82,7 +82,7 @@ static const struct dmi_system_id __initdata dell_device_table[] = { { } }; -static void parse_da_table(const struct dmi_header *dm) +static void __init parse_da_table(const struct dmi_header *dm) { /* Final token is a terminator, so we don't want to copy it */ int tokens = (dm->length-11)/sizeof(struct calling_interface_token)-1; @@ -111,7 +111,7 @@ static void parse_da_table(const struct dmi_header *dm) da_num_tokens += tokens; } -static void find_tokens(const struct dmi_header *dm, void *dummy) +static void __init find_tokens(const struct dmi_header *dm, void *dummy) { switch (dm->type) { case 0xd4: /* Indexed IO */ @@ -214,7 +214,7 @@ static const struct rfkill_ops dell_rfkill_ops = { .query = dell_rfkill_query, }; -static int dell_setup_rfkill(void) +static int __init dell_setup_rfkill(void) { struct calling_interface_buffer buffer; int status; -- cgit v0.10.2 From 8c5d30e590593495c5bb8bd4a2519ce1ac909a22 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Wed, 19 Aug 2009 15:44:10 +0100 Subject: dell-laptop: remove duplicate Kconfig entry under drivers/misc This showed up as an unselectable option when using xconfig and searching for "dell". It must been overlooked when dell-laptop was moved to drivers/platform/x86. Signed-off-by: Alan Jenkins Signed-off-by: Len Brown diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index df1f86b..ba137c8 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -210,19 +210,6 @@ config SGI_GRU_DEBUG This option enables addition debugging code for the SGI GRU driver. If you are unsure, say N. -config DELL_LAPTOP - tristate "Dell Laptop Extras (EXPERIMENTAL)" - depends on X86 - depends on DCDBAS - depends on EXPERIMENTAL - depends on BACKLIGHT_CLASS_DEVICE - depends on RFKILL - depends on POWER_SUPPLY - default n - ---help--- - This driver adds support for rfkill and backlight control to Dell - laptops. - config ISL29003 tristate "Intersil ISL29003 ambient light sensor" depends on I2C && SYSFS -- cgit v0.10.2 From 5ea2559726b786283236835dc2905c23b36ac91c Mon Sep 17 00:00:00 2001 From: Rezwanul Kabir Date: Mon, 2 Nov 2009 12:00:42 -0500 Subject: dell-wmi: Add support for new Dell systems Newer Dell systems support HotKey features differently from legacy systems. A new vendor specifc HotKey SMBIOS table (Type 0xB2) is defined. This table contains a mapping between scancode and the corresponding predefined keyfunction ( i.e. keycode).. Also, a new ACPI-WMI event type (called KeyIDList) with a value of 0x0010 is defined. Any BIOS containing 0xB2 table will send hotkey notifications using KeyIDList event. This is Rezwanul's patch, updated to ensure that brightness events are not sent if the backlight is controlled via ACPI and with the default keycode for the display output switching altered to match desktop expectations. Signed-off-by: Rezwanul Kabir Signed-off-by: Matthew Garrett Signed-off-by: Len Brown diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 0f900cc..67f3fe7 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -31,6 +31,7 @@ #include #include #include +#include MODULE_AUTHOR("Matthew Garrett "); MODULE_DESCRIPTION("Dell laptop WMI hotkeys driver"); @@ -38,6 +39,8 @@ MODULE_LICENSE("GPL"); #define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492" +static int acpi_video; + MODULE_ALIAS("wmi:"DELL_EVENT_GUID); struct key_entry { @@ -54,7 +57,7 @@ enum { KE_KEY, KE_SW, KE_IGNORE, KE_END }; * via the keyboard controller so should not be sent again. */ -static struct key_entry dell_wmi_keymap[] = { +static struct key_entry dell_legacy_wmi_keymap[] = { {KE_KEY, 0xe045, KEY_PROG1}, {KE_KEY, 0xe009, KEY_EJECTCD}, @@ -72,7 +75,7 @@ static struct key_entry dell_wmi_keymap[] = { /* The next device is at offset 6, the active devices are at offset 8 and the attached devices at offset 10 */ - {KE_KEY, 0xe00b, KEY_DISPLAYTOGGLE}, + {KE_KEY, 0xe00b, KEY_SWITCHVIDEOMODE}, {KE_IGNORE, 0xe00c, KEY_KBDILLUMTOGGLE}, @@ -96,6 +99,47 @@ static struct key_entry dell_wmi_keymap[] = { {KE_END, 0} }; +static bool dell_new_hk_type; + +struct dell_new_keymap_entry { + u16 scancode; + u16 keycode; +}; + +struct dell_hotkey_table { + struct dmi_header header; + struct dell_new_keymap_entry keymap[]; + +}; + +static struct key_entry *dell_new_wmi_keymap; + +static u16 bios_to_linux_keycode[256] = { + + KEY_MEDIA, KEY_NEXTSONG, KEY_PLAYPAUSE, KEY_PREVIOUSSONG, + KEY_STOPCD, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, + KEY_WWW, KEY_UNKNOWN, KEY_VOLUMEDOWN, KEY_MUTE, + KEY_VOLUMEUP, KEY_UNKNOWN, KEY_BATTERY, KEY_EJECTCD, + KEY_UNKNOWN, KEY_SLEEP, KEY_PROG1, KEY_BRIGHTNESSDOWN, + KEY_BRIGHTNESSUP, KEY_UNKNOWN, KEY_KBDILLUMTOGGLE, + KEY_UNKNOWN, KEY_SWITCHVIDEOMODE, KEY_UNKNOWN, KEY_UNKNOWN, + KEY_SWITCHVIDEOMODE, KEY_UNKNOWN, KEY_UNKNOWN, KEY_PROG2, + KEY_UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + KEY_PROG3 +}; + + +static struct key_entry *dell_wmi_keymap = dell_legacy_wmi_keymap; + static struct input_dev *dell_wmi_input_dev; static struct key_entry *dell_wmi_get_entry_by_scancode(int code) @@ -164,24 +208,78 @@ static void dell_wmi_notify(u32 value, void *context) obj = (union acpi_object *)response.pointer; if (obj && obj->type == ACPI_TYPE_BUFFER) { - int *buffer = (int *)obj->buffer.pointer; - /* - * The upper bytes of the event may contain - * additional information, so mask them off for the - * scancode lookup - */ - key = dell_wmi_get_entry_by_scancode(buffer[1] & 0xFFFF); - if (key) { + int reported_key; + u16 *buffer_entry = (u16 *)obj->buffer.pointer; + if (dell_new_hk_type && (buffer_entry[1] != 0x10)) { + printk(KERN_INFO "dell-wmi: Received unknown WMI event" + " (0x%x)\n", buffer_entry[1]); + return; + } + + if (dell_new_hk_type) + reported_key = (int)buffer_entry[2]; + else + reported_key = (int)buffer_entry[1] & 0xffff; + + key = dell_wmi_get_entry_by_scancode(reported_key); + + if (!key) { + printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n", + reported_key); + } else if ((key->keycode == KEY_BRIGHTNESSUP || + key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) { + /* Don't report brightness notifications that will also + * come via ACPI */ + return; + } else { input_report_key(dell_wmi_input_dev, key->keycode, 1); input_sync(dell_wmi_input_dev); input_report_key(dell_wmi_input_dev, key->keycode, 0); input_sync(dell_wmi_input_dev); - } else if (buffer[1] & 0xFFFF) - printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n", - buffer[1] & 0xFFFF); + } } } + +static void setup_new_hk_map(const struct dmi_header *dm) +{ + + int i; + int hotkey_num = (dm->length-4)/sizeof(struct dell_new_keymap_entry); + struct dell_hotkey_table *table = + container_of(dm, struct dell_hotkey_table, header); + + dell_new_wmi_keymap = kzalloc((hotkey_num+1) * + sizeof(struct key_entry), GFP_KERNEL); + + for (i = 0; i < hotkey_num; i++) { + dell_new_wmi_keymap[i].type = KE_KEY; + dell_new_wmi_keymap[i].code = table->keymap[i].scancode; + dell_new_wmi_keymap[i].keycode = + (table->keymap[i].keycode > 255) ? 0 : + bios_to_linux_keycode[table->keymap[i].keycode]; + } + + dell_new_wmi_keymap[i].type = KE_END; + dell_new_wmi_keymap[i].code = 0; + dell_new_wmi_keymap[i].keycode = 0; + + dell_wmi_keymap = dell_new_wmi_keymap; + +} + + +static void find_hk_type(const struct dmi_header *dm, void *dummy) +{ + + if ((dm->type == 0xb2) && (dm->length > 6)) { + dell_new_hk_type = true; + setup_new_hk_map(dm); + } + +} + + static int __init dell_wmi_input_setup(void) { struct key_entry *key; @@ -226,6 +324,9 @@ static int __init dell_wmi_init(void) int err; if (wmi_has_guid(DELL_EVENT_GUID)) { + + dmi_walk(find_hk_type, NULL); + err = dell_wmi_input_setup(); if (err) @@ -240,6 +341,8 @@ static int __init dell_wmi_init(void) return err; } + acpi_video = acpi_video_backlight_support(); + } else printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n"); -- cgit v0.10.2 From 08a036d583409e3517e3d15b7478d029b25f2cf2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 9 Dec 2009 23:44:43 -0800 Subject: sparc64: Don't specify IRQF_SHARED for LDC interrupts. IRQF_SHARED and IRQF_DISABLED don't mix. Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index cb3c72c..e0ba898 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c @@ -1242,13 +1242,13 @@ int ldc_bind(struct ldc_channel *lp, const char *name) snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); err = request_irq(lp->cfg.rx_irq, ldc_rx, - IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED, + IRQF_SAMPLE_RANDOM | IRQF_DISABLED, lp->rx_irq_name, lp); if (err) return err; err = request_irq(lp->cfg.tx_irq, ldc_tx, - IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED, + IRQF_SAMPLE_RANDOM | IRQF_DISABLED, lp->tx_irq_name, lp); if (err) { free_irq(lp->cfg.rx_irq, lp); -- cgit v0.10.2 From 936cf251787be41833afe2a1e44fbd5fb2adbdb6 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 9 Dec 2009 23:57:24 -0800 Subject: sparc: Validate that kprobe address is 4-byte aligned. Otherwise it isn't a valid instruction address. This is the sparc equivalent of commit b46b3d70c9c017d7c4ec49f7f3ffd0af5a622277 (kprobes: Checks probe address is instruction boudary on x86) Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/kprobes.c b/arch/sparc/kernel/kprobes.c index 3bc6527..6716584 100644 --- a/arch/sparc/kernel/kprobes.c +++ b/arch/sparc/kernel/kprobes.c @@ -46,6 +46,9 @@ struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}}; int __kprobes arch_prepare_kprobe(struct kprobe *p) { + if ((unsigned long) p->addr & 0x3UL) + return -EILSEQ; + p->ainsn.insn[0] = *p->addr; flushi(&p->ainsn.insn[0]); -- cgit v0.10.2 From 554554f60ad619e1efab01897208bc320b81d9da Mon Sep 17 00:00:00 2001 From: Gui Jianfeng Date: Thu, 10 Dec 2009 09:38:39 +0100 Subject: cfq: Remove wait_request flag when idle time is being deleted Remove wait_request flag when idle time is being deleted, otherwise it'll hit this path every time when a request is enqueued. Signed-off-by: Gui Jianfeng Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 69ecee7..96f59ae 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -3202,6 +3202,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, if (blk_rq_bytes(rq) > PAGE_CACHE_SIZE || cfqd->busy_queues > 1) { del_timer(&cfqd->idle_slice_timer); + cfq_clear_cfqq_wait_request(cfqq); __blk_run_queue(cfqd->queue); } else cfq_mark_cfqq_must_dispatch(cfqq); -- cgit v0.10.2 From 70c66567d1e41d8b2186a2d198997a1c8d79c0c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0tetiar?= Date: Wed, 9 Dec 2009 22:09:53 +0100 Subject: HID: blacklist ET&T TC5UH touchscreen controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds ET&T TC5UH touchscreen controller to HID blacklist, because this device is handled by input/usbtouchscreen driver. Signed-off-by: Petr Štetiar Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 80792d3..389cd5f 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1553,6 +1553,7 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) }, { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) }, { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 3839340..b9de32b 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -166,6 +166,9 @@ #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 +#define USB_VENDOR_ID_ETT 0x0664 +#define USB_DEVICE_ID_TC5UH 0x0309 + #define USB_VENDOR_ID_EZKEY 0x0518 #define USB_DEVICE_ID_BTC_8193 0x0002 -- cgit v0.10.2 From caf0e8e028516253afce6e40c52f0c193a221f8a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 10 Dec 2009 14:23:57 +0100 Subject: mtd: cfi_cmdset_0002, fix lock imbalance Stanse found a double unlock in get_chip. get_chip is called with chip->mutex held and caller is responsible for unlocking it too. Do not unlock the lock in get_chip on a fail path. This would mean a double unlock. Signed-off-by: Jiri Slaby Signed-off-by: David Woodhouse diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 1d49e18..f3600e8 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -569,7 +569,6 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr if (time_after(jiffies, timeo)) { printk(KERN_ERR "Waiting for chip to be ready timed out.\n"); - spin_unlock(chip->mutex); return -EIO; } spin_unlock(chip->mutex); -- cgit v0.10.2 From 8e68597d087977d3e4fd3e735d290ab45fd0b5ea Mon Sep 17 00:00:00 2001 From: Michael Reed Date: Fri, 18 Sep 2009 12:02:05 -0500 Subject: [SCSI] lpfc: fix hang on SGI ia64 platform In testing 2.6.31 on one of our ia64 platforms I've encountered a hang due to the driver using hardware ATEs which are a limited resource. This is because the driver does not set the dma consistent mask to 64 bits. Signed-off-by: Michael Reed Acked-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 226920d..d4da6bd 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -4506,9 +4506,13 @@ lpfc_sli_pci_mem_setup(struct lpfc_hba *phba) pdev = phba->pcidev; /* Set the device DMA mask size */ - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0 + || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(64)) != 0) { + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0 + || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(32)) != 0) { return error; + } + } /* Get the bus address of Bar0 and Bar2 and the number of bytes * required by each mapping. @@ -6021,9 +6025,13 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) pdev = phba->pcidev; /* Set the device DMA mask size */ - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0 + || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(64)) != 0) { + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0 + || pci_set_consistent_dma_mask(pdev,DMA_BIT_MASK(32)) != 0) { return error; + } + } /* Get the bus address of SLI4 device Bar0, Bar1, and Bar2 and the * number of bytes required by each mapping. They are actually -- cgit v0.10.2 From 6f4fdda41b01100cfe02afb1b84bf422cbf557d4 Mon Sep 17 00:00:00 2001 From: "Moger, Babu" Date: Wed, 4 Nov 2009 12:36:16 -0700 Subject: [SCSI] scsi_dh_rdac: Add two new IBM devices to rdac_dev_list This patch adds two new IBM storage devices which can use rdac device handlers. Signed-off-by: Babu Moger Signed-off-by: James Bottomley diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 47cfe1c..1a66019 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c @@ -748,6 +748,8 @@ static const struct scsi_dh_devlist rdac_dev_list[] = { {"IBM", "1724"}, {"IBM", "1726"}, {"IBM", "1742"}, + {"IBM", "1745"}, + {"IBM", "1746"}, {"IBM", "1814"}, {"IBM", "1815"}, {"IBM", "1818"}, -- cgit v0.10.2 From d685c262083dcd5fd98b7499b22a377a3225229c Mon Sep 17 00:00:00 2001 From: "Kashyap, Desai" Date: Tue, 17 Nov 2009 13:16:37 +0530 Subject: [SCSI] mpt2sas: add missing initialization of scsih_cmds Internal command scsih_cmds init is included in mpt2sas_base_attach. Signed-off-by: Kashyap Desai Cc: Stable Tree Signed-off-by: James Bottomley diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 6422e25..89d0240 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -3583,6 +3583,11 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) ioc->transport_cmds.status = MPT2_CMD_NOT_USED; mutex_init(&ioc->transport_cmds.mutex); + /* scsih internal command bits */ + ioc->scsih_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); + ioc->scsih_cmds.status = MPT2_CMD_NOT_USED; + mutex_init(&ioc->scsih_cmds.mutex); + /* task management internal command bits */ ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ioc->tm_cmds.status = MPT2_CMD_NOT_USED; -- cgit v0.10.2 From 48de68a40aef032a2e198437f4781a83bfb938db Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Tue, 17 Nov 2009 21:25:16 -0600 Subject: [SCSI] fc class: fix fc_transport_init error handling If transport_class_register fails we should unregister any registered classes, or we will leak memory or other resources. I did a quick modprobe of scsi_transport_fc to test the patch. Signed-off-by: Mike Christie Cc: Stable Tree Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 6531c91..ddfcecd 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -649,11 +649,22 @@ static __init int fc_transport_init(void) return error; error = transport_class_register(&fc_vport_class); if (error) - return error; + goto unreg_host_class; error = transport_class_register(&fc_rport_class); if (error) - return error; - return transport_class_register(&fc_transport_class); + goto unreg_vport_class; + error = transport_class_register(&fc_transport_class); + if (error) + goto unreg_rport_class; + return 0; + +unreg_rport_class: + transport_class_unregister(&fc_rport_class); +unreg_vport_class: + transport_class_unregister(&fc_vport_class); +unreg_host_class: + transport_class_unregister(&fc_host_class); + return error; } static void __exit fc_transport_exit(void) -- cgit v0.10.2 From 729c845666be7092a52bf6fcdcf223fe4d9287a4 Mon Sep 17 00:00:00 2001 From: Anil Ravindranath Date: Fri, 20 Nov 2009 09:39:30 -0800 Subject: [SCSI] pmcraid: support SMI-S object model of storage pool PMC-Sierra mgmt application uses SMI-S model. According to SMI-S, the object model exposed by the SMI-S provider should show an StoragePool which contains member disks of a RAID Virtual disk and StorageVolume based on the StoragePool. But according to SMI-S, there is a possibility where StoragePool is created but StorageVolume is not yet created. To satisfy this scenario, we are trying a hidden RAID Virtual disk. The hidden RAID virtual disk will not be exposed to OS. Once a StorageVolume is created for this RAID virtual disk it is exposed. Signed-off-by: Anil Ravindranath Signed-off-by: James Bottomley diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 34c6b89..e7d2688 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -1,7 +1,8 @@ /* * pmcraid.c -- driver for PMC Sierra MaxRAID controller adapters * - * Written By: PMC Sierra Corporation + * Written By: Anil Ravindranath + * PMC-Sierra Inc * * Copyright (C) 2008, 2009 PMC Sierra Inc * @@ -79,7 +80,7 @@ DECLARE_BITMAP(pmcraid_minor, PMCRAID_MAX_ADAPTERS); /* * Module parameters */ -MODULE_AUTHOR("PMC Sierra Corporation, anil_ravindranath@pmc-sierra.com"); +MODULE_AUTHOR("Anil Ravindranath"); MODULE_DESCRIPTION("PMC Sierra MaxRAID Controller Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(PMCRAID_DRIVER_VERSION); @@ -162,10 +163,10 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev) spin_lock_irqsave(&pinstance->resource_lock, lock_flags); list_for_each_entry(temp, &pinstance->used_res_q, queue) { - /* do not expose VSETs with order-ids >= 240 */ + /* do not expose VSETs with order-ids > MAX_VSET_TARGETS */ if (RES_IS_VSET(temp->cfg_entry)) { target = temp->cfg_entry.unique_flags1; - if (target >= PMCRAID_MAX_VSET_TARGETS) + if (target > PMCRAID_MAX_VSET_TARGETS) continue; bus = PMCRAID_VSET_BUS_ID; lun = 0; @@ -1210,7 +1211,7 @@ static int pmcraid_expose_resource(struct pmcraid_config_table_entry *cfgte) int retval = 0; if (cfgte->resource_type == RES_TYPE_VSET) - retval = ((cfgte->unique_flags1 & 0xFF) < 0xFE); + retval = ((cfgte->unique_flags1 & 0x80) == 0); else if (cfgte->resource_type == RES_TYPE_GSCSI) retval = (RES_BUS(cfgte->resource_address) != PMCRAID_VIRTUAL_ENCL_BUS_ID); @@ -1361,6 +1362,7 @@ static int pmcraid_notify_aen(struct pmcraid_instance *pinstance, u8 type) * Return value: * none */ + static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) { struct pmcraid_config_table_entry *cfg_entry; @@ -1368,9 +1370,10 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) struct pmcraid_cmd *cmd; struct pmcraid_cmd *cfgcmd; struct pmcraid_resource_entry *res = NULL; - u32 new_entry = 1; unsigned long lock_flags; unsigned long host_lock_flags; + u32 new_entry = 1; + u32 hidden_entry = 0; int rc; ccn_hcam = (struct pmcraid_hcam_ccn *)pinstance->ccn.hcam; @@ -1406,9 +1409,15 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) } /* If this resource is not going to be added to mid-layer, just notify - * applications and return + * applications and return. If this notification is about hiding a VSET + * resource, check if it was exposed already. */ - if (!pmcraid_expose_resource(cfg_entry)) + if (pinstance->ccn.hcam->notification_type == + NOTIFICATION_TYPE_ENTRY_CHANGED && + cfg_entry->resource_type == RES_TYPE_VSET && + cfg_entry->unique_flags1 & 0x80) { + hidden_entry = 1; + } else if (!pmcraid_expose_resource(cfg_entry)) goto out_notify_apps; spin_lock_irqsave(&pinstance->resource_lock, lock_flags); @@ -1424,6 +1433,12 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) if (new_entry) { + if (hidden_entry) { + spin_unlock_irqrestore(&pinstance->resource_lock, + lock_flags); + goto out_notify_apps; + } + /* If there are more number of resources than what driver can * manage, do not notify the applications about the CCN. Just * ignore this notifications and re-register the same HCAM @@ -1454,8 +1469,9 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) sizeof(struct pmcraid_config_table_entry)); if (pinstance->ccn.hcam->notification_type == - NOTIFICATION_TYPE_ENTRY_DELETED) { + NOTIFICATION_TYPE_ENTRY_DELETED || hidden_entry) { if (res->scsi_dev) { + res->cfg_entry.unique_flags1 &= 0x7F; res->change_detected = RES_CHANGE_DEL; res->cfg_entry.resource_handle = PMCRAID_INVALID_RES_HANDLE; diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h index 2752b56..92f89d5 100644 --- a/drivers/scsi/pmcraid.h +++ b/drivers/scsi/pmcraid.h @@ -1,6 +1,9 @@ /* * pmcraid.h -- PMC Sierra MaxRAID controller driver header file * + * Written By: Anil Ravindranath + * PMC-Sierra Inc + * * Copyright (C) 2008, 2009 PMC Sierra Inc. * * This program is free software; you can redistribute it and/or modify @@ -106,7 +109,7 @@ #define PMCRAID_VSET_LUN_ID 0x0 #define PMCRAID_PHYS_BUS_ID 0x0 #define PMCRAID_VIRTUAL_ENCL_BUS_ID 0x8 -#define PMCRAID_MAX_VSET_TARGETS 240 +#define PMCRAID_MAX_VSET_TARGETS 0x7F #define PMCRAID_MAX_VSET_LUNS_PER_TARGET 8 #define PMCRAID_IOA_MAX_SECTORS 32767 -- cgit v0.10.2 From 7ec4ad0125db0222e397508c190b01c8f2b5f7cd Mon Sep 17 00:00:00 2001 From: Srinivas Date: Tue, 24 Nov 2009 20:07:39 +0530 Subject: [SCSI] mvsas: add support for Adaptec ASC-1045/1405 SAS/SATA HBA This is support for Adaptec ASC-1045/1405 SAS/SATA HBA on mvsas, which is based on Marvell 88SE6440 chipset. Signed-off-by: Srinivas Cc: Andy Yan Signed-off-by: James Bottomley diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index c790d45..cae6b2c 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -657,6 +657,7 @@ static struct pci_device_id __devinitdata mvs_pci_table[] = { { PCI_VDEVICE(MARVELL, 0x9180), chip_9180 }, { PCI_VDEVICE(ARECA, PCI_DEVICE_ID_ARECA_1300), chip_1300 }, { PCI_VDEVICE(ARECA, PCI_DEVICE_ID_ARECA_1320), chip_1320 }, + { PCI_VDEVICE(ADAPTEC2, 0x0450), chip_6440 }, { } /* terminate list */ }; -- cgit v0.10.2 From 78b9fb6d38b1caf1c11cba5b10bb859e3cce071f Mon Sep 17 00:00:00 2001 From: Jayamohan Kallickal Date: Wed, 25 Nov 2009 01:41:37 +0530 Subject: [SCSI] be2iscsi: Adding support for various Async messages from chip This patch allows for future addition of various async messages from the chip. This ensures that the driver won't hit a BUG_ON if the Firmware used is newer than inbox driver and so is using latest async messages. Signed-off-by: Jayamohan Kallickal Reviewed-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index 698a527..f008708 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -135,11 +135,15 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba) while ((compl = be_mcc_compl_get(phba))) { if (compl->flags & CQE_FLAGS_ASYNC_MASK) { /* Interpret flags as an async trailer */ - BUG_ON(!is_link_state_evt(compl->flags)); + if (is_link_state_evt(compl->flags)) + /* Interpret compl as a async link evt */ + beiscsi_async_link_state_process(phba, + (struct be_async_event_link_state *) compl); + else + SE_DEBUG(DBG_LVL_1, + " Unsupported Async Event, flags" + " = 0x%08x \n", compl->flags); - /* Interpret compl as a async link evt */ - beiscsi_async_link_state_process(phba, - (struct be_async_event_link_state *) compl); } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { status = be_mcc_compl_process(ctrl, compl); atomic_dec(&phba->ctrl.mcc_obj.q.used); -- cgit v0.10.2 From c982c368bb90adbd312faa05d0cfd842e9ab45a7 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Thu, 26 Nov 2009 09:24:13 +0900 Subject: [SCSI] st: fix mdata->page_order handling dio transfer always resets mdata->page_order to zero. It breaks high-order pages previously allocated for non-dio transfer. This patches adds reserved_page_order to st_buffer structure to save page order for non-dio transfer. http://bugzilla.kernel.org/show_bug.cgi?id=14563 When enlarge_buffer() allocates 524288 from 0, st uses six-order page allocation. So mdata->page_order is 6 and frp_seg is 2. After that, if st uses dio, sgl_map_user_pages() sets mdata->page_order to 0 for st_do_scsi(). After that, when we call normalize_buffer(), it frees only free frp_seg * PAGE_SIZE (2 * 4096) though we should free frp_seg * PAGE_SIZE << 6 (2 * 4096 << 6). So we see buffer_size is set to 516096 (524288 - 8192). Reported-by: Joachim Breuer Tested-by: Joachim Breuer Acked-by: Kai Makisara Signed-off-by: FUJITA Tomonori Cc: stable@kernel.org Signed-off-by: James Bottomley diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index ad59abb..d04ea9a 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -552,13 +552,15 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd SRpnt->waiting = waiting; if (STp->buffer->do_dio) { + mdata->page_order = 0; mdata->nr_entries = STp->buffer->sg_segs; mdata->pages = STp->buffer->mapped_pages; } else { + mdata->page_order = STp->buffer->reserved_page_order; mdata->nr_entries = DIV_ROUND_UP(bytes, PAGE_SIZE << mdata->page_order); - STp->buffer->map_data.pages = STp->buffer->reserved_pages; - STp->buffer->map_data.offset = 0; + mdata->pages = STp->buffer->reserved_pages; + mdata->offset = 0; } memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd)); @@ -3719,7 +3721,7 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm priority |= __GFP_ZERO; if (STbuffer->frp_segs) { - order = STbuffer->map_data.page_order; + order = STbuffer->reserved_page_order; b_size = PAGE_SIZE << order; } else { for (b_size = PAGE_SIZE, order = 0; @@ -3752,7 +3754,7 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm segs++; } STbuffer->b_data = page_address(STbuffer->reserved_pages[0]); - STbuffer->map_data.page_order = order; + STbuffer->reserved_page_order = order; return 1; } @@ -3765,7 +3767,7 @@ static void clear_buffer(struct st_buffer * st_bp) for (i=0; i < st_bp->frp_segs; i++) memset(page_address(st_bp->reserved_pages[i]), 0, - PAGE_SIZE << st_bp->map_data.page_order); + PAGE_SIZE << st_bp->reserved_page_order); st_bp->cleared = 1; } @@ -3773,7 +3775,7 @@ static void clear_buffer(struct st_buffer * st_bp) /* Release the extra buffer */ static void normalize_buffer(struct st_buffer * STbuffer) { - int i, order = STbuffer->map_data.page_order; + int i, order = STbuffer->reserved_page_order; for (i = 0; i < STbuffer->frp_segs; i++) { __free_pages(STbuffer->reserved_pages[i], order); @@ -3781,7 +3783,7 @@ static void normalize_buffer(struct st_buffer * STbuffer) } STbuffer->frp_segs = 0; STbuffer->sg_segs = 0; - STbuffer->map_data.page_order = 0; + STbuffer->reserved_page_order = 0; STbuffer->map_data.offset = 0; } @@ -3791,7 +3793,7 @@ static void normalize_buffer(struct st_buffer * STbuffer) static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count) { int i, cnt, res, offset; - int length = PAGE_SIZE << st_bp->map_data.page_order; + int length = PAGE_SIZE << st_bp->reserved_page_order; for (i = 0, offset = st_bp->buffer_bytes; i < st_bp->frp_segs && offset >= length; i++) @@ -3823,7 +3825,7 @@ static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, in static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count) { int i, cnt, res, offset; - int length = PAGE_SIZE << st_bp->map_data.page_order; + int length = PAGE_SIZE << st_bp->reserved_page_order; for (i = 0, offset = st_bp->read_pointer; i < st_bp->frp_segs && offset >= length; i++) @@ -3856,7 +3858,7 @@ static void move_buffer_data(struct st_buffer * st_bp, int offset) { int src_seg, dst_seg, src_offset = 0, dst_offset; int count, total; - int length = PAGE_SIZE << st_bp->map_data.page_order; + int length = PAGE_SIZE << st_bp->reserved_page_order; if (offset == 0) return; @@ -4578,7 +4580,6 @@ static int sgl_map_user_pages(struct st_buffer *STbp, } mdata->offset = uaddr & ~PAGE_MASK; - mdata->page_order = 0; STbp->mapped_pages = pages; return nr_pages; diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 544dc6b..f91a67c 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -46,6 +46,7 @@ struct st_buffer { struct st_request *last_SRpnt; struct st_cmdstatus cmdstat; struct page **reserved_pages; + int reserved_page_order; struct page **mapped_pages; struct rq_map_data map_data; unsigned char *b_data; -- cgit v0.10.2 From cc9b2e9f6603190c009e5d2629ce8e3f99571346 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 26 Nov 2009 09:50:20 -0600 Subject: [SCSI] enclosure: fix oops while iterating enclosure_status array Based on patch originally by Jeff Mahoney enclosure_status is expected to be a NULL terminated array of strings but isn't actually NULL terminated. When writing an invalid value to /sys/class/enclosure/.../.../status, it goes off the end of the array and Oopses. Fix by making the assumption true and adding NULL at the end. Reported-by: Artur Wojcik Signed-off-by: James Bottomley diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index e9eae4a..1eac626 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c @@ -391,6 +391,7 @@ static const char *const enclosure_status [] = { [ENCLOSURE_STATUS_NOT_INSTALLED] = "not installed", [ENCLOSURE_STATUS_UNKNOWN] = "unknown", [ENCLOSURE_STATUS_UNAVAILABLE] = "unavailable", + [ENCLOSURE_STATUS_MAX] = NULL, }; static const char *const enclosure_type [] = { diff --git a/include/linux/enclosure.h b/include/linux/enclosure.h index 90d1c21..9a33c5f 100644 --- a/include/linux/enclosure.h +++ b/include/linux/enclosure.h @@ -42,6 +42,8 @@ enum enclosure_status { ENCLOSURE_STATUS_NOT_INSTALLED, ENCLOSURE_STATUS_UNKNOWN, ENCLOSURE_STATUS_UNAVAILABLE, + /* last element for counting purposes */ + ENCLOSURE_STATUS_MAX }; /* SFF-8485 activity light settings */ -- cgit v0.10.2 From e339c1a7c09ef736dca7b3a4353c7742557d9f8f Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Thu, 26 Nov 2009 12:00:40 -0500 Subject: [SCSI] sd: WRITE SAME(16) / UNMAP support Implement a function for handling discard requests that sends either WRITE SAME(16) or UNMAP(10) depending on parameters indicated by the device in the block limits VPD. Extract unmap constraints and report them to the block layer. Based in part by a patch by Christoph Hellwig . Signed-off-by: Martin K. Petersen Signed-off-by: James Bottomley diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 9093c72..255da53 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -264,6 +264,15 @@ sd_show_app_tag_own(struct device *dev, struct device_attribute *attr, return snprintf(buf, 20, "%u\n", sdkp->ATO); } +static ssize_t +sd_show_thin_provisioning(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + + return snprintf(buf, 20, "%u\n", sdkp->thin_provisioning); +} + static struct device_attribute sd_disk_attrs[] = { __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, sd_store_cache_type), @@ -274,6 +283,7 @@ static struct device_attribute sd_disk_attrs[] = { sd_store_manage_start_stop), __ATTR(protection_type, S_IRUGO, sd_show_protection_type, NULL), __ATTR(app_tag_own, S_IRUGO, sd_show_app_tag_own, NULL), + __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), __ATTR_NULL, }; @@ -399,6 +409,57 @@ static void sd_prot_op(struct scsi_cmnd *scmd, unsigned int dif) } /** + * sd_prepare_discard - unmap blocks on thinly provisioned device + * @rq: Request to prepare + * + * Will issue either UNMAP or WRITE SAME(16) depending on preference + * indicated by target device. + **/ +static int sd_prepare_discard(struct request *rq) +{ + struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); + struct bio *bio = rq->bio; + sector_t sector = bio->bi_sector; + unsigned int num = bio_sectors(bio); + + if (sdkp->device->sector_size == 4096) { + sector >>= 3; + num >>= 3; + } + + rq->cmd_type = REQ_TYPE_BLOCK_PC; + rq->timeout = SD_TIMEOUT; + + memset(rq->cmd, 0, rq->cmd_len); + + if (sdkp->unmap) { + char *buf = kmap_atomic(bio_page(bio), KM_USER0); + + rq->cmd[0] = UNMAP; + rq->cmd[8] = 24; + rq->cmd_len = 10; + + /* Ensure that data length matches payload */ + rq->__data_len = bio->bi_size = bio->bi_io_vec->bv_len = 24; + + put_unaligned_be16(6 + 16, &buf[0]); + put_unaligned_be16(16, &buf[2]); + put_unaligned_be64(sector, &buf[8]); + put_unaligned_be32(num, &buf[16]); + + kunmap_atomic(buf, KM_USER0); + } else { + rq->cmd[0] = WRITE_SAME_16; + rq->cmd[1] = 0x8; /* UNMAP */ + put_unaligned_be64(sector, &rq->cmd[2]); + put_unaligned_be32(num, &rq->cmd[10]); + rq->cmd_len = 16; + } + + return BLKPREP_OK; +} + +/** * sd_init_command - build a scsi (read or write) command from * information in the request structure. * @SCpnt: pointer to mid-level's per scsi command structure that @@ -418,6 +479,13 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) int ret, host_dif; unsigned char protect; + /* + * Discard request come in as REQ_TYPE_FS but we turn them into + * block PC requests to make life easier. + */ + if (blk_discard_rq(rq)) + ret = sd_prepare_discard(rq); + if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { ret = scsi_setup_blk_pc_cmnd(sdp, rq); goto out; @@ -1432,6 +1500,19 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, sd_printk(KERN_NOTICE, sdkp, "physical block alignment offset: %u\n", alignment); + if (buffer[14] & 0x80) { /* TPE */ + struct request_queue *q = sdp->request_queue; + + sdkp->thin_provisioning = 1; + q->limits.discard_granularity = sdkp->hw_sector_size; + q->limits.max_discard_sectors = 0xffffffff; + + if (buffer[14] & 0x40) /* TPRZ */ + q->limits.discard_zeroes_data = 1; + + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); + } + sdkp->capacity = lba + 1; return sector_size; } @@ -1863,6 +1944,7 @@ void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer) */ static void sd_read_block_limits(struct scsi_disk *sdkp) { + struct request_queue *q = sdkp->disk->queue; unsigned int sector_sz = sdkp->device->sector_size; char *buffer; @@ -1877,6 +1959,31 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) blk_queue_io_opt(sdkp->disk->queue, get_unaligned_be32(&buffer[12]) * sector_sz); + /* Thin provisioning enabled and page length indicates TP support */ + if (sdkp->thin_provisioning && buffer[3] == 0x3c) { + unsigned int lba_count, desc_count, granularity; + + lba_count = get_unaligned_be32(&buffer[20]); + desc_count = get_unaligned_be32(&buffer[24]); + + if (lba_count) { + q->limits.max_discard_sectors = + lba_count * sector_sz >> 9; + + if (desc_count) + sdkp->unmap = 1; + } + + granularity = get_unaligned_be32(&buffer[28]); + + if (granularity) + q->limits.discard_granularity = granularity * sector_sz; + + if (buffer[32] & 0x80) + q->limits.discard_alignment = + get_unaligned_be32(&buffer[32]) & ~(1 << 31); + } + kfree(buffer); } diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index e374804..43d3caf 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -60,6 +60,8 @@ struct scsi_disk { unsigned RCD : 1; /* state of disk RCD bit, unused */ unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ unsigned first_scan : 1; + unsigned thin_provisioning : 1; + unsigned unmap : 1; }; #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) -- cgit v0.10.2 From d8705f11d89cfabf4a9f0ea234d4809b22abb33e Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Thu, 26 Nov 2009 12:00:41 -0500 Subject: [SCSI] Correctly handle thin provisioning write error A thin provisioned device may temporarily be out of sufficient allocation units to fulfill a write request. In that case it will return a space allocation in progress error. Wait a bit and retry the write. Signed-off-by: Martin K. Petersen Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index e495d38..d892768 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -859,6 +859,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) case 0x07: /* operation in progress */ case 0x08: /* Long write in progress */ case 0x09: /* self test in progress */ + case 0x14: /* space allocation in progress */ action = ACTION_DELAYED_RETRY; break; default: -- cgit v0.10.2 From aeab3fd7b865bc4086a80a83cfdd67dded3b41a0 Mon Sep 17 00:00:00 2001 From: Noriyuki Fujii Date: Fri, 20 Nov 2009 16:27:20 +0900 Subject: [SCSI] megaraid_sas: make driver PCI legacy I/O port free driver On the large servers, I/O port resource may not be assigned to all the PCI devices since it is limited (to 64KB on Intel Architecture[1]) and it may also be fragmented (I/O base register of PCI-to-PCI bridge will usually be aligned to a 4KB boundary[2]). If no I/O port resource is assigned to devices, those devices do not work. [1] Some machines support 64KB I/O port space per PCI segment. [2] Some P2P bridges support optional 1KB aligned I/O base. Therefore, I made a patch for MegaRAID SAS driver to make PCI legacy I/O port free. I have also tested the patch and it had no problem. The way to make PCI legacy I/O port free is the same as Fusion-MPT driver's and it has been merged into 2.6.30.4. This has already been fixed in e1000 and lpfc. As a result of the above, the driver can handle its device even when there are a huge number of PCI devices being used on the system and no I/O port region assigned to the device. Signed-off-by: Noriyuki Fujii Acked-by: "Yang, Bo" Signed-off-by: James Bottomley diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 134c63e..99ff99e 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -2501,7 +2501,9 @@ static int megasas_init_mfi(struct megasas_instance *instance) instance->base_addr = pci_resource_start(instance->pdev, 0); } - if (pci_request_regions(instance->pdev, "megasas: LSI")) { + if (pci_request_selected_regions(instance->pdev, + pci_select_bars(instance->pdev, IORESOURCE_MEM), + "megasas: LSI")) { printk(KERN_DEBUG "megasas: IO memory region busy!\n"); return -EBUSY; } @@ -2642,7 +2644,8 @@ static int megasas_init_mfi(struct megasas_instance *instance) iounmap(instance->reg_set); fail_ioremap: - pci_release_regions(instance->pdev); + pci_release_selected_regions(instance->pdev, + pci_select_bars(instance->pdev, IORESOURCE_MEM)); return -EINVAL; } @@ -2662,7 +2665,8 @@ static void megasas_release_mfi(struct megasas_instance *instance) iounmap(instance->reg_set); - pci_release_regions(instance->pdev); + pci_release_selected_regions(instance->pdev, + pci_select_bars(instance->pdev, IORESOURCE_MEM)); } /** @@ -2971,7 +2975,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) /* * PCI prepping: enable device set bus mastering and dma mask */ - rval = pci_enable_device(pdev); + rval = pci_enable_device_mem(pdev); if (rval) { return rval; @@ -3276,7 +3280,7 @@ megasas_resume(struct pci_dev *pdev) /* * PCI prepping: enable device set bus mastering and dma mask */ - rval = pci_enable_device(pdev); + rval = pci_enable_device_mem(pdev); if (rval) { printk(KERN_ERR "megasas: Enable device failed\n"); -- cgit v0.10.2 From 5d0961fd1f25e117f907f3af3aaa870637049252 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Tue, 1 Dec 2009 17:36:21 +0200 Subject: [SCSI] libosd: Fix blk_put_request locking again So libosd has decided to sacrifice some code simplicity for the sake of a clean API. One of these things is the possibility for users to call osd_end_request, in any condition at any state. This opens up some problems with calling blk_put_request when out-side of the completion callback but calling __blk_put_request when detecting a from-completion state. The current hack was working just fine until exofs decided to operate on all devices in parallel and wait for the sum of the requests, before deallocating all osd-requests at once. There are two new possible cases 1. All request in a group are deallocated as part of the last request's async-done, request_queue is locked. 2. All request in a group where executed asynchronously, but de-allocation was delayed to after the async-done, in the context of another thread. Async execution but request_queue is not locked. The solution I chose was to separate the deallocation of the osd_request which has the information users need, from the deallocation of the internal(2) requests which impose the locking problem. The internal block-requests are freed unconditionally inside the async-done-callback, when we know the queue is always locked. If at osd_end_request time we still have a bock-request, then we know it did not come from within an async-done-callback and we can call the regular blk_put_request. The internal requests were used for carrying error information after execution. This information is now copied to osd_request members for later analysis by user code. The external API and behaviour was unchanged, except now it really supports what was previously advertised. Reported-by: Vineet Agarwal Signed-off-by: Boaz Harrosh Cc: Stable Tree Signed-off-by: James Bottomley diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 950202a..2422347 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c @@ -432,30 +432,23 @@ static void _osd_free_seg(struct osd_request *or __unused, seg->alloc_size = 0; } -static void _put_request(struct request *rq , bool is_async) +static void _put_request(struct request *rq) { - if (is_async) { - WARN_ON(rq->bio); - __blk_put_request(rq->q, rq); - } else { - /* - * If osd_finalize_request() was called but the request was not - * executed through the block layer, then we must release BIOs. - * TODO: Keep error code in or->async_error. Need to audit all - * code paths. - */ - if (unlikely(rq->bio)) - blk_end_request(rq, -ENOMEM, blk_rq_bytes(rq)); - else - blk_put_request(rq); - } + /* + * If osd_finalize_request() was called but the request was not + * executed through the block layer, then we must release BIOs. + * TODO: Keep error code in or->async_error. Need to audit all + * code paths. + */ + if (unlikely(rq->bio)) + blk_end_request(rq, -ENOMEM, blk_rq_bytes(rq)); + else + blk_put_request(rq); } void osd_end_request(struct osd_request *or) { struct request *rq = or->request; - /* IMPORTANT: make sure this agrees with osd_execute_request_async */ - bool is_async = (or->request->end_io_data == or); _osd_free_seg(or, &or->set_attr); _osd_free_seg(or, &or->enc_get_attr); @@ -463,20 +456,34 @@ void osd_end_request(struct osd_request *or) if (rq) { if (rq->next_rq) { - _put_request(rq->next_rq, is_async); + _put_request(rq->next_rq); rq->next_rq = NULL; } - _put_request(rq, is_async); + _put_request(rq); } _osd_request_free(or); } EXPORT_SYMBOL(osd_end_request); +static void _set_error_resid(struct osd_request *or, struct request *req, + int error) +{ + or->async_error = error; + or->req_errors = req->errors ? : error; + or->sense_len = req->sense_len; + if (or->out.req) + or->out.residual = or->out.req->resid_len; + if (or->in.req) + or->in.residual = or->in.req->resid_len; +} + int osd_execute_request(struct osd_request *or) { - return or->async_error = - blk_execute_rq(or->request->q, NULL, or->request, 0); + int error = blk_execute_rq(or->request->q, NULL, or->request, 0); + + _set_error_resid(or, or->request, error); + return error; } EXPORT_SYMBOL(osd_execute_request); @@ -484,15 +491,17 @@ static void osd_request_async_done(struct request *req, int error) { struct osd_request *or = req->end_io_data; - or->async_error = error; - - if (unlikely(error)) { - OSD_DEBUG("osd_request_async_done error recieved %d " - "errors 0x%x\n", error, req->errors); - if (!req->errors) /* don't miss out on this one */ - req->errors = error; + _set_error_resid(or, req, error); + if (req->next_rq) { + __blk_put_request(req->q, req->next_rq); + req->next_rq = NULL; } + __blk_put_request(req->q, req); + or->request = NULL; + or->in.req = NULL; + or->out.req = NULL; + if (or->async_done) or->async_done(or, or->async_private); else @@ -1489,21 +1498,18 @@ int osd_req_decode_sense_full(struct osd_request *or, #endif int ret; - if (likely(!or->request->errors)) { - osi->out_resid = 0; - osi->in_resid = 0; + if (likely(!or->req_errors)) return 0; - } osi = osi ? : &local_osi; memset(osi, 0, sizeof(*osi)); - ssdb = or->request->sense; - sense_len = or->request->sense_len; + ssdb = (typeof(ssdb))or->sense; + sense_len = or->sense_len; if ((sense_len < (int)sizeof(*ssdb) || !ssdb->sense_key)) { OSD_ERR("Block-layer returned error(0x%x) but " "sense_len(%u) || key(%d) is empty\n", - or->request->errors, sense_len, ssdb->sense_key); + or->req_errors, sense_len, ssdb->sense_key); goto analyze; } @@ -1525,7 +1531,7 @@ int osd_req_decode_sense_full(struct osd_request *or, "additional_code=0x%x async_error=%d errors=0x%x\n", osi->key, original_sense_len, sense_len, osi->additional_code, or->async_error, - or->request->errors); + or->req_errors); if (original_sense_len < sense_len) sense_len = original_sense_len; @@ -1695,10 +1701,10 @@ analyze: ret = -EIO; } - if (or->out.req) - osi->out_resid = or->out.req->resid_len ?: or->out.total_bytes; - if (or->in.req) - osi->in_resid = or->in.req->resid_len ?: or->in.total_bytes; + if (!or->out.residual) + or->out.residual = or->out.total_bytes; + if (!or->in.residual) + or->in.residual = or->in.total_bytes; return ret; } diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h index 39d6d10..a8f3701 100644 --- a/include/scsi/osd_initiator.h +++ b/include/scsi/osd_initiator.h @@ -142,6 +142,7 @@ struct osd_request { struct _osd_io_info { struct bio *bio; u64 total_bytes; + u64 residual; struct request *req; struct _osd_req_data_segment *last_seg; u8 *pad_buff; @@ -150,12 +151,14 @@ struct osd_request { gfp_t alloc_flags; unsigned timeout; unsigned retries; + unsigned sense_len; u8 sense[OSD_MAX_SENSE_LEN]; enum osd_attributes_mode attributes_mode; osd_req_done_fn *async_done; void *async_private; int async_error; + int req_errors; }; static inline bool osd_req_is_ver1(struct osd_request *or) @@ -297,8 +300,6 @@ enum osd_err_priority { }; struct osd_sense_info { - u64 out_resid; /* Zero on success otherwise out residual */ - u64 in_resid; /* Zero on success otherwise in residual */ enum osd_err_priority osd_err_pri; int key; /* one of enum scsi_sense_keys */ -- cgit v0.10.2 From 1486400f7edd009d49550da968d5744e246dc7f8 Mon Sep 17 00:00:00 2001 From: Michael Reed Date: Wed, 2 Dec 2009 09:11:16 -0600 Subject: [SCSI] qla2xxx: dpc thread can execute before scsi host has been added Fix crash in qla2x00_fdmi_register() due to the dpc thread executing before the scsi host has been fully added. Unable to handle kernel NULL pointer dereference (address 00000000000001d0) qla2xxx_7_dpc[4140]: Oops 8813272891392 [1] Call Trace: [] show_stack+0x50/0xa0 sp=e00000b07c59f930 bsp=e00000b07c591400 [] show_regs+0x820/0x860 sp=e00000b07c59fb00 bsp=e00000b07c5913a0 [] die+0x1a0/0x2e0 sp=e00000b07c59fb00 bsp=e00000b07c591360 [] ia64_do_page_fault+0x8c0/0x9e0 sp=e00000b07c59fb00 bsp=e00000b07c591310 [] ia64_native_leave_kernel+0x0/0x270 sp=e00000b07c59fb90 bsp=e00000b07c591310 [] qla2x00_fdmi_register+0x850/0xbe0 [qla2xxx] sp=e00000b07c59fd60 bsp=e00000b07c591290 [] qla2x00_configure_loop+0x1930/0x34c0 [qla2xxx] sp=e00000b07c59fd60 bsp=e00000b07c591128 [] qla2x00_loop_resync+0x1b0/0x2e0 [qla2xxx] sp=e00000b07c59fdf0 bsp=e00000b07c5910c0 [] qla2x00_do_dpc+0x9a0/0xce0 [qla2xxx] sp=e00000b07c59fdf0 bsp=e00000b07c590fa0 [] kthread+0x110/0x140 sp=e00000b07c59fe00 bsp=e00000b07c590f68 [] kernel_thread_helper+0xd0/0x100 sp=e00000b07c59fe30 bsp=e00000b07c590f40 [] start_kernel_thread+0x20/0x40 sp=e00000b07c59fe30 bsp=e00000b07c590f40 crash> dis a000000207197350 0xa000000207197350 : [MMI] ld1 r45=[r14];; crash> scsi_qla_host.host 0xe00000b058c73ff8 host = 0xe00000b058c73be0, crash> Scsi_Host.shost_data 0xe00000b058c73be0 shost_data = 0x0, <<<<<<<<<<< The fc_transport fc_* workqueue threads have yet to be created. crash> ps | grep _7 3891 2 2 e00000b075c80000 IN 0.0 0 0 [scsi_eh_7] 4140 2 3 e00000b07c590000 RU 0.0 0 0 [qla2xxx_7_dpc] The thread creating adding the Scsi_Host is blocked due to other activity in sysfs. crash> bt 3762 PID: 3762 TASK: e00000b071e70000 CPU: 3 COMMAND: "modprobe" #0 [BSP:e00000b071e71548] schedule at a000000100727e00 #1 [BSP:e00000b071e714c8] __mutex_lock_slowpath at a0000001007295a0 #2 [BSP:e00000b071e714a8] mutex_lock at a000000100729830 #3 [BSP:e00000b071e71478] sysfs_addrm_start at a0000001002584f0 #4 [BSP:e00000b071e71440] create_dir at a000000100259350 #5 [BSP:e00000b071e71410] sysfs_create_subdir at a000000100259510 #6 [BSP:e00000b071e713b0] internal_create_group at a00000010025c880 #7 [BSP:e00000b071e71388] sysfs_create_group at a00000010025cc50 #8 [BSP:e00000b071e71368] dpm_sysfs_add at a000000100425050 #9 [BSP:e00000b071e71310] device_add at a000000100417d90 #10 [BSP:e00000b071e712d8] scsi_add_host at a00000010045a380 #11 [BSP:e00000b071e71268] qla2x00_probe_one at a0000002071be950 #12 [BSP:e00000b071e71248] local_pci_probe at a00000010032e490 #13 [BSP:e00000b071e71218] pci_device_probe at a00000010032ecd0 #14 [BSP:e00000b071e711d8] driver_probe_device at a00000010041d480 #15 [BSP:e00000b071e711a8] __driver_attach at a00000010041d6e0 #16 [BSP:e00000b071e71170] bus_for_each_dev at a00000010041c240 #17 [BSP:e00000b071e71150] driver_attach at a00000010041d0a0 #18 [BSP:e00000b071e71108] bus_add_driver at a00000010041b080 #19 [BSP:e00000b071e710c0] driver_register at a00000010041dea0 #20 [BSP:e00000b071e71088] __pci_register_driver at a00000010032f610 #21 [BSP:e00000b071e71058] (unknown) at a000000207200270 #22 [BSP:e00000b071e71018] do_one_initcall at a00000010000a9c0 #23 [BSP:e00000b071e70f98] sys_init_module at a0000001000fef00 #24 [BSP:e00000b071e70f98] ia64_ret_from_syscall at a00000010000c740 So, it appears that qla2xxx dpc thread is moving forward before the scsi host has been completely added. This patch moves the setting of the init_done (and online) flag to after the call to scsi_add_host() to hold off the dpc thread. Found via large lun count testing using 2.6.31. Signed-off-by: Michael Reed Acked-by: Giridhar Malavali Cc: stable@kernel.org Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 4166935..58edc0d 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2003,13 +2003,13 @@ skip_dpc: DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n", base_vha->host_no, ha)); - base_vha->flags.init_done = 1; - base_vha->flags.online = 1; - ret = scsi_add_host(host, &pdev->dev); if (ret) goto probe_failed; + base_vha->flags.init_done = 1; + base_vha->flags.online = 1; + ha->isp_ops->enable_intrs(ha); scsi_scan_host(host); -- cgit v0.10.2 From c45dd30551c371cb1e7a742136b8b36f6aba63f8 Mon Sep 17 00:00:00 2001 From: Giridhar Malavali Date: Wed, 2 Dec 2009 10:36:54 -0800 Subject: [SCSI] qla2xxx: Queue depth ramp up/down modification changes. Removed the module parameters ql2xqfulltracking and ql2xqfullrampup since the queue depth ramp up/down functionality is moved to scsi-ml. Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 6b9bf23..7a81e98 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1570,9 +1570,6 @@ typedef struct fc_port { struct fc_rport *rport, *drport; u32 supported_classes; - unsigned long last_queue_full; - unsigned long last_ramp_up; - uint16_t vp_idx; } fc_port_t; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index e218513..0b6801f 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -72,8 +72,6 @@ extern int ql2xloginretrycount; extern int ql2xfdmienable; extern int ql2xallocfwdump; extern int ql2xextended_error_logging; -extern int ql2xqfullrampup; -extern int ql2xqfulltracking; extern int ql2xiidmaenable; extern int ql2xmaxqueues; extern int ql2xmultique_tag; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 8049873..bc07d83 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -811,78 +811,6 @@ skip_rio: qla2x00_alert_all_vps(rsp, mb); } -static void -qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data) -{ - fc_port_t *fcport = data; - struct scsi_qla_host *vha = fcport->vha; - struct qla_hw_data *ha = vha->hw; - struct req_que *req = NULL; - - if (!ql2xqfulltracking) - return; - - req = vha->req; - if (!req) - return; - if (req->max_q_depth <= sdev->queue_depth) - return; - - if (sdev->ordered_tags) - scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, - sdev->queue_depth + 1); - else - scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, - sdev->queue_depth + 1); - - fcport->last_ramp_up = jiffies; - - DEBUG2(qla_printk(KERN_INFO, ha, - "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n", - fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun, - sdev->queue_depth)); -} - -static void -qla2x00_adjust_sdev_qdepth_down(struct scsi_device *sdev, void *data) -{ - fc_port_t *fcport = data; - - if (!scsi_track_queue_full(sdev, sdev->queue_depth - 1)) - return; - - DEBUG2(qla_printk(KERN_INFO, fcport->vha->hw, - "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n", - fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun, - sdev->queue_depth)); -} - -static inline void -qla2x00_ramp_up_queue_depth(scsi_qla_host_t *vha, struct req_que *req, - srb_t *sp) -{ - fc_port_t *fcport; - struct scsi_device *sdev; - - if (!ql2xqfulltracking) - return; - - sdev = sp->cmd->device; - if (sdev->queue_depth >= req->max_q_depth) - return; - - fcport = sp->fcport; - if (time_before(jiffies, - fcport->last_ramp_up + ql2xqfullrampup * HZ)) - return; - if (time_before(jiffies, - fcport->last_queue_full + ql2xqfullrampup * HZ)) - return; - - starget_for_each_device(sdev->sdev_target, fcport, - qla2x00_adjust_sdev_qdepth_up); -} - /** * qla2x00_process_completed_request() - Process a Fast Post response. * @ha: SCSI driver HA context @@ -913,8 +841,6 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha, /* Save ISP completion status */ sp->cmd->result = DID_OK << 16; - - qla2x00_ramp_up_queue_depth(vha, req, sp); qla2x00_sp_compl(ha, sp); } else { DEBUG2(printk("scsi(%ld) Req:%d: Invalid ISP SCSI completion" @@ -1435,13 +1361,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) "scsi(%ld): QUEUE FULL status detected " "0x%x-0x%x.\n", vha->host_no, comp_status, scsi_status)); - - /* Adjust queue depth for all luns on the port. */ - if (!ql2xqfulltracking) - break; - fcport->last_queue_full = jiffies; - starget_for_each_device(cp->device->sdev_target, - fcport, qla2x00_adjust_sdev_qdepth_down); break; } if (lscsi_status != SS_CHECK_CONDITION) @@ -1516,17 +1435,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) "scsi(%ld): QUEUE FULL status detected " "0x%x-0x%x.\n", vha->host_no, comp_status, scsi_status)); - - /* - * Adjust queue depth for all luns on the - * port. - */ - if (!ql2xqfulltracking) - break; - fcport->last_queue_full = jiffies; - starget_for_each_device( - cp->device->sdev_target, fcport, - qla2x00_adjust_sdev_qdepth_down); break; } if (lscsi_status != SS_CHECK_CONDITION) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 58edc0d..2f873d2 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -78,21 +78,6 @@ module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(ql2xmaxqdepth, "Maximum queue depth to report for target devices."); -int ql2xqfulltracking = 1; -module_param(ql2xqfulltracking, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(ql2xqfulltracking, - "Controls whether the driver tracks queue full status " - "returns and dynamically adjusts a scsi device's queue " - "depth. Default is 1, perform tracking. Set to 0 to " - "disable dynamic tracking and adjustment of queue depth."); - -int ql2xqfullrampup = 120; -module_param(ql2xqfullrampup, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(ql2xqfullrampup, - "Number of seconds to wait to begin to ramp-up the queue " - "depth for a device after a queue-full condition has been " - "detected. Default is 120 seconds."); - int ql2xiidmaenable=1; module_param(ql2xiidmaenable, int, S_IRUGO|S_IRUSR); MODULE_PARM_DESC(ql2xiidmaenable, @@ -1217,13 +1202,61 @@ qla2xxx_slave_destroy(struct scsi_device *sdev) sdev->hostdata = NULL; } +static void qla2x00_handle_queue_full(struct scsi_device *sdev, int qdepth) +{ + fc_port_t *fcport = (struct fc_port *) sdev->hostdata; + + if (!scsi_track_queue_full(sdev, qdepth)) + return; + + DEBUG2(qla_printk(KERN_INFO, fcport->vha->hw, + "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n", + fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun, + sdev->queue_depth)); +} + +static void qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, int qdepth) +{ + fc_port_t *fcport = sdev->hostdata; + struct scsi_qla_host *vha = fcport->vha; + struct qla_hw_data *ha = vha->hw; + struct req_que *req = NULL; + + req = vha->req; + if (!req) + return; + + if (req->max_q_depth <= sdev->queue_depth || req->max_q_depth < qdepth) + return; + + if (sdev->ordered_tags) + scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, qdepth); + else + scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, qdepth); + + DEBUG2(qla_printk(KERN_INFO, ha, + "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n", + fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun, + sdev->queue_depth)); +} + static int qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) { - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; + switch (reason) { + case SCSI_QDEPTH_DEFAULT: + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth); + break; + case SCSI_QDEPTH_QFULL: + qla2x00_handle_queue_full(sdev, qdepth); + break; + case SCSI_QDEPTH_RAMP_UP: + qla2x00_adjust_sdev_qdepth_up(sdev, qdepth); + break; + default: + return EOPNOTSUPP; + } - scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth); return sdev->queue_depth; } -- cgit v0.10.2 From 3155754a6b7985a80c41d84dd06530ff543f52a8 Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Wed, 2 Dec 2009 10:36:55 -0800 Subject: [SCSI] qla2xxx: fix for multiqueue in MISX disabled case Fix to accommodate a hardware bug in multiqueue mode that does not work properly when acknowledgement of MSIX Interrupts is disabled. Signed-off-by: Anirban Chakraborty Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 7a81e98..384afda 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2262,6 +2262,7 @@ struct qla_hw_data { uint32_t port0 :1; uint32_t running_gold_fw :1; uint32_t cpu_affinity_enabled :1; + uint32_t disable_msix_handshake :1; } flags; /* This spinlock is used to protect "io transactions", you must @@ -2384,6 +2385,7 @@ struct qla_hw_data { #define IS_QLA81XX(ha) (IS_QLA8001(ha)) #define IS_QLA2XXX_MIDTYPE(ha) (IS_QLA24XX(ha) || IS_QLA84XX(ha) || \ IS_QLA25XX(ha) || IS_QLA81XX(ha)) +#define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha)) #define IS_NOPOLLING_TYPE(ha) ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && \ (ha)->flags.msix_enabled) #define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha)) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index b74924b..73a7935 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1442,7 +1442,17 @@ qla24xx_config_rings(struct scsi_qla_host *vha) icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_18); - icb->firmware_options_2 &= __constant_cpu_to_le32(~BIT_22); + /* Use Disable MSIX Handshake mode for capable adapters */ + if (IS_MSIX_NACK_CAPABLE(ha)) { + icb->firmware_options_2 &= + __constant_cpu_to_le32(~BIT_22); + ha->flags.disable_msix_handshake = 1; + qla_printk(KERN_INFO, ha, + "MSIX Handshake Disable Mode turned on\n"); + } else { + icb->firmware_options_2 |= + __constant_cpu_to_le32(BIT_22); + } icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_23); WRT_REG_DWORD(®->isp25mq.req_q_in, 0); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index bc07d83..1692a88 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1928,7 +1928,7 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) vha = qla25xx_get_host(rsp); qla24xx_process_response_queue(vha, rsp); - if (!ha->mqenable) { + if (!ha->flags.disable_msix_handshake) { WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); RD_REG_DWORD_RELAXED(®->hccr); } @@ -1942,6 +1942,7 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) { struct qla_hw_data *ha; struct rsp_que *rsp; + struct device_reg_24xx __iomem *reg; rsp = (struct rsp_que *) dev_id; if (!rsp) { @@ -1951,6 +1952,14 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) } ha = rsp->hw; + /* Clear the interrupt, if enabled, for this response queue */ + if (rsp->options & ~BIT_6) { + reg = &ha->iobase->isp24; + spin_lock_irq(&ha->hardware_lock); + WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); + RD_REG_DWORD_RELAXED(®->hccr); + spin_unlock_irq(&ha->hardware_lock); + } queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work); return IRQ_HANDLED; diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index a47d343..2a4c7f4 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -696,6 +696,10 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, /* Use alternate PCI devfn */ if (LSB(rsp->rid)) options |= BIT_5; + /* Enable MSIX handshake mode on for uncapable adapters */ + if (!IS_MSIX_NACK_CAPABLE(ha)) + options |= BIT_6; + rsp->options = options; rsp->id = que_id; reg = ISP_QUE_REG(ha, que_id); -- cgit v0.10.2 From 7729cb785d27afef500cc7e7071de8c01d7dfdae Mon Sep 17 00:00:00 2001 From: Giridhar Malavali Date: Wed, 2 Dec 2009 10:36:56 -0800 Subject: [SCSI] qla2xxx: Update version number to 8.03.01-k8. Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 807e0db..c482220 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.03.01-k7" +#define QLA2XXX_VERSION "8.03.01-k8" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 3 -- cgit v0.10.2 From e46b63b37c3296f0aca92d8b62bbf130f2bec7dd Mon Sep 17 00:00:00 2001 From: Pravin Bathija Date: Wed, 2 Dec 2009 17:51:46 -0800 Subject: [SCSI] mpt fusion: Fix 32 bit platforms with 64 bit resources. Powerpc 44x uses 36 bit real address while the real address defined in MPT Fusion driver is of type 32 bit. This causes ioremap to fail and driver fails to initialize. This fix changes the data types representing the real address from unsigned long 32-bit types to resource_size_t which is 64-bit. The driver has been tested, the disks get discovered correctly and can do IO. [jejb: added printk fix for resource_size_t object] Signed-off-by: Pravin Bathija Acked-by: "Desai, Kashyap" Signed-off-by: James Bottomley diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 610e914..85bc6a6 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -1587,7 +1587,7 @@ mpt_mapresources(MPT_ADAPTER *ioc) { u8 __iomem *mem; int ii; - unsigned long mem_phys; + resource_size_t mem_phys; unsigned long port; u32 msize; u32 psize; @@ -1677,8 +1677,8 @@ mpt_mapresources(MPT_ADAPTER *ioc) return -EINVAL; } ioc->memmap = mem; - dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n", - ioc->name, mem, mem_phys)); + dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n", + ioc->name, mem, (unsigned long long)mem_phys)); ioc->mem_phys = mem_phys; ioc->chip = (SYSIF_REGS __iomem *)mem; -- cgit v0.10.2 From dcece412da92aa619c0d891a17306b9adf86ab0e Mon Sep 17 00:00:00 2001 From: Yi Zou Date: Fri, 20 Nov 2009 15:22:21 -0800 Subject: [SCSI] fcoe: Use LLD's WWPN and WWNN for lport if LLD supports ndo_fcoe_get_wwn If the LLD wants its own WWNN/WWPN to be used, it should implement the netdev_ops.ndo_fcoe_get_wwn(). If that is the case, we query the LLD and use the queried WWNN/WWPN from the LLD. Signed-off-by: Yi Zou Signed-off-by: Robert Love Signed-off-by: James Bottomley diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index a30ffaa..9b6aebb 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -545,6 +545,23 @@ static void fcoe_queue_timer(ulong lport) } /** + * fcoe_get_wwn() - Get the world wide name from LLD if it supports it + * @netdev: the associated net device + * @wwn: the output WWN + * @type: the type of WWN (WWPN or WWNN) + * + * Returns: 0 for success + */ +static int fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type) +{ + const struct net_device_ops *ops = netdev->netdev_ops; + + if (ops->ndo_fcoe_get_wwn) + return ops->ndo_fcoe_get_wwn(netdev, wwn, type); + return -EINVAL; +} + +/** * fcoe_netdev_config() - Set up net devive for SW FCoE * @lport: The local port that is associated with the net device * @netdev: The associated net device @@ -611,9 +628,13 @@ static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev) */ if (netdev->priv_flags & IFF_802_1Q_VLAN) vid = vlan_dev_vlan_id(netdev); - wwnn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 1, 0); + + if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN)) + wwnn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 1, 0); fc_set_wwnn(lport, wwnn); - wwpn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 2, vid); + if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN)) + wwpn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, + 2, vid); fc_set_wwpn(lport, wwpn); } -- cgit v0.10.2 From 99c965dd9ee1a004efc083c3d760ba982bb76adf Mon Sep 17 00:00:00 2001 From: Kleber Sacilotto de Souza Date: Wed, 25 Nov 2009 20:13:43 -0200 Subject: [SCSI] ipr: fix EEH recovery After commits c82f63e411f1b58427c103bd95af2863b1c96dd1 (PCI: check saved state before restore) and 4b77b0a2ba27d64f58f16d8d4d48d8319dda36ff (PCI: Clear saved_state after the state has been restored) PCI drivers are prevented from restoring the device standard configuration registers twice in a row. These changes introduced a regression on ipr EEH recovery. The ipr device driver saves the PCI state only during the device probe and restores it on ipr_reset_restore_cfg_space() during IOA resets. This behavior is causing the EEH recovery to fail after the second error detected, since the registers are not being restored. One possible solution would be saving the registers after restoring them. The problem with this approach is that while recovering from an EEH error if pci_save_state() results in an EEH error, the adapter/slot will be reset, and end up back in ipr_reset_restore_cfg_space(), but it won't have a valid saved state to restore, so pci_restore_state() will fail. The following patch introduces a workaround for this problem, hacking around the PCI API by setting pdev->state_saved = true before we do the restore. It fixes the EEH regression and prevents that we hit another EEH error during EEH recovery. [jejb: fix is a hack ... Jesse and Rafael will fix properly] Signed-off-by: Kleber Sacilotto de Souza Acked-by: Brian King Cc: Jesse Barnes Cc: stable@kernel.org Signed-off-by: James Bottomley diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 206c2fa..83a6b92 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -6521,6 +6521,7 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) int rc; ENTER; + ioa_cfg->pdev->state_saved = true; rc = pci_restore_state(ioa_cfg->pdev); if (rc != PCIBIOS_SUCCESSFUL) { -- cgit v0.10.2 From 5d9e1fa99c2a9a5977f5757f4e0fd02697c995c2 Mon Sep 17 00:00:00 2001 From: Anil Veerabhadrappa Date: Mon, 7 Dec 2009 11:39:33 -0800 Subject: [SCSI] bnx2i: Add 5771E device support to bnx2i driver Signed-off-by: Anil Veerabhadrappa Reviewed-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c index 0c4210d..1dba86c 100644 --- a/drivers/scsi/bnx2i/bnx2i_init.c +++ b/drivers/scsi/bnx2i/bnx2i_init.c @@ -83,8 +83,12 @@ void bnx2i_identify_device(struct bnx2i_hba *hba) set_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type); hba->mail_queue_access = BNX2I_MQ_BIN_MODE; } else if (hba->pci_did == PCI_DEVICE_ID_NX2_57710 || - hba->pci_did == PCI_DEVICE_ID_NX2_57711) + hba->pci_did == PCI_DEVICE_ID_NX2_57711 || + hba->pci_did == PCI_DEVICE_ID_NX2_57711E) set_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type); + else + printk(KERN_ALERT "bnx2i: unknown device, 0x%x\n", + hba->pci_did); } -- cgit v0.10.2 From f8c9abe797c54e798b4025b54d71e5d2054c929a Mon Sep 17 00:00:00 2001 From: Anil Veerabhadrappa Date: Mon, 7 Dec 2009 11:39:54 -0800 Subject: [SCSI] bnx2i: Adjust sq_size module parametr to power of 2 only if a non-zero value is specified This issue was discovered during 10G iscsi testing Default value of 'sq_size' module parameter is '0' which means driver should use predefined SQ queue size when setting up iscsi connection. roundup_pow_of_two(0) results in '1' and forces driver to setup connections with send queue size of '1' and results in lower performance as well Signed-off-by: Anil Veerabhadrappa Reviewed-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c index 1dba86c..0307f85 100644 --- a/drivers/scsi/bnx2i/bnx2i_init.c +++ b/drivers/scsi/bnx2i/bnx2i_init.c @@ -367,7 +367,7 @@ static int __init bnx2i_mod_init(void) printk(KERN_INFO "%s", version); - if (!is_power_of_2(sq_size)) + if (sq_size && !is_power_of_2(sq_size)) sq_size = roundup_pow_of_two(sq_size); mutex_init(&bnx2i_dev_lock); -- cgit v0.10.2 From 8776193bc308553ac0011b3bb2dd1837e0c6ab28 Mon Sep 17 00:00:00 2001 From: Anil Veerabhadrappa Date: Mon, 7 Dec 2009 11:40:18 -0800 Subject: [SCSI] bnx2i: update CQ arming algorith for 5771x chipsets Only affects 5771x (10G chipsets) devices This is an optimized CQ arming algoritm which takes into account the number of outstanding tasks Signed-off-by: Anil Veerabhadrappa Signed-off-by: James Bottomley diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h index 2b973f3..6cf9dc3 100644 --- a/drivers/scsi/bnx2i/bnx2i.h +++ b/drivers/scsi/bnx2i/bnx2i.h @@ -684,6 +684,7 @@ extern unsigned int error_mask1, error_mask2; extern u64 iscsi_error_mask; extern unsigned int en_tcp_dack; extern unsigned int event_coal_div; +extern unsigned int event_coal_min; extern struct scsi_transport_template *bnx2i_scsi_xport_template; extern struct iscsi_transport bnx2i_iscsi_transport; diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index 5c8d763..bb69a14 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -133,20 +133,38 @@ void bnx2i_arm_cq_event_coalescing(struct bnx2i_endpoint *ep, u8 action) { struct bnx2i_5771x_cq_db *cq_db; u16 cq_index; + u16 next_index; + u32 num_active_cmds; + + /* Coalesce CQ entries only on 10G devices */ if (!test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) return; + /* Do not update CQ DB multiple times before firmware writes + * '0xFFFF' to CQDB->SQN field. Deviation may cause spurious + * interrupts and other unwanted results + */ + cq_db = (struct bnx2i_5771x_cq_db *) ep->qp.cq_pgtbl_virt; + if (cq_db->sqn[0] && cq_db->sqn[0] != 0xFFFF) + return; + if (action == CNIC_ARM_CQE) { - cq_index = ep->qp.cqe_exp_seq_sn + - ep->num_active_cmds / event_coal_div; - cq_index %= (ep->qp.cqe_size * 2 + 1); - if (!cq_index) { + num_active_cmds = ep->num_active_cmds; + if (num_active_cmds <= event_coal_min) + next_index = 1; + else + next_index = event_coal_min + + (num_active_cmds - event_coal_min) / event_coal_div; + if (!next_index) + next_index = 1; + cq_index = ep->qp.cqe_exp_seq_sn + next_index - 1; + if (cq_index > ep->qp.cqe_size * 2) + cq_index -= ep->qp.cqe_size * 2; + if (!cq_index) cq_index = 1; - cq_db = (struct bnx2i_5771x_cq_db *) - ep->qp.cq_pgtbl_virt; - cq_db->sqn[0] = cq_index; - } + + cq_db->sqn[0] = cq_index; } } diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c index 0307f85..465241d 100644 --- a/drivers/scsi/bnx2i/bnx2i_init.c +++ b/drivers/scsi/bnx2i/bnx2i_init.c @@ -32,6 +32,10 @@ MODULE_VERSION(DRV_MODULE_VERSION); static DEFINE_MUTEX(bnx2i_dev_lock); +unsigned int event_coal_min = 24; +module_param(event_coal_min, int, 0664); +MODULE_PARM_DESC(event_coal_min, "Event Coalescing Minimum Commands"); + unsigned int event_coal_div = 1; module_param(event_coal_div, int, 0664); MODULE_PARM_DESC(event_coal_div, "Event Coalescing Divide Factor"); -- cgit v0.10.2 From 85fef20222bda1ee41f97ff94a927180ef0b97e6 Mon Sep 17 00:00:00 2001 From: Anil Veerabhadrappa Date: Mon, 7 Dec 2009 11:40:29 -0800 Subject: [SCSI] bnx2i: Task management ABORT TASK fixes Due to typo error driver was failing TMF Abort Task request when ctask->sc != NULL. Fixed code to fail TMF ABORT Task request only when ctask->sc == NULL. Clear age component (19 most significant bits) of reference ITT carried in iSCSI TMF PDU. Age component is internal to initiator side and only lower bits of ITT as defined by ISCSI_ITT_MASK is is sent on wire. Retrieve LUN directly from the ref_sc and update SQ wqe as per chip HSI (Host Software Interface) specification Signed-off-by: Anil Veerabhadrappa Reviewed-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index bb69a14..1af578d 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -384,6 +384,7 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn, struct bnx2i_cmd *bnx2i_cmd; struct bnx2i_tmf_request *tmfabort_wqe; u32 dword; + u32 scsi_lun[2]; bnx2i_cmd = (struct bnx2i_cmd *)mtask->dd_data; tmfabort_hdr = (struct iscsi_tm *)mtask->hdr; @@ -394,27 +395,35 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn, tmfabort_wqe->op_attr = 0; tmfabort_wqe->op_attr = ISCSI_TMF_REQUEST_ALWAYS_ONE | ISCSI_TM_FUNC_ABORT_TASK; - tmfabort_wqe->lun[0] = be32_to_cpu(tmfabort_hdr->lun[0]); - tmfabort_wqe->lun[1] = be32_to_cpu(tmfabort_hdr->lun[1]); tmfabort_wqe->itt = (mtask->itt | (ISCSI_TASK_TYPE_MPATH << 14)); tmfabort_wqe->reserved2 = 0; tmfabort_wqe->cmd_sn = be32_to_cpu(tmfabort_hdr->cmdsn); ctask = iscsi_itt_to_task(conn, tmfabort_hdr->rtt); - if (!ctask || ctask->sc) + if (!ctask || !ctask->sc) /* * the iscsi layer must have completed the cmd while this * was starting up. + * + * Note: In the case of a SCSI cmd timeout, the task's sc + * is still active; hence ctask->sc != 0 + * In this case, the task must be aborted */ return 0; + ref_sc = ctask->sc; + /* Retrieve LUN directly from the ref_sc */ + int_to_scsilun(ref_sc->device->lun, (struct scsi_lun *) scsi_lun); + tmfabort_wqe->lun[0] = be32_to_cpu(scsi_lun[0]); + tmfabort_wqe->lun[1] = be32_to_cpu(scsi_lun[1]); + if (ref_sc->sc_data_direction == DMA_TO_DEVICE) dword = (ISCSI_TASK_TYPE_WRITE << ISCSI_CMD_REQUEST_TYPE_SHIFT); else dword = (ISCSI_TASK_TYPE_READ << ISCSI_CMD_REQUEST_TYPE_SHIFT); - tmfabort_wqe->ref_itt = (dword | tmfabort_hdr->rtt); + tmfabort_wqe->ref_itt = (dword | (tmfabort_hdr->rtt & ISCSI_ITT_MASK)); tmfabort_wqe->ref_cmd_sn = be32_to_cpu(tmfabort_hdr->refcmdsn); tmfabort_wqe->bd_list_addr_lo = (u32) bnx2i_conn->hba->mp_bd_dma; -- cgit v0.10.2 From 45ca38e753016432a266a18679268a4c4674fb52 Mon Sep 17 00:00:00 2001 From: Anil Veerabhadrappa Date: Mon, 7 Dec 2009 11:40:39 -0800 Subject: [SCSI] bnx2i: minor code cleanup and update driver version Removed duplicate function call and not-so-useful comment line Signed-off-by: Anil Veerabhadrappa Reviewed-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c index 465241d..6d8172e 100644 --- a/drivers/scsi/bnx2i/bnx2i_init.c +++ b/drivers/scsi/bnx2i/bnx2i_init.c @@ -17,8 +17,8 @@ static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list); static u32 adapter_count; #define DRV_MODULE_NAME "bnx2i" -#define DRV_MODULE_VERSION "2.0.1e" -#define DRV_MODULE_RELDATE "June 22, 2009" +#define DRV_MODULE_VERSION "2.1.0" +#define DRV_MODULE_RELDATE "Dec 06, 2009" static char version[] __devinitdata = "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \ diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index 132898c..33b2294 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -485,7 +485,6 @@ static int bnx2i_setup_cmd_pool(struct bnx2i_hba *hba, struct iscsi_task *task = session->cmds[i]; struct bnx2i_cmd *cmd = task->dd_data; - /* Anil */ task->hdr = &cmd->hdr; task->hdr_max = sizeof(struct iscsi_hdr); @@ -765,7 +764,6 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic) hba->pci_svid = hba->pcidev->subsystem_vendor; hba->pci_func = PCI_FUNC(hba->pcidev->devfn); hba->pci_devno = PCI_SLOT(hba->pcidev->devfn); - bnx2i_identify_device(hba); bnx2i_identify_device(hba); bnx2i_setup_host_queue_size(hba, shost); -- cgit v0.10.2 From 0109abffbf91b76e2a34e324a407d780a55fc1ab Mon Sep 17 00:00:00 2001 From: "kxie@chelsio.com" Date: Wed, 9 Dec 2009 21:25:36 -0800 Subject: [SCSI] cxgb3i: always use negative errno in case of error Signed-off-by: Karen Xie Signed-off-by: James Bottomley diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c index c1d5be4..26ffdcd 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.c +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c @@ -291,7 +291,7 @@ static void act_open_req_arp_failure(struct t3cdev *dev, struct sk_buff *skb) c3cn_hold(c3cn); spin_lock_bh(&c3cn->lock); if (c3cn->state == C3CN_STATE_CONNECTING) - fail_act_open(c3cn, EHOSTUNREACH); + fail_act_open(c3cn, -EHOSTUNREACH); spin_unlock_bh(&c3cn->lock); c3cn_put(c3cn); __kfree_skb(skb); @@ -792,18 +792,18 @@ static int act_open_rpl_status_to_errno(int status) { switch (status) { case CPL_ERR_CONN_RESET: - return ECONNREFUSED; + return -ECONNREFUSED; case CPL_ERR_ARP_MISS: - return EHOSTUNREACH; + return -EHOSTUNREACH; case CPL_ERR_CONN_TIMEDOUT: - return ETIMEDOUT; + return -ETIMEDOUT; case CPL_ERR_TCAM_FULL: - return ENOMEM; + return -ENOMEM; case CPL_ERR_CONN_EXIST: cxgb3i_log_error("ACTIVE_OPEN_RPL: 4-tuple in use\n"); - return EADDRINUSE; + return -EADDRINUSE; default: - return EIO; + return -EIO; } } @@ -817,7 +817,7 @@ static void act_open_retry_timer(unsigned long data) spin_lock_bh(&c3cn->lock); skb = alloc_skb(sizeof(struct cpl_act_open_req), GFP_ATOMIC); if (!skb) - fail_act_open(c3cn, ENOMEM); + fail_act_open(c3cn, -ENOMEM); else { skb->sk = (struct sock *)c3cn; set_arp_failure_handler(skb, act_open_req_arp_failure); @@ -966,14 +966,14 @@ static int abort_status_to_errno(struct s3_conn *c3cn, int abort_reason, case CPL_ERR_BAD_SYN: /* fall through */ case CPL_ERR_CONN_RESET: return c3cn->state > C3CN_STATE_ESTABLISHED ? - EPIPE : ECONNRESET; + -EPIPE : -ECONNRESET; case CPL_ERR_XMIT_TIMEDOUT: case CPL_ERR_PERSIST_TIMEDOUT: case CPL_ERR_FINWAIT2_TIMEDOUT: case CPL_ERR_KEEPALIVE_TIMEDOUT: - return ETIMEDOUT; + return -ETIMEDOUT; default: - return EIO; + return -EIO; } } @@ -1563,7 +1563,7 @@ free_tid: s3_free_atid(cdev, c3cn->tid); c3cn->tid = 0; out_err: - return -1; + return -EINVAL; } diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.c b/drivers/scsi/cxgb3i/cxgb3i_pdu.c index 7091050..1fe3b0f 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_pdu.c +++ b/drivers/scsi/cxgb3i/cxgb3i_pdu.c @@ -388,8 +388,8 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task) if (err > 0) { int pdulen = err; - cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n", - task, skb, skb->len, skb->data_len, err); + cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n", + task, skb, skb->len, skb->data_len, err); if (task->conn->hdrdgst_en) pdulen += ISCSI_DIGEST_SIZE; -- cgit v0.10.2 From edd163687ea59f01d6b43c9e1fdaa0126fa30191 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Tue, 8 Dec 2009 14:09:11 -0800 Subject: [SCSI] hpsa: add driver for HP Smart Array controllers. This driver supports a subset of HP Smart Array Controllers. It is a SCSI alternative to the cciss driver. [akpm@linux-foundation.org: avoid helpful cleanup patches] [achiang@hp.com: make device attrs static] [akpm@linux-foundation.org: msleep() does set_current_state() itself] Signed-off-by: Stephen M. Cameron Signed-off-by: Mike Miller Signed-off-by: Alex Chiang Signed-off-by: Andrew Morton Signed-off-by: James Bottomley diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 36900c7..9191d1e 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -388,6 +388,16 @@ config BLK_DEV_3W_XXXX_RAID Please read the comments at the top of . +config SCSI_HPSA + tristate "HP Smart Array SCSI driver" + depends on PCI && SCSI + help + This driver supports HP Smart Array Controllers (circa 2009). + It is a SCSI alternative to the cciss driver, which is a block + driver. Anyone wishing to use HP Smart Array controllers who + would prefer the devices be presented to linux as SCSI devices, + rather than as generic block devices should say Y here. + config SCSI_3W_9XXX tristate "3ware 9xxx SATA-RAID support" depends on PCI && SCSI diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 280d3c6..92a8c50 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -91,6 +91,7 @@ obj-$(CONFIG_SCSI_BFA_FC) += bfa/ obj-$(CONFIG_SCSI_PAS16) += pas16.o obj-$(CONFIG_SCSI_T128) += t128.o obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o +obj-$(CONFIG_SCSI_HPSA) += hpsa.o obj-$(CONFIG_SCSI_DTC3280) += dtc.o obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/ obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c new file mode 100644 index 0000000..bb96fdd --- /dev/null +++ b/drivers/scsi/hpsa.c @@ -0,0 +1,3531 @@ +/* + * Disk Array driver for HP Smart Array SAS controllers + * Copyright 2000, 2009 Hewlett-Packard Development Company, L.P. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Questions/Comments/Bugfixes to iss_storagedev@hp.com + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hpsa_cmd.h" +#include "hpsa.h" + +/* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */ +#define HPSA_DRIVER_VERSION "1.0.0" +#define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")" + +/* How long to wait (in milliseconds) for board to go into simple mode */ +#define MAX_CONFIG_WAIT 30000 +#define MAX_IOCTL_CONFIG_WAIT 1000 + +/*define how many times we will try a command because of bus resets */ +#define MAX_CMD_RETRIES 3 + +/* Embedded module documentation macros - see modules.h */ +MODULE_AUTHOR("Hewlett-Packard Company"); +MODULE_DESCRIPTION("Driver for HP Smart Array Controller version " \ + HPSA_DRIVER_VERSION); +MODULE_SUPPORTED_DEVICE("HP Smart Array Controllers"); +MODULE_VERSION(HPSA_DRIVER_VERSION); +MODULE_LICENSE("GPL"); + +static int hpsa_allow_any; +module_param(hpsa_allow_any, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(hpsa_allow_any, + "Allow hpsa driver to access unknown HP Smart Array hardware"); + +/* define the PCI info for the cards we can control */ +static const struct pci_device_id hpsa_pci_device_id[] = { + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3223}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3234}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x323D}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3241}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3243}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3245}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3247}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324a}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324b}, + {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, + {0,} +}; + +MODULE_DEVICE_TABLE(pci, hpsa_pci_device_id); + +/* board_id = Subsystem Device ID & Vendor ID + * product = Marketing Name for the board + * access = Address of the struct of function pointers + */ +static struct board_type products[] = { + {0x3223103C, "Smart Array P800", &SA5_access}, + {0x3234103C, "Smart Array P400", &SA5_access}, + {0x323d103c, "Smart Array P700M", &SA5_access}, + {0x3241103C, "Smart Array P212", &SA5_access}, + {0x3243103C, "Smart Array P410", &SA5_access}, + {0x3245103C, "Smart Array P410i", &SA5_access}, + {0x3247103C, "Smart Array P411", &SA5_access}, + {0x3249103C, "Smart Array P812", &SA5_access}, + {0x324a103C, "Smart Array P712m", &SA5_access}, + {0x324b103C, "Smart Array P711m", &SA5_access}, + {0xFFFF103C, "Unknown Smart Array", &SA5_access}, +}; + +static int number_of_controllers; + +static irqreturn_t do_hpsa_intr(int irq, void *dev_id); +static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg); +static void start_io(struct ctlr_info *h); + +#ifdef CONFIG_COMPAT +static int hpsa_compat_ioctl(struct scsi_device *dev, int cmd, void *arg); +#endif + +static void cmd_free(struct ctlr_info *h, struct CommandList *c); +static void cmd_special_free(struct ctlr_info *h, struct CommandList *c); +static struct CommandList *cmd_alloc(struct ctlr_info *h); +static struct CommandList *cmd_special_alloc(struct ctlr_info *h); +static void fill_cmd(struct CommandList *c, __u8 cmd, struct ctlr_info *h, + void *buff, size_t size, __u8 page_code, unsigned char *scsi3addr, + int cmd_type); + +static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd, + void (*done)(struct scsi_cmnd *)); + +static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd); +static int hpsa_slave_alloc(struct scsi_device *sdev); +static void hpsa_slave_destroy(struct scsi_device *sdev); + +static ssize_t raid_level_show(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t lunid_show(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t unique_id_show(struct device *dev, + struct device_attribute *attr, char *buf); +static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno); +static ssize_t host_store_rescan(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static int check_for_unit_attention(struct ctlr_info *h, + struct CommandList *c); +static void check_ioctl_unit_attention(struct ctlr_info *h, + struct CommandList *c); + +static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL); +static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL); +static DEVICE_ATTR(unique_id, S_IRUGO, unique_id_show, NULL); +static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan); + +static struct device_attribute *hpsa_sdev_attrs[] = { + &dev_attr_raid_level, + &dev_attr_lunid, + &dev_attr_unique_id, + NULL, +}; + +static struct device_attribute *hpsa_shost_attrs[] = { + &dev_attr_rescan, + NULL, +}; + +static struct scsi_host_template hpsa_driver_template = { + .module = THIS_MODULE, + .name = "hpsa", + .proc_name = "hpsa", + .queuecommand = hpsa_scsi_queue_command, + .can_queue = 512, + .this_id = -1, + .sg_tablesize = MAXSGENTRIES, + .cmd_per_lun = 512, + .use_clustering = ENABLE_CLUSTERING, + .eh_device_reset_handler = hpsa_eh_device_reset_handler, + .ioctl = hpsa_ioctl, + .slave_alloc = hpsa_slave_alloc, + .slave_destroy = hpsa_slave_destroy, +#ifdef CONFIG_COMPAT + .compat_ioctl = hpsa_compat_ioctl, +#endif + .sdev_attrs = hpsa_sdev_attrs, + .shost_attrs = hpsa_shost_attrs, +}; + +static inline struct ctlr_info *sdev_to_hba(struct scsi_device *sdev) +{ + unsigned long *priv = shost_priv(sdev->host); + return (struct ctlr_info *) *priv; +} + +static struct task_struct *hpsa_scan_thread; +static DEFINE_MUTEX(hpsa_scan_mutex); +static LIST_HEAD(hpsa_scan_q); +static int hpsa_scan_func(void *data); + +/** + * add_to_scan_list() - add controller to rescan queue + * @h: Pointer to the controller. + * + * Adds the controller to the rescan queue if not already on the queue. + * + * returns 1 if added to the queue, 0 if skipped (could be on the + * queue already, or the controller could be initializing or shutting + * down). + **/ +static int add_to_scan_list(struct ctlr_info *h) +{ + struct ctlr_info *test_h; + int found = 0; + int ret = 0; + + if (h->busy_initializing) + return 0; + + /* + * If we don't get the lock, it means the driver is unloading + * and there's no point in scheduling a new scan. + */ + if (!mutex_trylock(&h->busy_shutting_down)) + return 0; + + mutex_lock(&hpsa_scan_mutex); + list_for_each_entry(test_h, &hpsa_scan_q, scan_list) { + if (test_h == h) { + found = 1; + break; + } + } + if (!found && !h->busy_scanning) { + INIT_COMPLETION(h->scan_wait); + list_add_tail(&h->scan_list, &hpsa_scan_q); + ret = 1; + } + mutex_unlock(&hpsa_scan_mutex); + mutex_unlock(&h->busy_shutting_down); + + return ret; +} + +/** + * remove_from_scan_list() - remove controller from rescan queue + * @h: Pointer to the controller. + * + * Removes the controller from the rescan queue if present. Blocks if + * the controller is currently conducting a rescan. The controller + * can be in one of three states: + * 1. Doesn't need a scan + * 2. On the scan list, but not scanning yet (we remove it) + * 3. Busy scanning (and not on the list). In this case we want to wait for + * the scan to complete to make sure the scanning thread for this + * controller is completely idle. + **/ +static void remove_from_scan_list(struct ctlr_info *h) +{ + struct ctlr_info *test_h, *tmp_h; + + mutex_lock(&hpsa_scan_mutex); + list_for_each_entry_safe(test_h, tmp_h, &hpsa_scan_q, scan_list) { + if (test_h == h) { /* state 2. */ + list_del(&h->scan_list); + complete_all(&h->scan_wait); + mutex_unlock(&hpsa_scan_mutex); + return; + } + } + if (h->busy_scanning) { /* state 3. */ + mutex_unlock(&hpsa_scan_mutex); + wait_for_completion(&h->scan_wait); + } else { /* state 1, nothing to do. */ + mutex_unlock(&hpsa_scan_mutex); + } +} + +/* hpsa_scan_func() - kernel thread used to rescan controllers + * @data: Ignored. + * + * A kernel thread used scan for drive topology changes on + * controllers. The thread processes only one controller at a time + * using a queue. Controllers are added to the queue using + * add_to_scan_list() and removed from the queue either after done + * processing or using remove_from_scan_list(). + * + * returns 0. + **/ +static int hpsa_scan_func(__attribute__((unused)) void *data) +{ + struct ctlr_info *h; + int host_no; + + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + if (kthread_should_stop()) + break; + + while (1) { + mutex_lock(&hpsa_scan_mutex); + if (list_empty(&hpsa_scan_q)) { + mutex_unlock(&hpsa_scan_mutex); + break; + } + h = list_entry(hpsa_scan_q.next, struct ctlr_info, + scan_list); + list_del(&h->scan_list); + h->busy_scanning = 1; + mutex_unlock(&hpsa_scan_mutex); + host_no = h->scsi_host ? h->scsi_host->host_no : -1; + hpsa_update_scsi_devices(h, host_no); + complete_all(&h->scan_wait); + mutex_lock(&hpsa_scan_mutex); + h->busy_scanning = 0; + mutex_unlock(&hpsa_scan_mutex); + } + } + return 0; +} + +static int check_for_unit_attention(struct ctlr_info *h, + struct CommandList *c) +{ + if (c->err_info->SenseInfo[2] != UNIT_ATTENTION) + return 0; + + switch (c->err_info->SenseInfo[12]) { + case STATE_CHANGED: + dev_warn(&h->pdev->dev, "hpsa%d: a state change " + "detected, command retried\n", h->ctlr); + break; + case LUN_FAILED: + dev_warn(&h->pdev->dev, "hpsa%d: LUN failure " + "detected, action required\n", h->ctlr); + break; + case REPORT_LUNS_CHANGED: + dev_warn(&h->pdev->dev, "hpsa%d: report LUN data " + "changed\n", h->ctlr); + /* + * Here, we could call add_to_scan_list and wake up the scan thread, + * except that it's quite likely that we will get more than one + * REPORT_LUNS_CHANGED condition in quick succession, which means + * that those which occur after the first one will likely happen + * *during* the hpsa_scan_thread's rescan. And the rescan code is not + * robust enough to restart in the middle, undoing what it has already + * done, and it's not clear that it's even possible to do this, since + * part of what it does is notify the SCSI mid layer, which starts + * doing it's own i/o to read partition tables and so on, and the + * driver doesn't have visibility to know what might need undoing. + * In any event, if possible, it is horribly complicated to get right + * so we just don't do it for now. + * + * Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012. + */ + break; + case POWER_OR_RESET: + dev_warn(&h->pdev->dev, "hpsa%d: a power on " + "or device reset detected\n", h->ctlr); + break; + case UNIT_ATTENTION_CLEARED: + dev_warn(&h->pdev->dev, "hpsa%d: unit attention " + "cleared by another initiator\n", h->ctlr); + break; + default: + dev_warn(&h->pdev->dev, "hpsa%d: unknown " + "unit attention detected\n", h->ctlr); + break; + } + return 1; +} + +static ssize_t host_store_rescan(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ctlr_info *h; + struct Scsi_Host *shost = class_to_shost(dev); + unsigned long *priv = shost_priv(shost); + h = (struct ctlr_info *) *priv; + if (add_to_scan_list(h)) { + wake_up_process(hpsa_scan_thread); + wait_for_completion_interruptible(&h->scan_wait); + } + return count; +} + +/* Enqueuing and dequeuing functions for cmdlists. */ +static inline void addQ(struct hlist_head *list, struct CommandList *c) +{ + hlist_add_head(&c->list, list); +} + +static void enqueue_cmd_and_start_io(struct ctlr_info *h, + struct CommandList *c) +{ + unsigned long flags; + spin_lock_irqsave(&h->lock, flags); + addQ(&h->reqQ, c); + h->Qdepth++; + start_io(h); + spin_unlock_irqrestore(&h->lock, flags); +} + +static inline void removeQ(struct CommandList *c) +{ + if (WARN_ON(hlist_unhashed(&c->list))) + return; + hlist_del_init(&c->list); +} + +static inline int is_hba_lunid(unsigned char scsi3addr[]) +{ + return memcmp(scsi3addr, RAID_CTLR_LUNID, 8) == 0; +} + +static inline int is_logical_dev_addr_mode(unsigned char scsi3addr[]) +{ + return (scsi3addr[3] & 0xC0) == 0x40; +} + +static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", + "UNKNOWN" +}; +#define RAID_UNKNOWN (ARRAY_SIZE(raid_label) - 1) + +static ssize_t raid_level_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t l = 0; + int rlevel; + struct ctlr_info *h; + struct scsi_device *sdev; + struct hpsa_scsi_dev_t *hdev; + unsigned long flags; + + sdev = to_scsi_device(dev); + h = sdev_to_hba(sdev); + spin_lock_irqsave(&h->lock, flags); + hdev = sdev->hostdata; + if (!hdev) { + spin_unlock_irqrestore(&h->lock, flags); + return -ENODEV; + } + + /* Is this even a logical drive? */ + if (!is_logical_dev_addr_mode(hdev->scsi3addr)) { + spin_unlock_irqrestore(&h->lock, flags); + l = snprintf(buf, PAGE_SIZE, "N/A\n"); + return l; + } + + rlevel = hdev->raid_level; + spin_unlock_irqrestore(&h->lock, flags); + if (rlevel < 0 || rlevel > RAID_UNKNOWN) + rlevel = RAID_UNKNOWN; + l = snprintf(buf, PAGE_SIZE, "RAID %s\n", raid_label[rlevel]); + return l; +} + +static ssize_t lunid_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ctlr_info *h; + struct scsi_device *sdev; + struct hpsa_scsi_dev_t *hdev; + unsigned long flags; + unsigned char lunid[8]; + + sdev = to_scsi_device(dev); + h = sdev_to_hba(sdev); + spin_lock_irqsave(&h->lock, flags); + hdev = sdev->hostdata; + if (!hdev) { + spin_unlock_irqrestore(&h->lock, flags); + return -ENODEV; + } + memcpy(lunid, hdev->scsi3addr, sizeof(lunid)); + spin_unlock_irqrestore(&h->lock, flags); + return snprintf(buf, 20, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", + lunid[0], lunid[1], lunid[2], lunid[3], + lunid[4], lunid[5], lunid[6], lunid[7]); +} + +static ssize_t unique_id_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ctlr_info *h; + struct scsi_device *sdev; + struct hpsa_scsi_dev_t *hdev; + unsigned long flags; + unsigned char sn[16]; + + sdev = to_scsi_device(dev); + h = sdev_to_hba(sdev); + spin_lock_irqsave(&h->lock, flags); + hdev = sdev->hostdata; + if (!hdev) { + spin_unlock_irqrestore(&h->lock, flags); + return -ENODEV; + } + memcpy(sn, hdev->device_id, sizeof(sn)); + spin_unlock_irqrestore(&h->lock, flags); + return snprintf(buf, 16 * 2 + 2, + "%02X%02X%02X%02X%02X%02X%02X%02X" + "%02X%02X%02X%02X%02X%02X%02X%02X\n", + sn[0], sn[1], sn[2], sn[3], + sn[4], sn[5], sn[6], sn[7], + sn[8], sn[9], sn[10], sn[11], + sn[12], sn[13], sn[14], sn[15]); +} + +static int hpsa_find_target_lun(struct ctlr_info *h, + unsigned char scsi3addr[], int bus, int *target, int *lun) +{ + /* finds an unused bus, target, lun for a new physical device + * assumes h->devlock is held + */ + int i, found = 0; + DECLARE_BITMAP(lun_taken, HPSA_MAX_SCSI_DEVS_PER_HBA); + + memset(&lun_taken[0], 0, HPSA_MAX_SCSI_DEVS_PER_HBA >> 3); + + for (i = 0; i < h->ndevices; i++) { + if (h->dev[i]->bus == bus && h->dev[i]->target != -1) + set_bit(h->dev[i]->target, lun_taken); + } + + for (i = 0; i < HPSA_MAX_SCSI_DEVS_PER_HBA; i++) { + if (!test_bit(i, lun_taken)) { + /* *bus = 1; */ + *target = i; + *lun = 0; + found = 1; + break; + } + } + return !found; +} + +/* Add an entry into h->dev[] array. */ +static int hpsa_scsi_add_entry(struct ctlr_info *h, int hostno, + struct hpsa_scsi_dev_t *device, + struct hpsa_scsi_dev_t *added[], int *nadded) +{ + /* assumes h->devlock is held */ + int n = h->ndevices; + int i; + unsigned char addr1[8], addr2[8]; + struct hpsa_scsi_dev_t *sd; + + if (n >= HPSA_MAX_SCSI_DEVS_PER_HBA) { + dev_err(&h->pdev->dev, "too many devices, some will be " + "inaccessible.\n"); + return -1; + } + + /* physical devices do not have lun or target assigned until now. */ + if (device->lun != -1) + /* Logical device, lun is already assigned. */ + goto lun_assigned; + + /* If this device a non-zero lun of a multi-lun device + * byte 4 of the 8-byte LUN addr will contain the logical + * unit no, zero otherise. + */ + if (device->scsi3addr[4] == 0) { + /* This is not a non-zero lun of a multi-lun device */ + if (hpsa_find_target_lun(h, device->scsi3addr, + device->bus, &device->target, &device->lun) != 0) + return -1; + goto lun_assigned; + } + + /* This is a non-zero lun of a multi-lun device. + * Search through our list and find the device which + * has the same 8 byte LUN address, excepting byte 4. + * Assign the same bus and target for this new LUN. + * Use the logical unit number from the firmware. + */ + memcpy(addr1, device->scsi3addr, 8); + addr1[4] = 0; + for (i = 0; i < n; i++) { + sd = h->dev[i]; + memcpy(addr2, sd->scsi3addr, 8); + addr2[4] = 0; + /* differ only in byte 4? */ + if (memcmp(addr1, addr2, 8) == 0) { + device->bus = sd->bus; + device->target = sd->target; + device->lun = device->scsi3addr[4]; + break; + } + } + if (device->lun == -1) { + dev_warn(&h->pdev->dev, "physical device with no LUN=0," + " suspect firmware bug or unsupported hardware " + "configuration.\n"); + return -1; + } + +lun_assigned: + + h->dev[n] = device; + h->ndevices++; + added[*nadded] = device; + (*nadded)++; + + /* initially, (before registering with scsi layer) we don't + * know our hostno and we don't want to print anything first + * time anyway (the scsi layer's inquiries will show that info) + */ + /* if (hostno != -1) */ + dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d added.\n", + scsi_device_type(device->devtype), hostno, + device->bus, device->target, device->lun); + return 0; +} + +/* Remove an entry from h->dev[] array. */ +static void hpsa_scsi_remove_entry(struct ctlr_info *h, int hostno, int entry, + struct hpsa_scsi_dev_t *removed[], int *nremoved) +{ + /* assumes h->devlock is held */ + int i; + struct hpsa_scsi_dev_t *sd; + + if (entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA) + BUG(); + + sd = h->dev[entry]; + removed[*nremoved] = h->dev[entry]; + (*nremoved)++; + + for (i = entry; i < h->ndevices-1; i++) + h->dev[i] = h->dev[i+1]; + h->ndevices--; + dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d removed.\n", + scsi_device_type(sd->devtype), hostno, sd->bus, sd->target, + sd->lun); +} + +#define SCSI3ADDR_EQ(a, b) ( \ + (a)[7] == (b)[7] && \ + (a)[6] == (b)[6] && \ + (a)[5] == (b)[5] && \ + (a)[4] == (b)[4] && \ + (a)[3] == (b)[3] && \ + (a)[2] == (b)[2] && \ + (a)[1] == (b)[1] && \ + (a)[0] == (b)[0]) + +static void fixup_botched_add(struct ctlr_info *h, + struct hpsa_scsi_dev_t *added) +{ + /* called when scsi_add_device fails in order to re-adjust + * h->dev[] to match the mid layer's view. + */ + unsigned long flags; + int i, j; + + spin_lock_irqsave(&h->lock, flags); + for (i = 0; i < h->ndevices; i++) { + if (h->dev[i] == added) { + for (j = i; j < h->ndevices-1; j++) + h->dev[j] = h->dev[j+1]; + h->ndevices--; + break; + } + } + spin_unlock_irqrestore(&h->lock, flags); + kfree(added); +} + +static inline int device_is_the_same(struct hpsa_scsi_dev_t *dev1, + struct hpsa_scsi_dev_t *dev2) +{ + if ((is_logical_dev_addr_mode(dev1->scsi3addr) || + (dev1->lun != -1 && dev2->lun != -1)) && + dev1->devtype != 0x0C) + return (memcmp(dev1, dev2, sizeof(*dev1)) == 0); + + /* we compare everything except lun and target as these + * are not yet assigned. Compare parts likely + * to differ first + */ + if (memcmp(dev1->scsi3addr, dev2->scsi3addr, + sizeof(dev1->scsi3addr)) != 0) + return 0; + if (memcmp(dev1->device_id, dev2->device_id, + sizeof(dev1->device_id)) != 0) + return 0; + if (memcmp(dev1->model, dev2->model, sizeof(dev1->model)) != 0) + return 0; + if (memcmp(dev1->vendor, dev2->vendor, sizeof(dev1->vendor)) != 0) + return 0; + if (memcmp(dev1->revision, dev2->revision, sizeof(dev1->revision)) != 0) + return 0; + if (dev1->devtype != dev2->devtype) + return 0; + if (dev1->raid_level != dev2->raid_level) + return 0; + if (dev1->bus != dev2->bus) + return 0; + return 1; +} + +/* Find needle in haystack. If exact match found, return DEVICE_SAME, + * and return needle location in *index. If scsi3addr matches, but not + * vendor, model, serial num, etc. return DEVICE_CHANGED, and return needle + * location in *index. If needle not found, return DEVICE_NOT_FOUND. + */ +static int hpsa_scsi_find_entry(struct hpsa_scsi_dev_t *needle, + struct hpsa_scsi_dev_t *haystack[], int haystack_size, + int *index) +{ + int i; +#define DEVICE_NOT_FOUND 0 +#define DEVICE_CHANGED 1 +#define DEVICE_SAME 2 + for (i = 0; i < haystack_size; i++) { + if (SCSI3ADDR_EQ(needle->scsi3addr, haystack[i]->scsi3addr)) { + *index = i; + if (device_is_the_same(needle, haystack[i])) + return DEVICE_SAME; + else + return DEVICE_CHANGED; + } + } + *index = -1; + return DEVICE_NOT_FOUND; +} + +static int adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno, + struct hpsa_scsi_dev_t *sd[], int nsds) +{ + /* sd contains scsi3 addresses and devtypes, and inquiry + * data. This function takes what's in sd to be the current + * reality and updates h->dev[] to reflect that reality. + */ + int i, entry, device_change, changes = 0; + struct hpsa_scsi_dev_t *csd; + unsigned long flags; + struct hpsa_scsi_dev_t **added, **removed; + int nadded, nremoved; + struct Scsi_Host *sh = NULL; + + added = kzalloc(sizeof(*added) * HPSA_MAX_SCSI_DEVS_PER_HBA, + GFP_KERNEL); + removed = kzalloc(sizeof(*removed) * HPSA_MAX_SCSI_DEVS_PER_HBA, + GFP_KERNEL); + + if (!added || !removed) { + dev_warn(&h->pdev->dev, "out of memory in " + "adjust_hpsa_scsi_table\n"); + goto free_and_out; + } + + spin_lock_irqsave(&h->devlock, flags); + + /* find any devices in h->dev[] that are not in + * sd[] and remove them from h->dev[], and for any + * devices which have changed, remove the old device + * info and add the new device info. + */ + i = 0; + nremoved = 0; + nadded = 0; + while (i < h->ndevices) { + csd = h->dev[i]; + device_change = hpsa_scsi_find_entry(csd, sd, nsds, &entry); + if (device_change == DEVICE_NOT_FOUND) { + changes++; + hpsa_scsi_remove_entry(h, hostno, i, + removed, &nremoved); + continue; /* remove ^^^, hence i not incremented */ + } else if (device_change == DEVICE_CHANGED) { + changes++; + hpsa_scsi_remove_entry(h, hostno, i, + removed, &nremoved); + (void) hpsa_scsi_add_entry(h, hostno, sd[entry], + added, &nadded); + /* add can't fail, we just removed one. */ + sd[entry] = NULL; /* prevent it from being freed */ + } + i++; + } + + /* Now, make sure every device listed in sd[] is also + * listed in h->dev[], adding them if they aren't found + */ + + for (i = 0; i < nsds; i++) { + if (!sd[i]) /* if already added above. */ + continue; + device_change = hpsa_scsi_find_entry(sd[i], h->dev, + h->ndevices, &entry); + if (device_change == DEVICE_NOT_FOUND) { + changes++; + if (hpsa_scsi_add_entry(h, hostno, sd[i], + added, &nadded) != 0) + break; + sd[i] = NULL; /* prevent from being freed later. */ + } else if (device_change == DEVICE_CHANGED) { + /* should never happen... */ + changes++; + dev_warn(&h->pdev->dev, + "device unexpectedly changed.\n"); + /* but if it does happen, we just ignore that device */ + } + } + spin_unlock_irqrestore(&h->devlock, flags); + + /* Don't notify scsi mid layer of any changes the first time through + * (or if there are no changes) scsi_scan_host will do it later the + * first time through. + */ + if (hostno == -1 || !changes) + goto free_and_out; + + sh = h->scsi_host; + /* Notify scsi mid layer of any removed devices */ + for (i = 0; i < nremoved; i++) { + struct scsi_device *sdev = + scsi_device_lookup(sh, removed[i]->bus, + removed[i]->target, removed[i]->lun); + if (sdev != NULL) { + scsi_remove_device(sdev); + scsi_device_put(sdev); + } else { + /* We don't expect to get here. + * future cmds to this device will get selection + * timeout as if the device was gone. + */ + dev_warn(&h->pdev->dev, "didn't find c%db%dt%dl%d " + " for removal.", hostno, removed[i]->bus, + removed[i]->target, removed[i]->lun); + } + kfree(removed[i]); + removed[i] = NULL; + } + + /* Notify scsi mid layer of any added devices */ + for (i = 0; i < nadded; i++) { + if (scsi_add_device(sh, added[i]->bus, + added[i]->target, added[i]->lun) == 0) + continue; + dev_warn(&h->pdev->dev, "scsi_add_device c%db%dt%dl%d failed, " + "device not added.\n", hostno, added[i]->bus, + added[i]->target, added[i]->lun); + /* now we have to remove it from h->dev, + * since it didn't get added to scsi mid layer + */ + fixup_botched_add(h, added[i]); + } + +free_and_out: + kfree(added); + kfree(removed); + return 0; +} + +/* + * Lookup bus/target/lun and retrun corresponding struct hpsa_scsi_dev_t * + * Assume's h->devlock is held. + */ +static struct hpsa_scsi_dev_t *lookup_hpsa_scsi_dev(struct ctlr_info *h, + int bus, int target, int lun) +{ + int i; + struct hpsa_scsi_dev_t *sd; + + for (i = 0; i < h->ndevices; i++) { + sd = h->dev[i]; + if (sd->bus == bus && sd->target == target && sd->lun == lun) + return sd; + } + return NULL; +} + +/* link sdev->hostdata to our per-device structure. */ +static int hpsa_slave_alloc(struct scsi_device *sdev) +{ + struct hpsa_scsi_dev_t *sd; + unsigned long flags; + struct ctlr_info *h; + + h = sdev_to_hba(sdev); + spin_lock_irqsave(&h->devlock, flags); + sd = lookup_hpsa_scsi_dev(h, sdev_channel(sdev), + sdev_id(sdev), sdev->lun); + if (sd != NULL) + sdev->hostdata = sd; + spin_unlock_irqrestore(&h->devlock, flags); + return 0; +} + +static void hpsa_slave_destroy(struct scsi_device *sdev) +{ + return; /* nothing to do. */ +} + +static void hpsa_scsi_setup(struct ctlr_info *h) +{ + h->ndevices = 0; + h->scsi_host = NULL; + spin_lock_init(&h->devlock); + return; +} + +static void complete_scsi_command(struct CommandList *cp, + int timeout, __u32 tag) +{ + struct scsi_cmnd *cmd; + struct ctlr_info *h; + struct ErrorInfo *ei; + + unsigned char sense_key; + unsigned char asc; /* additional sense code */ + unsigned char ascq; /* additional sense code qualifier */ + + ei = cp->err_info; + cmd = (struct scsi_cmnd *) cp->scsi_cmd; + h = cp->h; + + scsi_dma_unmap(cmd); /* undo the DMA mappings */ + + cmd->result = (DID_OK << 16); /* host byte */ + cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ + cmd->result |= (ei->ScsiStatus << 1); + + /* copy the sense data whether we need to or not. */ + memcpy(cmd->sense_buffer, ei->SenseInfo, + ei->SenseLen > SCSI_SENSE_BUFFERSIZE ? + SCSI_SENSE_BUFFERSIZE : + ei->SenseLen); + scsi_set_resid(cmd, ei->ResidualCnt); + + if (ei->CommandStatus == 0) { + cmd->scsi_done(cmd); + cmd_free(h, cp); + return; + } + + /* an error has occurred */ + switch (ei->CommandStatus) { + + case CMD_TARGET_STATUS: + if (ei->ScsiStatus) { + /* Get sense key */ + sense_key = 0xf & ei->SenseInfo[2]; + /* Get additional sense code */ + asc = ei->SenseInfo[12]; + /* Get addition sense code qualifier */ + ascq = ei->SenseInfo[13]; + } + + if (ei->ScsiStatus == SAM_STAT_CHECK_CONDITION) { + if (check_for_unit_attention(h, cp)) { + cmd->result = DID_SOFT_ERROR << 16; + break; + } + if (sense_key == ILLEGAL_REQUEST) { + /* + * SCSI REPORT_LUNS is commonly unsupported on + * Smart Array. Suppress noisy complaint. + */ + if (cp->Request.CDB[0] == REPORT_LUNS) + break; + + /* If ASC/ASCQ indicate Logical Unit + * Not Supported condition, + */ + if ((asc == 0x25) && (ascq == 0x0)) { + dev_warn(&h->pdev->dev, "cp %p " + "has check condition\n", cp); + break; + } + } + + if (sense_key == NOT_READY) { + /* If Sense is Not Ready, Logical Unit + * Not ready, Manual Intervention + * required + */ + if ((asc == 0x04) && (ascq == 0x03)) { + cmd->result = DID_NO_CONNECT << 16; + dev_warn(&h->pdev->dev, "cp %p " + "has check condition: unit " + "not ready, manual " + "intervention required\n", cp); + break; + } + } + + + /* Must be some other type of check condition */ + dev_warn(&h->pdev->dev, "cp %p has check condition: " + "unknown type: " + "Sense: 0x%x, ASC: 0x%x, ASCQ: 0x%x, " + "Returning result: 0x%x, " + "cmd=[%02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x]\n", + cp, sense_key, asc, ascq, + cmd->result, + cmd->cmnd[0], cmd->cmnd[1], + cmd->cmnd[2], cmd->cmnd[3], + cmd->cmnd[4], cmd->cmnd[5], + cmd->cmnd[6], cmd->cmnd[7], + cmd->cmnd[8], cmd->cmnd[9]); + break; + } + + + /* Problem was not a check condition + * Pass it up to the upper layers... + */ + if (ei->ScsiStatus) { + dev_warn(&h->pdev->dev, "cp %p has status 0x%x " + "Sense: 0x%x, ASC: 0x%x, ASCQ: 0x%x, " + "Returning result: 0x%x\n", + cp, ei->ScsiStatus, + sense_key, asc, ascq, + cmd->result); + } else { /* scsi status is zero??? How??? */ + dev_warn(&h->pdev->dev, "cp %p SCSI status was 0. " + "Returning no connection.\n", cp), + + /* Ordinarily, this case should never happen, + * but there is a bug in some released firmware + * revisions that allows it to happen if, for + * example, a 4100 backplane loses power and + * the tape drive is in it. We assume that + * it's a fatal error of some kind because we + * can't show that it wasn't. We will make it + * look like selection timeout since that is + * the most common reason for this to occur, + * and it's severe enough. + */ + + cmd->result = DID_NO_CONNECT << 16; + } + break; + + case CMD_DATA_UNDERRUN: /* let mid layer handle it. */ + break; + case CMD_DATA_OVERRUN: + dev_warn(&h->pdev->dev, "cp %p has" + " completed with data overrun " + "reported\n", cp); + break; + case CMD_INVALID: { + /* print_bytes(cp, sizeof(*cp), 1, 0); + print_cmd(cp); */ + /* We get CMD_INVALID if you address a non-existent device + * instead of a selection timeout (no response). You will + * see this if you yank out a drive, then try to access it. + * This is kind of a shame because it means that any other + * CMD_INVALID (e.g. driver bug) will get interpreted as a + * missing target. */ + cmd->result = DID_NO_CONNECT << 16; + } + break; + case CMD_PROTOCOL_ERR: + dev_warn(&h->pdev->dev, "cp %p has " + "protocol error \n", cp); + break; + case CMD_HARDWARE_ERR: + cmd->result = DID_ERROR << 16; + dev_warn(&h->pdev->dev, "cp %p had hardware error\n", cp); + break; + case CMD_CONNECTION_LOST: + cmd->result = DID_ERROR << 16; + dev_warn(&h->pdev->dev, "cp %p had connection lost\n", cp); + break; + case CMD_ABORTED: + cmd->result = DID_ABORT << 16; + dev_warn(&h->pdev->dev, "cp %p was aborted with status 0x%x\n", + cp, ei->ScsiStatus); + break; + case CMD_ABORT_FAILED: + cmd->result = DID_ERROR << 16; + dev_warn(&h->pdev->dev, "cp %p reports abort failed\n", cp); + break; + case CMD_UNSOLICITED_ABORT: + cmd->result = DID_ABORT << 16; + dev_warn(&h->pdev->dev, "cp %p aborted do to an unsolicited " + "abort\n", cp); + break; + case CMD_TIMEOUT: + cmd->result = DID_TIME_OUT << 16; + dev_warn(&h->pdev->dev, "cp %p timedout\n", cp); + break; + default: + cmd->result = DID_ERROR << 16; + dev_warn(&h->pdev->dev, "cp %p returned unknown status %x\n", + cp, ei->CommandStatus); + } + cmd->scsi_done(cmd); + cmd_free(h, cp); +} + +static int hpsa_scsi_detect(struct ctlr_info *h) +{ + struct Scsi_Host *sh; + int error; + + sh = scsi_host_alloc(&hpsa_driver_template, sizeof(h)); + if (sh == NULL) + goto fail; + + sh->io_port = 0; + sh->n_io_port = 0; + sh->this_id = -1; + sh->max_channel = 3; + sh->max_cmd_len = MAX_COMMAND_SIZE; + sh->max_lun = HPSA_MAX_LUN; + sh->max_id = HPSA_MAX_LUN; + h->scsi_host = sh; + sh->hostdata[0] = (unsigned long) h; + sh->irq = h->intr[SIMPLE_MODE_INT]; + sh->unique_id = sh->irq; + error = scsi_add_host(sh, &h->pdev->dev); + if (error) + goto fail_host_put; + scsi_scan_host(sh); + return 0; + + fail_host_put: + dev_err(&h->pdev->dev, "hpsa_scsi_detect: scsi_add_host" + " failed for controller %d\n", h->ctlr); + scsi_host_put(sh); + return -1; + fail: + dev_err(&h->pdev->dev, "hpsa_scsi_detect: scsi_host_alloc" + " failed for controller %d\n", h->ctlr); + return -1; +} + +static void hpsa_pci_unmap(struct pci_dev *pdev, + struct CommandList *c, int sg_used, int data_direction) +{ + int i; + union u64bit addr64; + + for (i = 0; i < sg_used; i++) { + addr64.val32.lower = c->SG[i].Addr.lower; + addr64.val32.upper = c->SG[i].Addr.upper; + pci_unmap_single(pdev, (dma_addr_t) addr64.val, c->SG[i].Len, + data_direction); + } +} + +static void hpsa_map_one(struct pci_dev *pdev, + struct CommandList *cp, + unsigned char *buf, + size_t buflen, + int data_direction) +{ + __u64 addr64; + + if (buflen == 0 || data_direction == PCI_DMA_NONE) { + cp->Header.SGList = 0; + cp->Header.SGTotal = 0; + return; + } + + addr64 = (__u64) pci_map_single(pdev, buf, buflen, data_direction); + cp->SG[0].Addr.lower = + (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF); + cp->SG[0].Addr.upper = + (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF); + cp->SG[0].Len = buflen; + cp->Header.SGList = (__u8) 1; /* no. SGs contig in this cmd */ + cp->Header.SGTotal = (__u16) 1; /* total sgs in this cmd list */ +} + +static inline void hpsa_scsi_do_simple_cmd_core(struct ctlr_info *h, + struct CommandList *c) +{ + DECLARE_COMPLETION_ONSTACK(wait); + + c->waiting = &wait; + enqueue_cmd_and_start_io(h, c); + wait_for_completion(&wait); +} + +static void hpsa_scsi_do_simple_cmd_with_retry(struct ctlr_info *h, + struct CommandList *c, int data_direction) +{ + int retry_count = 0; + + do { + memset(c->err_info, 0, sizeof(c->err_info)); + hpsa_scsi_do_simple_cmd_core(h, c); + retry_count++; + } while (check_for_unit_attention(h, c) && retry_count <= 3); + hpsa_pci_unmap(h->pdev, c, 1, data_direction); +} + +static void hpsa_scsi_interpret_error(struct CommandList *cp) +{ + struct ErrorInfo *ei; + struct device *d = &cp->h->pdev->dev; + + ei = cp->err_info; + switch (ei->CommandStatus) { + case CMD_TARGET_STATUS: + dev_warn(d, "cmd %p has completed with errors\n", cp); + dev_warn(d, "cmd %p has SCSI Status = %x\n", cp, + ei->ScsiStatus); + if (ei->ScsiStatus == 0) + dev_warn(d, "SCSI status is abnormally zero. " + "(probably indicates selection timeout " + "reported incorrectly due to a known " + "firmware bug, circa July, 2001.)\n"); + break; + case CMD_DATA_UNDERRUN: /* let mid layer handle it. */ + dev_info(d, "UNDERRUN\n"); + break; + case CMD_DATA_OVERRUN: + dev_warn(d, "cp %p has completed with data overrun\n", cp); + break; + case CMD_INVALID: { + /* controller unfortunately reports SCSI passthru's + * to non-existent targets as invalid commands. + */ + dev_warn(d, "cp %p is reported invalid (probably means " + "target device no longer present)\n", cp); + /* print_bytes((unsigned char *) cp, sizeof(*cp), 1, 0); + print_cmd(cp); */ + } + break; + case CMD_PROTOCOL_ERR: + dev_warn(d, "cp %p has protocol error \n", cp); + break; + case CMD_HARDWARE_ERR: + /* cmd->result = DID_ERROR << 16; */ + dev_warn(d, "cp %p had hardware error\n", cp); + break; + case CMD_CONNECTION_LOST: + dev_warn(d, "cp %p had connection lost\n", cp); + break; + case CMD_ABORTED: + dev_warn(d, "cp %p was aborted\n", cp); + break; + case CMD_ABORT_FAILED: + dev_warn(d, "cp %p reports abort failed\n", cp); + break; + case CMD_UNSOLICITED_ABORT: + dev_warn(d, "cp %p aborted due to an unsolicited abort\n", cp); + break; + case CMD_TIMEOUT: + dev_warn(d, "cp %p timed out\n", cp); + break; + default: + dev_warn(d, "cp %p returned unknown status %x\n", cp, + ei->CommandStatus); + } +} + +static int hpsa_scsi_do_inquiry(struct ctlr_info *h, unsigned char *scsi3addr, + unsigned char page, unsigned char *buf, + unsigned char bufsize) +{ + int rc = IO_OK; + struct CommandList *c; + struct ErrorInfo *ei; + + c = cmd_special_alloc(h); + + if (c == NULL) { /* trouble... */ + dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); + return -1; + } + + fill_cmd(c, HPSA_INQUIRY, h, buf, bufsize, page, scsi3addr, TYPE_CMD); + hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE); + ei = c->err_info; + if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) { + hpsa_scsi_interpret_error(c); + rc = -1; + } + cmd_special_free(h, c); + return rc; +} + +static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr) +{ + int rc = IO_OK; + struct CommandList *c; + struct ErrorInfo *ei; + + c = cmd_special_alloc(h); + + if (c == NULL) { /* trouble... */ + dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); + return -1; + } + + fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, scsi3addr, TYPE_MSG); + hpsa_scsi_do_simple_cmd_core(h, c); + /* no unmap needed here because no data xfer. */ + + ei = c->err_info; + if (ei->CommandStatus != 0) { + hpsa_scsi_interpret_error(c); + rc = -1; + } + cmd_special_free(h, c); + return rc; +} + +static void hpsa_get_raid_level(struct ctlr_info *h, + unsigned char *scsi3addr, unsigned char *raid_level) +{ + int rc; + unsigned char *buf; + + *raid_level = RAID_UNKNOWN; + buf = kzalloc(64, GFP_KERNEL); + if (!buf) + return; + rc = hpsa_scsi_do_inquiry(h, scsi3addr, 0xC1, buf, 64); + if (rc == 0) + *raid_level = buf[8]; + if (*raid_level > RAID_UNKNOWN) + *raid_level = RAID_UNKNOWN; + kfree(buf); + return; +} + +/* Get the device id from inquiry page 0x83 */ +static int hpsa_get_device_id(struct ctlr_info *h, unsigned char *scsi3addr, + unsigned char *device_id, int buflen) +{ + int rc; + unsigned char *buf; + + if (buflen > 16) + buflen = 16; + buf = kzalloc(64, GFP_KERNEL); + if (!buf) + return -1; + rc = hpsa_scsi_do_inquiry(h, scsi3addr, 0x83, buf, 64); + if (rc == 0) + memcpy(device_id, &buf[8], buflen); + kfree(buf); + return rc != 0; +} + +static int hpsa_scsi_do_report_luns(struct ctlr_info *h, int logical, + struct ReportLUNdata *buf, int bufsize, + int extended_response) +{ + int rc = IO_OK; + struct CommandList *c; + unsigned char scsi3addr[8]; + struct ErrorInfo *ei; + + c = cmd_special_alloc(h); + if (c == NULL) { /* trouble... */ + dev_err(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); + return -1; + } + + memset(&scsi3addr[0], 0, 8); /* address the controller */ + + fill_cmd(c, logical ? HPSA_REPORT_LOG : HPSA_REPORT_PHYS, h, + buf, bufsize, 0, scsi3addr, TYPE_CMD); + if (extended_response) + c->Request.CDB[1] = extended_response; + hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE); + ei = c->err_info; + if (ei->CommandStatus != 0 && + ei->CommandStatus != CMD_DATA_UNDERRUN) { + hpsa_scsi_interpret_error(c); + rc = -1; + } + cmd_special_free(h, c); + return rc; +} + +static inline int hpsa_scsi_do_report_phys_luns(struct ctlr_info *h, + struct ReportLUNdata *buf, + int bufsize, int extended_response) +{ + return hpsa_scsi_do_report_luns(h, 0, buf, bufsize, extended_response); +} + +static inline int hpsa_scsi_do_report_log_luns(struct ctlr_info *h, + struct ReportLUNdata *buf, int bufsize) +{ + return hpsa_scsi_do_report_luns(h, 1, buf, bufsize, 0); +} + +static inline void hpsa_set_bus_target_lun(struct hpsa_scsi_dev_t *device, + int bus, int target, int lun) +{ + device->bus = bus; + device->target = target; + device->lun = lun; +} + +static int hpsa_update_device_info(struct ctlr_info *h, + unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device) +{ +#define OBDR_TAPE_INQ_SIZE 49 + unsigned char *inq_buff = NULL; + + inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); + if (!inq_buff) + goto bail_out; + + memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE); + /* Do an inquiry to the device to see what it is. */ + if (hpsa_scsi_do_inquiry(h, scsi3addr, 0, inq_buff, + (unsigned char) OBDR_TAPE_INQ_SIZE) != 0) { + /* Inquiry failed (msg printed already) */ + dev_err(&h->pdev->dev, + "hpsa_update_device_info: inquiry failed\n"); + goto bail_out; + } + + /* As a side effect, record the firmware version number + * if we happen to be talking to the RAID controller. + */ + if (is_hba_lunid(scsi3addr)) + memcpy(h->firm_ver, &inq_buff[32], 4); + + this_device->devtype = (inq_buff[0] & 0x1f); + memcpy(this_device->scsi3addr, scsi3addr, 8); + memcpy(this_device->vendor, &inq_buff[8], + sizeof(this_device->vendor)); + memcpy(this_device->model, &inq_buff[16], + sizeof(this_device->model)); + memcpy(this_device->revision, &inq_buff[32], + sizeof(this_device->revision)); + memset(this_device->device_id, 0, + sizeof(this_device->device_id)); + hpsa_get_device_id(h, scsi3addr, this_device->device_id, + sizeof(this_device->device_id)); + + if (this_device->devtype == TYPE_DISK && + is_logical_dev_addr_mode(scsi3addr)) + hpsa_get_raid_level(h, scsi3addr, &this_device->raid_level); + else + this_device->raid_level = RAID_UNKNOWN; + + kfree(inq_buff); + return 0; + +bail_out: + kfree(inq_buff); + return 1; +} + +static unsigned char *msa2xxx_model[] = { + "MSA2012", + "MSA2024", + "MSA2312", + "MSA2324", + NULL, +}; + +static int is_msa2xxx(struct ctlr_info *h, struct hpsa_scsi_dev_t *device) +{ + int i; + + for (i = 0; msa2xxx_model[i]; i++) + if (strncmp(device->model, msa2xxx_model[i], + strlen(msa2xxx_model[i])) == 0) + return 1; + return 0; +} + +/* Helper function to assign bus, target, lun mapping of devices. + * Puts non-msa2xxx logical volumes on bus 0, msa2xxx logical + * volumes on bus 1, physical devices on bus 2. and the hba on bus 3. + * Logical drive target and lun are assigned at this time, but + * physical device lun and target assignment are deferred (assigned + * in hpsa_find_target_lun, called by hpsa_scsi_add_entry.) + */ +static void figure_bus_target_lun(struct ctlr_info *h, + __u8 *lunaddrbytes, int *bus, int *target, int *lun, + struct hpsa_scsi_dev_t *device) +{ + + __u32 lunid; + + if (is_logical_dev_addr_mode(lunaddrbytes)) { + /* logical device */ + memcpy(&lunid, lunaddrbytes, sizeof(lunid)); + lunid = le32_to_cpu(lunid); + + if (is_msa2xxx(h, device)) { + *bus = 1; + *target = (lunid >> 16) & 0x3fff; + *lun = lunid & 0x00ff; + } else { + *bus = 0; + *lun = 0; + *target = lunid & 0x3fff; + } + } else { + /* physical device */ + if (is_hba_lunid(lunaddrbytes)) + *bus = 3; + else + *bus = 2; + *target = -1; + *lun = -1; /* we will fill these in later. */ + } +} + +/* + * If there is no lun 0 on a target, linux won't find any devices. + * For the MSA2xxx boxes, we have to manually detect the enclosure + * which is at lun zero, as CCISS_REPORT_PHYSICAL_LUNS doesn't report + * it for some reason. *tmpdevice is the target we're adding, + * this_device is a pointer into the current element of currentsd[] + * that we're building up in update_scsi_devices(), below. + * lunzerobits is a bitmap that tracks which targets already have a + * lun 0 assigned. + * Returns 1 if an enclosure was added, 0 if not. + */ +static int add_msa2xxx_enclosure_device(struct ctlr_info *h, + struct hpsa_scsi_dev_t *tmpdevice, + struct hpsa_scsi_dev_t *this_device, __u8 *lunaddrbytes, + int bus, int target, int lun, unsigned long lunzerobits[], + int *nmsa2xxx_enclosures) +{ + unsigned char scsi3addr[8]; + + if (test_bit(target, lunzerobits)) + return 0; /* There is already a lun 0 on this target. */ + + if (!is_logical_dev_addr_mode(lunaddrbytes)) + return 0; /* It's the logical targets that may lack lun 0. */ + + if (!is_msa2xxx(h, tmpdevice)) + return 0; /* It's only the MSA2xxx that have this problem. */ + + if (lun == 0) /* if lun is 0, then obviously we have a lun 0. */ + return 0; + + if (is_hba_lunid(scsi3addr)) + return 0; /* Don't add the RAID controller here. */ + +#define MAX_MSA2XXX_ENCLOSURES 32 + if (*nmsa2xxx_enclosures >= MAX_MSA2XXX_ENCLOSURES) { + dev_warn(&h->pdev->dev, "Maximum number of MSA2XXX " + "enclosures exceeded. Check your hardware " + "configuration."); + return 0; + } + + memset(scsi3addr, 0, 8); + scsi3addr[3] = target; + if (hpsa_update_device_info(h, scsi3addr, this_device)) + return 0; + (*nmsa2xxx_enclosures)++; + hpsa_set_bus_target_lun(this_device, bus, target, 0); + set_bit(target, lunzerobits); + return 1; +} + +/* + * Do CISS_REPORT_PHYS and CISS_REPORT_LOG. Data is returned in physdev, + * logdev. The number of luns in physdev and logdev are returned in + * *nphysicals and *nlogicals, respectively. + * Returns 0 on success, -1 otherwise. + */ +static int hpsa_gather_lun_info(struct ctlr_info *h, + int reportlunsize, + struct ReportLUNdata *physdev, __u32 *nphysicals, + struct ReportLUNdata *logdev, __u32 *nlogicals) +{ + if (hpsa_scsi_do_report_phys_luns(h, physdev, reportlunsize, 0)) { + dev_err(&h->pdev->dev, "report physical LUNs failed.\n"); + return -1; + } + memcpy(nphysicals, &physdev->LUNListLength[0], sizeof(*nphysicals)); + *nphysicals = be32_to_cpu(*nphysicals) / 8; +#ifdef DEBUG + dev_info(&h->pdev->dev, "number of physical luns is %d\n", *nphysicals); +#endif + if (*nphysicals > HPSA_MAX_PHYS_LUN) { + dev_warn(&h->pdev->dev, "maximum physical LUNs (%d) exceeded." + " %d LUNs ignored.\n", HPSA_MAX_PHYS_LUN, + *nphysicals - HPSA_MAX_PHYS_LUN); + *nphysicals = HPSA_MAX_PHYS_LUN; + } + if (hpsa_scsi_do_report_log_luns(h, logdev, reportlunsize)) { + dev_err(&h->pdev->dev, "report logical LUNs failed.\n"); + return -1; + } + memcpy(nlogicals, &logdev->LUNListLength[0], sizeof(*nlogicals)); + *nlogicals = be32_to_cpu(*nlogicals) / 8; +#ifdef DEBUG + dev_info(&h->pdev->dev, "number of logical luns is %d\n", *nlogicals); +#endif + /* Reject Logicals in excess of our max capability. */ + if (*nlogicals > HPSA_MAX_LUN) { + dev_warn(&h->pdev->dev, + "maximum logical LUNs (%d) exceeded. " + "%d LUNs ignored.\n", HPSA_MAX_LUN, + *nlogicals - HPSA_MAX_LUN); + *nlogicals = HPSA_MAX_LUN; + } + if (*nlogicals + *nphysicals > HPSA_MAX_PHYS_LUN) { + dev_warn(&h->pdev->dev, + "maximum logical + physical LUNs (%d) exceeded. " + "%d LUNs ignored.\n", HPSA_MAX_PHYS_LUN, + *nphysicals + *nlogicals - HPSA_MAX_PHYS_LUN); + *nlogicals = HPSA_MAX_PHYS_LUN - *nphysicals; + } + return 0; +} + +static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) +{ + /* the idea here is we could get notified + * that some devices have changed, so we do a report + * physical luns and report logical luns cmd, and adjust + * our list of devices accordingly. + * + * The scsi3addr's of devices won't change so long as the + * adapter is not reset. That means we can rescan and + * tell which devices we already know about, vs. new + * devices, vs. disappearing devices. + */ + struct ReportLUNdata *physdev_list = NULL; + struct ReportLUNdata *logdev_list = NULL; + unsigned char *inq_buff = NULL; + __u32 nphysicals = 0; + __u32 nlogicals = 0; + __u32 ndev_allocated = 0; + struct hpsa_scsi_dev_t **currentsd, *this_device, *tmpdevice; + int ncurrent = 0; + int reportlunsize = sizeof(*physdev_list) + HPSA_MAX_PHYS_LUN * 8; + int i, nmsa2xxx_enclosures, ndevs_to_allocate; + int bus, target, lun; + DECLARE_BITMAP(lunzerobits, HPSA_MAX_TARGETS_PER_CTLR); + + currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_SCSI_DEVS_PER_HBA, + GFP_KERNEL); + physdev_list = kzalloc(reportlunsize, GFP_KERNEL); + logdev_list = kzalloc(reportlunsize, GFP_KERNEL); + inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); + tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL); + + if (!currentsd || !physdev_list || !logdev_list || + !inq_buff || !tmpdevice) { + dev_err(&h->pdev->dev, "out of memory\n"); + goto out; + } + memset(lunzerobits, 0, sizeof(lunzerobits)); + + if (hpsa_gather_lun_info(h, reportlunsize, physdev_list, &nphysicals, + logdev_list, &nlogicals)) + goto out; + + /* We might see up to 32 MSA2xxx enclosures, actually 8 of them + * but each of them 4 times through different paths. The plus 1 + * is for the RAID controller. + */ + ndevs_to_allocate = nphysicals + nlogicals + MAX_MSA2XXX_ENCLOSURES + 1; + + /* Allocate the per device structures */ + for (i = 0; i < ndevs_to_allocate; i++) { + currentsd[i] = kzalloc(sizeof(*currentsd[i]), GFP_KERNEL); + if (!currentsd[i]) { + dev_warn(&h->pdev->dev, "out of memory at %s:%d\n", + __FILE__, __LINE__); + goto out; + } + ndev_allocated++; + } + + /* adjust our table of devices */ + nmsa2xxx_enclosures = 0; + for (i = 0; i < nphysicals + nlogicals + 1; i++) { + __u8 *lunaddrbytes; + + /* Figure out where the LUN ID info is coming from */ + if (i < nphysicals) + lunaddrbytes = &physdev_list->LUN[i][0]; + else + if (i < nphysicals + nlogicals) + lunaddrbytes = + &logdev_list->LUN[i-nphysicals][0]; + else /* jam in the RAID controller at the end */ + lunaddrbytes = RAID_CTLR_LUNID; + + /* skip masked physical devices. */ + if (lunaddrbytes[3] & 0xC0 && i < nphysicals) + continue; + + /* Get device type, vendor, model, device id */ + if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice)) + continue; /* skip it if we can't talk to it. */ + figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun, + tmpdevice); + this_device = currentsd[ncurrent]; + + /* + * For the msa2xxx boxes, we have to insert a LUN 0 which + * doesn't show up in CCISS_REPORT_PHYSICAL data, but there + * is nonetheless an enclosure device there. We have to + * present that otherwise linux won't find anything if + * there is no lun 0. + */ + if (add_msa2xxx_enclosure_device(h, tmpdevice, this_device, + lunaddrbytes, bus, target, lun, lunzerobits, + &nmsa2xxx_enclosures)) { + ncurrent++; + this_device = currentsd[ncurrent]; + } + + *this_device = *tmpdevice; + hpsa_set_bus_target_lun(this_device, bus, target, lun); + + switch (this_device->devtype) { + case TYPE_ROM: { + /* We don't *really* support actual CD-ROM devices, + * just "One Button Disaster Recovery" tape drive + * which temporarily pretends to be a CD-ROM drive. + * So we check that the device is really an OBDR tape + * device by checking for "$DR-10" in bytes 43-48 of + * the inquiry data. + */ + char obdr_sig[7]; +#define OBDR_TAPE_SIG "$DR-10" + strncpy(obdr_sig, &inq_buff[43], 6); + obdr_sig[6] = '\0'; + if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0) + /* Not OBDR device, ignore it. */ + break; + } + ncurrent++; + break; + case TYPE_DISK: + if (i < nphysicals) + break; + ncurrent++; + break; + case TYPE_TAPE: + case TYPE_MEDIUM_CHANGER: + ncurrent++; + break; + case TYPE_RAID: + /* Only present the Smartarray HBA as a RAID controller. + * If it's a RAID controller other than the HBA itself + * (an external RAID controller, MSA500 or similar) + * don't present it. + */ + if (!is_hba_lunid(lunaddrbytes)) + break; + ncurrent++; + break; + default: + break; + } + if (ncurrent >= HPSA_MAX_SCSI_DEVS_PER_HBA) + break; + } + adjust_hpsa_scsi_table(h, hostno, currentsd, ncurrent); +out: + kfree(tmpdevice); + for (i = 0; i < ndev_allocated; i++) + kfree(currentsd[i]); + kfree(currentsd); + kfree(inq_buff); + kfree(physdev_list); + kfree(logdev_list); + return; +} + +/* hpsa_scatter_gather takes a struct scsi_cmnd, (cmd), and does the pci + * dma mapping and fills in the scatter gather entries of the + * hpsa command, cp. + */ +static int hpsa_scatter_gather(struct pci_dev *pdev, + struct CommandList *cp, + struct scsi_cmnd *cmd) +{ + unsigned int len; + struct scatterlist *sg; + __u64 addr64; + int use_sg, i; + + BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES); + + use_sg = scsi_dma_map(cmd); + if (use_sg < 0) + return use_sg; + + if (!use_sg) + goto sglist_finished; + + scsi_for_each_sg(cmd, sg, use_sg, i) { + addr64 = (__u64) sg_dma_address(sg); + len = sg_dma_len(sg); + cp->SG[i].Addr.lower = + (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF); + cp->SG[i].Addr.upper = + (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF); + cp->SG[i].Len = len; + cp->SG[i].Ext = 0; /* we are not chaining */ + } + +sglist_finished: + + cp->Header.SGList = (__u8) use_sg; /* no. SGs contig in this cmd */ + cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */ + return 0; +} + + +static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd, + void (*done)(struct scsi_cmnd *)) +{ + struct ctlr_info *h; + struct hpsa_scsi_dev_t *dev; + unsigned char scsi3addr[8]; + struct CommandList *c; + unsigned long flags; + + /* Get the ptr to our adapter structure out of cmd->host. */ + h = sdev_to_hba(cmd->device); + dev = cmd->device->hostdata; + if (!dev) { + cmd->result = DID_NO_CONNECT << 16; + done(cmd); + return 0; + } + memcpy(scsi3addr, dev->scsi3addr, sizeof(scsi3addr)); + + /* Need a lock as this is being allocated from the pool */ + spin_lock_irqsave(&h->lock, flags); + c = cmd_alloc(h); + spin_unlock_irqrestore(&h->lock, flags); + if (c == NULL) { /* trouble... */ + dev_err(&h->pdev->dev, "cmd_alloc returned NULL!\n"); + return SCSI_MLQUEUE_HOST_BUSY; + } + + /* Fill in the command list header */ + + cmd->scsi_done = done; /* save this for use by completion code */ + + /* save c in case we have to abort it */ + cmd->host_scribble = (unsigned char *) c; + + c->cmd_type = CMD_SCSI; + c->scsi_cmd = cmd; + c->Header.ReplyQueue = 0; /* unused in simple mode */ + memcpy(&c->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8); + c->Header.Tag.lower = c->busaddr; /* Use k. address of cmd as tag */ + + /* Fill in the request block... */ + + c->Request.Timeout = 0; + memset(c->Request.CDB, 0, sizeof(c->Request.CDB)); + BUG_ON(cmd->cmd_len > sizeof(c->Request.CDB)); + c->Request.CDBLen = cmd->cmd_len; + memcpy(c->Request.CDB, cmd->cmnd, cmd->cmd_len); + c->Request.Type.Type = TYPE_CMD; + c->Request.Type.Attribute = ATTR_SIMPLE; + switch (cmd->sc_data_direction) { + case DMA_TO_DEVICE: + c->Request.Type.Direction = XFER_WRITE; + break; + case DMA_FROM_DEVICE: + c->Request.Type.Direction = XFER_READ; + break; + case DMA_NONE: + c->Request.Type.Direction = XFER_NONE; + break; + case DMA_BIDIRECTIONAL: + /* This can happen if a buggy application does a scsi passthru + * and sets both inlen and outlen to non-zero. ( see + * ../scsi/scsi_ioctl.c:scsi_ioctl_send_command() ) + */ + + c->Request.Type.Direction = XFER_RSVD; + /* This is technically wrong, and hpsa controllers should + * reject it with CMD_INVALID, which is the most correct + * response, but non-fibre backends appear to let it + * slide by, and give the same results as if this field + * were set correctly. Either way is acceptable for + * our purposes here. + */ + + break; + + default: + dev_err(&h->pdev->dev, "unknown data direction: %d\n", + cmd->sc_data_direction); + BUG(); + break; + } + + if (hpsa_scatter_gather(h->pdev, c, cmd) < 0) { /* Fill SG list */ + cmd_free(h, c); + return SCSI_MLQUEUE_HOST_BUSY; + } + enqueue_cmd_and_start_io(h, c); + /* the cmd'll come back via intr handler in complete_scsi_command() */ + return 0; +} + +static void hpsa_unregister_scsi(struct ctlr_info *h) +{ + /* we are being forcibly unloaded, and may not refuse. */ + scsi_remove_host(h->scsi_host); + scsi_host_put(h->scsi_host); + h->scsi_host = NULL; +} + +static int hpsa_register_scsi(struct ctlr_info *h) +{ + int rc; + + hpsa_update_scsi_devices(h, -1); + rc = hpsa_scsi_detect(h); + if (rc != 0) + dev_err(&h->pdev->dev, "hpsa_register_scsi: failed" + " hpsa_scsi_detect(), rc is %d\n", rc); + return rc; +} + +static int wait_for_device_to_become_ready(struct ctlr_info *h, + unsigned char lunaddr[]) +{ + int rc = 0; + int count = 0; + int waittime = 1; /* seconds */ + struct CommandList *c; + + c = cmd_special_alloc(h); + if (!c) { + dev_warn(&h->pdev->dev, "out of memory in " + "wait_for_device_to_become_ready.\n"); + return IO_ERROR; + } + + /* Send test unit ready until device ready, or give up. */ + while (count < HPSA_TUR_RETRY_LIMIT) { + + /* Wait for a bit. do this first, because if we send + * the TUR right away, the reset will just abort it. + */ + msleep(1000 * waittime); + count++; + + /* Increase wait time with each try, up to a point. */ + if (waittime < HPSA_MAX_WAIT_INTERVAL_SECS) + waittime = waittime * 2; + + /* Send the Test Unit Ready */ + fill_cmd(c, TEST_UNIT_READY, h, NULL, 0, 0, lunaddr, TYPE_CMD); + hpsa_scsi_do_simple_cmd_core(h, c); + /* no unmap needed here because no data xfer. */ + + if (c->err_info->CommandStatus == CMD_SUCCESS) + break; + + if (c->err_info->CommandStatus == CMD_TARGET_STATUS && + c->err_info->ScsiStatus == SAM_STAT_CHECK_CONDITION && + (c->err_info->SenseInfo[2] == NO_SENSE || + c->err_info->SenseInfo[2] == UNIT_ATTENTION)) + break; + + dev_warn(&h->pdev->dev, "waiting %d secs " + "for device to become ready.\n", waittime); + rc = 1; /* device not ready. */ + } + + if (rc) + dev_warn(&h->pdev->dev, "giving up on device.\n"); + else + dev_warn(&h->pdev->dev, "device is ready.\n"); + + cmd_special_free(h, c); + return rc; +} + +/* Need at least one of these error handlers to keep ../scsi/hosts.c from + * complaining. Doing a host- or bus-reset can't do anything good here. + */ +static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd) +{ + int rc; + struct ctlr_info *h; + struct hpsa_scsi_dev_t *dev; + + /* find the controller to which the command to be aborted was sent */ + h = sdev_to_hba(scsicmd->device); + if (h == NULL) /* paranoia */ + return FAILED; + dev_warn(&h->pdev->dev, "resetting drive\n"); + + dev = scsicmd->device->hostdata; + if (!dev) { + dev_err(&h->pdev->dev, "hpsa_eh_device_reset_handler: " + "device lookup failed.\n"); + return FAILED; + } + /* send a reset to the SCSI LUN which the command was sent to */ + rc = hpsa_send_reset(h, dev->scsi3addr); + if (rc == 0 && wait_for_device_to_become_ready(h, dev->scsi3addr) == 0) + return SUCCESS; + + dev_warn(&h->pdev->dev, "resetting device failed.\n"); + return FAILED; +} + +/* + * For operations that cannot sleep, a command block is allocated at init, + * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track + * which ones are free or in use. Lock must be held when calling this. + * cmd_free() is the complement. + */ +static struct CommandList *cmd_alloc(struct ctlr_info *h) +{ + struct CommandList *c; + int i; + union u64bit temp64; + dma_addr_t cmd_dma_handle, err_dma_handle; + + do { + i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds); + if (i == h->nr_cmds) + return NULL; + } while (test_and_set_bit + (i & (BITS_PER_LONG - 1), + h->cmd_pool_bits + (i / BITS_PER_LONG)) != 0); + c = h->cmd_pool + i; + memset(c, 0, sizeof(*c)); + cmd_dma_handle = h->cmd_pool_dhandle + + i * sizeof(*c); + c->err_info = h->errinfo_pool + i; + memset(c->err_info, 0, sizeof(*c->err_info)); + err_dma_handle = h->errinfo_pool_dhandle + + i * sizeof(*c->err_info); + h->nr_allocs++; + + c->cmdindex = i; + + INIT_HLIST_NODE(&c->list); + c->busaddr = (__u32) cmd_dma_handle; + temp64.val = (__u64) err_dma_handle; + c->ErrDesc.Addr.lower = temp64.val32.lower; + c->ErrDesc.Addr.upper = temp64.val32.upper; + c->ErrDesc.Len = sizeof(*c->err_info); + + c->h = h; + return c; +} + +/* For operations that can wait for kmalloc to possibly sleep, + * this routine can be called. Lock need not be held to call + * cmd_special_alloc. cmd_special_free() is the complement. + */ +static struct CommandList *cmd_special_alloc(struct ctlr_info *h) +{ + struct CommandList *c; + union u64bit temp64; + dma_addr_t cmd_dma_handle, err_dma_handle; + + c = pci_alloc_consistent(h->pdev, sizeof(*c), &cmd_dma_handle); + if (c == NULL) + return NULL; + memset(c, 0, sizeof(*c)); + + c->cmdindex = -1; + + c->err_info = pci_alloc_consistent(h->pdev, sizeof(*c->err_info), + &err_dma_handle); + + if (c->err_info == NULL) { + pci_free_consistent(h->pdev, + sizeof(*c), c, cmd_dma_handle); + return NULL; + } + memset(c->err_info, 0, sizeof(*c->err_info)); + + INIT_HLIST_NODE(&c->list); + c->busaddr = (__u32) cmd_dma_handle; + temp64.val = (__u64) err_dma_handle; + c->ErrDesc.Addr.lower = temp64.val32.lower; + c->ErrDesc.Addr.upper = temp64.val32.upper; + c->ErrDesc.Len = sizeof(*c->err_info); + + c->h = h; + return c; +} + +static void cmd_free(struct ctlr_info *h, struct CommandList *c) +{ + int i; + + i = c - h->cmd_pool; + clear_bit(i & (BITS_PER_LONG - 1), + h->cmd_pool_bits + (i / BITS_PER_LONG)); + h->nr_frees++; +} + +static void cmd_special_free(struct ctlr_info *h, struct CommandList *c) +{ + union u64bit temp64; + + temp64.val32.lower = c->ErrDesc.Addr.lower; + temp64.val32.upper = c->ErrDesc.Addr.upper; + pci_free_consistent(h->pdev, sizeof(*c->err_info), + c->err_info, (dma_addr_t) temp64.val); + pci_free_consistent(h->pdev, sizeof(*c), + c, (dma_addr_t) c->busaddr); +} + +#ifdef CONFIG_COMPAT + +static int do_ioctl(struct scsi_device *dev, int cmd, void *arg) +{ + int ret; + + lock_kernel(); + ret = hpsa_ioctl(dev, cmd, arg); + unlock_kernel(); + return ret; +} + +static int hpsa_ioctl32_passthru(struct scsi_device *dev, int cmd, void *arg); +static int hpsa_ioctl32_big_passthru(struct scsi_device *dev, + int cmd, void *arg); + +static int hpsa_compat_ioctl(struct scsi_device *dev, int cmd, void *arg) +{ + switch (cmd) { + case CCISS_GETPCIINFO: + case CCISS_GETINTINFO: + case CCISS_SETINTINFO: + case CCISS_GETNODENAME: + case CCISS_SETNODENAME: + case CCISS_GETHEARTBEAT: + case CCISS_GETBUSTYPES: + case CCISS_GETFIRMVER: + case CCISS_GETDRIVVER: + case CCISS_REVALIDVOLS: + case CCISS_DEREGDISK: + case CCISS_REGNEWDISK: + case CCISS_REGNEWD: + case CCISS_RESCANDISK: + case CCISS_GETLUNINFO: + return do_ioctl(dev, cmd, arg); + + case CCISS_PASSTHRU32: + return hpsa_ioctl32_passthru(dev, cmd, arg); + case CCISS_BIG_PASSTHRU32: + return hpsa_ioctl32_big_passthru(dev, cmd, arg); + + default: + return -ENOIOCTLCMD; + } +} + +static int hpsa_ioctl32_passthru(struct scsi_device *dev, int cmd, void *arg) +{ + IOCTL32_Command_struct __user *arg32 = + (IOCTL32_Command_struct __user *) arg; + IOCTL_Command_struct arg64; + IOCTL_Command_struct __user *p = compat_alloc_user_space(sizeof(arg64)); + int err; + u32 cp; + + err = 0; + err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info, + sizeof(arg64.LUN_info)); + err |= copy_from_user(&arg64.Request, &arg32->Request, + sizeof(arg64.Request)); + err |= copy_from_user(&arg64.error_info, &arg32->error_info, + sizeof(arg64.error_info)); + err |= get_user(arg64.buf_size, &arg32->buf_size); + err |= get_user(cp, &arg32->buf); + arg64.buf = compat_ptr(cp); + err |= copy_to_user(p, &arg64, sizeof(arg64)); + + if (err) + return -EFAULT; + + err = do_ioctl(dev, CCISS_PASSTHRU, (void *)p); + if (err) + return err; + err |= copy_in_user(&arg32->error_info, &p->error_info, + sizeof(arg32->error_info)); + if (err) + return -EFAULT; + return err; +} + +static int hpsa_ioctl32_big_passthru(struct scsi_device *dev, + int cmd, void *arg) +{ + BIG_IOCTL32_Command_struct __user *arg32 = + (BIG_IOCTL32_Command_struct __user *) arg; + BIG_IOCTL_Command_struct arg64; + BIG_IOCTL_Command_struct __user *p = + compat_alloc_user_space(sizeof(arg64)); + int err; + u32 cp; + + err = 0; + err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info, + sizeof(arg64.LUN_info)); + err |= copy_from_user(&arg64.Request, &arg32->Request, + sizeof(arg64.Request)); + err |= copy_from_user(&arg64.error_info, &arg32->error_info, + sizeof(arg64.error_info)); + err |= get_user(arg64.buf_size, &arg32->buf_size); + err |= get_user(arg64.malloc_size, &arg32->malloc_size); + err |= get_user(cp, &arg32->buf); + arg64.buf = compat_ptr(cp); + err |= copy_to_user(p, &arg64, sizeof(arg64)); + + if (err) + return -EFAULT; + + err = do_ioctl(dev, CCISS_BIG_PASSTHRU, (void *)p); + if (err) + return err; + err |= copy_in_user(&arg32->error_info, &p->error_info, + sizeof(arg32->error_info)); + if (err) + return -EFAULT; + return err; +} +#endif + +static int hpsa_getpciinfo_ioctl(struct ctlr_info *h, void __user *argp) +{ + struct hpsa_pci_info pciinfo; + + if (!argp) + return -EINVAL; + pciinfo.domain = pci_domain_nr(h->pdev->bus); + pciinfo.bus = h->pdev->bus->number; + pciinfo.dev_fn = h->pdev->devfn; + pciinfo.board_id = h->board_id; + if (copy_to_user(argp, &pciinfo, sizeof(pciinfo))) + return -EFAULT; + return 0; +} + +static int hpsa_getdrivver_ioctl(struct ctlr_info *h, void __user *argp) +{ + DriverVer_type DriverVer; + unsigned char vmaj, vmin, vsubmin; + int rc; + + rc = sscanf(HPSA_DRIVER_VERSION, "%hhu.%hhu.%hhu", + &vmaj, &vmin, &vsubmin); + if (rc != 3) { + dev_info(&h->pdev->dev, "driver version string '%s' " + "unrecognized.", HPSA_DRIVER_VERSION); + vmaj = 0; + vmin = 0; + vsubmin = 0; + } + DriverVer = (vmaj << 16) | (vmin << 8) | vsubmin; + if (!argp) + return -EINVAL; + if (copy_to_user(argp, &DriverVer, sizeof(DriverVer_type))) + return -EFAULT; + return 0; +} + +static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp) +{ + IOCTL_Command_struct iocommand; + struct CommandList *c; + char *buff = NULL; + union u64bit temp64; + + if (!argp) + return -EINVAL; + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + if (copy_from_user(&iocommand, argp, sizeof(iocommand))) + return -EFAULT; + if ((iocommand.buf_size < 1) && + (iocommand.Request.Type.Direction != XFER_NONE)) { + return -EINVAL; + } + if (iocommand.buf_size > 0) { + buff = kmalloc(iocommand.buf_size, GFP_KERNEL); + if (buff == NULL) + return -EFAULT; + } + if (iocommand.Request.Type.Direction == XFER_WRITE) { + /* Copy the data into the buffer we created */ + if (copy_from_user(buff, iocommand.buf, iocommand.buf_size)) { + kfree(buff); + return -EFAULT; + } + } else + memset(buff, 0, iocommand.buf_size); + c = cmd_special_alloc(h); + if (c == NULL) { + kfree(buff); + return -ENOMEM; + } + /* Fill in the command type */ + c->cmd_type = CMD_IOCTL_PEND; + /* Fill in Command Header */ + c->Header.ReplyQueue = 0; /* unused in simple mode */ + if (iocommand.buf_size > 0) { /* buffer to fill */ + c->Header.SGList = 1; + c->Header.SGTotal = 1; + } else { /* no buffers to fill */ + c->Header.SGList = 0; + c->Header.SGTotal = 0; + } + memcpy(&c->Header.LUN, &iocommand.LUN_info, sizeof(c->Header.LUN)); + /* use the kernel address the cmd block for tag */ + c->Header.Tag.lower = c->busaddr; + + /* Fill in Request block */ + memcpy(&c->Request, &iocommand.Request, + sizeof(c->Request)); + + /* Fill in the scatter gather information */ + if (iocommand.buf_size > 0) { + temp64.val = pci_map_single(h->pdev, buff, + iocommand.buf_size, PCI_DMA_BIDIRECTIONAL); + c->SG[0].Addr.lower = temp64.val32.lower; + c->SG[0].Addr.upper = temp64.val32.upper; + c->SG[0].Len = iocommand.buf_size; + c->SG[0].Ext = 0; /* we are not chaining*/ + } + hpsa_scsi_do_simple_cmd_core(h, c); + hpsa_pci_unmap(h->pdev, c, 1, PCI_DMA_BIDIRECTIONAL); + check_ioctl_unit_attention(h, c); + + /* Copy the error information out */ + memcpy(&iocommand.error_info, c->err_info, + sizeof(iocommand.error_info)); + if (copy_to_user(argp, &iocommand, sizeof(iocommand))) { + kfree(buff); + cmd_special_free(h, c); + return -EFAULT; + } + + if (iocommand.Request.Type.Direction == XFER_READ) { + /* Copy the data out of the buffer we created */ + if (copy_to_user(iocommand.buf, buff, iocommand.buf_size)) { + kfree(buff); + cmd_special_free(h, c); + return -EFAULT; + } + } + kfree(buff); + cmd_special_free(h, c); + return 0; +} + +static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp) +{ + BIG_IOCTL_Command_struct *ioc; + struct CommandList *c; + unsigned char **buff = NULL; + int *buff_size = NULL; + union u64bit temp64; + BYTE sg_used = 0; + int status = 0; + int i; + __u32 left; + __u32 sz; + BYTE __user *data_ptr; + + if (!argp) + return -EINVAL; + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + ioc = (BIG_IOCTL_Command_struct *) + kmalloc(sizeof(*ioc), GFP_KERNEL); + if (!ioc) { + status = -ENOMEM; + goto cleanup1; + } + if (copy_from_user(ioc, argp, sizeof(*ioc))) { + status = -EFAULT; + goto cleanup1; + } + if ((ioc->buf_size < 1) && + (ioc->Request.Type.Direction != XFER_NONE)) { + status = -EINVAL; + goto cleanup1; + } + /* Check kmalloc limits using all SGs */ + if (ioc->malloc_size > MAX_KMALLOC_SIZE) { + status = -EINVAL; + goto cleanup1; + } + if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES) { + status = -EINVAL; + goto cleanup1; + } + buff = kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL); + if (!buff) { + status = -ENOMEM; + goto cleanup1; + } + buff_size = kmalloc(MAXSGENTRIES * sizeof(int), GFP_KERNEL); + if (!buff_size) { + status = -ENOMEM; + goto cleanup1; + } + left = ioc->buf_size; + data_ptr = ioc->buf; + while (left) { + sz = (left > ioc->malloc_size) ? ioc->malloc_size : left; + buff_size[sg_used] = sz; + buff[sg_used] = kmalloc(sz, GFP_KERNEL); + if (buff[sg_used] == NULL) { + status = -ENOMEM; + goto cleanup1; + } + if (ioc->Request.Type.Direction == XFER_WRITE) { + if (copy_from_user(buff[sg_used], data_ptr, sz)) { + status = -ENOMEM; + goto cleanup1; + } + } else + memset(buff[sg_used], 0, sz); + left -= sz; + data_ptr += sz; + sg_used++; + } + c = cmd_special_alloc(h); + if (c == NULL) { + status = -ENOMEM; + goto cleanup1; + } + c->cmd_type = CMD_IOCTL_PEND; + c->Header.ReplyQueue = 0; + + if (ioc->buf_size > 0) { + c->Header.SGList = sg_used; + c->Header.SGTotal = sg_used; + } else { + c->Header.SGList = 0; + c->Header.SGTotal = 0; + } + memcpy(&c->Header.LUN, &ioc->LUN_info, sizeof(c->Header.LUN)); + c->Header.Tag.lower = c->busaddr; + memcpy(&c->Request, &ioc->Request, sizeof(c->Request)); + if (ioc->buf_size > 0) { + int i; + for (i = 0; i < sg_used; i++) { + temp64.val = pci_map_single(h->pdev, buff[i], + buff_size[i], PCI_DMA_BIDIRECTIONAL); + c->SG[i].Addr.lower = temp64.val32.lower; + c->SG[i].Addr.upper = temp64.val32.upper; + c->SG[i].Len = buff_size[i]; + /* we are not chaining */ + c->SG[i].Ext = 0; + } + } + hpsa_scsi_do_simple_cmd_core(h, c); + hpsa_pci_unmap(h->pdev, c, sg_used, PCI_DMA_BIDIRECTIONAL); + check_ioctl_unit_attention(h, c); + /* Copy the error information out */ + memcpy(&ioc->error_info, c->err_info, sizeof(ioc->error_info)); + if (copy_to_user(argp, ioc, sizeof(*ioc))) { + cmd_special_free(h, c); + status = -EFAULT; + goto cleanup1; + } + if (ioc->Request.Type.Direction == XFER_READ) { + /* Copy the data out of the buffer we created */ + BYTE __user *ptr = ioc->buf; + for (i = 0; i < sg_used; i++) { + if (copy_to_user(ptr, buff[i], buff_size[i])) { + cmd_special_free(h, c); + status = -EFAULT; + goto cleanup1; + } + ptr += buff_size[i]; + } + } + cmd_special_free(h, c); + status = 0; +cleanup1: + if (buff) { + for (i = 0; i < sg_used; i++) + kfree(buff[i]); + kfree(buff); + } + kfree(buff_size); + kfree(ioc); + return status; +} + +static void check_ioctl_unit_attention(struct ctlr_info *h, + struct CommandList *c) +{ + if (c->err_info->CommandStatus == CMD_TARGET_STATUS && + c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION) + (void) check_for_unit_attention(h, c); +} +/* + * ioctl + */ +static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg) +{ + struct ctlr_info *h; + void __user *argp = (void __user *)arg; + + h = sdev_to_hba(dev); + + switch (cmd) { + case CCISS_DEREGDISK: + case CCISS_REGNEWDISK: + case CCISS_REGNEWD: + hpsa_update_scsi_devices(h, dev->host->host_no); + return 0; + case CCISS_GETPCIINFO: + return hpsa_getpciinfo_ioctl(h, argp); + case CCISS_GETDRIVVER: + return hpsa_getdrivver_ioctl(h, argp); + case CCISS_PASSTHRU: + return hpsa_passthru_ioctl(h, argp); + case CCISS_BIG_PASSTHRU: + return hpsa_big_passthru_ioctl(h, argp); + default: + return -ENOTTY; + } +} + +static void fill_cmd(struct CommandList *c, __u8 cmd, struct ctlr_info *h, + void *buff, size_t size, __u8 page_code, unsigned char *scsi3addr, + int cmd_type) +{ + int pci_dir = XFER_NONE; + + c->cmd_type = CMD_IOCTL_PEND; + c->Header.ReplyQueue = 0; + if (buff != NULL && size > 0) { + c->Header.SGList = 1; + c->Header.SGTotal = 1; + } else { + c->Header.SGList = 0; + c->Header.SGTotal = 0; + } + c->Header.Tag.lower = c->busaddr; + memcpy(c->Header.LUN.LunAddrBytes, scsi3addr, 8); + + c->Request.Type.Type = cmd_type; + if (cmd_type == TYPE_CMD) { + switch (cmd) { + case HPSA_INQUIRY: + /* are we trying to read a vital product page */ + if (page_code != 0) { + c->Request.CDB[1] = 0x01; + c->Request.CDB[2] = page_code; + } + c->Request.CDBLen = 6; + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = XFER_READ; + c->Request.Timeout = 0; + c->Request.CDB[0] = HPSA_INQUIRY; + c->Request.CDB[4] = size & 0xFF; + break; + case HPSA_REPORT_LOG: + case HPSA_REPORT_PHYS: + /* Talking to controller so It's a physical command + mode = 00 target = 0. Nothing to write. + */ + c->Request.CDBLen = 12; + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = XFER_READ; + c->Request.Timeout = 0; + c->Request.CDB[0] = cmd; + c->Request.CDB[6] = (size >> 24) & 0xFF; /* MSB */ + c->Request.CDB[7] = (size >> 16) & 0xFF; + c->Request.CDB[8] = (size >> 8) & 0xFF; + c->Request.CDB[9] = size & 0xFF; + break; + + case HPSA_READ_CAPACITY: + c->Request.CDBLen = 10; + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = XFER_READ; + c->Request.Timeout = 0; + c->Request.CDB[0] = cmd; + break; + case HPSA_CACHE_FLUSH: + c->Request.CDBLen = 12; + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = XFER_WRITE; + c->Request.Timeout = 0; + c->Request.CDB[0] = BMIC_WRITE; + c->Request.CDB[6] = BMIC_CACHE_FLUSH; + break; + case TEST_UNIT_READY: + c->Request.CDBLen = 6; + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = XFER_NONE; + c->Request.Timeout = 0; + break; + default: + dev_warn(&h->pdev->dev, "unknown command 0x%c\n", cmd); + BUG(); + return; + } + } else if (cmd_type == TYPE_MSG) { + switch (cmd) { + + case HPSA_DEVICE_RESET_MSG: + c->Request.CDBLen = 16; + c->Request.Type.Type = 1; /* It is a MSG not a CMD */ + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = XFER_NONE; + c->Request.Timeout = 0; /* Don't time out */ + c->Request.CDB[0] = 0x01; /* RESET_MSG is 0x01 */ + c->Request.CDB[1] = 0x03; /* Reset target above */ + /* If bytes 4-7 are zero, it means reset the */ + /* LunID device */ + c->Request.CDB[4] = 0x00; + c->Request.CDB[5] = 0x00; + c->Request.CDB[6] = 0x00; + c->Request.CDB[7] = 0x00; + break; + + default: + dev_warn(&h->pdev->dev, "unknown message type %d\n", + cmd); + BUG(); + } + } else { + dev_warn(&h->pdev->dev, "unknown command type %d\n", cmd_type); + BUG(); + } + + switch (c->Request.Type.Direction) { + case XFER_READ: + pci_dir = PCI_DMA_FROMDEVICE; + break; + case XFER_WRITE: + pci_dir = PCI_DMA_TODEVICE; + break; + case XFER_NONE: + pci_dir = PCI_DMA_NONE; + break; + default: + pci_dir = PCI_DMA_BIDIRECTIONAL; + } + + hpsa_map_one(h->pdev, c, buff, size, pci_dir); + + return; +} + +/* + * Map (physical) PCI mem into (virtual) kernel space + */ +static void __iomem *remap_pci_mem(ulong base, ulong size) +{ + ulong page_base = ((ulong) base) & PAGE_MASK; + ulong page_offs = ((ulong) base) - page_base; + void __iomem *page_remapped = ioremap(page_base, page_offs + size); + + return page_remapped ? (page_remapped + page_offs) : NULL; +} + +/* Takes cmds off the submission queue and sends them to the hardware, + * then puts them on the queue of cmds waiting for completion. + */ +static void start_io(struct ctlr_info *h) +{ + struct CommandList *c; + + while (!hlist_empty(&h->reqQ)) { + c = hlist_entry(h->reqQ.first, struct CommandList, list); + /* can't do anything if fifo is full */ + if ((h->access.fifo_full(h))) { + dev_warn(&h->pdev->dev, "fifo full\n"); + break; + } + + /* Get the first entry from the Request Q */ + removeQ(c); + h->Qdepth--; + + /* Tell the controller execute command */ + h->access.submit_command(h, c); + + /* Put job onto the completed Q */ + addQ(&h->cmpQ, c); + } +} + +static inline unsigned long get_next_completion(struct ctlr_info *h) +{ + return h->access.command_completed(h); +} + +static inline int interrupt_pending(struct ctlr_info *h) +{ + return h->access.intr_pending(h); +} + +static inline long interrupt_not_for_us(struct ctlr_info *h) +{ + return ((h->access.intr_pending(h) == 0) || + (h->interrupts_enabled == 0)); +} + +static inline int bad_tag(struct ctlr_info *h, __u32 tag_index, + __u32 raw_tag) +{ + if (unlikely(tag_index >= h->nr_cmds)) { + dev_warn(&h->pdev->dev, "bad tag 0x%08x ignored.\n", raw_tag); + return 1; + } + return 0; +} + +static inline void finish_cmd(struct CommandList *c, __u32 raw_tag) +{ + removeQ(c); + if (likely(c->cmd_type == CMD_SCSI)) + complete_scsi_command(c, 0, raw_tag); + else if (c->cmd_type == CMD_IOCTL_PEND) + complete(c->waiting); +} + +static irqreturn_t do_hpsa_intr(int irq, void *dev_id) +{ + struct ctlr_info *h = dev_id; + struct CommandList *c; + unsigned long flags; + __u32 raw_tag, tag, tag_index; + struct hlist_node *tmp; + + if (interrupt_not_for_us(h)) + return IRQ_NONE; + spin_lock_irqsave(&h->lock, flags); + while (interrupt_pending(h)) { + while ((raw_tag = get_next_completion(h)) != FIFO_EMPTY) { + if (likely(HPSA_TAG_CONTAINS_INDEX(raw_tag))) { + tag_index = HPSA_TAG_TO_INDEX(raw_tag); + if (bad_tag(h, tag_index, raw_tag)) + return IRQ_HANDLED; + c = h->cmd_pool + tag_index; + finish_cmd(c, raw_tag); + continue; + } + tag = HPSA_TAG_DISCARD_ERROR_BITS(raw_tag); + c = NULL; + hlist_for_each_entry(c, tmp, &h->cmpQ, list) { + if (c->busaddr == tag) { + finish_cmd(c, raw_tag); + break; + } + } + } + } + spin_unlock_irqrestore(&h->lock, flags); + return IRQ_HANDLED; +} + +/* Send a message CDB to the firmware. */ +static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode, + unsigned char type) +{ + struct Command { + struct CommandListHeader CommandHeader; + struct RequestBlock Request; + struct ErrDescriptor ErrorDescriptor; + }; + struct Command *cmd; + static const size_t cmd_sz = sizeof(*cmd) + + sizeof(cmd->ErrorDescriptor); + dma_addr_t paddr64; + uint32_t paddr32, tag; + void __iomem *vaddr; + int i, err; + + vaddr = pci_ioremap_bar(pdev, 0); + if (vaddr == NULL) + return -ENOMEM; + + /* The Inbound Post Queue only accepts 32-bit physical addresses for the + * CCISS commands, so they must be allocated from the lower 4GiB of + * memory. + */ + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + if (err) { + iounmap(vaddr); + return -ENOMEM; + } + + cmd = pci_alloc_consistent(pdev, cmd_sz, &paddr64); + if (cmd == NULL) { + iounmap(vaddr); + return -ENOMEM; + } + + /* This must fit, because of the 32-bit consistent DMA mask. Also, + * although there's no guarantee, we assume that the address is at + * least 4-byte aligned (most likely, it's page-aligned). + */ + paddr32 = paddr64; + + cmd->CommandHeader.ReplyQueue = 0; + cmd->CommandHeader.SGList = 0; + cmd->CommandHeader.SGTotal = 0; + cmd->CommandHeader.Tag.lower = paddr32; + cmd->CommandHeader.Tag.upper = 0; + memset(&cmd->CommandHeader.LUN.LunAddrBytes, 0, 8); + + cmd->Request.CDBLen = 16; + cmd->Request.Type.Type = TYPE_MSG; + cmd->Request.Type.Attribute = ATTR_HEADOFQUEUE; + cmd->Request.Type.Direction = XFER_NONE; + cmd->Request.Timeout = 0; /* Don't time out */ + cmd->Request.CDB[0] = opcode; + cmd->Request.CDB[1] = type; + memset(&cmd->Request.CDB[2], 0, 14); /* rest of the CDB is reserved */ + cmd->ErrorDescriptor.Addr.lower = paddr32 + sizeof(*cmd); + cmd->ErrorDescriptor.Addr.upper = 0; + cmd->ErrorDescriptor.Len = sizeof(struct ErrorInfo); + + writel(paddr32, vaddr + SA5_REQUEST_PORT_OFFSET); + + for (i = 0; i < HPSA_MSG_SEND_RETRY_LIMIT; i++) { + tag = readl(vaddr + SA5_REPLY_PORT_OFFSET); + if (HPSA_TAG_DISCARD_ERROR_BITS(tag) == paddr32) + break; + msleep(HPSA_MSG_SEND_RETRY_INTERVAL_MSECS); + } + + iounmap(vaddr); + + /* we leak the DMA buffer here ... no choice since the controller could + * still complete the command. + */ + if (i == HPSA_MSG_SEND_RETRY_LIMIT) { + dev_err(&pdev->dev, "controller message %02x:%02x timed out\n", + opcode, type); + return -ETIMEDOUT; + } + + pci_free_consistent(pdev, cmd_sz, cmd, paddr64); + + if (tag & HPSA_ERROR_BIT) { + dev_err(&pdev->dev, "controller message %02x:%02x failed\n", + opcode, type); + return -EIO; + } + + dev_info(&pdev->dev, "controller message %02x:%02x succeeded\n", + opcode, type); + return 0; +} + +#define hpsa_soft_reset_controller(p) hpsa_message(p, 1, 0) +#define hpsa_noop(p) hpsa_message(p, 3, 0) + +static __devinit int hpsa_reset_msi(struct pci_dev *pdev) +{ +/* the #defines are stolen from drivers/pci/msi.h. */ +#define msi_control_reg(base) (base + PCI_MSI_FLAGS) +#define PCI_MSIX_FLAGS_ENABLE (1 << 15) + + int pos; + u16 control = 0; + + pos = pci_find_capability(pdev, PCI_CAP_ID_MSI); + if (pos) { + pci_read_config_word(pdev, msi_control_reg(pos), &control); + if (control & PCI_MSI_FLAGS_ENABLE) { + dev_info(&pdev->dev, "resetting MSI\n"); + pci_write_config_word(pdev, msi_control_reg(pos), + control & ~PCI_MSI_FLAGS_ENABLE); + } + } + + pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); + if (pos) { + pci_read_config_word(pdev, msi_control_reg(pos), &control); + if (control & PCI_MSIX_FLAGS_ENABLE) { + dev_info(&pdev->dev, "resetting MSI-X\n"); + pci_write_config_word(pdev, msi_control_reg(pos), + control & ~PCI_MSIX_FLAGS_ENABLE); + } + } + + return 0; +} + +/* This does a hard reset of the controller using PCI power management + * states. + */ +static __devinit int hpsa_hard_reset_controller(struct pci_dev *pdev) +{ + u16 pmcsr, saved_config_space[32]; + int i, pos; + + dev_info(&pdev->dev, "using PCI PM to reset controller\n"); + + /* This is very nearly the same thing as + * + * pci_save_state(pci_dev); + * pci_set_power_state(pci_dev, PCI_D3hot); + * pci_set_power_state(pci_dev, PCI_D0); + * pci_restore_state(pci_dev); + * + * but we can't use these nice canned kernel routines on + * kexec, because they also check the MSI/MSI-X state in PCI + * configuration space and do the wrong thing when it is + * set/cleared. Also, the pci_save/restore_state functions + * violate the ordering requirements for restoring the + * configuration space from the CCISS document (see the + * comment below). So we roll our own .... + */ + + for (i = 0; i < 32; i++) + pci_read_config_word(pdev, 2*i, &saved_config_space[i]); + + pos = pci_find_capability(pdev, PCI_CAP_ID_PM); + if (pos == 0) { + dev_err(&pdev->dev, + "hpsa_reset_controller: PCI PM not supported\n"); + return -ENODEV; + } + + /* Quoting from the Open CISS Specification: "The Power + * Management Control/Status Register (CSR) controls the power + * state of the device. The normal operating state is D0, + * CSR=00h. The software off state is D3, CSR=03h. To reset + * the controller, place the interface device in D3 then to + * D0, this causes a secondary PCI reset which will reset the + * controller." + */ + + /* enter the D3hot power management state */ + pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); + pmcsr &= ~PCI_PM_CTRL_STATE_MASK; + pmcsr |= PCI_D3hot; + pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); + + msleep(500); + + /* enter the D0 power management state */ + pmcsr &= ~PCI_PM_CTRL_STATE_MASK; + pmcsr |= PCI_D0; + pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); + + msleep(500); + + /* Restore the PCI configuration space. The Open CISS + * Specification says, "Restore the PCI Configuration + * Registers, offsets 00h through 60h. It is important to + * restore the command register, 16-bits at offset 04h, + * last. Do not restore the configuration status register, + * 16-bits at offset 06h." Note that the offset is 2*i. + */ + for (i = 0; i < 32; i++) { + if (i == 2 || i == 3) + continue; + pci_write_config_word(pdev, 2*i, saved_config_space[i]); + } + wmb(); + pci_write_config_word(pdev, 4, saved_config_space[2]); + + return 0; +} + +/* + * We cannot read the structure directly, for portability we must use + * the io functions. + * This is for debug only. + */ +#ifdef HPSA_DEBUG +static void print_cfg_table(struct device *dev, struct CfgTable *tb) +{ + int i; + char temp_name[17]; + + dev_info(dev, "Controller Configuration information\n"); + dev_info(dev, "------------------------------------\n"); + for (i = 0; i < 4; i++) + temp_name[i] = readb(&(tb->Signature[i])); + temp_name[4] = '\0'; + dev_info(dev, " Signature = %s\n", temp_name); + dev_info(dev, " Spec Number = %d\n", readl(&(tb->SpecValence))); + dev_info(dev, " Transport methods supported = 0x%x\n", + readl(&(tb->TransportSupport))); + dev_info(dev, " Transport methods active = 0x%x\n", + readl(&(tb->TransportActive))); + dev_info(dev, " Requested transport Method = 0x%x\n", + readl(&(tb->HostWrite.TransportRequest))); + dev_info(dev, " Coalesce Interrupt Delay = 0x%x\n", + readl(&(tb->HostWrite.CoalIntDelay))); + dev_info(dev, " Coalesce Interrupt Count = 0x%x\n", + readl(&(tb->HostWrite.CoalIntCount))); + dev_info(dev, " Max outstanding commands = 0x%d\n", + readl(&(tb->CmdsOutMax))); + dev_info(dev, " Bus Types = 0x%x\n", readl(&(tb->BusTypes))); + for (i = 0; i < 16; i++) + temp_name[i] = readb(&(tb->ServerName[i])); + temp_name[16] = '\0'; + dev_info(dev, " Server Name = %s\n", temp_name); + dev_info(dev, " Heartbeat Counter = 0x%x\n\n\n", + readl(&(tb->HeartBeat))); +} +#endif /* HPSA_DEBUG */ + +static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) +{ + int i, offset, mem_type, bar_type; + + if (pci_bar_addr == PCI_BASE_ADDRESS_0) /* looking for BAR zero? */ + return 0; + offset = 0; + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + bar_type = pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE; + if (bar_type == PCI_BASE_ADDRESS_SPACE_IO) + offset += 4; + else { + mem_type = pci_resource_flags(pdev, i) & + PCI_BASE_ADDRESS_MEM_TYPE_MASK; + switch (mem_type) { + case PCI_BASE_ADDRESS_MEM_TYPE_32: + case PCI_BASE_ADDRESS_MEM_TYPE_1M: + offset += 4; /* 32 bit */ + break; + case PCI_BASE_ADDRESS_MEM_TYPE_64: + offset += 8; + break; + default: /* reserved in PCI 2.2 */ + dev_warn(&pdev->dev, + "base address is invalid\n"); + return -1; + break; + } + } + if (offset == pci_bar_addr - PCI_BASE_ADDRESS_0) + return i + 1; + } + return -1; +} + +/* If MSI/MSI-X is supported by the kernel we will try to enable it on + * controllers that are capable. If not, we use IO-APIC mode. + */ + +static void __devinit hpsa_interrupt_mode(struct ctlr_info *h, + struct pci_dev *pdev, __u32 board_id) +{ +#ifdef CONFIG_PCI_MSI + int err; + struct msix_entry hpsa_msix_entries[4] = { {0, 0}, {0, 1}, + {0, 2}, {0, 3} + }; + + /* Some boards advertise MSI but don't really support it */ + if ((board_id == 0x40700E11) || + (board_id == 0x40800E11) || + (board_id == 0x40820E11) || (board_id == 0x40830E11)) + goto default_int_mode; + if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { + dev_info(&pdev->dev, "MSIX\n"); + err = pci_enable_msix(pdev, hpsa_msix_entries, 4); + if (!err) { + h->intr[0] = hpsa_msix_entries[0].vector; + h->intr[1] = hpsa_msix_entries[1].vector; + h->intr[2] = hpsa_msix_entries[2].vector; + h->intr[3] = hpsa_msix_entries[3].vector; + h->msix_vector = 1; + return; + } + if (err > 0) { + dev_warn(&pdev->dev, "only %d MSI-X vectors " + "available\n", err); + goto default_int_mode; + } else { + dev_warn(&pdev->dev, "MSI-X init failed %d\n", + err); + goto default_int_mode; + } + } + if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) { + dev_info(&pdev->dev, "MSI\n"); + if (!pci_enable_msi(pdev)) + h->msi_vector = 1; + else + dev_warn(&pdev->dev, "MSI init failed\n"); + } +default_int_mode: +#endif /* CONFIG_PCI_MSI */ + /* if we get here we're going to use the default interrupt mode */ + h->intr[SIMPLE_MODE_INT] = pdev->irq; + return; +} + +static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev) +{ + ushort subsystem_vendor_id, subsystem_device_id, command; + __u32 board_id, scratchpad = 0; + __u64 cfg_offset; + __u32 cfg_base_addr; + __u64 cfg_base_addr_index; + int i, prod_index, err; + + subsystem_vendor_id = pdev->subsystem_vendor; + subsystem_device_id = pdev->subsystem_device; + board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) | + subsystem_vendor_id); + + for (i = 0; i < ARRAY_SIZE(products); i++) + if (board_id == products[i].board_id) + break; + + prod_index = i; + + if (prod_index == ARRAY_SIZE(products)) { + prod_index--; + if (subsystem_vendor_id != PCI_VENDOR_ID_HP || + !hpsa_allow_any) { + dev_warn(&pdev->dev, "unrecognized board ID:" + " 0x%08lx, ignoring.\n", + (unsigned long) board_id); + return -ENODEV; + } + } + /* check to see if controller has been disabled + * BEFORE trying to enable it + */ + (void)pci_read_config_word(pdev, PCI_COMMAND, &command); + if (!(command & 0x02)) { + dev_warn(&pdev->dev, "controller appears to be disabled\n"); + return -ENODEV; + } + + err = pci_enable_device(pdev); + if (err) { + dev_warn(&pdev->dev, "unable to enable PCI device\n"); + return err; + } + + err = pci_request_regions(pdev, "hpsa"); + if (err) { + dev_err(&pdev->dev, "cannot obtain PCI resources, aborting\n"); + return err; + } + + /* If the kernel supports MSI/MSI-X we will try to enable that, + * else we use the IO-APIC interrupt assigned to us by system ROM. + */ + hpsa_interrupt_mode(h, pdev, board_id); + + /* find the memory BAR */ + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) + break; + } + if (i == DEVICE_COUNT_RESOURCE) { + dev_warn(&pdev->dev, "no memory BAR found\n"); + err = -ENODEV; + goto err_out_free_res; + } + + h->paddr = pci_resource_start(pdev, i); /* addressing mode bits + * already removed + */ + + h->vaddr = remap_pci_mem(h->paddr, 0x250); + + /* Wait for the board to become ready. */ + for (i = 0; i < HPSA_BOARD_READY_ITERATIONS; i++) { + scratchpad = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); + if (scratchpad == HPSA_FIRMWARE_READY) + break; + msleep(HPSA_BOARD_READY_POLL_INTERVAL_MSECS); + } + if (scratchpad != HPSA_FIRMWARE_READY) { + dev_warn(&pdev->dev, "board not ready, timed out.\n"); + err = -ENODEV; + goto err_out_free_res; + } + + /* get the address index number */ + cfg_base_addr = readl(h->vaddr + SA5_CTCFG_OFFSET); + cfg_base_addr &= (__u32) 0x0000ffff; + cfg_base_addr_index = find_PCI_BAR_index(pdev, cfg_base_addr); + if (cfg_base_addr_index == -1) { + dev_warn(&pdev->dev, "cannot find cfg_base_addr_index\n"); + err = -ENODEV; + goto err_out_free_res; + } + + cfg_offset = readl(h->vaddr + SA5_CTMEM_OFFSET); + h->cfgtable = remap_pci_mem(pci_resource_start(pdev, + cfg_base_addr_index) + cfg_offset, + sizeof(h->cfgtable)); + h->board_id = board_id; + + /* Query controller for max supported commands: */ + h->max_commands = readl(&(h->cfgtable->CmdsOutMax)); + + h->product_name = products[prod_index].product_name; + h->access = *(products[prod_index].access); + /* Allow room for some ioctls */ + h->nr_cmds = h->max_commands - 4; + + if ((readb(&h->cfgtable->Signature[0]) != 'C') || + (readb(&h->cfgtable->Signature[1]) != 'I') || + (readb(&h->cfgtable->Signature[2]) != 'S') || + (readb(&h->cfgtable->Signature[3]) != 'S')) { + dev_warn(&pdev->dev, "not a valid CISS config table\n"); + err = -ENODEV; + goto err_out_free_res; + } +#ifdef CONFIG_X86 + { + /* Need to enable prefetch in the SCSI core for 6400 in x86 */ + __u32 prefetch; + prefetch = readl(&(h->cfgtable->SCSI_Prefetch)); + prefetch |= 0x100; + writel(prefetch, &(h->cfgtable->SCSI_Prefetch)); + } +#endif + + /* Disabling DMA prefetch for the P600 + * An ASIC bug may result in a prefetch beyond + * physical memory. + */ + if (board_id == 0x3225103C) { + __u32 dma_prefetch; + dma_prefetch = readl(h->vaddr + I2O_DMA1_CFG); + dma_prefetch |= 0x8000; + writel(dma_prefetch, h->vaddr + I2O_DMA1_CFG); + } + + h->max_commands = readl(&(h->cfgtable->CmdsOutMax)); + /* Update the field, and then ring the doorbell */ + writel(CFGTBL_Trans_Simple, &(h->cfgtable->HostWrite.TransportRequest)); + writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); + + /* under certain very rare conditions, this can take awhile. + * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right + * as we enter this code.) + */ + for (i = 0; i < MAX_CONFIG_WAIT; i++) { + if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) + break; + /* delay and try again */ + msleep(10); + } + +#ifdef HPSA_DEBUG + print_cfg_table(&pdev->dev, h->cfgtable); +#endif /* HPSA_DEBUG */ + + if (!(readl(&(h->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) { + dev_warn(&pdev->dev, "unable to get board into simple mode\n"); + err = -ENODEV; + goto err_out_free_res; + } + return 0; + +err_out_free_res: + /* + * Deliberately omit pci_disable_device(): it does something nasty to + * Smart Array controllers that pci_enable_device does not undo + */ + pci_release_regions(pdev); + return err; +} + +static int __devinit hpsa_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int i; + int dac; + struct ctlr_info *h; + + if (number_of_controllers == 0) + printk(KERN_INFO DRIVER_NAME "\n"); + if (reset_devices) { + /* Reset the controller with a PCI power-cycle */ + if (hpsa_hard_reset_controller(pdev) || hpsa_reset_msi(pdev)) + return -ENODEV; + + /* Some devices (notably the HP Smart Array 5i Controller) + need a little pause here */ + msleep(HPSA_POST_RESET_PAUSE_MSECS); + + /* Now try to get the controller to respond to a no-op */ + for (i = 0; i < HPSA_POST_RESET_NOOP_RETRIES; i++) { + if (hpsa_noop(pdev) == 0) + break; + else + dev_warn(&pdev->dev, "no-op failed%s\n", + (i < 11 ? "; re-trying" : "")); + } + } + + BUILD_BUG_ON(sizeof(struct CommandList) % 8); + h = kzalloc(sizeof(*h), GFP_KERNEL); + if (!h) + return -1; + + h->busy_initializing = 1; + INIT_HLIST_HEAD(&h->cmpQ); + INIT_HLIST_HEAD(&h->reqQ); + mutex_init(&h->busy_shutting_down); + init_completion(&h->scan_wait); + if (hpsa_pci_init(h, pdev) != 0) + goto clean1; + + sprintf(h->devname, "hpsa%d", number_of_controllers); + h->ctlr = number_of_controllers; + number_of_controllers++; + h->pdev = pdev; + + /* configure PCI DMA stuff */ + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) + dac = 1; + else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) + dac = 0; + else { + dev_err(&pdev->dev, "no suitable DMA available\n"); + goto clean1; + } + + /* make sure the board interrupts are off */ + h->access.set_intr_mask(h, HPSA_INTR_OFF); + if (request_irq(h->intr[SIMPLE_MODE_INT], do_hpsa_intr, + IRQF_DISABLED | IRQF_SHARED, h->devname, h)) { + dev_err(&pdev->dev, "unable to get irq %d for %s\n", + h->intr[SIMPLE_MODE_INT], h->devname); + goto clean2; + } + + dev_info(&pdev->dev, "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n", + h->devname, pdev->device, pci_name(pdev), + h->intr[SIMPLE_MODE_INT], dac ? "" : " not"); + + h->cmd_pool_bits = + kmalloc(((h->nr_cmds + BITS_PER_LONG - + 1) / BITS_PER_LONG) * sizeof(unsigned long), GFP_KERNEL); + h->cmd_pool = pci_alloc_consistent(h->pdev, + h->nr_cmds * sizeof(*h->cmd_pool), + &(h->cmd_pool_dhandle)); + h->errinfo_pool = pci_alloc_consistent(h->pdev, + h->nr_cmds * sizeof(*h->errinfo_pool), + &(h->errinfo_pool_dhandle)); + if ((h->cmd_pool_bits == NULL) + || (h->cmd_pool == NULL) + || (h->errinfo_pool == NULL)) { + dev_err(&pdev->dev, "out of memory"); + goto clean4; + } + spin_lock_init(&h->lock); + + pci_set_drvdata(pdev, h); + memset(h->cmd_pool_bits, 0, + ((h->nr_cmds + BITS_PER_LONG - + 1) / BITS_PER_LONG) * sizeof(unsigned long)); + + hpsa_scsi_setup(h); + + /* Turn the interrupts on so we can service requests */ + h->access.set_intr_mask(h, HPSA_INTR_ON); + + hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */ + h->busy_initializing = 0; + return 1; + +clean4: + kfree(h->cmd_pool_bits); + if (h->cmd_pool) + pci_free_consistent(h->pdev, + h->nr_cmds * sizeof(struct CommandList), + h->cmd_pool, h->cmd_pool_dhandle); + if (h->errinfo_pool) + pci_free_consistent(h->pdev, + h->nr_cmds * sizeof(struct ErrorInfo), + h->errinfo_pool, + h->errinfo_pool_dhandle); + free_irq(h->intr[SIMPLE_MODE_INT], h); +clean2: +clean1: + h->busy_initializing = 0; + kfree(h); + return -1; +} + +static void hpsa_flush_cache(struct ctlr_info *h) +{ + char *flush_buf; + struct CommandList *c; + + flush_buf = kzalloc(4, GFP_KERNEL); + if (!flush_buf) + return; + + c = cmd_special_alloc(h); + if (!c) { + dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); + goto out_of_memory; + } + fill_cmd(c, HPSA_CACHE_FLUSH, h, flush_buf, 4, 0, + RAID_CTLR_LUNID, TYPE_CMD); + hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_TODEVICE); + if (c->err_info->CommandStatus != 0) + dev_warn(&h->pdev->dev, + "error flushing cache on controller\n"); + cmd_special_free(h, c); +out_of_memory: + kfree(flush_buf); +} + +static void hpsa_shutdown(struct pci_dev *pdev) +{ + struct ctlr_info *h; + + h = pci_get_drvdata(pdev); + /* Turn board interrupts off and send the flush cache command + * sendcmd will turn off interrupt, and send the flush... + * To write all data in the battery backed cache to disks + */ + hpsa_flush_cache(h); + h->access.set_intr_mask(h, HPSA_INTR_OFF); + free_irq(h->intr[2], h); +#ifdef CONFIG_PCI_MSI + if (h->msix_vector) + pci_disable_msix(h->pdev); + else if (h->msi_vector) + pci_disable_msi(h->pdev); +#endif /* CONFIG_PCI_MSI */ +} + +static void __devexit hpsa_remove_one(struct pci_dev *pdev) +{ + struct ctlr_info *h; + + if (pci_get_drvdata(pdev) == NULL) { + dev_err(&pdev->dev, "unable to remove device \n"); + return; + } + h = pci_get_drvdata(pdev); + mutex_lock(&h->busy_shutting_down); + remove_from_scan_list(h); + hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */ + hpsa_shutdown(pdev); + iounmap(h->vaddr); + pci_free_consistent(h->pdev, + h->nr_cmds * sizeof(struct CommandList), + h->cmd_pool, h->cmd_pool_dhandle); + pci_free_consistent(h->pdev, + h->nr_cmds * sizeof(struct ErrorInfo), + h->errinfo_pool, h->errinfo_pool_dhandle); + kfree(h->cmd_pool_bits); + /* + * Deliberately omit pci_disable_device(): it does something nasty to + * Smart Array controllers that pci_enable_device does not undo + */ + pci_release_regions(pdev); + pci_set_drvdata(pdev, NULL); + mutex_unlock(&h->busy_shutting_down); + kfree(h); +} + +static int hpsa_suspend(__attribute__((unused)) struct pci_dev *pdev, + __attribute__((unused)) pm_message_t state) +{ + return -ENOSYS; +} + +static int hpsa_resume(__attribute__((unused)) struct pci_dev *pdev) +{ + return -ENOSYS; +} + +static struct pci_driver hpsa_pci_driver = { + .name = "hpsa", + .probe = hpsa_init_one, + .remove = __devexit_p(hpsa_remove_one), + .id_table = hpsa_pci_device_id, /* id_table */ + .shutdown = hpsa_shutdown, + .suspend = hpsa_suspend, + .resume = hpsa_resume, +}; + +/* + * This is it. Register the PCI driver information for the cards we control + * the OS will call our registered routines when it finds one of our cards. + */ +static int __init hpsa_init(void) +{ + int err; + /* Start the scan thread */ + hpsa_scan_thread = kthread_run(hpsa_scan_func, NULL, "hpsa_scan"); + if (IS_ERR(hpsa_scan_thread)) { + err = PTR_ERR(hpsa_scan_thread); + return -ENODEV; + } + err = pci_register_driver(&hpsa_pci_driver); + if (err) + kthread_stop(hpsa_scan_thread); + return err; +} + +static void __exit hpsa_cleanup(void) +{ + pci_unregister_driver(&hpsa_pci_driver); + kthread_stop(hpsa_scan_thread); +} + +module_init(hpsa_init); +module_exit(hpsa_cleanup); diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h new file mode 100644 index 0000000..6bd1949 --- /dev/null +++ b/drivers/scsi/hpsa.h @@ -0,0 +1,273 @@ +/* + * Disk Array driver for HP Smart Array SAS controllers + * Copyright 2000, 2009 Hewlett-Packard Development Company, L.P. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Questions/Comments/Bugfixes to iss_storagedev@hp.com + * + */ +#ifndef HPSA_H +#define HPSA_H + +#include + +#define IO_OK 0 +#define IO_ERROR 1 + +struct ctlr_info; + +struct access_method { + void (*submit_command)(struct ctlr_info *h, + struct CommandList *c); + void (*set_intr_mask)(struct ctlr_info *h, unsigned long val); + unsigned long (*fifo_full)(struct ctlr_info *h); + unsigned long (*intr_pending)(struct ctlr_info *h); + unsigned long (*command_completed)(struct ctlr_info *h); +}; + +struct hpsa_scsi_dev_t { + int devtype; + int bus, target, lun; /* as presented to the OS */ + unsigned char scsi3addr[8]; /* as presented to the HW */ +#define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0" + unsigned char device_id[16]; /* from inquiry pg. 0x83 */ + unsigned char vendor[8]; /* bytes 8-15 of inquiry data */ + unsigned char model[16]; /* bytes 16-31 of inquiry data */ + unsigned char revision[4]; /* bytes 32-35 of inquiry data */ + unsigned char raid_level; /* from inquiry page 0xC1 */ +}; + +struct ctlr_info { + int ctlr; + char devname[8]; + char *product_name; + char firm_ver[4]; /* Firmware version */ + struct pci_dev *pdev; + __u32 board_id; + void __iomem *vaddr; + unsigned long paddr; + int nr_cmds; /* Number of commands allowed on this controller */ + struct CfgTable __iomem *cfgtable; + int interrupts_enabled; + int major; + int max_commands; + int commands_outstanding; + int max_outstanding; /* Debug */ + int usage_count; /* number of opens all all minor devices */ +# define DOORBELL_INT 0 +# define PERF_MODE_INT 1 +# define SIMPLE_MODE_INT 2 +# define MEMQ_MODE_INT 3 + unsigned int intr[4]; + unsigned int msix_vector; + unsigned int msi_vector; + struct access_method access; + + /* queue and queue Info */ + struct hlist_head reqQ; + struct hlist_head cmpQ; + unsigned int Qdepth; + unsigned int maxQsinceinit; + unsigned int maxSG; + spinlock_t lock; + + /* pointers to command and error info pool */ + struct CommandList *cmd_pool; + dma_addr_t cmd_pool_dhandle; + struct ErrorInfo *errinfo_pool; + dma_addr_t errinfo_pool_dhandle; + unsigned long *cmd_pool_bits; + int nr_allocs; + int nr_frees; + int busy_initializing; + int busy_scanning; + struct mutex busy_shutting_down; + struct list_head scan_list; + struct completion scan_wait; + + struct Scsi_Host *scsi_host; + spinlock_t devlock; /* to protect hba[ctlr]->dev[]; */ + int ndevices; /* number of used elements in .dev[] array. */ +#define HPSA_MAX_SCSI_DEVS_PER_HBA 256 + struct hpsa_scsi_dev_t *dev[HPSA_MAX_SCSI_DEVS_PER_HBA]; +}; +#define HPSA_ABORT_MSG 0 +#define HPSA_DEVICE_RESET_MSG 1 +#define HPSA_BUS_RESET_MSG 2 +#define HPSA_HOST_RESET_MSG 3 +#define HPSA_MSG_SEND_RETRY_LIMIT 10 +#define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS 1000 + +/* Maximum time in seconds driver will wait for command completions + * when polling before giving up. + */ +#define HPSA_MAX_POLL_TIME_SECS (20) + +/* During SCSI error recovery, HPSA_TUR_RETRY_LIMIT defines + * how many times to retry TEST UNIT READY on a device + * while waiting for it to become ready before giving up. + * HPSA_MAX_WAIT_INTERVAL_SECS is the max wait interval + * between sending TURs while waiting for a device + * to become ready. + */ +#define HPSA_TUR_RETRY_LIMIT (20) +#define HPSA_MAX_WAIT_INTERVAL_SECS (30) + +/* HPSA_BOARD_READY_WAIT_SECS is how long to wait for a board + * to become ready, in seconds, before giving up on it. + * HPSA_BOARD_READY_POLL_INTERVAL_MSECS * is how long to wait + * between polling the board to see if it is ready, in + * milliseconds. HPSA_BOARD_READY_POLL_INTERVAL and + * HPSA_BOARD_READY_ITERATIONS are derived from those. + */ +#define HPSA_BOARD_READY_WAIT_SECS (120) +#define HPSA_BOARD_READY_POLL_INTERVAL_MSECS (100) +#define HPSA_BOARD_READY_POLL_INTERVAL \ + ((HPSA_BOARD_READY_POLL_INTERVAL_MSECS * HZ) / 1000) +#define HPSA_BOARD_READY_ITERATIONS \ + ((HPSA_BOARD_READY_WAIT_SECS * 1000) / \ + HPSA_BOARD_READY_POLL_INTERVAL_MSECS) +#define HPSA_POST_RESET_PAUSE_MSECS (3000) +#define HPSA_POST_RESET_NOOP_RETRIES (12) + +/* Defining the diffent access_menthods */ +/* + * Memory mapped FIFO interface (SMART 53xx cards) + */ +#define SA5_DOORBELL 0x20 +#define SA5_REQUEST_PORT_OFFSET 0x40 +#define SA5_REPLY_INTR_MASK_OFFSET 0x34 +#define SA5_REPLY_PORT_OFFSET 0x44 +#define SA5_INTR_STATUS 0x30 +#define SA5_SCRATCHPAD_OFFSET 0xB0 + +#define SA5_CTCFG_OFFSET 0xB4 +#define SA5_CTMEM_OFFSET 0xB8 + +#define SA5_INTR_OFF 0x08 +#define SA5B_INTR_OFF 0x04 +#define SA5_INTR_PENDING 0x08 +#define SA5B_INTR_PENDING 0x04 +#define FIFO_EMPTY 0xffffffff +#define HPSA_FIRMWARE_READY 0xffff0000 /* value in scratchpad register */ + +#define HPSA_ERROR_BIT 0x02 +#define HPSA_TAG_CONTAINS_INDEX(tag) ((tag) & 0x04) +#define HPSA_TAG_TO_INDEX(tag) ((tag) >> 3) +#define HPSA_TAG_DISCARD_ERROR_BITS(tag) ((tag) & ~3) + +#define HPSA_INTR_ON 1 +#define HPSA_INTR_OFF 0 +/* + Send the command to the hardware +*/ +static void SA5_submit_command(struct ctlr_info *h, + struct CommandList *c) +{ +#ifdef HPSA_DEBUG + printk(KERN_WARNING "hpsa: Sending %x - down to controller\n", + c->busaddr); +#endif /* HPSA_DEBUG */ + writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); + h->commands_outstanding++; + if (h->commands_outstanding > h->max_outstanding) + h->max_outstanding = h->commands_outstanding; +} + +/* + * This card is the opposite of the other cards. + * 0 turns interrupts on... + * 0x08 turns them off... + */ +static void SA5_intr_mask(struct ctlr_info *h, unsigned long val) +{ + if (val) { /* Turn interrupts on */ + h->interrupts_enabled = 1; + writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); + } else { /* Turn them off */ + h->interrupts_enabled = 0; + writel(SA5_INTR_OFF, + h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); + } +} +/* + * Returns true if fifo is full. + * + */ +static unsigned long SA5_fifo_full(struct ctlr_info *h) +{ + if (h->commands_outstanding >= h->max_commands) + return 1; + else + return 0; + +} +/* + * returns value read from hardware. + * returns FIFO_EMPTY if there is nothing to read + */ +static unsigned long SA5_completed(struct ctlr_info *h) +{ + unsigned long register_value + = readl(h->vaddr + SA5_REPLY_PORT_OFFSET); + + if (register_value != FIFO_EMPTY) + h->commands_outstanding--; + +#ifdef HPSA_DEBUG + if (register_value != FIFO_EMPTY) + printk(KERN_INFO "hpsa: Read %lx back from board\n", + register_value); + else + printk(KERN_INFO "hpsa: FIFO Empty read\n"); +#endif + + return register_value; +} +/* + * Returns true if an interrupt is pending.. + */ +static unsigned long SA5_intr_pending(struct ctlr_info *h) +{ + unsigned long register_value = + readl(h->vaddr + SA5_INTR_STATUS); +#ifdef HPSA_DEBUG + printk(KERN_INFO "hpsa: intr_pending %lx\n", register_value); +#endif /* HPSA_DEBUG */ + if (register_value & SA5_INTR_PENDING) + return 1; + return 0 ; +} + + +static struct access_method SA5_access = { + SA5_submit_command, + SA5_intr_mask, + SA5_fifo_full, + SA5_intr_pending, + SA5_completed, +}; + +struct board_type { + __u32 board_id; + char *product_name; + struct access_method *access; +}; + + +/* end of old hpsa_scsi.h file */ + +#endif /* HPSA_H */ + diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h new file mode 100644 index 0000000..12d7138 --- /dev/null +++ b/drivers/scsi/hpsa_cmd.h @@ -0,0 +1,326 @@ +/* + * Disk Array driver for HP Smart Array SAS controllers + * Copyright 2000, 2009 Hewlett-Packard Development Company, L.P. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Questions/Comments/Bugfixes to iss_storagedev@hp.com + * + */ +#ifndef HPSA_CMD_H +#define HPSA_CMD_H + +/* general boundary defintions */ +#define SENSEINFOBYTES 32 /* may vary between hbas */ +#define MAXSGENTRIES 31 +#define MAXREPLYQS 256 + +/* Command Status value */ +#define CMD_SUCCESS 0x0000 +#define CMD_TARGET_STATUS 0x0001 +#define CMD_DATA_UNDERRUN 0x0002 +#define CMD_DATA_OVERRUN 0x0003 +#define CMD_INVALID 0x0004 +#define CMD_PROTOCOL_ERR 0x0005 +#define CMD_HARDWARE_ERR 0x0006 +#define CMD_CONNECTION_LOST 0x0007 +#define CMD_ABORTED 0x0008 +#define CMD_ABORT_FAILED 0x0009 +#define CMD_UNSOLICITED_ABORT 0x000A +#define CMD_TIMEOUT 0x000B +#define CMD_UNABORTABLE 0x000C + +/* Unit Attentions ASC's as defined for the MSA2012sa */ +#define POWER_OR_RESET 0x29 +#define STATE_CHANGED 0x2a +#define UNIT_ATTENTION_CLEARED 0x2f +#define LUN_FAILED 0x3e +#define REPORT_LUNS_CHANGED 0x3f + +/* Unit Attentions ASCQ's as defined for the MSA2012sa */ + + /* These ASCQ's defined for ASC = POWER_OR_RESET */ +#define POWER_ON_RESET 0x00 +#define POWER_ON_REBOOT 0x01 +#define SCSI_BUS_RESET 0x02 +#define MSA_TARGET_RESET 0x03 +#define CONTROLLER_FAILOVER 0x04 +#define TRANSCEIVER_SE 0x05 +#define TRANSCEIVER_LVD 0x06 + + /* These ASCQ's defined for ASC = STATE_CHANGED */ +#define RESERVATION_PREEMPTED 0x03 +#define ASYM_ACCESS_CHANGED 0x06 +#define LUN_CAPACITY_CHANGED 0x09 + +/* transfer direction */ +#define XFER_NONE 0x00 +#define XFER_WRITE 0x01 +#define XFER_READ 0x02 +#define XFER_RSVD 0x03 + +/* task attribute */ +#define ATTR_UNTAGGED 0x00 +#define ATTR_SIMPLE 0x04 +#define ATTR_HEADOFQUEUE 0x05 +#define ATTR_ORDERED 0x06 +#define ATTR_ACA 0x07 + +/* cdb type */ +#define TYPE_CMD 0x00 +#define TYPE_MSG 0x01 + +/* config space register offsets */ +#define CFG_VENDORID 0x00 +#define CFG_DEVICEID 0x02 +#define CFG_I2OBAR 0x10 +#define CFG_MEM1BAR 0x14 + +/* i2o space register offsets */ +#define I2O_IBDB_SET 0x20 +#define I2O_IBDB_CLEAR 0x70 +#define I2O_INT_STATUS 0x30 +#define I2O_INT_MASK 0x34 +#define I2O_IBPOST_Q 0x40 +#define I2O_OBPOST_Q 0x44 +#define I2O_DMA1_CFG 0x214 + +/* Configuration Table */ +#define CFGTBL_ChangeReq 0x00000001l +#define CFGTBL_AccCmds 0x00000001l + +#define CFGTBL_Trans_Simple 0x00000002l + +#define CFGTBL_BusType_Ultra2 0x00000001l +#define CFGTBL_BusType_Ultra3 0x00000002l +#define CFGTBL_BusType_Fibre1G 0x00000100l +#define CFGTBL_BusType_Fibre2G 0x00000200l +struct vals32 { + __u32 lower; + __u32 upper; +}; + +union u64bit { + struct vals32 val32; + __u64 val; +}; + +/* FIXME this is a per controller value (barf!) */ +#define HPSA_MAX_TARGETS_PER_CTLR 16 +#define HPSA_MAX_LUN 256 +#define HPSA_MAX_PHYS_LUN 1024 + +/* SCSI-3 Commands */ +#pragma pack(1) + +#define HPSA_INQUIRY 0x12 +struct InquiryData { + __u8 data_byte[36]; +}; + +#define HPSA_REPORT_LOG 0xc2 /* Report Logical LUNs */ +#define HPSA_REPORT_PHYS 0xc3 /* Report Physical LUNs */ +struct ReportLUNdata { + __u8 LUNListLength[4]; + __u32 reserved; + __u8 LUN[HPSA_MAX_LUN][8]; +}; + +struct ReportExtendedLUNdata { + __u8 LUNListLength[4]; + __u8 extended_response_flag; + __u8 reserved[3]; + __u8 LUN[HPSA_MAX_LUN][24]; +}; + +struct SenseSubsystem_info { + __u8 reserved[36]; + __u8 portname[8]; + __u8 reserved1[1108]; +}; + +#define HPSA_READ_CAPACITY 0x25 /* Read Capacity */ +struct ReadCapdata { + __u8 total_size[4]; /* Total size in blocks */ + __u8 block_size[4]; /* Size of blocks in bytes */ +}; + +#if 0 +/* 12 byte commands not implemented in firmware yet. */ +#define HPSA_READ 0xa8 +#define HPSA_WRITE 0xaa +#endif + +#define HPSA_READ 0x28 /* Read(10) */ +#define HPSA_WRITE 0x2a /* Write(10) */ + +/* BMIC commands */ +#define BMIC_READ 0x26 +#define BMIC_WRITE 0x27 +#define BMIC_CACHE_FLUSH 0xc2 +#define HPSA_CACHE_FLUSH 0x01 /* C2 was already being used by HPSA */ + +/* Command List Structure */ +union SCSI3Addr { + struct { + __u8 Dev; + __u8 Bus:6; + __u8 Mode:2; /* b00 */ + } PeripDev; + struct { + __u8 DevLSB; + __u8 DevMSB:6; + __u8 Mode:2; /* b01 */ + } LogDev; + struct { + __u8 Dev:5; + __u8 Bus:3; + __u8 Targ:6; + __u8 Mode:2; /* b10 */ + } LogUnit; +}; + +struct PhysDevAddr { + __u32 TargetId:24; + __u32 Bus:6; + __u32 Mode:2; + /* 2 level target device addr */ + union SCSI3Addr Target[2]; +}; + +struct LogDevAddr { + __u32 VolId:30; + __u32 Mode:2; + __u8 reserved[4]; +}; + +union LUNAddr { + __u8 LunAddrBytes[8]; + union SCSI3Addr SCSI3Lun[4]; + struct PhysDevAddr PhysDev; + struct LogDevAddr LogDev; +}; + +struct CommandListHeader { + __u8 ReplyQueue; + __u8 SGList; + __u16 SGTotal; + struct vals32 Tag; + union LUNAddr LUN; +}; + +struct RequestBlock { + __u8 CDBLen; + struct { + __u8 Type:3; + __u8 Attribute:3; + __u8 Direction:2; + } Type; + __u16 Timeout; + __u8 CDB[16]; +}; + +struct ErrDescriptor { + struct vals32 Addr; + __u32 Len; +}; + +struct SGDescriptor { + struct vals32 Addr; + __u32 Len; + __u32 Ext; +}; + +union MoreErrInfo { + struct { + __u8 Reserved[3]; + __u8 Type; + __u32 ErrorInfo; + } Common_Info; + struct { + __u8 Reserved[2]; + __u8 offense_size; /* size of offending entry */ + __u8 offense_num; /* byte # of offense 0-base */ + __u32 offense_value; + } Invalid_Cmd; +}; +struct ErrorInfo { + __u8 ScsiStatus; + __u8 SenseLen; + __u16 CommandStatus; + __u32 ResidualCnt; + union MoreErrInfo MoreErrInfo; + __u8 SenseInfo[SENSEINFOBYTES]; +}; +/* Command types */ +#define CMD_IOCTL_PEND 0x01 +#define CMD_SCSI 0x03 + +struct ctlr_info; /* defined in hpsa.h */ +/* The size of this structure needs to be divisible by 8 + * od on all architectures, because the controller uses 2 + * lower bits of the address, and the driver uses 1 lower + * bit (3 bits total.) + */ +struct CommandList { + struct CommandListHeader Header; + struct RequestBlock Request; + struct ErrDescriptor ErrDesc; + struct SGDescriptor SG[MAXSGENTRIES]; + /* information associated with the command */ + __u32 busaddr; /* physical addr of this record */ + struct ErrorInfo *err_info; /* pointer to the allocated mem */ + struct ctlr_info *h; + int cmd_type; + long cmdindex; + struct hlist_node list; + struct CommandList *prev; + struct CommandList *next; + struct request *rq; + struct completion *waiting; + int retry_count; + void *scsi_cmd; +}; + +/* Configuration Table Structure */ +struct HostWrite { + __u32 TransportRequest; + __u32 Reserved; + __u32 CoalIntDelay; + __u32 CoalIntCount; +}; + +struct CfgTable { + __u8 Signature[4]; + __u32 SpecValence; + __u32 TransportSupport; + __u32 TransportActive; + struct HostWrite HostWrite; + __u32 CmdsOutMax; + __u32 BusTypes; + __u32 Reserved; + __u8 ServerName[16]; + __u32 HeartBeat; + __u32 SCSI_Prefetch; +}; + +struct hpsa_pci_info { + unsigned char bus; + unsigned char dev_fn; + unsigned short domain; + __u32 board_id; +}; + +#pragma pack() +#endif /* HPSA_CMD_H */ -- cgit v0.10.2 From 9e79e12554d651f586ff2364e69a8e9cd5e9dbcb Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:22:36 +0800 Subject: [SCSI] pm8001: Fix for sata io circular lock dependency. This patch fix for sata IO circular lock dependency. When we call task_done for SATA IO, we have got pm8001_ha->lock ,and in sas_ata_task_done, it will get (dev->sata_dev.ap->lock. then cause circular lock dependency .So we should drop pm8001_ha->lock when we call task_done for SATA task. Signed-off-by: Jack Wang Signed-off-by: Lindar Liu Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index a3de306..68695b7 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -1901,7 +1901,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) { struct sas_task *t; struct pm8001_ccb_info *ccb; - unsigned long flags; + unsigned long flags = 0; u32 param; u32 status; u32 tag; @@ -2040,7 +2040,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->stat = SAS_QUEUE_FULL; pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/*in order to force CPU ordering*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); return; } break; @@ -2058,7 +2060,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->stat = SAS_QUEUE_FULL; pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/*ditto*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); return; } break; @@ -2084,7 +2088,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->stat = SAS_QUEUE_FULL; pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/* ditto*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); return; } break; @@ -2149,7 +2155,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->stat = SAS_QUEUE_FULL; pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/*ditto*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); return; } break; @@ -2171,7 +2179,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->stat = SAS_QUEUE_FULL; pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/*ditto*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); return; } break; @@ -2200,11 +2210,20 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) " resp 0x%x stat 0x%x but aborted by upper layer!\n", t, status, ts->resp, ts->stat)); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - } else { + } else if (t->uldd_task) { spin_unlock_irqrestore(&t->task_state_lock, flags); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/* ditto */ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); + } else if (!t->uldd_task) { + spin_unlock_irqrestore(&t->task_state_lock, flags); + pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); + mb();/*ditto*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); } } @@ -2212,7 +2231,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) { struct sas_task *t; - unsigned long flags; + unsigned long flags = 0; struct task_status_struct *ts; struct pm8001_ccb_info *ccb; struct pm8001_device *pm8001_dev; @@ -2292,7 +2311,9 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->stat = SAS_QUEUE_FULL; pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/*ditto*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); return; } break; @@ -2401,11 +2422,20 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) " resp 0x%x stat 0x%x but aborted by upper layer!\n", t, event, ts->resp, ts->stat)); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - } else { + } else if (t->uldd_task) { spin_unlock_irqrestore(&t->task_state_lock, flags); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/* in order to force CPU ordering */ + mb();/* ditto */ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); + } else if (!t->uldd_task) { + spin_unlock_irqrestore(&t->task_state_lock, flags); + pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); + mb();/*ditto*/ + spin_unlock_irqrestore(&pm8001_ha->lock, flags); t->task_done(t); + spin_lock_irqsave(&pm8001_ha->lock, flags); } } -- cgit v0.10.2 From 1cc943ae5003e4612a73119cb6fb637a45c2714d Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:22:42 +0800 Subject: [SCSI] pm8001: enhance error handle for IO patch Enhance error handle for IO patch, when the port is down, fast return phy down for task. Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 68695b7..3a121fb 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -2906,13 +2906,17 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) le32_to_cpu(pPayload->lr_evt_status_phyid_portid); u8 link_rate = (u8)((lr_evt_status_phyid_portid & 0xF0000000) >> 28); + u8 port_id = (u8)(lr_evt_status_phyid_portid & 0x0000000F); u8 phy_id = (u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4); + u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate); + u8 portstate = (u8)(npip_portstate & 0x0000000F); + struct pm8001_port *port = &pm8001_ha->port[port_id]; struct sas_ha_struct *sas_ha = pm8001_ha->sas; struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; unsigned long flags; u8 deviceType = pPayload->sas_identify.dev_type; - + port->port_state = portstate; PM8001_MSG_DBG(pm8001_ha, pm8001_printk("HW_EVENT_SAS_PHY_UP \n")); @@ -2925,16 +2929,19 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) PM8001_MSG_DBG(pm8001_ha, pm8001_printk("end device.\n")); pm8001_chip_phy_ctl_req(pm8001_ha, phy_id, PHY_NOTIFY_ENABLE_SPINUP); + port->port_attached = 1; get_lrate_mode(phy, link_rate); break; case SAS_EDGE_EXPANDER_DEVICE: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("expander device.\n")); + port->port_attached = 1; get_lrate_mode(phy, link_rate); break; case SAS_FANOUT_EXPANDER_DEVICE: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("fanout expander device.\n")); + port->port_attached = 1; get_lrate_mode(phy, link_rate); break; default: @@ -2976,11 +2983,17 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) le32_to_cpu(pPayload->lr_evt_status_phyid_portid); u8 link_rate = (u8)((lr_evt_status_phyid_portid & 0xF0000000) >> 28); + u8 port_id = (u8)(lr_evt_status_phyid_portid & 0x0000000F); u8 phy_id = (u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4); + u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate); + u8 portstate = (u8)(npip_portstate & 0x0000000F); + struct pm8001_port *port = &pm8001_ha->port[port_id]; struct sas_ha_struct *sas_ha = pm8001_ha->sas; struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; unsigned long flags; + port->port_state = portstate; + port->port_attached = 1; get_lrate_mode(phy, link_rate); phy->phy_type |= PORT_TYPE_SATA; phy->phy_attached = 1; @@ -3014,7 +3027,13 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb) (u8)((lr_evt_status_phyid_portid & 0x000000F0) >> 4); u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate); u8 portstate = (u8)(npip_portstate & 0x0000000F); - + struct pm8001_port *port = &pm8001_ha->port[port_id]; + struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; + port->port_state = portstate; + phy->phy_type = 0; + phy->identify.device_type = 0; + phy->phy_attached = 0; + memset(&phy->dev_sas_addr, 0, SAS_ADDR_SIZE); switch (portstate) { case PORT_VALID: break; @@ -3023,26 +3042,30 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_printk(" PortInvalid portID %d \n", port_id)); PM8001_MSG_DBG(pm8001_ha, pm8001_printk(" Last phy Down and port invalid\n")); + port->port_attached = 0; pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN, port_id, phy_id, 0, 0); break; case PORT_IN_RESET: PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" PortInReset portID %d \n", port_id)); + pm8001_printk(" Port In Reset portID %d \n", port_id)); break; case PORT_NOT_ESTABLISHED: PM8001_MSG_DBG(pm8001_ha, pm8001_printk(" phy Down and PORT_NOT_ESTABLISHED\n")); + port->port_attached = 0; break; case PORT_LOSTCOMM: PM8001_MSG_DBG(pm8001_ha, pm8001_printk(" phy Down and PORT_LOSTCOMM\n")); PM8001_MSG_DBG(pm8001_ha, pm8001_printk(" Last phy Down and port invalid\n")); + port->port_attached = 0; pm8001_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN, port_id, phy_id, 0, 0); break; default: + port->port_attached = 0; PM8001_MSG_DBG(pm8001_ha, pm8001_printk(" phy Down and(default) = %x\n", portstate)); diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 42ebe72..fb6379a 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -200,8 +200,13 @@ static int __devinit pm8001_alloc(struct pm8001_hba_info *pm8001_ha) { int i; spin_lock_init(&pm8001_ha->lock); - for (i = 0; i < pm8001_ha->chip->n_phy; i++) + for (i = 0; i < pm8001_ha->chip->n_phy; i++) { pm8001_phy_init(pm8001_ha, i); + pm8001_ha->port[i].wide_port_phymap = 0; + pm8001_ha->port[i].port_attached = 0; + pm8001_ha->port[i].port_state = 0; + INIT_LIST_HEAD(&pm8001_ha->port[i].list); + } pm8001_ha->tags = kzalloc(PM8001_MAX_CCB, GFP_KERNEL); if (!pm8001_ha->tags) diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 1f767a0..49721c8 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -329,6 +329,23 @@ int pm8001_slave_configure(struct scsi_device *sdev) } return 0; } + /* Find the local port id that's attached to this device */ +static int sas_find_local_port_id(struct domain_device *dev) +{ + struct domain_device *pdev = dev->parent; + + /* Directly attached device */ + if (!pdev) + return dev->port->id; + while (pdev) { + struct domain_device *pdev_p = pdev->parent; + if (!pdev_p) + return pdev->port->id; + pdev = pdev->parent; + } + return 0; +} + /** * pm8001_task_exec - queue the task(ssp, smp && ata) to the hardware. * @task: the task to be execute. @@ -346,11 +363,12 @@ static int pm8001_task_exec(struct sas_task *task, const int num, struct domain_device *dev = task->dev; struct pm8001_hba_info *pm8001_ha; struct pm8001_device *pm8001_dev; + struct pm8001_port *port = NULL; struct sas_task *t = task; struct pm8001_ccb_info *ccb; u32 tag = 0xdeadbeef, rc, n_elem = 0; u32 n = num; - unsigned long flags = 0; + unsigned long flags = 0, flags_libsas = 0; if (!dev->port) { struct task_status_struct *tsm = &t->task_status; @@ -379,6 +397,35 @@ static int pm8001_task_exec(struct sas_task *task, const int num, rc = SAS_PHY_DOWN; goto out_done; } + port = &pm8001_ha->port[sas_find_local_port_id(dev)]; + if (!port->port_attached) { + if (sas_protocol_ata(t->task_proto)) { + struct task_status_struct *ts = &t->task_status; + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_PHY_DOWN; + + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + spin_unlock_irqrestore(dev->sata_dev.ap->lock, + flags_libsas); + t->task_done(t); + spin_lock_irqsave(dev->sata_dev.ap->lock, + flags_libsas); + spin_lock_irqsave(&pm8001_ha->lock, flags); + if (n > 1) + t = list_entry(t->list.next, + struct sas_task, list); + continue; + } else { + struct task_status_struct *ts = &t->task_status; + ts->resp = SAS_TASK_UNDELIVERED; + ts->stat = SAS_PHY_DOWN; + t->task_done(t); + if (n > 1) + t = list_entry(t->list.next, + struct sas_task, list); + continue; + } + } rc = pm8001_tag_alloc(pm8001_ha, &tag); if (rc) goto err_out; diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 30f2ede..c44a115 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -164,6 +164,10 @@ struct pm8001_chip_info { struct pm8001_port { struct asd_sas_port sas_port; + u8 port_attached; + u8 wide_port_phymap; + u8 port_state; + struct list_head list; }; struct pm8001_phy { -- cgit v0.10.2 From afc5ca9ddc6c223dbea8a2f8816a88b21a0883b5 Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:22:47 +0800 Subject: [SCSI] pm8001: fix endian issues with SAS address Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 3a121fb..b4426b5 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -3823,7 +3823,8 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, u32 opc = OPC_INB_SSPINIIOSTART; memset(&ssp_cmd, 0, sizeof(ssp_cmd)); memcpy(ssp_cmd.ssp_iu.lun, task->ssp_task.LUN, 8); - ssp_cmd.dir_m_tlr = data_dir_flags[task->data_dir] << 8 | 0x0;/*0 for + ssp_cmd.dir_m_tlr = + cpu_to_le32(data_dir_flags[task->data_dir] << 8 | 0x0);/*0 for SAS 1.1 compatible TLR*/ ssp_cmd.data_len = cpu_to_le32(task->total_xfer_len); ssp_cmd.device_id = cpu_to_le32(pm8001_dev->device_id); @@ -3894,7 +3895,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, } } if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) - ncg_tag = cpu_to_le32(hdr_tag); + ncg_tag = hdr_tag; dir = data_dir_flags[task->data_dir] << 8; sata_cmd.tag = cpu_to_le32(tag); sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id); @@ -4039,7 +4040,7 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha, ((stp_sspsmp_sata & 0x03) * 0x10000000)); payload.firstburstsize_ITNexustimeout = cpu_to_le32(ITNT | (firstBurstSize * 0x10000)); - memcpy(&payload.sas_addr_hi, pm8001_dev->sas_device->sas_addr, + memcpy(payload.sas_addr, pm8001_dev->sas_device->sas_addr, SAS_ADDR_SIZE); rc = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload); return rc; diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h index 96e4daa..833a520 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.h +++ b/drivers/scsi/pm8001/pm8001_hwi.h @@ -242,8 +242,7 @@ struct reg_dev_req { __le32 phyid_portid; __le32 dtype_dlr_retry; __le32 firstburstsize_ITNexustimeout; - u32 sas_addr_hi; - u32 sas_addr_low; + u8 sas_addr[SAS_ADDR_SIZE]; __le32 upper_device_id; u32 reserved[8]; } __attribute__((packed, aligned(4))); -- cgit v0.10.2 From 0330dba36127768a2e2df2eabb902b5530102871 Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:46:22 +0800 Subject: [SCSI] pm8001: set SSC down-spreading only to get less errors on some 6G device. Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index b4426b5..6e1bdd8 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -373,10 +373,7 @@ static int bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue) static void __devinit mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit) { - u32 offset; - u32 value; - u32 i, j; - u32 bit_cnt; + u32 value, offset, i; #define SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR 0x00030000 #define SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR 0x00040000 @@ -392,55 +389,35 @@ mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit) */ if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR)) return; - /* set SSC bit of PHY 0 - 3 */ + for (i = 0; i < 4; i++) { offset = SAS2_SETTINGS_LOCAL_PHY_0_3_OFFSET + 0x4000 * i; - value = pm8001_cr32(pm8001_ha, 2, offset); - if (SSCbit) { - value |= 0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT; - value &= ~(0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT); - } else { - value |= 0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT; - value &= ~(0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT); - } - bit_cnt = 0; - for (j = 0; j < 31; j++) - if ((value >> j) & 0x00000001) - bit_cnt++; - if (bit_cnt % 2) - value &= ~(0x00000001 << SNW3_PHY_CAPABILITIES_PARITY); - else - value |= 0x00000001 << SNW3_PHY_CAPABILITIES_PARITY; - - pm8001_cw32(pm8001_ha, 2, offset, value); + pm8001_cw32(pm8001_ha, 2, offset, 0x80001501); } - /* shift membase 3 for SAS2_SETTINGS_LOCAL_PHY 4 - 7 */ if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR)) return; - - /* set SSC bit of PHY 4 - 7 */ for (i = 4; i < 8; i++) { offset = SAS2_SETTINGS_LOCAL_PHY_4_7_OFFSET + 0x4000 * (i-4); - value = pm8001_cr32(pm8001_ha, 2, offset); - if (SSCbit) { - value |= 0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT; - value &= ~(0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT); - } else { - value |= 0x00000001 << PHY_G3_WITHOUT_SSC_BIT_SHIFT; - value &= ~(0x00000001 << PHY_G3_WITH_SSC_BIT_SHIFT); - } - bit_cnt = 0; - for (j = 0; j < 31; j++) - if ((value >> j) & 0x00000001) - bit_cnt++; - if (bit_cnt % 2) - value &= ~(0x00000001 << SNW3_PHY_CAPABILITIES_PARITY); - else - value |= 0x00000001 << SNW3_PHY_CAPABILITIES_PARITY; - - pm8001_cw32(pm8001_ha, 2, offset, value); + pm8001_cw32(pm8001_ha, 2, offset, 0x80001501); } + /************************************************************* + Change the SSC upspreading value to 0x0 so that upspreading is disabled. + Device MABC SMOD0 Controls + Address: (via MEMBASE-III): + Using shifted destination address 0x0_0000: with Offset 0xD8 + + 31:28 R/W Reserved Do not change + 27:24 R/W SAS_SMOD_SPRDUP 0000 + 23:20 R/W SAS_SMOD_SPRDDN 0000 + 19:0 R/W Reserved Do not change + Upon power-up this register will read as 0x8990c016, + and I would like you to change the SAS_SMOD_SPRDUP bits to 0b0000 + so that the written value will be 0x8090c016. + This will ensure only down-spreading SSC is enabled on the SPC. + *************************************************************/ + value = pm8001_cr32(pm8001_ha, 2, 0xd8); + pm8001_cw32(pm8001_ha, 2, 0xd8, 0x8000C016); /*set the shifted destination address to 0x0 to avoid error operation */ bar4_shift(pm8001_ha, 0x0); -- cgit v0.10.2 From f01f4e6a1cb343fc75dc580ec9203d9719f78f95 Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:22:55 +0800 Subject: [SCSI] pm8001:fix potential NULL pointer dereference Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 49721c8..487f78f 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -616,11 +616,11 @@ static int pm8001_dev_found_notify(struct domain_device *dev) spin_lock_irqsave(&pm8001_ha->lock, flags); pm8001_device = pm8001_alloc_dev(pm8001_ha); - pm8001_device->sas_device = dev; if (!pm8001_device) { res = -1; goto found_out; } + pm8001_device->sas_device = dev; dev->lldd_dev = pm8001_device; pm8001_device->dev_type = dev->dev_type; pm8001_device->dcompletion = &completion; -- cgit v0.10.2 From a61b8699c764cccf85ccbf489e1772b2950ba4c6 Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:22:59 +0800 Subject: [SCSI] pm8001: bit set pm8001_ha->flags Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 487f78f..c86f921 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -656,7 +656,7 @@ static int pm8001_dev_found_notify(struct domain_device *dev) wait_for_completion(&completion); if (dev->dev_type == SAS_END_DEV) msleep(50); - pm8001_ha->flags = PM8001F_RUN_TIME ; + pm8001_ha->flags |= PM8001F_RUN_TIME ; return 0; found_out: spin_unlock_irqrestore(&pm8001_ha->lock, flags); -- cgit v0.10.2 From 8257ec80ba5b333dedf3395acf90055075aeba94 Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:23:05 +0800 Subject: [SCSI] pm8001: do not reset local sata as it will not be found if reset Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index c86f921..e3d4f38 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -944,6 +944,8 @@ int pm8001_I_T_nexus_reset(struct domain_device *dev) if (dev_is_sata(dev)) { DECLARE_COMPLETION_ONSTACK(completion_setstate); + if (scsi_is_sas_phy_local(phy)) + return 0; rc = sas_phy_reset(phy, 1); msleep(2000); rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , -- cgit v0.10.2 From 7c8356d969e203a8f2f740a9a80d4944eb8cf1d1 Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:23:08 +0800 Subject: [SCSI] pm8001: enable read HBA SAS address from VPD Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_ctl.h b/drivers/scsi/pm8001/pm8001_ctl.h index 22644de..63ad4aa 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.h +++ b/drivers/scsi/pm8001/pm8001_ctl.h @@ -45,16 +45,6 @@ #define HEADER_LEN 28 #define SIZE_OFFSET 16 -struct pm8001_ioctl_payload { - u32 signature; - u16 major_function; - u16 minor_function; - u16 length; - u16 status; - u16 offset; - u16 id; - u8 func_specific[1]; -}; #define FLASH_OK 0x000000 #define FAIL_OPEN_BIOS_FILE 0x000100 diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index fb6379a..c2f1032 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -516,19 +516,23 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) u8 i; #ifdef PM8001_READ_VPD DECLARE_COMPLETION_ONSTACK(completion); + struct pm8001_ioctl_payload payload; pm8001_ha->nvmd_completion = &completion; - PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, 0, 0); + payload.minor_function = 0; + payload.length = 128; + payload.func_specific = kzalloc(128, GFP_KERNEL); + PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload); wait_for_completion(&completion); for (i = 0; i < pm8001_ha->chip->n_phy; i++) { memcpy(&pm8001_ha->phy[i].dev_sas_addr, pm8001_ha->sas_addr, SAS_ADDR_SIZE); PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("phy %d sas_addr = %x \n", i, - (u64)pm8001_ha->phy[i].dev_sas_addr)); + pm8001_printk("phy %d sas_addr = %016llx \n", i, + pm8001_ha->phy[i].dev_sas_addr)); } #else for (i = 0; i < pm8001_ha->chip->n_phy; i++) { - pm8001_ha->phy[i].dev_sas_addr = 0x500e004010000004ULL; + pm8001_ha->phy[i].dev_sas_addr = 0x50010c600047f9d0ULL; pm8001_ha->phy[i].dev_sas_addr = cpu_to_be64((u64) (*(u64 *)&pm8001_ha->phy[i].dev_sas_addr)); diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index c44a115..599601e 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -100,6 +100,7 @@ do { \ #define PM8001_USE_TASKLET #define PM8001_USE_MSIX +#define PM8001_READ_VPD #define DEV_IS_EXPANDER(type) ((type == EDGE_DEV) || (type == FANOUT_DEV)) @@ -111,7 +112,22 @@ extern const struct pm8001_dispatch pm8001_8001_dispatch; struct pm8001_hba_info; struct pm8001_ccb_info; struct pm8001_device; -struct pm8001_tmf_task; +/* define task management IU */ +struct pm8001_tmf_task { + u8 tmf; + u32 tag_of_task_to_be_managed; +}; +struct pm8001_ioctl_payload { + u32 signature; + u16 major_function; + u16 minor_function; + u16 length; + u16 status; + u16 offset; + u16 id; + u8 *func_specific; +}; + struct pm8001_dispatch { char *name; int (*chip_init)(struct pm8001_hba_info *pm8001_ha); @@ -390,11 +406,7 @@ struct pm8001_fw_image_header { __be32 startup_entry; } __attribute__((packed, aligned(4))); -/* define task management IU */ -struct pm8001_tmf_task { - u8 tmf; - u32 tag_of_task_to_be_managed; -}; + /** * FW Flash Update status values */ -- cgit v0.10.2 From 83e7332941e3e2621502aadb0e5c8a3b11fd1197 Mon Sep 17 00:00:00 2001 From: jack wang Date: Mon, 7 Dec 2009 17:23:11 +0800 Subject: [SCSI] pm8001: misc code cleanup Add more data to printk's, add some spaces around arithmetic ops and improve comments. Signed-off-by: Jack Wang Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 6e1bdd8..9b44c6f 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -2895,7 +2895,8 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) u8 deviceType = pPayload->sas_identify.dev_type; port->port_state = portstate; PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_SAS_PHY_UP \n")); + pm8001_printk("HW_EVENT_SAS_PHY_UP port id = %d, phy id = %d\n", + port_id, phy_id)); switch (deviceType) { case SAS_PHY_UNUSED: @@ -2969,6 +2970,9 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) struct sas_ha_struct *sas_ha = pm8001_ha->sas; struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; unsigned long flags; + PM8001_MSG_DBG(pm8001_ha, + pm8001_printk("HW_EVENT_SATA_PHY_UP port id = %d," + " phy id = %d\n", port_id, phy_id)); port->port_state = portstate; port->port_attached = 1; get_lrate_mode(phy, link_rate); @@ -4058,7 +4062,7 @@ static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha, struct inbound_queue_table *circularQ; int ret; u32 opc = OPC_INB_LOCAL_PHY_CONTROL; - memset((u8 *)&payload, 0, sizeof(payload)); + memset(&payload, 0, sizeof(payload)); circularQ = &pm8001_ha->inbnd_q_tbl[0]; payload.tag = 1; payload.phyop_phyid = diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index e3d4f38..7f9c83a 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -819,7 +819,7 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha, task->task_done = pm8001_task_done; task->timer.data = (unsigned long)task; task->timer.function = pm8001_tmf_timedout; - task->timer.expires = jiffies + PM8001_TASK_TIMEOUT*HZ; + task->timer.expires = jiffies + PM8001_TASK_TIMEOUT * HZ; add_timer(&task->timer); res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 599601e..8e38ca8 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -59,11 +59,11 @@ #define DRV_NAME "pm8001" #define DRV_VERSION "0.1.36" -#define PM8001_FAIL_LOGGING 0x01 /* libsas EH function logging */ +#define PM8001_FAIL_LOGGING 0x01 /* Error message logging */ #define PM8001_INIT_LOGGING 0x02 /* driver init logging */ #define PM8001_DISC_LOGGING 0x04 /* discovery layer logging */ #define PM8001_IO_LOGGING 0x08 /* I/O path logging */ -#define PM8001_EH_LOGGING 0x10 /* Error message logging */ +#define PM8001_EH_LOGGING 0x10 /* libsas EH function logging*/ #define PM8001_IOCTL_LOGGING 0x20 /* IOCTL message logging */ #define PM8001_MSG_LOGGING 0x40 /* misc message logging */ #define pm8001_printk(format, arg...) printk(KERN_INFO "%s %d:" format,\ -- cgit v0.10.2 From 82bbbf28db4beefcd8b897800153e21378270cd1 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Thu, 10 Dec 2009 19:25:41 +0100 Subject: Fix a CFQ crash in "for-2.6.33" branch of block tree I think my previous patch introduced a bug which can lead to CFQ hitting BUG_ON(). The offending commit in for-2.6.33 branch is. commit 7667aa0630407bc07dc38dcc79d29cc0a65553c1 Author: Vivek Goyal Date: Tue Dec 8 17:52:58 2009 -0500 cfq-iosched: Take care of corner cases of group losing share due to deletion While doing some stress testing on my box, I enountered following. login: [ 3165.148841] BUG: scheduling while atomic: swapper/0/0x10000100 [ 3165.149821] Modules linked in: cfq_iosched dm_multipath qla2xxx igb scsi_transport_fc dm_snapshot [last unloaded: scsi_wait_scan] [ 3165.149821] Pid: 0, comm: swapper Not tainted 2.6.32-block-for-33-merged-new #3 [ 3165.149821] Call Trace: [ 3165.149821] [] __schedule_bug+0x5c/0x60 [ 3165.149821] [] ? __wake_up+0x44/0x4d [ 3165.149821] [] schedule+0xe3/0x7bc [ 3165.149821] [] ? cpumask_next+0x1d/0x1f [ 3165.149821] [] ? cfq_dispatch_requests+0x6ba/0x93e [cfq_iosched] [ 3165.149821] [] __cond_resched+0x2a/0x35 [ 3165.149821] [] ? cfq_dispatch_requests+0x6ba/0x93e [cfq_iosched] [ 3165.149821] [] _cond_resched+0x2c/0x37 [ 3165.149821] [] is_valid_bugaddr+0x16/0x2f [ 3165.149821] [] report_bug+0x18/0xac [ 3165.149821] [] die+0x39/0x63 [ 3165.149821] [] do_trap+0x11a/0x129 [ 3165.149821] [] do_invalid_op+0x96/0x9f [ 3165.149821] [] ? cfq_dispatch_requests+0x6ba/0x93e [cfq_iosched] [ 3165.149821] [] ? enqueue_task+0x5c/0x67 [ 3165.149821] [] ? task_rq_unlock+0x11/0x13 [ 3165.149821] [] ? try_to_wake_up+0x292/0x2a4 [ 3165.149821] [] invalid_op+0x15/0x20 [ 3165.149821] [] ? cfq_dispatch_requests+0x6ba/0x93e [cfq_iosched] [ 3165.149821] [] ? virt_to_head_page+0xe/0x2f [ 3165.149821] [] blk_peek_request+0x191/0x1a7 [ 3165.149821] [] ? kobject_get+0x1a/0x21 [ 3165.149821] [] scsi_request_fn+0x82/0x3df [ 3165.149821] [] ? bio_fs_destructor+0x15/0x17 [ 3165.149821] [] ? virt_to_head_page+0xe/0x2f [ 3165.149821] [] __blk_run_queue+0x42/0x71 [ 3165.149821] [] blk_run_queue+0x26/0x3a [ 3165.149821] [] scsi_run_queue+0x2de/0x375 [ 3165.149821] [] ? put_device+0x17/0x19 [ 3165.149821] [] scsi_next_command+0x3b/0x4b [ 3165.149821] [] scsi_io_completion+0x1c9/0x3f5 [ 3165.149821] [] scsi_finish_command+0xb5/0xbe I think I have hit following BUG_ON() in cfq_dispatch_request(). BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list)); Please find attached the patch to fix it. I have done some stress testing with it and have not seen it happening again. o We should wait on a queue even after slice expiry only if it is empty. If queue is not empty then continue to expire it. o If we decide to keep the queue then make cfqq=NULL. Otherwise select_queue() will return a valid cfqq and cfq_dispatch_request() can hit following BUG_ON(). BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list)) Reviewed-by: Jeff Moyer Signed-off-by: Vivek Goyal Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 96f59ae..f3f6239 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -2151,10 +2151,11 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd) * have been idling all along on this queue and it should be * ok to wait for this request to complete. */ - if (cfqq->cfqg->nr_cfqq == 1 && cfqq->dispatched - && cfq_should_idle(cfqd, cfqq)) + if (cfqq->cfqg->nr_cfqq == 1 && RB_EMPTY_ROOT(&cfqq->sort_list) + && cfqq->dispatched && cfq_should_idle(cfqd, cfqq)) { + cfqq = NULL; goto keep_queue; - else + } else goto expire; } -- cgit v0.10.2 From b22b97c15eed893a6768aad2f596706c56bf194e Mon Sep 17 00:00:00 2001 From: Mark Ware Date: Thu, 10 Dec 2009 22:14:34 +1100 Subject: powerpc/cpm2_pic: Allow correct flow_types for port C interrupts Port C interrupts can be either falling edge, or either edge. Other external interrupts are either falling edge or active low. Tested on a custom 8280 based board. Signed-off-by: Mark Ware Acked-by: Anton Vorontsov Acked-by: Scott Wood Signed-off-by: Kumar Gala diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c index 971483f..1709ac5 100644 --- a/arch/powerpc/sysdev/cpm2_pic.c +++ b/arch/powerpc/sysdev/cpm2_pic.c @@ -143,13 +143,23 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type) struct irq_desc *desc = irq_to_desc(virq); unsigned int vold, vnew, edibit; - if (flow_type == IRQ_TYPE_NONE) - flow_type = IRQ_TYPE_LEVEL_LOW; - - if (flow_type & IRQ_TYPE_EDGE_RISING) { - printk(KERN_ERR "CPM2 PIC: sense type 0x%x not supported\n", - flow_type); - return -EINVAL; + /* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or + * IRQ_TYPE_EDGE_BOTH (default). All others are IRQ_TYPE_EDGE_FALLING + * or IRQ_TYPE_LEVEL_LOW (default) + */ + if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0) { + if (flow_type == IRQ_TYPE_NONE) + flow_type = IRQ_TYPE_EDGE_BOTH; + + if (flow_type != IRQ_TYPE_EDGE_BOTH && + flow_type != IRQ_TYPE_EDGE_FALLING) + goto err_sense; + } else { + if (flow_type == IRQ_TYPE_NONE) + flow_type = IRQ_TYPE_LEVEL_LOW; + + if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)) + goto err_sense; } desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); @@ -181,6 +191,10 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type) if (vold != vnew) out_be32(&cpm2_intctl->ic_siexr, vnew); return 0; + +err_sense: + pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type); + return -EINVAL; } static struct irq_chip cpm2_pic = { -- cgit v0.10.2 From 14d8c9f3c09e7fd7b9af80904289fe204f5b93c6 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 10 Dec 2009 00:53:17 +0000 Subject: signal: Fix racy access to __task_cred in kill_pid_info_as_uid() kill_pid_info_as_uid() accesses __task_cred() without being in a RCU read side critical section. tasklist_lock is not protecting that when CONFIG_TREE_PREEMPT_RCU=y. Convert the whole tasklist_lock section to rcu and use lock_task_sighand to prevent the exit race. Signed-off-by: Thomas Gleixner LKML-Reference: <20091210004703.232302055@linutronix.de> Acked-by: Oleg Nesterov diff --git a/kernel/signal.c b/kernel/signal.c index 6b982f2..7331656 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1175,11 +1175,12 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid, int ret = -EINVAL; struct task_struct *p; const struct cred *pcred; + unsigned long flags; if (!valid_signal(sig)) return ret; - read_lock(&tasklist_lock); + rcu_read_lock(); p = pid_task(pid, PIDTYPE_PID); if (!p) { ret = -ESRCH; @@ -1196,14 +1197,16 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid, ret = security_task_kill(p, info, sig, secid); if (ret) goto out_unlock; - if (sig && p->sighand) { - unsigned long flags; - spin_lock_irqsave(&p->sighand->siglock, flags); - ret = __send_signal(sig, info, p, 1, 0); - spin_unlock_irqrestore(&p->sighand->siglock, flags); + + if (sig) { + if (lock_task_sighand(p, &flags)) { + ret = __send_signal(sig, info, p, 1, 0); + unlock_task_sighand(p, &flags); + } else + ret = -ESRCH; } out_unlock: - read_unlock(&tasklist_lock); + rcu_read_unlock(); return ret; } EXPORT_SYMBOL_GPL(kill_pid_info_as_uid); -- cgit v0.10.2 From 7cf7db8df0b78076eafa4ead47559344ca7b7a43 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 10 Dec 2009 00:53:21 +0000 Subject: signals: Fix more rcu assumptions 1) Remove the misleading comment in __sigqueue_alloc() which claims that holding a spinlock is equivalent to rcu_read_lock(). 2) Add a rcu_read_lock/unlock around the __task_cred() access in __sigqueue_alloc() This needs to be revisited to remove the remaining users of read_lock(&tasklist_lock) but that's outside the scope of this patch. Signed-off-by: Thomas Gleixner LKML-Reference: <20091210004703.269843657@linutronix.de> diff --git a/kernel/signal.c b/kernel/signal.c index 7331656..f67545f 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -218,13 +218,13 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi struct user_struct *user; /* - * We won't get problems with the target's UID changing under us - * because changing it requires RCU be used, and if t != current, the - * caller must be holding the RCU readlock (by way of a spinlock) and - * we use RCU protection here + * Protect access to @t credentials. This can go away when all + * callers hold rcu read lock. */ + rcu_read_lock(); user = get_uid(__task_cred(t)->user); atomic_inc(&user->sigpending); + rcu_read_unlock(); if (override_rlimit || atomic_read(&user->sigpending) <= -- cgit v0.10.2 From d4581a239a40319205762b76c01eb6363f277efa Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 10 Dec 2009 00:52:51 +0000 Subject: sys: Fix missing rcu protection for __task_cred() access commit c69e8d9 (CRED: Use RCU to access another task's creds and to release a task's own creds) added non rcu_read_lock() protected access to task creds of the target task in set_prio_one(). The comment above the function says: * - the caller must hold the RCU read lock The calling code in sys_setpriority does read_lock(&tasklist_lock) but not rcu_read_lock(). This works only when CONFIG_TREE_PREEMPT_RCU=n. With CONFIG_TREE_PREEMPT_RCU=y the rcu_callbacks can run in the tick interrupt when they see no read side critical section. There is another instance of __task_cred() in sys_setpriority() itself which is equally unprotected. Wrap the whole code section into a rcu read side critical section to fix this quick and dirty. Will be revisited in course of the read_lock(&tasklist_lock) -> rcu crusade. Oleg noted further: This also fixes another bug here. find_task_by_vpid() is not safe without rcu_read_lock(). I do not mean it is not safe to use the result, just find_pid_ns() by itself is not safe. Usually tasklist gives enough protection, but if copy_process() fails it calls free_pid() lockless and does call_rcu(delayed_put_pid(). This means, without rcu lock find_pid_ns() can't scan the hash table safely. Signed-off-by: Thomas Gleixner LKML-Reference: <20091210004703.029784964@linutronix.de> Acked-by: Paul E. McKenney diff --git a/kernel/sys.c b/kernel/sys.c index 9968c5f..bc1dc61 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -163,6 +163,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval) if (niceval > 19) niceval = 19; + rcu_read_lock(); read_lock(&tasklist_lock); switch (which) { case PRIO_PROCESS: @@ -200,6 +201,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval) } out_unlock: read_unlock(&tasklist_lock); + rcu_read_unlock(); out: return error; } -- cgit v0.10.2 From d954fbf0ff6b5fdfb32350e85a2f15d3db976506 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 10 Dec 2009 23:46:52 +0100 Subject: tracing: Fix wrong usage of strstrip in trace_ksyms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit strstrip returns a pointer to the first non space character, but the code in parse_ksym_trace_str() ignores that. strstrip is now must_check and therefor we get the correct warning: kernel/trace/trace_ksym.c:294: warning: ignoring return value of ‘strstrip’, declared with attribute warn_unused_result We are really not interested in leading whitespace here. Fix that and cleanup the dozen kfree() exit pathes. Signed-off-by: Thomas Gleixner Cc: Xiao Guangrong Cc: Steven Rostedt diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c index ddfa0fd..64e7a5b 100644 --- a/kernel/trace/trace_ksym.c +++ b/kernel/trace/trace_ksym.c @@ -277,21 +277,20 @@ static ssize_t ksym_trace_filter_write(struct file *file, { struct trace_ksym *entry; struct hlist_node *node; - char *input_string, *ksymname = NULL; + char *buf, *input_string, *ksymname = NULL; unsigned long ksym_addr = 0; int ret, op, changed = 0; - input_string = kzalloc(count + 1, GFP_KERNEL); - if (!input_string) + buf = kzalloc(count + 1, GFP_KERNEL); + if (!buf) return -ENOMEM; - if (copy_from_user(input_string, buffer, count)) { - kfree(input_string); - return -EFAULT; - } - input_string[count] = '\0'; + ret = -EFAULT; + if (copy_from_user(buf, buffer, count)) + goto out; - strstrip(input_string); + buf[count] = '\0'; + input_string = strstrip(buf); /* * Clear all breakpoints if: @@ -302,15 +301,13 @@ static ssize_t ksym_trace_filter_write(struct file *file, if (!input_string[0] || !strcmp(input_string, "0") || !strcmp(input_string, "*:---")) { __ksym_trace_reset(); - kfree(input_string); - return count; + ret = 0; + goto out; } ret = op = parse_ksym_trace_str(input_string, &ksymname, &ksym_addr); - if (ret < 0) { - kfree(input_string); - return ret; - } + if (ret < 0) + goto out; mutex_lock(&ksym_tracer_mutex); @@ -321,7 +318,7 @@ static ssize_t ksym_trace_filter_write(struct file *file, if (entry->attr.bp_type != op) changed = 1; else - goto out; + goto out_unlock; break; } } @@ -336,28 +333,24 @@ static ssize_t ksym_trace_filter_write(struct file *file, if (IS_ERR(entry->ksym_hbp)) ret = PTR_ERR(entry->ksym_hbp); else - goto out; + goto out_unlock; } /* Error or "symbol:---" case: drop it */ ksym_filter_entry_count--; hlist_del_rcu(&(entry->ksym_hlist)); synchronize_rcu(); kfree(entry); - goto out; + goto out_unlock; } else { /* Check for malformed request: (4) */ - if (op == 0) - goto out; - ret = process_new_ksym_entry(ksymname, op, ksym_addr); + if (op) + ret = process_new_ksym_entry(ksymname, op, ksym_addr); } -out: +out_unlock: mutex_unlock(&ksym_tracer_mutex); - - kfree(input_string); - - if (!ret) - ret = count; - return ret; +out: + kfree(buf); + return !ret ? count : ret; } static const struct file_operations ksym_tracing_fops = { -- cgit v0.10.2 From 6076905b5ef39e0ea58db32583c9e0036c05e47b Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:51:52 +0000 Subject: dm: avoid _hash_lock deadlock Fix a reported deadlock if there are still unprocessed multipath events on a device that is being removed. _hash_lock is held during dev_remove while trying to send the outstanding events. Sending the events requests the _hash_lock again in dm_copy_name_and_uuid. This patch introduces a separate lock around regions that modify the link to the hash table (dm_set_mdptr) or the name or uuid so that dm_copy_name_and_uuid no longer needs _hash_lock. Additionally, dm_copy_name_and_uuid can only be called if md exists so we can drop the dm_get() and dm_put() which can lead to a BUG() while md is being freed. The deadlock: #0 [ffff8106298dfb48] schedule at ffffffff80063035 #1 [ffff8106298dfc20] __down_read at ffffffff8006475d #2 [ffff8106298dfc60] dm_copy_name_and_uuid at ffffffff8824f740 #3 [ffff8106298dfc90] dm_send_uevents at ffffffff88252685 #4 [ffff8106298dfcd0] event_callback at ffffffff8824c678 #5 [ffff8106298dfd00] dm_table_event at ffffffff8824dd01 #6 [ffff8106298dfd10] __hash_remove at ffffffff882507ad #7 [ffff8106298dfd30] dev_remove at ffffffff88250865 #8 [ffff8106298dfd60] ctl_ioctl at ffffffff88250d80 #9 [ffff8106298dfee0] do_ioctl at ffffffff800418c4 #10 [ffff8106298dff00] vfs_ioctl at ffffffff8002fab9 #11 [ffff8106298dff40] sys_ioctl at ffffffff8004bdaf #12 [ffff8106298dff80] tracesys at ffffffff8005d28d (via system_call) Cc: stable@kernel.org Reported-by: guy keren Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index a679429..d19854c 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -56,6 +56,11 @@ static void dm_hash_remove_all(int keep_open_devices); */ static DECLARE_RWSEM(_hash_lock); +/* + * Protects use of mdptr to obtain hash cell name and uuid from mapped device. + */ +static DEFINE_MUTEX(dm_hash_cells_mutex); + static void init_buckets(struct list_head *buckets) { unsigned int i; @@ -206,7 +211,9 @@ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_devi list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid)); } dm_get(md); + mutex_lock(&dm_hash_cells_mutex); dm_set_mdptr(md, cell); + mutex_unlock(&dm_hash_cells_mutex); up_write(&_hash_lock); return 0; @@ -224,7 +231,9 @@ static void __hash_remove(struct hash_cell *hc) /* remove from the dev hash */ list_del(&hc->uuid_list); list_del(&hc->name_list); + mutex_lock(&dm_hash_cells_mutex); dm_set_mdptr(hc->md, NULL); + mutex_unlock(&dm_hash_cells_mutex); table = dm_get_table(hc->md); if (table) { @@ -321,7 +330,9 @@ static int dm_hash_rename(uint32_t cookie, const char *old, const char *new) */ list_del(&hc->name_list); old_name = hc->name; + mutex_lock(&dm_hash_cells_mutex); hc->name = new_name; + mutex_unlock(&dm_hash_cells_mutex); list_add(&hc->name_list, _name_buckets + hash_str(new_name)); /* @@ -1582,8 +1593,7 @@ int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid) if (!md) return -ENXIO; - dm_get(md); - down_read(&_hash_lock); + mutex_lock(&dm_hash_cells_mutex); hc = dm_get_mdptr(md); if (!hc || hc->md != md) { r = -ENXIO; @@ -1596,8 +1606,7 @@ int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid) strcpy(uuid, hc->uuid ? : ""); out: - up_read(&_hash_lock); - dm_put(md); + mutex_unlock(&dm_hash_cells_mutex); return r; } diff --git a/drivers/md/dm-uevent.c b/drivers/md/dm-uevent.c index 6f65883..c7c555a 100644 --- a/drivers/md/dm-uevent.c +++ b/drivers/md/dm-uevent.c @@ -139,14 +139,13 @@ void dm_send_uevents(struct list_head *events, struct kobject *kobj) list_del_init(&event->elist); /* - * Need to call dm_copy_name_and_uuid from here for now. - * Context of previous var adds and locking used for - * hash_cell not compatable. + * When a device is being removed this copy fails and we + * discard these unsent events. */ if (dm_copy_name_and_uuid(event->md, event->name, event->uuid)) { - DMERR("%s: dm_copy_name_and_uuid() failed", - __func__); + DMINFO("%s: skipping sending uevent for lost device", + __func__); goto uevent_free; } -- cgit v0.10.2 From 613978f8711c7fd4d0aa856872375d2abd7c92ff Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 10 Dec 2009 23:51:52 +0000 Subject: dm exception store: free tmp_store on persistent flag error Error handling code following a kmalloc should free the allocated data. Cc: stable@kernel.org Signed-off-by: Julia Lawall Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c index 7dbe652..2052159 100644 --- a/drivers/md/dm-exception-store.c +++ b/drivers/md/dm-exception-store.c @@ -216,7 +216,8 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, type = get_type("N"); else { ti->error = "Persistent flag is not P or N"; - return -EINVAL; + r = -EINVAL; + goto bad_type; } if (!type) { -- cgit v0.10.2 From d2bb7df8cac647b92f51fb84ae735771e7adbfa7 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Thu, 10 Dec 2009 23:51:53 +0000 Subject: dm: sysfs add empty release function to avoid debug warning This patch just removes an unnecessary warning: kobject: 'dm': does not have a release() function, it is broken and must be fixed. The kobject is embedded in mapped device struct, so code does not need to release memory explicitly here. Cc: stable@kernel.org Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-sysfs.c b/drivers/md/dm-sysfs.c index 4b04590..b000de3 100644 --- a/drivers/md/dm-sysfs.c +++ b/drivers/md/dm-sysfs.c @@ -80,12 +80,20 @@ static struct sysfs_ops dm_sysfs_ops = { }; /* + * The sysfs structure is embedded in md struct, nothing to do here + */ +static void dm_sysfs_release(struct kobject *kobj) +{ +} + +/* * dm kobject is embedded in mapped_device structure * no need to define release function here */ static struct kobj_type dm_ktype = { .sysfs_ops = &dm_sysfs_ops, .default_attrs = dm_attrs, + .release = dm_sysfs_release }; /* -- cgit v0.10.2 From 94e76572b5dd37b1f0f4b3742ee8a565daead932 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:51:53 +0000 Subject: dm snapshot: only take lock for statustype info not table Take snapshot lock only for STATUSTYPE_INFO, not STATUSTYPE_TABLE. Commit 4c6fff445d7aa753957856278d4d93bcad6e2c14 (dm-snapshot-lock-snapshot-while-supplying-status.patch) introduced this use of the lock, but userspace applications using libdevmapper have been found to request STATUSTYPE_TABLE while the device is suspended and the lock is already held, leading to deadlock. Since the lock is not necessary in this case, don't try to take it. Cc: stable@kernel.org Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 3a3ba46..d1352129 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -1152,10 +1152,11 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, unsigned sz = 0; struct dm_snapshot *snap = ti->private; - down_write(&snap->lock); - switch (type) { case STATUSTYPE_INFO: + + down_write(&snap->lock); + if (!snap->valid) DMEMIT("Invalid"); else { @@ -1171,6 +1172,9 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, else DMEMIT("Unknown"); } + + up_write(&snap->lock); + break; case STATUSTYPE_TABLE: @@ -1185,8 +1189,6 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, break; } - up_write(&snap->lock); - return 0; } -- cgit v0.10.2 From 8e87b9b81b3c370f7e53c1ab6e1c3519ef37a644 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:51:54 +0000 Subject: dm snapshot: cope with chunk size larger than origin Under some special conditions the snapshot hash_size is calculated as zero. This patch instead sets a minimum value of 64, the same as for the pending exception table. rounddown_pow_of_two(0) is an undefined operation (it expands to shift by -1). init_exception_table with an argument of 0 would fail with -ENOMEM. The way to trigger the problem is to create a snapshot with a chunk size that is larger than the origin device. Cc: stable@kernel.org Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index d1352129..8a4a9c8 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -553,6 +553,8 @@ static int init_hash_tables(struct dm_snapshot *s) hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift; hash_size = min(hash_size, max_buckets); + if (hash_size < 64) + hash_size = 64; hash_size = rounddown_pow_of_two(hash_size); if (init_exception_table(&s->complete, hash_size, DM_CHUNK_CONSECUTIVE_BITS)) -- cgit v0.10.2 From 0b4309581b5be8749afdd5a9087fd82a2a5c9932 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Thu, 10 Dec 2009 23:51:55 +0000 Subject: dm crypt: make wipe message also wipe tfm key The "wipe key" message is used to wipe a volume key from memory temporarily, for example when suspending to RAM. There are two instances of the key in memory (inside crypto tfm) but only one got wiped. This patch wipes them both. Cc: stable@kernel.org Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index e412980..f2c1393 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -934,14 +934,14 @@ static int crypt_set_key(struct crypt_config *cc, char *key) set_bit(DM_CRYPT_KEY_VALID, &cc->flags); - return 0; + return crypto_ablkcipher_setkey(cc->tfm, cc->key, cc->key_size); } static int crypt_wipe_key(struct crypt_config *cc) { clear_bit(DM_CRYPT_KEY_VALID, &cc->flags); memset(&cc->key, 0, cc->key_size * sizeof(u8)); - return 0; + return crypto_ablkcipher_setkey(cc->tfm, cc->key, cc->key_size); } /* @@ -983,11 +983,6 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -ENOMEM; } - if (crypt_set_key(cc, argv[1])) { - ti->error = "Error decoding key"; - goto bad_cipher; - } - /* Compatibility mode for old dm-crypt cipher strings */ if (!chainmode || (strcmp(chainmode, "plain") == 0 && !ivmode)) { chainmode = "cbc"; @@ -1015,6 +1010,11 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) strcpy(cc->chainmode, chainmode); cc->tfm = tfm; + if (crypt_set_key(cc, argv[1]) < 0) { + ti->error = "Error decoding and setting key"; + goto bad_ivmode; + } + /* * Choose ivmode. Valid modes: "plain", "essiv:", "benbi". * See comments at iv code @@ -1085,11 +1085,6 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad_bs; } - if (crypto_ablkcipher_setkey(tfm, cc->key, key_size) < 0) { - ti->error = "Error setting key"; - goto bad_device; - } - if (sscanf(argv[2], "%llu", &tmpll) != 1) { ti->error = "Invalid iv_offset sector"; goto bad_device; -- cgit v0.10.2 From 6047359277517c4e56d8bfd6ea4966d7a3924151 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Thu, 10 Dec 2009 23:51:55 +0000 Subject: dm crypt: move private iv fields to structs Define private structures for IV so it's easy to add further attributes in a following patch which fixes the way key material is wiped from memory. Also move ESSIV destructor and remove unnecessary 'status' operation. There are no functional changes in this patch. Cc: stable@kernel.org Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index f2c1393..bec5ac5 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -71,10 +71,17 @@ struct crypt_iv_operations { int (*ctr)(struct crypt_config *cc, struct dm_target *ti, const char *opts); void (*dtr)(struct crypt_config *cc); - const char *(*status)(struct crypt_config *cc); int (*generator)(struct crypt_config *cc, u8 *iv, sector_t sector); }; +struct iv_essiv_private { + struct crypto_cipher *tfm; +}; + +struct iv_benbi_private { + int shift; +}; + /* * Crypt: maps a linear range of a block device * and encrypts / decrypts at the same time. @@ -102,8 +109,8 @@ struct crypt_config { struct crypt_iv_operations *iv_gen_ops; char *iv_mode; union { - struct crypto_cipher *essiv_tfm; - int benbi_shift; + struct iv_essiv_private essiv; + struct iv_benbi_private benbi; } iv_gen_private; sector_t iv_offset; unsigned int iv_size; @@ -169,6 +176,14 @@ static int crypt_iv_plain_gen(struct crypt_config *cc, u8 *iv, sector_t sector) return 0; } +static void crypt_iv_essiv_dtr(struct crypt_config *cc) +{ + struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv; + + crypto_free_cipher(essiv->tfm); + essiv->tfm = NULL; +} + static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, const char *opts) { @@ -236,21 +251,15 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, } kfree(salt); - cc->iv_gen_private.essiv_tfm = essiv_tfm; + cc->iv_gen_private.essiv.tfm = essiv_tfm; return 0; } -static void crypt_iv_essiv_dtr(struct crypt_config *cc) -{ - crypto_free_cipher(cc->iv_gen_private.essiv_tfm); - cc->iv_gen_private.essiv_tfm = NULL; -} - static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector) { memset(iv, 0, cc->iv_size); *(u64 *)iv = cpu_to_le64(sector); - crypto_cipher_encrypt_one(cc->iv_gen_private.essiv_tfm, iv, iv); + crypto_cipher_encrypt_one(cc->iv_gen_private.essiv.tfm, iv, iv); return 0; } @@ -273,7 +282,7 @@ static int crypt_iv_benbi_ctr(struct crypt_config *cc, struct dm_target *ti, return -EINVAL; } - cc->iv_gen_private.benbi_shift = 9 - log; + cc->iv_gen_private.benbi.shift = 9 - log; return 0; } @@ -288,7 +297,7 @@ static int crypt_iv_benbi_gen(struct crypt_config *cc, u8 *iv, sector_t sector) memset(iv, 0, cc->iv_size - sizeof(u64)); /* rest is cleared below */ - val = cpu_to_be64(((u64)sector << cc->iv_gen_private.benbi_shift) + 1); + val = cpu_to_be64(((u64)sector << cc->iv_gen_private.benbi.shift) + 1); put_unaligned(val, (__be64 *)(iv + cc->iv_size - sizeof(u64))); return 0; -- cgit v0.10.2 From 5861f1be00b3b70f8ab5e5a81392a6cf69666cd2 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Thu, 10 Dec 2009 23:51:56 +0000 Subject: dm crypt: restructure essiv error path Use kzfree for salt deallocation because it is derived from the volume key. Use a common error path in ESSIV constructor. Required by a later patch which fixes the way key material is wiped from memory. Cc: stable@kernel.org Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index bec5ac5..2301d22 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -187,15 +187,15 @@ static void crypt_iv_essiv_dtr(struct crypt_config *cc) static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, const char *opts) { - struct crypto_cipher *essiv_tfm; - struct crypto_hash *hash_tfm; + struct crypto_cipher *essiv_tfm = NULL; + struct crypto_hash *hash_tfm = NULL; struct hash_desc desc; struct scatterlist sg; unsigned int saltsize; - u8 *salt; + u8 *salt = NULL; int err; - if (opts == NULL) { + if (!opts) { ti->error = "Digest algorithm missing for ESSIV mode"; return -EINVAL; } @@ -204,15 +204,16 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, hash_tfm = crypto_alloc_hash(opts, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(hash_tfm)) { ti->error = "Error initializing ESSIV hash"; - return PTR_ERR(hash_tfm); + err = PTR_ERR(hash_tfm); + goto bad; } saltsize = crypto_hash_digestsize(hash_tfm); - salt = kmalloc(saltsize, GFP_KERNEL); - if (salt == NULL) { + salt = kzalloc(saltsize, GFP_KERNEL); + if (!salt) { ti->error = "Error kmallocing salt storage in ESSIV"; - crypto_free_hash(hash_tfm); - return -ENOMEM; + err = -ENOMEM; + goto bad; } sg_init_one(&sg, cc->key, cc->key_size); @@ -220,39 +221,44 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; err = crypto_hash_digest(&desc, &sg, cc->key_size, salt); crypto_free_hash(hash_tfm); + hash_tfm = NULL; if (err) { ti->error = "Error calculating hash in ESSIV"; - kfree(salt); - return err; + goto bad; } /* Setup the essiv_tfm with the given salt */ essiv_tfm = crypto_alloc_cipher(cc->cipher, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(essiv_tfm)) { ti->error = "Error allocating crypto tfm for ESSIV"; - kfree(salt); - return PTR_ERR(essiv_tfm); + err = PTR_ERR(essiv_tfm); + goto bad; } if (crypto_cipher_blocksize(essiv_tfm) != crypto_ablkcipher_ivsize(cc->tfm)) { ti->error = "Block size of ESSIV cipher does " "not match IV size of block cipher"; - crypto_free_cipher(essiv_tfm); - kfree(salt); - return -EINVAL; + err = -EINVAL; + goto bad; } err = crypto_cipher_setkey(essiv_tfm, salt, saltsize); if (err) { ti->error = "Failed to set key for ESSIV cipher"; - crypto_free_cipher(essiv_tfm); - kfree(salt); - return err; + goto bad; } - kfree(salt); + kzfree(salt); cc->iv_gen_private.essiv.tfm = essiv_tfm; return 0; + +bad: + if (essiv_tfm && !IS_ERR(essiv_tfm)) + crypto_free_cipher(essiv_tfm); + if (hash_tfm && !IS_ERR(hash_tfm)) + crypto_free_hash(hash_tfm); + kzfree(salt); + return err; } static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector) -- cgit v0.10.2 From b95bf2d3d5a48b095bffe2a0cd8c40453cf59557 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Thu, 10 Dec 2009 23:51:56 +0000 Subject: dm crypt: separate essiv allocation from initialisation This patch separates the construction of IV from its initialisation. (For ESSIV it is a hash calculation based on volume key.) Constructor code now preallocates hash tfm and salt array and saves it in a private IV structure. The next patch requires this to reinitialise the wiped IV without reallocating memory when resuming a suspended device. Cc: stable@kernel.org Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 2301d22..446153a 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -71,11 +71,14 @@ struct crypt_iv_operations { int (*ctr)(struct crypt_config *cc, struct dm_target *ti, const char *opts); void (*dtr)(struct crypt_config *cc); + int (*init)(struct crypt_config *cc); int (*generator)(struct crypt_config *cc, u8 *iv, sector_t sector); }; struct iv_essiv_private { struct crypto_cipher *tfm; + struct crypto_hash *hash_tfm; + u8 *salt; }; struct iv_benbi_private { @@ -176,12 +179,38 @@ static int crypt_iv_plain_gen(struct crypt_config *cc, u8 *iv, sector_t sector) return 0; } +/* Initialise ESSIV - compute salt but no local memory allocations */ +static int crypt_iv_essiv_init(struct crypt_config *cc) +{ + struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv; + struct hash_desc desc; + struct scatterlist sg; + int err; + + sg_init_one(&sg, cc->key, cc->key_size); + desc.tfm = essiv->hash_tfm; + desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; + + err = crypto_hash_digest(&desc, &sg, cc->key_size, essiv->salt); + if (err) + return err; + + return crypto_cipher_setkey(essiv->tfm, essiv->salt, + crypto_hash_digestsize(essiv->hash_tfm)); +} + static void crypt_iv_essiv_dtr(struct crypt_config *cc) { struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv; crypto_free_cipher(essiv->tfm); essiv->tfm = NULL; + + crypto_free_hash(essiv->hash_tfm); + essiv->hash_tfm = NULL; + + kzfree(essiv->salt); + essiv->salt = NULL; } static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, @@ -189,9 +218,6 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, { struct crypto_cipher *essiv_tfm = NULL; struct crypto_hash *hash_tfm = NULL; - struct hash_desc desc; - struct scatterlist sg; - unsigned int saltsize; u8 *salt = NULL; int err; @@ -200,7 +226,7 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, return -EINVAL; } - /* Hash the cipher key with the given hash algorithm */ + /* Allocate hash algorithm */ hash_tfm = crypto_alloc_hash(opts, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(hash_tfm)) { ti->error = "Error initializing ESSIV hash"; @@ -208,27 +234,14 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, goto bad; } - saltsize = crypto_hash_digestsize(hash_tfm); - salt = kzalloc(saltsize, GFP_KERNEL); + salt = kzalloc(crypto_hash_digestsize(hash_tfm), GFP_KERNEL); if (!salt) { ti->error = "Error kmallocing salt storage in ESSIV"; err = -ENOMEM; goto bad; } - sg_init_one(&sg, cc->key, cc->key_size); - desc.tfm = hash_tfm; - desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; - err = crypto_hash_digest(&desc, &sg, cc->key_size, salt); - crypto_free_hash(hash_tfm); - hash_tfm = NULL; - - if (err) { - ti->error = "Error calculating hash in ESSIV"; - goto bad; - } - - /* Setup the essiv_tfm with the given salt */ + /* Allocate essiv_tfm */ essiv_tfm = crypto_alloc_cipher(cc->cipher, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(essiv_tfm)) { ti->error = "Error allocating crypto tfm for ESSIV"; @@ -242,14 +255,11 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, err = -EINVAL; goto bad; } - err = crypto_cipher_setkey(essiv_tfm, salt, saltsize); - if (err) { - ti->error = "Failed to set key for ESSIV cipher"; - goto bad; - } - kzfree(salt); + cc->iv_gen_private.essiv.salt = salt; cc->iv_gen_private.essiv.tfm = essiv_tfm; + cc->iv_gen_private.essiv.hash_tfm = hash_tfm; + return 0; bad: @@ -257,7 +267,7 @@ bad: crypto_free_cipher(essiv_tfm); if (hash_tfm && !IS_ERR(hash_tfm)) crypto_free_hash(hash_tfm); - kzfree(salt); + kfree(salt); return err; } @@ -323,6 +333,7 @@ static struct crypt_iv_operations crypt_iv_plain_ops = { static struct crypt_iv_operations crypt_iv_essiv_ops = { .ctr = crypt_iv_essiv_ctr, .dtr = crypt_iv_essiv_dtr, + .init = crypt_iv_essiv_init, .generator = crypt_iv_essiv_gen }; @@ -1054,6 +1065,12 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) cc->iv_gen_ops->ctr(cc, ti, ivopts) < 0) goto bad_ivmode; + if (cc->iv_gen_ops && cc->iv_gen_ops->init && + cc->iv_gen_ops->init(cc) < 0) { + ti->error = "Error initialising IV"; + goto bad_slab_pool; + } + cc->iv_size = crypto_ablkcipher_ivsize(tfm); if (cc->iv_size) /* at least a 64 bit sector number should fit in our buffer */ -- cgit v0.10.2 From 542da317668c35036e8471822a564b609d05af66 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Thu, 10 Dec 2009 23:51:57 +0000 Subject: dm crypt: make wipe message also wipe essiv key The "wipe key" message is used to wipe the volume key from memory temporarily, for example when suspending to RAM. But the initialisation vector in ESSIV mode is calculated from the hashed volume key, so the wipe message should wipe this IV key too and reinitialise it when the volume key is reinstated. This patch adds an IV wipe method called from a wipe message callback. ESSIV is then reinitialised using the init function added by the last patch. Cc: stable@kernel.org Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 446153a..91e1bf9 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2003 Christophe Saout * Copyright (C) 2004 Clemens Fruhwirth - * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. + * Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved. * * This file is released under the GPL. */ @@ -72,6 +72,7 @@ struct crypt_iv_operations { const char *opts); void (*dtr)(struct crypt_config *cc); int (*init)(struct crypt_config *cc); + int (*wipe)(struct crypt_config *cc); int (*generator)(struct crypt_config *cc, u8 *iv, sector_t sector); }; @@ -199,6 +200,17 @@ static int crypt_iv_essiv_init(struct crypt_config *cc) crypto_hash_digestsize(essiv->hash_tfm)); } +/* Wipe salt and reset key derived from volume key */ +static int crypt_iv_essiv_wipe(struct crypt_config *cc) +{ + struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv; + unsigned salt_size = crypto_hash_digestsize(essiv->hash_tfm); + + memset(essiv->salt, 0, salt_size); + + return crypto_cipher_setkey(essiv->tfm, essiv->salt, salt_size); +} + static void crypt_iv_essiv_dtr(struct crypt_config *cc) { struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv; @@ -334,6 +346,7 @@ static struct crypt_iv_operations crypt_iv_essiv_ops = { .ctr = crypt_iv_essiv_ctr, .dtr = crypt_iv_essiv_dtr, .init = crypt_iv_essiv_init, + .wipe = crypt_iv_essiv_wipe, .generator = crypt_iv_essiv_gen }; @@ -1305,6 +1318,7 @@ static void crypt_resume(struct dm_target *ti) static int crypt_message(struct dm_target *ti, unsigned argc, char **argv) { struct crypt_config *cc = ti->private; + int ret = -EINVAL; if (argc < 2) goto error; @@ -1314,10 +1328,22 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv) DMWARN("not suspended during key manipulation."); return -EINVAL; } - if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) - return crypt_set_key(cc, argv[2]); - if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) + if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) { + ret = crypt_set_key(cc, argv[2]); + if (ret) + return ret; + if (cc->iv_gen_ops && cc->iv_gen_ops->init) + ret = cc->iv_gen_ops->init(cc); + return ret; + } + if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) { + if (cc->iv_gen_ops && cc->iv_gen_ops->wipe) { + ret = cc->iv_gen_ops->wipe(cc); + if (ret) + return ret; + } return crypt_wipe_key(cc); + } } error: -- cgit v0.10.2 From 952b355760c196ec014dd0b6878f85a11496e3da Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:51:57 +0000 Subject: dm io: use slab for struct io Allocate "struct io" from a slab. This patch changes dm-io, so that "struct io" is allocated from a slab cache. It used to be allocated with kmalloc. Allocating from a slab will be needed for the next patch, because it requires a special alignment of "struct io" and kmalloc cannot meet this alignment. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 3a2e6a2..b0d264e 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -5,6 +5,8 @@ * This file is released under the GPL. */ +#include "dm.h" + #include #include @@ -30,6 +32,8 @@ struct io { void *context; }; +static struct kmem_cache *_dm_io_cache; + /* * io contexts are only dynamically allocated for asynchronous * io. Since async io is likely to be the majority of io we'll @@ -53,7 +57,7 @@ struct dm_io_client *dm_io_client_create(unsigned num_pages) if (!client) return ERR_PTR(-ENOMEM); - client->pool = mempool_create_kmalloc_pool(ios, sizeof(struct io)); + client->pool = mempool_create_slab_pool(ios, _dm_io_cache); if (!client->pool) goto bad; @@ -472,3 +476,18 @@ int dm_io(struct dm_io_request *io_req, unsigned num_regions, &dp, io_req->notify.fn, io_req->notify.context); } EXPORT_SYMBOL(dm_io); + +int __init dm_io_init(void) +{ + _dm_io_cache = KMEM_CACHE(io, 0); + if (!_dm_io_cache) + return -ENOMEM; + + return 0; +} + +void dm_io_exit(void) +{ + kmem_cache_destroy(_dm_io_cache); + _dm_io_cache = NULL; +} diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 724efc6..473f0c3 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -275,6 +275,7 @@ static int (*_inits[])(void) __initdata = { dm_target_init, dm_linear_init, dm_stripe_init, + dm_io_init, dm_kcopyd_init, dm_interface_init, }; @@ -284,6 +285,7 @@ static void (*_exits[])(void) = { dm_target_exit, dm_linear_exit, dm_stripe_exit, + dm_io_exit, dm_kcopyd_exit, dm_interface_exit, }; diff --git a/drivers/md/dm.h b/drivers/md/dm.h index a7663eb..4a95e8f 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -118,6 +118,9 @@ int dm_lock_for_deletion(struct mapped_device *md); void dm_kobject_uevent(struct mapped_device *md, enum kobject_action action, unsigned cookie); +int dm_io_init(void); +void dm_io_exit(void); + int dm_kcopyd_init(void); void dm_kcopyd_exit(void); -- cgit v0.10.2 From f1e539874655ae9e74c1644fd54133b19f1b14e2 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:51:58 +0000 Subject: dm io: remove extra bi_io_vec region hack Remove the hack where we allocate an extra bi_io_vec to store additional private data. This hack prevents us from supporting barriers in dm-raid1 without first making another little block layer change. Instead of doing that, this patch eliminates the bi_io_vec abuse by storing the region number directly in the low bits of bi_private. We need to store two things for each bio, the pointer to the main io structure and, if parallel writes were requested, an index indicating which of these writes this bio belongs to. There can be at most BITS_PER_LONG regions - 32 or 64. The index (region number) was stored in the last (hidden) bio vector and the pointer to struct io was stored in bi_private. This patch now aligns "struct io" on BITS_PER_LONG bytes and stores the region number in the low BITS_PER_LONG bits of bi_private. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index b0d264e..f6a714c 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -16,12 +16,19 @@ #include #include +#define DM_MSG_PREFIX "io" + +#define DM_IO_MAX_REGIONS BITS_PER_LONG + struct dm_io_client { mempool_t *pool; struct bio_set *bios; }; -/* FIXME: can we shrink this ? */ +/* + * Aligning 'struct io' reduces the number of bits required to store + * its address. Refer to store_io_and_region_in_bio() below. + */ struct io { unsigned long error_bits; unsigned long eopnotsupp_bits; @@ -30,7 +37,7 @@ struct io { struct dm_io_client *client; io_notify_fn callback; void *context; -}; +} __attribute__((aligned(DM_IO_MAX_REGIONS))); static struct kmem_cache *_dm_io_cache; @@ -92,18 +99,29 @@ EXPORT_SYMBOL(dm_io_client_destroy); /*----------------------------------------------------------------- * We need to keep track of which region a bio is doing io for. - * In order to save a memory allocation we store this the last - * bvec which we know is unused (blech). - * XXX This is ugly and can OOPS with some configs... find another way. + * To avoid a memory allocation to store just 5 or 6 bits, we + * ensure the 'struct io' pointer is aligned so enough low bits are + * always zero and then combine it with the region number directly in + * bi_private. *---------------------------------------------------------------*/ -static inline void bio_set_region(struct bio *bio, unsigned region) +static void store_io_and_region_in_bio(struct bio *bio, struct io *io, + unsigned region) { - bio->bi_io_vec[bio->bi_max_vecs].bv_len = region; + if (unlikely(!IS_ALIGNED((unsigned long)io, DM_IO_MAX_REGIONS))) { + DMCRIT("Unaligned struct io pointer %p", io); + BUG(); + } + + bio->bi_private = (void *)((unsigned long)io | region); } -static inline unsigned bio_get_region(struct bio *bio) +static void retrieve_io_and_region_from_bio(struct bio *bio, struct io **io, + unsigned *region) { - return bio->bi_io_vec[bio->bi_max_vecs].bv_len; + unsigned long val = (unsigned long)bio->bi_private; + + *io = (void *)(val & -(unsigned long)DM_IO_MAX_REGIONS); + *region = val & (DM_IO_MAX_REGIONS - 1); } /*----------------------------------------------------------------- @@ -144,10 +162,8 @@ static void endio(struct bio *bio, int error) /* * The bio destructor in bio_put() may use the io object. */ - io = bio->bi_private; - region = bio_get_region(bio); + retrieve_io_and_region_from_bio(bio, &io, ®ion); - bio->bi_max_vecs++; bio_put(bio); dec_count(io, region, error); @@ -247,7 +263,10 @@ static void vm_dp_init(struct dpages *dp, void *data) static void dm_bio_destructor(struct bio *bio) { - struct io *io = bio->bi_private; + unsigned region; + struct io *io; + + retrieve_io_and_region_from_bio(bio, &io, ®ion); bio_free(bio, io->client->bios); } @@ -292,24 +311,17 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, while (remaining) { /* - * Allocate a suitably sized-bio: we add an extra - * bvec for bio_get/set_region() and decrement bi_max_vecs - * to hide it from bio_add_page(). + * Allocate a suitably sized-bio. */ num_bvecs = dm_sector_div_up(remaining, (PAGE_SIZE >> SECTOR_SHIFT)); - num_bvecs = 1 + min_t(int, bio_get_nr_vecs(where->bdev), - num_bvecs); - if (unlikely(num_bvecs > BIO_MAX_PAGES)) - num_bvecs = BIO_MAX_PAGES; + num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev), num_bvecs); bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios); bio->bi_sector = where->sector + (where->count - remaining); bio->bi_bdev = where->bdev; bio->bi_end_io = endio; - bio->bi_private = io; bio->bi_destructor = dm_bio_destructor; - bio->bi_max_vecs--; - bio_set_region(bio, region); + store_io_and_region_in_bio(bio, io, region); /* * Try and add as many pages as possible. @@ -337,6 +349,8 @@ static void dispatch_io(int rw, unsigned int num_regions, int i; struct dpages old_pages = *dp; + BUG_ON(num_regions > DM_IO_MAX_REGIONS); + if (sync) rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); @@ -361,7 +375,14 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, struct dm_io_region *where, int rw, struct dpages *dp, unsigned long *error_bits) { - struct io io; + /* + * gcc <= 4.3 can't do the alignment for stack variables, so we must + * align it on our own. + * volatile prevents the optimizer from removing or reusing + * "io_" field from the stack frame (allowed in ANSI C). + */ + volatile char io_[sizeof(struct io) + __alignof__(struct io) - 1]; + struct io *io = (struct io *)PTR_ALIGN(&io_, __alignof__(struct io)); if (num_regions > 1 && (rw & RW_MASK) != WRITE) { WARN_ON(1); @@ -369,33 +390,33 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, } retry: - io.error_bits = 0; - io.eopnotsupp_bits = 0; - atomic_set(&io.count, 1); /* see dispatch_io() */ - io.sleeper = current; - io.client = client; + io->error_bits = 0; + io->eopnotsupp_bits = 0; + atomic_set(&io->count, 1); /* see dispatch_io() */ + io->sleeper = current; + io->client = client; - dispatch_io(rw, num_regions, where, dp, &io, 1); + dispatch_io(rw, num_regions, where, dp, io, 1); while (1) { set_current_state(TASK_UNINTERRUPTIBLE); - if (!atomic_read(&io.count)) + if (!atomic_read(&io->count)) break; io_schedule(); } set_current_state(TASK_RUNNING); - if (io.eopnotsupp_bits && (rw & (1 << BIO_RW_BARRIER))) { + if (io->eopnotsupp_bits && (rw & (1 << BIO_RW_BARRIER))) { rw &= ~(1 << BIO_RW_BARRIER); goto retry; } if (error_bits) - *error_bits = io.error_bits; + *error_bits = io->error_bits; - return io.error_bits ? -EIO : 0; + return io->error_bits ? -EIO : 0; } static int async_io(struct dm_io_client *client, unsigned int num_regions, -- cgit v0.10.2 From 4184153f9e483f9bb63339ed316e059962fe9794 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:51:59 +0000 Subject: dm raid1: support flush Flush support for dm-raid1. When it receives an empty barrier, submit it to all the devices via dm-io. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index cc9dc79..752a29e 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -396,6 +396,8 @@ static int mirror_available(struct mirror_set *ms, struct bio *bio) */ static sector_t map_sector(struct mirror *m, struct bio *bio) { + if (unlikely(!bio->bi_size)) + return 0; return m->offset + (bio->bi_sector - m->ms->ti->begin); } @@ -562,7 +564,7 @@ static void do_write(struct mirror_set *ms, struct bio *bio) struct dm_io_region io[ms->nr_mirrors], *dest = io; struct mirror *m; struct dm_io_request io_req = { - .bi_rw = WRITE, + .bi_rw = WRITE | (bio->bi_rw & WRITE_BARRIER), .mem.type = DM_IO_BVEC, .mem.ptr.bvec = bio->bi_io_vec + bio->bi_idx, .notify.fn = write_callback, @@ -603,6 +605,11 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes) bio_list_init(&requeue); while ((bio = bio_list_pop(writes))) { + if (unlikely(bio_empty_barrier(bio))) { + bio_list_add(&sync, bio); + continue; + } + region = dm_rh_bio_to_region(ms->rh, bio); if (log->type->is_remote_recovering && @@ -995,6 +1002,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) ti->private = ms; ti->split_io = dm_rh_get_region_size(ms->rh); + ti->num_flush_requests = 1; ms->kmirrord_wq = create_singlethread_workqueue("kmirrord"); if (!ms->kmirrord_wq) { @@ -1122,7 +1130,8 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, * We need to dec pending if this was a write. */ if (rw == WRITE) { - dm_rh_dec(ms->rh, map_context->ll); + if (likely(!bio_empty_barrier(bio))) + dm_rh_dec(ms->rh, map_context->ll); return error; } diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c index 36dbe29..00806b7 100644 --- a/drivers/md/dm-region-hash.c +++ b/drivers/md/dm-region-hash.c @@ -79,6 +79,11 @@ struct dm_region_hash { struct list_head recovered_regions; struct list_head failed_recovered_regions; + /* + * If there was a barrier failure no regions can be marked clean. + */ + int barrier_failure; + void *context; sector_t target_begin; @@ -211,6 +216,7 @@ struct dm_region_hash *dm_region_hash_create( INIT_LIST_HEAD(&rh->quiesced_regions); INIT_LIST_HEAD(&rh->recovered_regions); INIT_LIST_HEAD(&rh->failed_recovered_regions); + rh->barrier_failure = 0; rh->region_pool = mempool_create_kmalloc_pool(MIN_REGIONS, sizeof(struct dm_region)); @@ -395,6 +401,11 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, region_t region = dm_rh_bio_to_region(rh, bio); int recovering = 0; + if (bio_empty_barrier(bio)) { + rh->barrier_failure = 1; + return; + } + /* We must inform the log that the sync count has changed. */ log->type->set_region_sync(log, region, 0); @@ -515,8 +526,11 @@ void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios) { struct bio *bio; - for (bio = bios->head; bio; bio = bio->bi_next) + for (bio = bios->head; bio; bio = bio->bi_next) { + if (bio_empty_barrier(bio)) + continue; rh_inc(rh, dm_rh_bio_to_region(rh, bio)); + } } EXPORT_SYMBOL_GPL(dm_rh_inc_pending); @@ -544,7 +558,14 @@ void dm_rh_dec(struct dm_region_hash *rh, region_t region) */ /* do nothing for DM_RH_NOSYNC */ - if (reg->state == DM_RH_RECOVERING) { + if (unlikely(rh->barrier_failure)) { + /* + * If a write barrier failed some time ago, we + * don't know whether or not this write made it + * to the disk, so we must resync the device. + */ + reg->state = DM_RH_NOSYNC; + } else if (reg->state == DM_RH_RECOVERING) { list_add_tail(®->list, &rh->quiesced_regions); } else if (reg->state == DM_RH_DIRTY) { reg->state = DM_RH_CLEAN; -- cgit v0.10.2 From b09acf1aa79462bdacfe6744b469a17722a52702 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:51:59 +0000 Subject: dm raid1: split touched state into two Split the variable "touched" into two, "touched_dirtied" and "touched_cleaned", set when some region was dirtied or cleaned. This will be used to optimize flushes. After a transition from "dirty" to "clean" state we don't have flush hardware cache on the log device. After a transition from "clean" to "dirty" the cache must be flushed. Before a transition from "clean" to "dirty" state we don't have to flush all the raid legs. Before a transition from "dirty" to "clean" we must flush all the legs to make sure that they are really in sync. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 9443896..31dc33d 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -208,7 +208,8 @@ struct log_header { struct log_c { struct dm_target *ti; - int touched; + int touched_dirtied; + int touched_cleaned; uint32_t region_size; unsigned int region_count; region_t sync_count; @@ -253,14 +254,14 @@ static inline void log_set_bit(struct log_c *l, uint32_t *bs, unsigned bit) { ext2_set_bit(bit, (unsigned long *) bs); - l->touched = 1; + l->touched_cleaned = 1; } static inline void log_clear_bit(struct log_c *l, uint32_t *bs, unsigned bit) { ext2_clear_bit(bit, (unsigned long *) bs); - l->touched = 1; + l->touched_dirtied = 1; } /*---------------------------------------------------------------- @@ -378,7 +379,8 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, } lc->ti = ti; - lc->touched = 0; + lc->touched_dirtied = 0; + lc->touched_cleaned = 0; lc->region_size = region_size; lc->region_count = region_count; lc->sync = sync; @@ -660,14 +662,16 @@ static int disk_flush(struct dm_dirty_log *log) struct log_c *lc = (struct log_c *) log->context; /* only write if the log has changed */ - if (!lc->touched) + if (!lc->touched_cleaned && !lc->touched_dirtied) return 0; r = rw_header(lc, WRITE); if (r) fail_log_device(lc); - else - lc->touched = 0; + else { + lc->touched_dirtied = 0; + lc->touched_cleaned = 0; + } return r; } -- cgit v0.10.2 From 20a34a8ecc7d03eaa5054f58169ebff12f5f1f8c Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:00 +0000 Subject: dm log: add flush_header function Introduce flush_header and use it to flush the log device. Note that we don't have to flush if all the regions transition from "dirty" to "clean" state. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 31dc33d..6b23631 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -288,6 +288,19 @@ static int rw_header(struct log_c *lc, int rw) return dm_io(&lc->io_req, 1, &lc->header_location, NULL); } +static int flush_header(struct log_c *lc) +{ + struct dm_io_region null_location = { + .bdev = lc->header_location.bdev, + .sector = 0, + .count = 0, + }; + + lc->io_req.bi_rw = WRITE_BARRIER; + + return dm_io(&lc->io_req, 1, &null_location, NULL); +} + static int read_header(struct log_c *log) { int r; @@ -616,6 +629,8 @@ static int disk_resume(struct dm_dirty_log *log) /* write the new header */ r = rw_header(lc, WRITE); + if (!r) + r = flush_header(lc); if (r) { DMWARN("%s: Failed to write header on dirty region log device", lc->log_dev->name); @@ -669,7 +684,13 @@ static int disk_flush(struct dm_dirty_log *log) if (r) fail_log_device(lc); else { - lc->touched_dirtied = 0; + if (lc->touched_dirtied) { + r = flush_header(lc); + if (r) + fail_log_device(lc); + else + lc->touched_dirtied = 0; + } lc->touched_cleaned = 0; } -- cgit v0.10.2 From 5adc78d0d231b030405b31759f125f13404fdb64 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:00 +0000 Subject: dm log: introduce flush_failed variable Introduce "flush failed" variable. When a flush before clearing a bit in the log fails, we don't know anything about which which regions are in-sync and which not. So we need to set all regions as not-in-sync and set the variable "flush_failed" to prevent setting the in-sync bit in the future. A target reload is the only way to get out of this situation. The variable will be set in following patches. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 6b23631..d779f8c 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -210,6 +210,7 @@ struct log_c { struct dm_target *ti; int touched_dirtied; int touched_cleaned; + int flush_failed; uint32_t region_size; unsigned int region_count; region_t sync_count; @@ -394,6 +395,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, lc->ti = ti; lc->touched_dirtied = 0; lc->touched_cleaned = 0; + lc->flush_failed = 0; lc->region_size = region_size; lc->region_count = region_count; lc->sync = sync; @@ -706,7 +708,8 @@ static void core_mark_region(struct dm_dirty_log *log, region_t region) static void core_clear_region(struct dm_dirty_log *log, region_t region) { struct log_c *lc = (struct log_c *) log->context; - log_set_bit(lc, lc->clean_bits, region); + if (likely(!lc->flush_failed)) + log_set_bit(lc, lc->clean_bits, region); } static int core_get_resync_work(struct dm_dirty_log *log, region_t *region) -- cgit v0.10.2 From 87a8f240e9bcf025ba45e4563c842b0d59c5e8ef Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:01 +0000 Subject: dm log: add flush callback fn Introduce a callback pointer from the log to dm-raid1 layer. Before some region is set as "in-sync", we need to flush hardware cache on all the disks. But the log module doesn't have access to the mirror_set structure. So it will use this callback. So far the callback is unused, it will be used in further patches. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index d779f8c..666a80e 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -145,8 +145,9 @@ int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type) EXPORT_SYMBOL(dm_dirty_log_type_unregister); struct dm_dirty_log *dm_dirty_log_create(const char *type_name, - struct dm_target *ti, - unsigned int argc, char **argv) + struct dm_target *ti, + int (*flush_callback_fn)(struct dm_target *ti), + unsigned int argc, char **argv) { struct dm_dirty_log_type *type; struct dm_dirty_log *log; @@ -161,6 +162,7 @@ struct dm_dirty_log *dm_dirty_log_create(const char *type_name, return NULL; } + log->flush_callback_fn = flush_callback_fn; log->type = type; if (type->ctr(log, ti, argc, argv)) { kfree(log); diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 752a29e..d44bc49 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -896,7 +896,7 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti, return NULL; } - dl = dm_dirty_log_create(argv[0], ti, param_count, argv + 2); + dl = dm_dirty_log_create(argv[0], ti, NULL, param_count, argv + 2); if (!dl) { ti->error = "Error creating mirror dirty log"; return NULL; diff --git a/include/linux/dm-dirty-log.h b/include/linux/dm-dirty-log.h index 5e8b11d..7084503 100644 --- a/include/linux/dm-dirty-log.h +++ b/include/linux/dm-dirty-log.h @@ -21,6 +21,7 @@ struct dm_dirty_log_type; struct dm_dirty_log { struct dm_dirty_log_type *type; + int (*flush_callback_fn)(struct dm_target *ti); void *context; }; @@ -136,8 +137,9 @@ int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type); * type->constructor/destructor() directly. */ struct dm_dirty_log *dm_dirty_log_create(const char *type_name, - struct dm_target *ti, - unsigned argc, char **argv); + struct dm_target *ti, + int (*flush_callback_fn)(struct dm_target *ti), + unsigned argc, char **argv); void dm_dirty_log_destroy(struct dm_dirty_log *log); #endif /* __KERNEL__ */ -- cgit v0.10.2 From 076010e2e6ea5b66dfd1f81a6133fb014c9b291d Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:01 +0000 Subject: dm log: use flush callback fn Call the flush callback from the log. If flush failed, we have no alternative but to mark the whole log as dirty. Also we set the variable flush_failed to prevent any bits ever being marked as clean again. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 666a80e..315e36a 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -677,13 +677,26 @@ static int core_flush(struct dm_dirty_log *log) static int disk_flush(struct dm_dirty_log *log) { - int r; - struct log_c *lc = (struct log_c *) log->context; + int r, i; + struct log_c *lc = log->context; /* only write if the log has changed */ if (!lc->touched_cleaned && !lc->touched_dirtied) return 0; + if (lc->touched_cleaned && log->flush_callback_fn && + log->flush_callback_fn(lc->ti)) { + /* + * At this point it is impossible to determine which + * regions are clean and which are dirty (without + * re-reading the log off disk). So mark all of them + * dirty. + */ + lc->flush_failed = 1; + for (i = 0; i < lc->region_count; i++) + log_clear_bit(lc, lc->clean_bits, i); + } + r = rw_header(lc, WRITE); if (r) fail_log_device(lc); -- cgit v0.10.2 From c0da3748b9a894b9f9b561ecc2d090a913988a0f Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:02 +0000 Subject: dm raid1: implement mirror_flush Implement flush callee. It uses dm_io to send zero-size barrier synchronously and concurrently to all the mirror legs. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index d44bc49..751660b 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -237,6 +237,40 @@ out: schedule_work(&ms->trigger_event); } +static int mirror_flush(struct dm_target *ti) +{ + struct mirror_set *ms = ti->private; + unsigned long error_bits; + + unsigned int i; + struct dm_io_region io[ms->nr_mirrors]; + struct mirror *m; + struct dm_io_request io_req = { + .bi_rw = WRITE_BARRIER, + .mem.type = DM_IO_KMEM, + .mem.ptr.bvec = NULL, + .client = ms->io_client, + }; + + for (i = 0, m = ms->mirror; i < ms->nr_mirrors; i++, m++) { + io[i].bdev = m->dev->bdev; + io[i].sector = 0; + io[i].count = 0; + } + + error_bits = -1; + dm_io(&io_req, ms->nr_mirrors, io, &error_bits); + if (unlikely(error_bits != 0)) { + for (i = 0; i < ms->nr_mirrors; i++) + if (test_bit(i, &error_bits)) + fail_mirror(ms->mirror + i, + DM_RAID1_WRITE_ERROR); + return -EIO; + } + + return 0; +} + /*----------------------------------------------------------------- * Recovery. * @@ -896,7 +930,8 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti, return NULL; } - dl = dm_dirty_log_create(argv[0], ti, NULL, param_count, argv + 2); + dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count, + argv + 2); if (!dl) { ti->error = "Error creating mirror dirty log"; return NULL; -- cgit v0.10.2 From 64b30c46e866bbff8a9e17883a18636adc358455 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:02 +0000 Subject: dm raid1: report flush errors separately in status Report flush errors as 'F' instead of 'D' for log and mirror devices. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 315e36a..7035582 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -237,6 +237,7 @@ struct log_c { * Disk log fields */ int log_dev_failed; + int log_dev_flush_failed; struct dm_dev *log_dev; struct log_header header; @@ -425,6 +426,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, } else { lc->log_dev = dev; lc->log_dev_failed = 0; + lc->log_dev_flush_failed = 0; lc->header_location.bdev = lc->log_dev->bdev; lc->header_location.sector = 0; @@ -633,8 +635,11 @@ static int disk_resume(struct dm_dirty_log *log) /* write the new header */ r = rw_header(lc, WRITE); - if (!r) + if (!r) { r = flush_header(lc); + if (r) + lc->log_dev_flush_failed = 1; + } if (r) { DMWARN("%s: Failed to write header on dirty region log device", lc->log_dev->name); @@ -703,9 +708,10 @@ static int disk_flush(struct dm_dirty_log *log) else { if (lc->touched_dirtied) { r = flush_header(lc); - if (r) + if (r) { + lc->log_dev_flush_failed = 1; fail_log_device(lc); - else + } else lc->touched_dirtied = 0; } lc->touched_cleaned = 0; @@ -805,7 +811,9 @@ static int disk_status(struct dm_dirty_log *log, status_type_t status, switch(status) { case STATUSTYPE_INFO: DMEMIT("3 %s %s %c", log->type->name, lc->log_dev->name, - lc->log_dev_failed ? 'D' : 'A'); + lc->log_dev_flush_failed ? 'F' : + lc->log_dev_failed ? 'D' : + 'A'); break; case STATUSTYPE_TABLE: diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 751660b..85c8704 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -35,6 +35,7 @@ static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped); *---------------------------------------------------------------*/ enum dm_raid1_error { DM_RAID1_WRITE_ERROR, + DM_RAID1_FLUSH_ERROR, DM_RAID1_SYNC_ERROR, DM_RAID1_READ_ERROR }; @@ -264,7 +265,7 @@ static int mirror_flush(struct dm_target *ti) for (i = 0; i < ms->nr_mirrors; i++) if (test_bit(i, &error_bits)) fail_mirror(ms->mirror + i, - DM_RAID1_WRITE_ERROR); + DM_RAID1_FLUSH_ERROR); return -EIO; } @@ -1288,7 +1289,8 @@ static char device_status_char(struct mirror *m) if (!atomic_read(&(m->error_count))) return 'A'; - return (test_bit(DM_RAID1_WRITE_ERROR, &(m->error_type))) ? 'D' : + return (test_bit(DM_RAID1_FLUSH_ERROR, &(m->error_type))) ? 'F' : + (test_bit(DM_RAID1_WRITE_ERROR, &(m->error_type))) ? 'D' : (test_bit(DM_RAID1_SYNC_ERROR, &(m->error_type))) ? 'S' : (test_bit(DM_RAID1_READ_ERROR, &(m->error_type))) ? 'R' : 'U'; } -- cgit v0.10.2 From 04788507686d184d8166918b70ef52311bc36dcb Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:03 +0000 Subject: dm raid1: add framework to hold bios during suspend Add framework to delay bios until a suspend and then resubmit them with either DM_ENDIO_REQUEUE (if the suspend was noflush) or complete them with -EIO. I/O barrier support will use this. Signed-off-by: Mikulas Patocka Reviewed-by: Takahiro Yasui Tested-by: Takahiro Yasui Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 85c8704..895cce7 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -58,6 +58,7 @@ struct mirror_set { struct bio_list reads; struct bio_list writes; struct bio_list failures; + struct bio_list holds; /* bios are waiting until suspend */ struct dm_region_hash *rh; struct dm_kcopyd_client *kcopyd_client; @@ -450,6 +451,27 @@ static void map_region(struct dm_io_region *io, struct mirror *m, io->count = bio->bi_size >> 9; } +static void hold_bio(struct mirror_set *ms, struct bio *bio) +{ + /* + * If device is suspended, complete the bio. + */ + if (atomic_read(&ms->suspend)) { + if (dm_noflush_suspending(ms->ti)) + bio_endio(bio, DM_ENDIO_REQUEUE); + else + bio_endio(bio, -EIO); + return; + } + + /* + * Hold bio until the suspend is complete. + */ + spin_lock_irq(&ms->lock); + bio_list_add(&ms->holds, bio); + spin_unlock_irq(&ms->lock); +} + /*----------------------------------------------------------------- * Reads *---------------------------------------------------------------*/ @@ -1225,6 +1247,9 @@ static void mirror_presuspend(struct dm_target *ti) struct mirror_set *ms = (struct mirror_set *) ti->private; struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh); + struct bio_list holds; + struct bio *bio; + atomic_set(&ms->suspend, 1); /* @@ -1247,6 +1272,22 @@ static void mirror_presuspend(struct dm_target *ti) * we know that all of our I/O has been pushed. */ flush_workqueue(ms->kmirrord_wq); + + /* + * Now set ms->suspend is set and the workqueue flushed, no more + * entries can be added to ms->hold list, so process it. + * + * Bios can still arrive concurrently with or after this + * presuspend function, but they cannot join the hold list + * because ms->suspend is set. + */ + spin_lock_irq(&ms->lock); + holds = ms->holds; + bio_list_init(&ms->holds); + spin_unlock_irq(&ms->lock); + + while ((bio = bio_list_pop(&holds))) + hold_bio(ms, bio); } static void mirror_postsuspend(struct dm_target *ti) -- cgit v0.10.2 From 0f398a8403e31c737b429fddc3850093d0bf58d0 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:04 +0000 Subject: dm raid1: use hold framework in do_failures Use the hold framework in do_failures. This patch doesn't change the bio processing logic, it just simplifies failure handling and avoids periodically polling the failures list. Signed-off-by: Mikulas Patocka Reviewed-by: Takahiro Yasui Tested-by: Takahiro Yasui Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 895cce7..0253130 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -745,20 +745,12 @@ static void do_failures(struct mirror_set *ms, struct bio_list *failures) { struct bio *bio; - if (!failures->head) + if (likely(!failures->head)) return; - if (!ms->log_failure) { - while ((bio = bio_list_pop(failures))) { - ms->in_sync = 0; - dm_rh_mark_nosync(ms->rh, bio, bio->bi_size, 0); - } - return; - } - /* * If the log has failed, unattempted writes are being - * put on the failures list. We can't issue those writes + * put on the holds list. We can't issue those writes * until a log has been marked, so we must store them. * * If a 'noflush' suspend is in progress, we can requeue @@ -773,23 +765,15 @@ static void do_failures(struct mirror_set *ms, struct bio_list *failures) * for us to treat them the same and requeue them * as well. */ - if (dm_noflush_suspending(ms->ti)) { - while ((bio = bio_list_pop(failures))) - bio_endio(bio, DM_ENDIO_REQUEUE); - return; - } - if (atomic_read(&ms->suspend)) { - while ((bio = bio_list_pop(failures))) - bio_endio(bio, -EIO); - return; + while ((bio = bio_list_pop(failures))) { + if (ms->log_failure) + hold_bio(ms, bio); + else { + ms->in_sync = 0; + dm_rh_mark_nosync(ms->rh, bio, bio->bi_size, 0); + } } - - spin_lock_irq(&ms->lock); - bio_list_merge(&ms->failures, failures); - spin_unlock_irq(&ms->lock); - - delayed_wake(ms); } static void trigger_event(struct work_struct *work) -- cgit v0.10.2 From 87968ddd2f3be1c21b932cac30157a83a1c4f935 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:04 +0000 Subject: dm raid1: abstract get_valid_mirror function Move the logic to get a valid mirror leg into a function for re-use in a later patch. Signed-off-by: Mikulas Patocka Reviewed-by: Takahiro Yasui Tested-by: Takahiro Yasui Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 0253130..d1a7f1a 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -181,6 +181,17 @@ static void set_default_mirror(struct mirror *m) atomic_set(&ms->default_mirror, m - m0); } +static struct mirror *get_valid_mirror(struct mirror_set *ms) +{ + struct mirror *m; + + for (m = ms->mirror; m < ms->mirror + ms->nr_mirrors; m++) + if (!atomic_read(&m->error_count)) + return m; + + return NULL; +} + /* fail_mirror * @m: mirror device to fail * @error_type: one of the enum's, DM_RAID1_*_ERROR @@ -226,13 +237,10 @@ static void fail_mirror(struct mirror *m, enum dm_raid1_error error_type) goto out; } - for (new = ms->mirror; new < ms->mirror + ms->nr_mirrors; new++) - if (!atomic_read(&new->error_count)) { - set_default_mirror(new); - break; - } - - if (unlikely(new == ms->mirror + ms->nr_mirrors)) + new = get_valid_mirror(ms); + if (new) + set_default_mirror(new); + else DMWARN("All sides of mirror have failed."); out: -- cgit v0.10.2 From c58098be979509a54021e837a47fcad08db31f94 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:05 +0000 Subject: dm raid1: remove bio_endio from dm_rh_mark_nosync Move bio completion out of dm_rh_mark_nosync in preparation for the next patch. Signed-off-by: Mikulas Patocka Reviewed-by: Takahiro Yasui Tested-by: Takahiro Yasui Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index d1a7f1a..4f466ad 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -779,7 +779,8 @@ static void do_failures(struct mirror_set *ms, struct bio_list *failures) hold_bio(ms, bio); else { ms->in_sync = 0; - dm_rh_mark_nosync(ms->rh, bio, bio->bi_size, 0); + dm_rh_mark_nosync(ms->rh, bio); + bio_endio(bio, 0); } } } diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c index 00806b7..5f19ceb 100644 --- a/drivers/md/dm-region-hash.c +++ b/drivers/md/dm-region-hash.c @@ -383,8 +383,6 @@ static void complete_resync_work(struct dm_region *reg, int success) /* dm_rh_mark_nosync * @ms * @bio - * @done - * @error * * The bio was written on some mirror(s) but failed on other mirror(s). * We can successfully endio the bio but should avoid the region being @@ -392,8 +390,7 @@ static void complete_resync_work(struct dm_region *reg, int success) * * This function is _not_ safe in interrupt context! */ -void dm_rh_mark_nosync(struct dm_region_hash *rh, - struct bio *bio, unsigned done, int error) +void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio) { unsigned long flags; struct dm_dirty_log *log = rh->log; @@ -430,7 +427,6 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, BUG_ON(!list_empty(®->list)); spin_unlock_irqrestore(&rh->region_lock, flags); - bio_endio(bio, error); if (recovering) complete_resync_work(reg, 0); } diff --git a/include/linux/dm-region-hash.h b/include/linux/dm-region-hash.h index a9e652a..9e2a7a4 100644 --- a/include/linux/dm-region-hash.h +++ b/include/linux/dm-region-hash.h @@ -78,8 +78,7 @@ void dm_rh_dec(struct dm_region_hash *rh, region_t region); /* Delay bios on regions. */ void dm_rh_delay(struct dm_region_hash *rh, struct bio *bio); -void dm_rh_mark_nosync(struct dm_region_hash *rh, - struct bio *bio, unsigned done, int error); +void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio); /* * Region recovery control. -- cgit v0.10.2 From 60f355ead31e2be8d06ac8acb163df91a1c64e3b Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:05 +0000 Subject: dm raid1: hold write bios when errors are handled Hold all write bios when errors are handled. Previously the failures list was used only when handling errors with a userspace daemon such as dmeventd. Now, it is always used for all bios. The regions where some writes failed must be marked as nosync. This can only be done in process context (i.e. in raid1 workqueue), not in the write_callback function. Previously the write would succeed if writing to at least one leg succeeded. This is wrong because data from the failed leg may be replicated to the correct leg. Now, if using a userspace daemon, the write with some failures will be held until the daemon has done its job and reconfigured the array. If not using a daemon, the write still succeeds if at least one leg succeeds. This is bad, but it is consistent with current behavior. Signed-off-by: Mikulas Patocka Reviewed-by: Takahiro Yasui Tested-by: Takahiro Yasui Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 4f466ad..e363335 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -578,7 +578,6 @@ static void write_callback(unsigned long error, void *context) unsigned i, ret = 0; struct bio *bio = (struct bio *) context; struct mirror_set *ms; - int uptodate = 0; int should_wake = 0; unsigned long flags; @@ -591,36 +590,27 @@ static void write_callback(unsigned long error, void *context) * This way we handle both writes to SYNC and NOSYNC * regions with the same code. */ - if (likely(!error)) - goto out; + if (likely(!error)) { + bio_endio(bio, ret); + return; + } for (i = 0; i < ms->nr_mirrors; i++) if (test_bit(i, &error)) fail_mirror(ms->mirror + i, DM_RAID1_WRITE_ERROR); - else - uptodate = 1; - if (unlikely(!uptodate)) { - DMERR("All replicated volumes dead, failing I/O"); - /* None of the writes succeeded, fail the I/O. */ - ret = -EIO; - } else if (errors_handled(ms)) { - /* - * Need to raise event. Since raising - * events can block, we need to do it in - * the main thread. - */ - spin_lock_irqsave(&ms->lock, flags); - if (!ms->failures.head) - should_wake = 1; - bio_list_add(&ms->failures, bio); - spin_unlock_irqrestore(&ms->lock, flags); - if (should_wake) - wakeup_mirrord(ms); - return; - } -out: - bio_endio(bio, ret); + /* + * Need to raise event. Since raising + * events can block, we need to do it in + * the main thread. + */ + spin_lock_irqsave(&ms->lock, flags); + if (!ms->failures.head) + should_wake = 1; + bio_list_add(&ms->failures, bio); + spin_unlock_irqrestore(&ms->lock, flags); + if (should_wake) + wakeup_mirrord(ms); } static void do_write(struct mirror_set *ms, struct bio *bio) @@ -773,15 +763,26 @@ static void do_failures(struct mirror_set *ms, struct bio_list *failures) * for us to treat them the same and requeue them * as well. */ - while ((bio = bio_list_pop(failures))) { - if (ms->log_failure) - hold_bio(ms, bio); - else { + if (!ms->log_failure) { ms->in_sync = 0; dm_rh_mark_nosync(ms->rh, bio); - bio_endio(bio, 0); } + + /* + * If all the legs are dead, fail the I/O. + * If we have been told to handle errors, hold the bio + * and wait for userspace to deal with the problem. + * Otherwise pretend that the I/O succeeded. (This would + * be wrong if the failed leg returned after reboot and + * got replicated back to the good legs.) + */ + if (!get_valid_mirror(ms)) + bio_endio(bio, -EIO); + else if (errors_handled(ms)) + hold_bio(ms, bio); + else + bio_endio(bio, 0); } } -- cgit v0.10.2 From 929be8fcb4b4b65d038e73d3bb34715851a95ca2 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:06 +0000 Subject: dm raid1: hold all write bios when leg fails Hold all write bios when leg fails and errors are handled When using a userspace daemon such as dmeventd to handle errors, we must delay completing bios until it has done its job. This patch prevents the following race: - primary leg fails - write "1" fail, the write is held, secondary leg is set default - write "2" goes straight to the secondary leg Signed-off-by: Mikulas Patocka Reviewed-by: Takahiro Yasui Tested-by: Takahiro Yasui Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index e363335..f8d7b3a 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -69,6 +69,7 @@ struct mirror_set { region_t nr_regions; int in_sync; int log_failure; + int leg_failure; atomic_t suspend; atomic_t default_mirror; /* Default mirror */ @@ -211,6 +212,8 @@ static void fail_mirror(struct mirror *m, enum dm_raid1_error error_type) struct mirror_set *ms = m->ms; struct mirror *new; + ms->leg_failure = 1; + /* * error_count is used for nothing more than a * simple way to tell if a device has encountered @@ -734,8 +737,12 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes) dm_rh_delay(ms->rh, bio); while ((bio = bio_list_pop(&nosync))) { - map_bio(get_default_mirror(ms), bio); - generic_make_request(bio); + if (unlikely(ms->leg_failure) && errors_handled(ms)) + hold_bio(ms, bio); + else { + map_bio(get_default_mirror(ms), bio); + generic_make_request(bio); + } } } @@ -848,6 +855,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, ms->nr_regions = dm_sector_div_up(ti->len, region_size); ms->in_sync = 0; ms->log_failure = 0; + ms->leg_failure = 0; atomic_set(&ms->suspend, 0); atomic_set(&ms->default_mirror, DEFAULT_MIRROR); -- cgit v0.10.2 From 5339fc2d47d1d720e027b9b832bf5aae8fba2ac0 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:06 +0000 Subject: dm raid1: explicitly initialise bio_lists Explicitly initialize bio lists instead of relying on kzalloc. Signed-off-by: Mikulas Patocka Reviewed-by: Takahiro Yasui Tested-by: Takahiro Yasui Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index f8d7b3a..ad779bd 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -849,6 +849,10 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, } spin_lock_init(&ms->lock); + bio_list_init(&ms->reads); + bio_list_init(&ms->writes); + bio_list_init(&ms->failures); + bio_list_init(&ms->holds); ms->ti = ti; ms->nr_mirrors = nr_mirrors; -- cgit v0.10.2 From a518b86d0b1b6a474f154697dc6f33e0a317ae72 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Thu, 10 Dec 2009 23:52:07 +0000 Subject: dm ioctl: prefer strlcpy over strncpy strlcpy() will always null terminate the string. The code should already guarantee this as the last bytes are already NULs and the string lengths were restricted before being stored in hc. Removing the '-1' becomes necessary so strlcpy() doesn't lose the last character of a maximum-length string. - agk Signed-off-by: Roel Kluin Signed-off-by: Andrew Morton Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index d19854c..99de0e4 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -645,9 +645,9 @@ static struct mapped_device *find_device(struct dm_ioctl *param) * Sneakily write in both the name and the uuid * while we have the cell. */ - strncpy(param->name, hc->name, sizeof(param->name)); + strlcpy(param->name, hc->name, sizeof(param->name)); if (hc->uuid) - strncpy(param->uuid, hc->uuid, sizeof(param->uuid)-1); + strlcpy(param->uuid, hc->uuid, sizeof(param->uuid)); else param->uuid[0] = '\0'; -- cgit v0.10.2 From f5acc834287dd4f6cf712093ce0e779e38caad70 Mon Sep 17 00:00:00 2001 From: Jon Brassow Date: Thu, 10 Dec 2009 23:52:07 +0000 Subject: dm snapshot: avoid else clause in persistent_read_metadata Minor code touch-up. We don't need the 'else'. Signed-off-by: Jonathan Brassow Reviewed-by: Mikulas Patocka Reviewed-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 0c74642..7e855fb 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c @@ -552,35 +552,31 @@ static int persistent_read_metadata(struct dm_exception_store *store, ps->current_area = 0; zero_memory_area(ps); r = zero_disk_area(ps, 0); - if (r) { + if (r) DMWARN("zero_disk_area(0) failed"); - return r; - } - } else { - /* - * Sanity checks. - */ - if (ps->version != SNAPSHOT_DISK_VERSION) { - DMWARN("unable to handle snapshot disk version %d", - ps->version); - return -EINVAL; - } + return r; + } + /* + * Sanity checks. + */ + if (ps->version != SNAPSHOT_DISK_VERSION) { + DMWARN("unable to handle snapshot disk version %d", + ps->version); + return -EINVAL; + } - /* - * Metadata are valid, but snapshot is invalidated - */ - if (!ps->valid) - return 1; + /* + * Metadata are valid, but snapshot is invalidated + */ + if (!ps->valid) + return 1; - /* - * Read the metadata. - */ - r = read_exceptions(ps, callback, callback_context); - if (r) - return r; - } + /* + * Read the metadata. + */ + r = read_exceptions(ps, callback, callback_context); - return 0; + return r; } static int persistent_prepare_exception(struct dm_exception_store *store, -- cgit v0.10.2 From 102c6ddb1d081a6a1fede38c43a42c9811313ec7 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:08 +0000 Subject: dm snapshot: simplify sector_to_chunk expression Removed unnecessary 'and' masking: The right shift discards the lower bits so there is no need to clear them. (A later patch needs this change to support a 32-bit chunk_mask.) Signed-off-by: Mikulas Patocka Reviewed-by: Mike Snitzer Reviewed-by: Jonathan Brassow Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h index 8a223a4..5f9315b 100644 --- a/drivers/md/dm-exception-store.h +++ b/drivers/md/dm-exception-store.h @@ -162,7 +162,7 @@ static inline sector_t get_dev_size(struct block_device *bdev) static inline chunk_t sector_to_chunk(struct dm_exception_store *store, sector_t sector) { - return (sector & ~store->chunk_mask) >> store->chunk_shift; + return sector >> store->chunk_shift; } int dm_exception_store_type_register(struct dm_exception_store_type *type); -- cgit v0.10.2 From 7e201b35132a1f02c931a0a06760766c846bb49b Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:08 +0000 Subject: dm snapshot: abstract minimum_chunk_size fn The origin needs to find minimum chunksize of all snapshots. This logic is moved to a separate function because it will be used at another place in the snapshot merge patches. Signed-off-by: Mikulas Patocka Reviewed-by: Mike Snitzer Reviewed-by: Jonathan Brassow Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 8a4a9c8..48978ab 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -523,6 +523,25 @@ static int dm_add_exception(void *context, chunk_t old, chunk_t new) return 0; } +#define min_not_zero(l, r) (((l) == 0) ? (r) : (((r) == 0) ? (l) : min(l, r))) + +/* + * Return a minimum chunk size of all snapshots that have the specified origin. + * Return zero if the origin has no snapshots. + */ +static sector_t __minimum_chunk_size(struct origin *o) +{ + struct dm_snapshot *snap; + unsigned chunk_size = 0; + + if (o) + list_for_each_entry(snap, &o->snapshots, list) + chunk_size = min_not_zero(chunk_size, + snap->store->chunk_size); + + return chunk_size; +} + /* * Hard coded magic. */ @@ -1395,8 +1414,6 @@ static int origin_map(struct dm_target *ti, struct bio *bio, return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : DM_MAPIO_REMAPPED; } -#define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r)) - /* * Set the target "split_io" field to the minimum of all the snapshots' * chunk sizes. @@ -1404,19 +1421,12 @@ static int origin_map(struct dm_target *ti, struct bio *bio, static void origin_resume(struct dm_target *ti) { struct dm_dev *dev = ti->private; - struct dm_snapshot *snap; - struct origin *o; - unsigned chunk_size = 0; down_read(&_origins_lock); - o = __lookup_origin(dev->bdev); - if (o) - list_for_each_entry (snap, &o->snapshots, list) - chunk_size = min_not_zero(chunk_size, - snap->store->chunk_size); - up_read(&_origins_lock); - ti->split_io = chunk_size; + ti->split_io = __minimum_chunk_size(__lookup_origin(dev->bdev)); + + up_read(&_origins_lock); } static int origin_status(struct dm_target *ti, status_type_t type, char *result, -- cgit v0.10.2 From d32a6ea65fbc33621f9c790da3dff10201640b2a Mon Sep 17 00:00:00 2001 From: Jon Brassow Date: Thu, 10 Dec 2009 23:52:09 +0000 Subject: dm snapshot: consolidate insert exception functions Consolidate the insert_*exception functions. 'insert_completed_exception' already contains all the logic to handle 'insert_exception' (via check for a hash_shift of 0), so remove redundant function. Signed-off-by: Jonathan Brassow Reviewed-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 48978ab..9135498 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -390,13 +390,6 @@ static uint32_t exception_hash(struct exception_table *et, chunk_t chunk) return (chunk >> et->hash_shift) & et->hash_mask; } -static void insert_exception(struct exception_table *eh, - struct dm_snap_exception *e) -{ - struct list_head *l = &eh->table[exception_hash(eh, e->old_chunk)]; - list_add(&e->hash_list, l); -} - static void remove_exception(struct dm_snap_exception *e) { list_del(&e->hash_list); @@ -457,10 +450,9 @@ static void free_pending_exception(struct dm_snap_pending_exception *pe) atomic_dec(&s->pending_exceptions_count); } -static void insert_completed_exception(struct dm_snapshot *s, - struct dm_snap_exception *new_e) +static void insert_exception(struct exception_table *eh, + struct dm_snap_exception *new_e) { - struct exception_table *eh = &s->complete; struct list_head *l; struct dm_snap_exception *e = NULL; @@ -518,7 +510,7 @@ static int dm_add_exception(void *context, chunk_t old, chunk_t new) /* Consecutive_count is implicitly initialised to zero */ e->new_chunk = new; - insert_completed_exception(s, e); + insert_exception(&s->complete, e); return 0; } @@ -925,7 +917,7 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) * Add a proper exception, and remove the * in-flight exception from the list. */ - insert_completed_exception(s, e); + insert_exception(&s->complete, e); out: remove_exception(&pe->e); -- cgit v0.10.2 From 1d4989c858093bda0426be536fc7f9c415857836 Mon Sep 17 00:00:00 2001 From: Jon Brassow Date: Thu, 10 Dec 2009 23:52:10 +0000 Subject: dm snapshot: rename dm_snap_exception to dm_exception The exception structure is not necessarily just a snapshot element (especially after we pull it out of dm-snap.c). Renaming appropriately. Signed-off-by: Jonathan Brassow Reviewed-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h index 5f9315b..9274969 100644 --- a/drivers/md/dm-exception-store.h +++ b/drivers/md/dm-exception-store.h @@ -26,7 +26,7 @@ typedef sector_t chunk_t; * of chunks that follow contiguously. Remaining bits hold the number of the * chunk within the device. */ -struct dm_snap_exception { +struct dm_exception { struct list_head hash_list; chunk_t old_chunk; @@ -64,13 +64,13 @@ struct dm_exception_store_type { * Find somewhere to store the next exception. */ int (*prepare_exception) (struct dm_exception_store *store, - struct dm_snap_exception *e); + struct dm_exception *e); /* * Update the metadata with this exception. */ void (*commit_exception) (struct dm_exception_store *store, - struct dm_snap_exception *e, + struct dm_exception *e, void (*callback) (void *, int success), void *callback_context); @@ -120,12 +120,12 @@ static inline chunk_t dm_chunk_number(chunk_t chunk) return chunk & (chunk_t)((1ULL << DM_CHUNK_NUMBER_BITS) - 1ULL); } -static inline unsigned dm_consecutive_chunk_count(struct dm_snap_exception *e) +static inline unsigned dm_consecutive_chunk_count(struct dm_exception *e) { return e->new_chunk >> DM_CHUNK_NUMBER_BITS; } -static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e) +static inline void dm_consecutive_chunk_count_inc(struct dm_exception *e) { e->new_chunk += (1ULL << DM_CHUNK_NUMBER_BITS); @@ -140,12 +140,12 @@ static inline chunk_t dm_chunk_number(chunk_t chunk) return chunk; } -static inline unsigned dm_consecutive_chunk_count(struct dm_snap_exception *e) +static inline unsigned dm_consecutive_chunk_count(struct dm_exception *e) { return 0; } -static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e) +static inline void dm_consecutive_chunk_count_inc(struct dm_exception *e) { } diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 7e855fb..24b8acd 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c @@ -580,7 +580,7 @@ static int persistent_read_metadata(struct dm_exception_store *store, } static int persistent_prepare_exception(struct dm_exception_store *store, - struct dm_snap_exception *e) + struct dm_exception *e) { struct pstore *ps = get_info(store); uint32_t stride; @@ -607,7 +607,7 @@ static int persistent_prepare_exception(struct dm_exception_store *store, } static void persistent_commit_exception(struct dm_exception_store *store, - struct dm_snap_exception *e, + struct dm_exception *e, void (*callback) (void *, int success), void *callback_context) { diff --git a/drivers/md/dm-snap-transient.c b/drivers/md/dm-snap-transient.c index cde5aa5..267801b 100644 --- a/drivers/md/dm-snap-transient.c +++ b/drivers/md/dm-snap-transient.c @@ -36,7 +36,7 @@ static int transient_read_metadata(struct dm_exception_store *store, } static int transient_prepare_exception(struct dm_exception_store *store, - struct dm_snap_exception *e) + struct dm_exception *e) { struct transient_c *tc = store->context; sector_t size = get_dev_size(store->cow->bdev); @@ -51,7 +51,7 @@ static int transient_prepare_exception(struct dm_exception_store *store, } static void transient_commit_exception(struct dm_exception_store *store, - struct dm_snap_exception *e, + struct dm_exception *e, void (*callback) (void *, int success), void *callback_context) { diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 9135498..a7d60f6 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -116,7 +116,7 @@ static int bdev_equal(struct block_device *lhs, struct block_device *rhs) } struct dm_snap_pending_exception { - struct dm_snap_exception e; + struct dm_exception e; /* * Origin buffers waiting for this to complete are held @@ -371,7 +371,7 @@ static int init_exception_table(struct exception_table *et, uint32_t size, static void exit_exception_table(struct exception_table *et, struct kmem_cache *mem) { struct list_head *slot; - struct dm_snap_exception *ex, *next; + struct dm_exception *ex, *next; int i, size; size = et->hash_mask + 1; @@ -390,7 +390,7 @@ static uint32_t exception_hash(struct exception_table *et, chunk_t chunk) return (chunk >> et->hash_shift) & et->hash_mask; } -static void remove_exception(struct dm_snap_exception *e) +static void remove_exception(struct dm_exception *e) { list_del(&e->hash_list); } @@ -399,11 +399,11 @@ static void remove_exception(struct dm_snap_exception *e) * Return the exception data for a sector, or NULL if not * remapped. */ -static struct dm_snap_exception *lookup_exception(struct exception_table *et, +static struct dm_exception *lookup_exception(struct exception_table *et, chunk_t chunk) { struct list_head *slot; - struct dm_snap_exception *e; + struct dm_exception *e; slot = &et->table[exception_hash(et, chunk)]; list_for_each_entry (e, slot, hash_list) @@ -414,9 +414,9 @@ static struct dm_snap_exception *lookup_exception(struct exception_table *et, return NULL; } -static struct dm_snap_exception *alloc_exception(void) +static struct dm_exception *alloc_exception(void) { - struct dm_snap_exception *e; + struct dm_exception *e; e = kmem_cache_alloc(exception_cache, GFP_NOIO); if (!e) @@ -425,7 +425,7 @@ static struct dm_snap_exception *alloc_exception(void) return e; } -static void free_exception(struct dm_snap_exception *e) +static void free_exception(struct dm_exception *e) { kmem_cache_free(exception_cache, e); } @@ -451,10 +451,10 @@ static void free_pending_exception(struct dm_snap_pending_exception *pe) } static void insert_exception(struct exception_table *eh, - struct dm_snap_exception *new_e) + struct dm_exception *new_e) { struct list_head *l; - struct dm_snap_exception *e = NULL; + struct dm_exception *e = NULL; l = &eh->table[exception_hash(eh, new_e->old_chunk)]; @@ -499,7 +499,7 @@ out: static int dm_add_exception(void *context, chunk_t old, chunk_t new) { struct dm_snapshot *s = context; - struct dm_snap_exception *e; + struct dm_exception *e; e = alloc_exception(); if (!e) @@ -876,7 +876,7 @@ static struct bio *put_pending_exception(struct dm_snap_pending_exception *pe) static void pending_complete(struct dm_snap_pending_exception *pe, int success) { - struct dm_snap_exception *e; + struct dm_exception *e; struct dm_snapshot *s = pe->snap; struct bio *origin_bios = NULL; struct bio *snapshot_bios = NULL; @@ -988,7 +988,7 @@ static void start_copy(struct dm_snap_pending_exception *pe) static struct dm_snap_pending_exception * __lookup_pending_exception(struct dm_snapshot *s, chunk_t chunk) { - struct dm_snap_exception *e = lookup_exception(&s->pending, chunk); + struct dm_exception *e = lookup_exception(&s->pending, chunk); if (!e) return NULL; @@ -1034,7 +1034,7 @@ __find_pending_exception(struct dm_snapshot *s, return pe; } -static void remap_exception(struct dm_snapshot *s, struct dm_snap_exception *e, +static void remap_exception(struct dm_snapshot *s, struct dm_exception *e, struct bio *bio, chunk_t chunk) { bio->bi_bdev = s->store->cow->bdev; @@ -1048,7 +1048,7 @@ static void remap_exception(struct dm_snapshot *s, struct dm_snap_exception *e, static int snapshot_map(struct dm_target *ti, struct bio *bio, union map_info *map_context) { - struct dm_snap_exception *e; + struct dm_exception *e; struct dm_snapshot *s = ti->private; int r = DM_MAPIO_REMAPPED; chunk_t chunk; @@ -1221,7 +1221,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) { int r = DM_MAPIO_REMAPPED, first = 0; struct dm_snapshot *snap; - struct dm_snap_exception *e; + struct dm_exception *e; struct dm_snap_pending_exception *pe, *next_pe, *primary_pe = NULL; chunk_t chunk; LIST_HEAD(pe_queue); @@ -1500,7 +1500,7 @@ static int __init dm_snapshot_init(void) goto bad2; } - exception_cache = KMEM_CACHE(dm_snap_exception, 0); + exception_cache = KMEM_CACHE(dm_exception, 0); if (!exception_cache) { DMERR("Couldn't create exception cache."); r = -ENOMEM; -- cgit v0.10.2 From 191437a53c8269df3a2c6199206781e742c57bb5 Mon Sep 17 00:00:00 2001 From: Jon Brassow Date: Thu, 10 Dec 2009 23:52:10 +0000 Subject: dm snapshot: rename exception_table to dm_exception_table Rename exception_table for broader use outside dm-snap.c Signed-off-by: Jonathan Brassow Reviewed-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index a7d60f6..f40331c 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -49,7 +49,7 @@ #define DM_TRACKED_CHUNK_HASH(x) ((unsigned long)(x) & \ (DM_TRACKED_CHUNK_HASH_SIZE - 1)) -struct exception_table { +struct dm_exception_table { uint32_t hash_mask; unsigned hash_shift; struct list_head *table; @@ -73,8 +73,8 @@ struct dm_snapshot { atomic_t pending_exceptions_count; - struct exception_table pending; - struct exception_table complete; + struct dm_exception_table pending; + struct dm_exception_table complete; /* * pe_lock protects all pending_exception operations and access @@ -351,7 +351,7 @@ static void unregister_snapshot(struct dm_snapshot *s) * The lowest hash_shift bits of the chunk number are ignored, allowing * some consecutive chunks to be grouped together. */ -static int init_exception_table(struct exception_table *et, uint32_t size, +static int init_exception_table(struct dm_exception_table *et, uint32_t size, unsigned hash_shift) { unsigned int i; @@ -368,7 +368,8 @@ static int init_exception_table(struct exception_table *et, uint32_t size, return 0; } -static void exit_exception_table(struct exception_table *et, struct kmem_cache *mem) +static void exit_exception_table(struct dm_exception_table *et, + struct kmem_cache *mem) { struct list_head *slot; struct dm_exception *ex, *next; @@ -385,7 +386,7 @@ static void exit_exception_table(struct exception_table *et, struct kmem_cache * vfree(et->table); } -static uint32_t exception_hash(struct exception_table *et, chunk_t chunk) +static uint32_t exception_hash(struct dm_exception_table *et, chunk_t chunk) { return (chunk >> et->hash_shift) & et->hash_mask; } @@ -399,7 +400,7 @@ static void remove_exception(struct dm_exception *e) * Return the exception data for a sector, or NULL if not * remapped. */ -static struct dm_exception *lookup_exception(struct exception_table *et, +static struct dm_exception *lookup_exception(struct dm_exception_table *et, chunk_t chunk) { struct list_head *slot; @@ -450,7 +451,7 @@ static void free_pending_exception(struct dm_snap_pending_exception *pe) atomic_dec(&s->pending_exceptions_count); } -static void insert_exception(struct exception_table *eh, +static void insert_exception(struct dm_exception_table *eh, struct dm_exception *new_e) { struct list_head *l; -- cgit v0.10.2 From 3510cb94ff7b04b016bd22bfee913e2c1c05c066 Mon Sep 17 00:00:00 2001 From: Jon Brassow Date: Thu, 10 Dec 2009 23:52:11 +0000 Subject: dm snapshot: rename exception functions Rename exception functions. Preparing to pull them out of dm-snap.c for broader use. Signed-off-by: Jonathan Brassow Reviewed-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index f40331c..cb4c2c3 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -351,8 +351,8 @@ static void unregister_snapshot(struct dm_snapshot *s) * The lowest hash_shift bits of the chunk number are ignored, allowing * some consecutive chunks to be grouped together. */ -static int init_exception_table(struct dm_exception_table *et, uint32_t size, - unsigned hash_shift) +static int dm_exception_table_init(struct dm_exception_table *et, + uint32_t size, unsigned hash_shift) { unsigned int i; @@ -368,8 +368,8 @@ static int init_exception_table(struct dm_exception_table *et, uint32_t size, return 0; } -static void exit_exception_table(struct dm_exception_table *et, - struct kmem_cache *mem) +static void dm_exception_table_exit(struct dm_exception_table *et, + struct kmem_cache *mem) { struct list_head *slot; struct dm_exception *ex, *next; @@ -391,7 +391,7 @@ static uint32_t exception_hash(struct dm_exception_table *et, chunk_t chunk) return (chunk >> et->hash_shift) & et->hash_mask; } -static void remove_exception(struct dm_exception *e) +static void dm_remove_exception(struct dm_exception *e) { list_del(&e->hash_list); } @@ -400,8 +400,8 @@ static void remove_exception(struct dm_exception *e) * Return the exception data for a sector, or NULL if not * remapped. */ -static struct dm_exception *lookup_exception(struct dm_exception_table *et, - chunk_t chunk) +static struct dm_exception *dm_lookup_exception(struct dm_exception_table *et, + chunk_t chunk) { struct list_head *slot; struct dm_exception *e; @@ -415,7 +415,7 @@ static struct dm_exception *lookup_exception(struct dm_exception_table *et, return NULL; } -static struct dm_exception *alloc_exception(void) +static struct dm_exception *alloc_completed_exception(void) { struct dm_exception *e; @@ -426,7 +426,7 @@ static struct dm_exception *alloc_exception(void) return e; } -static void free_exception(struct dm_exception *e) +static void free_completed_exception(struct dm_exception *e) { kmem_cache_free(exception_cache, e); } @@ -451,8 +451,8 @@ static void free_pending_exception(struct dm_snap_pending_exception *pe) atomic_dec(&s->pending_exceptions_count); } -static void insert_exception(struct dm_exception_table *eh, - struct dm_exception *new_e) +static void dm_insert_exception(struct dm_exception_table *eh, + struct dm_exception *new_e) { struct list_head *l; struct dm_exception *e = NULL; @@ -471,7 +471,7 @@ static void insert_exception(struct dm_exception_table *eh, new_e->new_chunk == (dm_chunk_number(e->new_chunk) + dm_consecutive_chunk_count(e) + 1)) { dm_consecutive_chunk_count_inc(e); - free_exception(new_e); + free_completed_exception(new_e); return; } @@ -481,7 +481,7 @@ static void insert_exception(struct dm_exception_table *eh, dm_consecutive_chunk_count_inc(e); e->old_chunk--; e->new_chunk--; - free_exception(new_e); + free_completed_exception(new_e); return; } @@ -502,7 +502,7 @@ static int dm_add_exception(void *context, chunk_t old, chunk_t new) struct dm_snapshot *s = context; struct dm_exception *e; - e = alloc_exception(); + e = alloc_completed_exception(); if (!e) return -ENOMEM; @@ -511,7 +511,7 @@ static int dm_add_exception(void *context, chunk_t old, chunk_t new) /* Consecutive_count is implicitly initialised to zero */ e->new_chunk = new; - insert_exception(&s->complete, e); + dm_insert_exception(&s->complete, e); return 0; } @@ -568,8 +568,8 @@ static int init_hash_tables(struct dm_snapshot *s) if (hash_size < 64) hash_size = 64; hash_size = rounddown_pow_of_two(hash_size); - if (init_exception_table(&s->complete, hash_size, - DM_CHUNK_CONSECUTIVE_BITS)) + if (dm_exception_table_init(&s->complete, hash_size, + DM_CHUNK_CONSECUTIVE_BITS)) return -ENOMEM; /* @@ -580,8 +580,8 @@ static int init_hash_tables(struct dm_snapshot *s) if (hash_size < 64) hash_size = 64; - if (init_exception_table(&s->pending, hash_size, 0)) { - exit_exception_table(&s->complete, exception_cache); + if (dm_exception_table_init(&s->pending, hash_size, 0)) { + dm_exception_table_exit(&s->complete, exception_cache); return -ENOMEM; } @@ -716,8 +716,8 @@ bad_pending_pool: dm_kcopyd_client_destroy(s->kcopyd_client); bad_kcopyd: - exit_exception_table(&s->pending, pending_cache); - exit_exception_table(&s->complete, exception_cache); + dm_exception_table_exit(&s->pending, pending_cache); + dm_exception_table_exit(&s->complete, exception_cache); bad_hash_tables: dm_put_device(ti, s->origin); @@ -737,8 +737,8 @@ static void __free_exceptions(struct dm_snapshot *s) dm_kcopyd_client_destroy(s->kcopyd_client); s->kcopyd_client = NULL; - exit_exception_table(&s->pending, pending_cache); - exit_exception_table(&s->complete, exception_cache); + dm_exception_table_exit(&s->pending, pending_cache); + dm_exception_table_exit(&s->complete, exception_cache); } static void snapshot_dtr(struct dm_target *ti) @@ -891,7 +891,7 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) goto out; } - e = alloc_exception(); + e = alloc_completed_exception(); if (!e) { down_write(&s->lock); __invalidate_snapshot(s, -ENOMEM); @@ -902,7 +902,7 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) down_write(&s->lock); if (!s->valid) { - free_exception(e); + free_completed_exception(e); error = 1; goto out; } @@ -918,10 +918,10 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) * Add a proper exception, and remove the * in-flight exception from the list. */ - insert_exception(&s->complete, e); + dm_insert_exception(&s->complete, e); out: - remove_exception(&pe->e); + dm_remove_exception(&pe->e); snapshot_bios = bio_list_get(&pe->snapshot_bios); origin_bios = put_pending_exception(pe); @@ -989,7 +989,7 @@ static void start_copy(struct dm_snap_pending_exception *pe) static struct dm_snap_pending_exception * __lookup_pending_exception(struct dm_snapshot *s, chunk_t chunk) { - struct dm_exception *e = lookup_exception(&s->pending, chunk); + struct dm_exception *e = dm_lookup_exception(&s->pending, chunk); if (!e) return NULL; @@ -1030,7 +1030,7 @@ __find_pending_exception(struct dm_snapshot *s, } get_pending_exception(pe); - insert_exception(&s->pending, &pe->e); + dm_insert_exception(&s->pending, &pe->e); return pe; } @@ -1077,7 +1077,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, } /* If the block is already remapped - use that, else remap it */ - e = lookup_exception(&s->complete, chunk); + e = dm_lookup_exception(&s->complete, chunk); if (e) { remap_exception(s, e, bio, chunk); goto out_unlock; @@ -1101,7 +1101,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, goto out_unlock; } - e = lookup_exception(&s->complete, chunk); + e = dm_lookup_exception(&s->complete, chunk); if (e) { free_pending_exception(pe); remap_exception(s, e, bio, chunk); @@ -1254,7 +1254,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) * ref_count is initialised to 1 so pending_complete() * won't destroy the primary_pe while we're inside this loop. */ - e = lookup_exception(&snap->complete, chunk); + e = dm_lookup_exception(&snap->complete, chunk); if (e) goto next_snapshot; @@ -1269,7 +1269,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) goto next_snapshot; } - e = lookup_exception(&snap->complete, chunk); + e = dm_lookup_exception(&snap->complete, chunk); if (e) { free_pending_exception(pe); goto next_snapshot; -- cgit v0.10.2 From 985903bb3a6d98623360ab6c855417f638840029 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 10 Dec 2009 23:52:11 +0000 Subject: dm snapshot: add allocated metadata to snapshot status Add number of sectors used by metadata to the end of the snapshot's status line. Renamed dm_exception_store_type's 'fraction_full' to 'usage'. Renamed arguments to be clearer about what is being returned. Also added 'metadata_sectors'. Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h index 9274969..366c8b1 100644 --- a/drivers/md/dm-exception-store.h +++ b/drivers/md/dm-exception-store.h @@ -86,9 +86,9 @@ struct dm_exception_store_type { /* * Return how full the snapshot is. */ - void (*fraction_full) (struct dm_exception_store *store, - sector_t *numerator, - sector_t *denominator); + void (*usage) (struct dm_exception_store *store, + sector_t *total_sectors, sector_t *sectors_allocated, + sector_t *metadata_sectors); /* For internal device-mapper use only. */ struct list_head list; diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 24b8acd..767065f 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c @@ -489,11 +489,22 @@ static struct pstore *get_info(struct dm_exception_store *store) return (struct pstore *) store->context; } -static void persistent_fraction_full(struct dm_exception_store *store, - sector_t *numerator, sector_t *denominator) +static void persistent_usage(struct dm_exception_store *store, + sector_t *total_sectors, + sector_t *sectors_allocated, + sector_t *metadata_sectors) { - *numerator = get_info(store)->next_free * store->chunk_size; - *denominator = get_dev_size(store->cow->bdev); + struct pstore *ps = get_info(store); + + *sectors_allocated = ps->next_free * store->chunk_size; + *total_sectors = get_dev_size(store->cow->bdev); + + /* + * First chunk is the fixed header. + * Then there are (ps->current_area + 1) metadata chunks, each one + * separated from the next by ps->exceptions_per_area data chunks. + */ + *metadata_sectors = (ps->current_area + 2) * store->chunk_size; } static void persistent_dtr(struct dm_exception_store *store) @@ -738,7 +749,7 @@ static struct dm_exception_store_type _persistent_type = { .prepare_exception = persistent_prepare_exception, .commit_exception = persistent_commit_exception, .drop_snapshot = persistent_drop_snapshot, - .fraction_full = persistent_fraction_full, + .usage = persistent_usage, .status = persistent_status, }; @@ -751,7 +762,7 @@ static struct dm_exception_store_type _persistent_compat_type = { .prepare_exception = persistent_prepare_exception, .commit_exception = persistent_commit_exception, .drop_snapshot = persistent_drop_snapshot, - .fraction_full = persistent_fraction_full, + .usage = persistent_usage, .status = persistent_status, }; diff --git a/drivers/md/dm-snap-transient.c b/drivers/md/dm-snap-transient.c index 267801b..245a50c 100644 --- a/drivers/md/dm-snap-transient.c +++ b/drivers/md/dm-snap-transient.c @@ -59,11 +59,14 @@ static void transient_commit_exception(struct dm_exception_store *store, callback(callback_context, 1); } -static void transient_fraction_full(struct dm_exception_store *store, - sector_t *numerator, sector_t *denominator) +static void transient_usage(struct dm_exception_store *store, + sector_t *total_sectors, + sector_t *sectors_allocated, + sector_t *metadata_sectors) { - *numerator = ((struct transient_c *) store->context)->next_free; - *denominator = get_dev_size(store->cow->bdev); + *sectors_allocated = ((struct transient_c *) store->context)->next_free; + *total_sectors = get_dev_size(store->cow->bdev); + *metadata_sectors = 0; } static int transient_ctr(struct dm_exception_store *store, @@ -106,7 +109,7 @@ static struct dm_exception_store_type _transient_type = { .read_metadata = transient_read_metadata, .prepare_exception = transient_prepare_exception, .commit_exception = transient_commit_exception, - .fraction_full = transient_fraction_full, + .usage = transient_usage, .status = transient_status, }; @@ -118,7 +121,7 @@ static struct dm_exception_store_type _transient_compat_type = { .read_metadata = transient_read_metadata, .prepare_exception = transient_prepare_exception, .commit_exception = transient_commit_exception, - .fraction_full = transient_fraction_full, + .usage = transient_usage, .status = transient_status, }; diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index cb4c2c3..8bd77cb 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -1174,14 +1174,17 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, if (!snap->valid) DMEMIT("Invalid"); else { - if (snap->store->type->fraction_full) { - sector_t numerator, denominator; - snap->store->type->fraction_full(snap->store, - &numerator, - &denominator); - DMEMIT("%llu/%llu", - (unsigned long long)numerator, - (unsigned long long)denominator); + if (snap->store->type->usage) { + sector_t total_sectors, sectors_allocated, + metadata_sectors; + snap->store->type->usage(snap->store, + &total_sectors, + §ors_allocated, + &metadata_sectors); + DMEMIT("%llu/%llu %llu", + (unsigned long long)sectors_allocated, + (unsigned long long)total_sectors, + (unsigned long long)metadata_sectors); } else DMEMIT("Unknown"); @@ -1462,7 +1465,7 @@ static struct target_type origin_target = { static struct target_type snapshot_target = { .name = "snapshot", - .version = {1, 7, 0}, + .version = {1, 8, 0}, .module = THIS_MODULE, .ctr = snapshot_ctr, .dtr = snapshot_dtr, -- cgit v0.10.2 From fc56f6fbcca3672c63c93c65f45105faacfc13cb Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 10 Dec 2009 23:52:12 +0000 Subject: dm snapshot: move cow ref from exception store to snap core Store the reference to the snapshot cow device in the core snapshot code instead of each exception store. It can be accessed through the new function dm_snap_cow(). Exception stores should each now maintain a reference to their parent snapshot struct. This is cleaner and makes part of the forthcoming snapshot merge code simpler. Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon Reviewed-by: Jonathan Brassow Cc: Mikulas Patocka diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c index 2052159..2b7907b 100644 --- a/drivers/md/dm-exception-store.c +++ b/drivers/md/dm-exception-store.c @@ -172,7 +172,8 @@ int dm_exception_store_set_chunk_size(struct dm_exception_store *store, } /* Validate the chunk size against the device block size */ - if (chunk_size % (bdev_logical_block_size(store->cow->bdev) >> 9)) { + if (chunk_size % + (bdev_logical_block_size(dm_snap_cow(store->snap)->bdev) >> 9)) { *error = "Chunk size is not a multiple of device blocksize"; return -EINVAL; } @@ -190,6 +191,7 @@ int dm_exception_store_set_chunk_size(struct dm_exception_store *store, } int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, + struct dm_snapshot *snap, unsigned *args_used, struct dm_exception_store **store) { @@ -198,7 +200,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, struct dm_exception_store *tmp_store; char persistent; - if (argc < 3) { + if (argc < 2) { ti->error = "Insufficient exception store arguments"; return -EINVAL; } @@ -209,7 +211,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, return -ENOMEM; } - persistent = toupper(*argv[1]); + persistent = toupper(*argv[0]); if (persistent == 'P') type = get_type("P"); else if (persistent == 'N') @@ -227,32 +229,23 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, } tmp_store->type = type; - tmp_store->ti = ti; + tmp_store->snap = snap; - r = dm_get_device(ti, argv[0], 0, 0, - FMODE_READ | FMODE_WRITE, &tmp_store->cow); - if (r) { - ti->error = "Cannot get COW device"; - goto bad_cow; - } - - r = set_chunk_size(tmp_store, argv[2], &ti->error); + r = set_chunk_size(tmp_store, argv[1], &ti->error); if (r) - goto bad_ctr; + goto bad; r = type->ctr(tmp_store, 0, NULL); if (r) { ti->error = "Exception store type constructor failed"; - goto bad_ctr; + goto bad; } - *args_used = 3; + *args_used = 2; *store = tmp_store; return 0; -bad_ctr: - dm_put_device(ti, tmp_store->cow); -bad_cow: +bad: put_type(type); bad_type: kfree(tmp_store); @@ -263,7 +256,6 @@ EXPORT_SYMBOL(dm_exception_store_create); void dm_exception_store_destroy(struct dm_exception_store *store) { store->type->dtr(store); - dm_put_device(store->ti, store->cow); put_type(store->type); kfree(store); } diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h index 366c8b1..bb88746 100644 --- a/drivers/md/dm-exception-store.h +++ b/drivers/md/dm-exception-store.h @@ -94,11 +94,11 @@ struct dm_exception_store_type { struct list_head list; }; +struct dm_snapshot; + struct dm_exception_store { struct dm_exception_store_type *type; - struct dm_target *ti; - - struct dm_dev *cow; + struct dm_snapshot *snap; /* Size of data blocks saved - must be a power of 2 */ unsigned chunk_size; @@ -109,6 +109,11 @@ struct dm_exception_store { }; /* + * Obtain the cow device used by a given snapshot. + */ +struct dm_dev *dm_snap_cow(struct dm_snapshot *snap); + +/* * Funtions to manipulate consecutive chunks */ # if defined(CONFIG_LBDAF) || (BITS_PER_LONG == 64) @@ -173,6 +178,7 @@ int dm_exception_store_set_chunk_size(struct dm_exception_store *store, char **error); int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, + struct dm_snapshot *snap, unsigned *args_used, struct dm_exception_store **store); void dm_exception_store_destroy(struct dm_exception_store *store); diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 767065f..157999e 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c @@ -214,7 +214,7 @@ static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, int rw, int metadata) { struct dm_io_region where = { - .bdev = ps->store->cow->bdev, + .bdev = dm_snap_cow(ps->store->snap)->bdev, .sector = ps->store->chunk_size * chunk, .count = ps->store->chunk_size, }; @@ -294,7 +294,8 @@ static int read_header(struct pstore *ps, int *new_snapshot) */ if (!ps->store->chunk_size) { ps->store->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS, - bdev_logical_block_size(ps->store->cow->bdev) >> 9); + bdev_logical_block_size(dm_snap_cow(ps->store->snap)-> + bdev) >> 9); ps->store->chunk_mask = ps->store->chunk_size - 1; ps->store->chunk_shift = ffs(ps->store->chunk_size) - 1; chunk_size_supplied = 0; @@ -497,7 +498,7 @@ static void persistent_usage(struct dm_exception_store *store, struct pstore *ps = get_info(store); *sectors_allocated = ps->next_free * store->chunk_size; - *total_sectors = get_dev_size(store->cow->bdev); + *total_sectors = get_dev_size(dm_snap_cow(store->snap)->bdev); /* * First chunk is the fixed header. @@ -596,7 +597,7 @@ static int persistent_prepare_exception(struct dm_exception_store *store, struct pstore *ps = get_info(store); uint32_t stride; chunk_t next_free; - sector_t size = get_dev_size(store->cow->bdev); + sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev); /* Is there enough room ? */ if (size < ((ps->next_free + 1) * store->chunk_size)) @@ -733,8 +734,7 @@ static unsigned persistent_status(struct dm_exception_store *store, case STATUSTYPE_INFO: break; case STATUSTYPE_TABLE: - DMEMIT(" %s P %llu", store->cow->name, - (unsigned long long)store->chunk_size); + DMEMIT(" P %llu", (unsigned long long)store->chunk_size); } return sz; diff --git a/drivers/md/dm-snap-transient.c b/drivers/md/dm-snap-transient.c index 245a50c..a0898a6 100644 --- a/drivers/md/dm-snap-transient.c +++ b/drivers/md/dm-snap-transient.c @@ -39,7 +39,7 @@ static int transient_prepare_exception(struct dm_exception_store *store, struct dm_exception *e) { struct transient_c *tc = store->context; - sector_t size = get_dev_size(store->cow->bdev); + sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev); if (size < (tc->next_free + store->chunk_size)) return -1; @@ -65,7 +65,7 @@ static void transient_usage(struct dm_exception_store *store, sector_t *metadata_sectors) { *sectors_allocated = ((struct transient_c *) store->context)->next_free; - *total_sectors = get_dev_size(store->cow->bdev); + *total_sectors = get_dev_size(dm_snap_cow(store->snap)->bdev); *metadata_sectors = 0; } @@ -94,8 +94,7 @@ static unsigned transient_status(struct dm_exception_store *store, case STATUSTYPE_INFO: break; case STATUSTYPE_TABLE: - DMEMIT(" %s N %llu", store->cow->name, - (unsigned long long)store->chunk_size); + DMEMIT(" N %llu", (unsigned long long)store->chunk_size); } return sz; diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 8bd77cb..dc500a6 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -59,6 +59,9 @@ struct dm_snapshot { struct rw_semaphore lock; struct dm_dev *origin; + struct dm_dev *cow; + + struct dm_target *ti; /* List of snapshots per Origin */ struct list_head list; @@ -97,6 +100,12 @@ struct dm_snapshot { struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE]; }; +struct dm_dev *dm_snap_cow(struct dm_snapshot *s) +{ + return s->cow; +} +EXPORT_SYMBOL(dm_snap_cow); + static struct workqueue_struct *ksnapd; static void flush_queued_bios(struct work_struct *work); @@ -558,7 +567,7 @@ static int init_hash_tables(struct dm_snapshot *s) * Calculate based on the size of the original volume or * the COW volume... */ - cow_dev_size = get_dev_size(s->store->cow->bdev); + cow_dev_size = get_dev_size(s->cow->bdev); origin_dev_size = get_dev_size(s->origin->bdev); max_buckets = calc_max_buckets(); @@ -596,45 +605,55 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) struct dm_snapshot *s; int i; int r = -EINVAL; - char *origin_path; - struct dm_exception_store *store; + char *origin_path, *cow_path; unsigned args_used; if (argc != 4) { ti->error = "requires exactly 4 arguments"; r = -EINVAL; - goto bad_args; + goto bad; } origin_path = argv[0]; argv++; argc--; - r = dm_exception_store_create(ti, argc, argv, &args_used, &store); + s = kmalloc(sizeof(*s), GFP_KERNEL); + if (!s) { + ti->error = "Cannot allocate snapshot context private " + "structure"; + r = -ENOMEM; + goto bad; + } + + cow_path = argv[0]; + argv++; + argc--; + + r = dm_get_device(ti, cow_path, 0, 0, + FMODE_READ | FMODE_WRITE, &s->cow); + if (r) { + ti->error = "Cannot get COW device"; + goto bad_cow; + } + + r = dm_exception_store_create(ti, argc, argv, s, &args_used, &s->store); if (r) { ti->error = "Couldn't create exception store"; r = -EINVAL; - goto bad_args; + goto bad_store; } argv += args_used; argc -= args_used; - s = kmalloc(sizeof(*s), GFP_KERNEL); - if (!s) { - ti->error = "Cannot allocate snapshot context private " - "structure"; - r = -ENOMEM; - goto bad_snap; - } - r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin); if (r) { ti->error = "Cannot get origin device"; goto bad_origin; } - s->store = store; + s->ti = ti; s->valid = 1; s->active = 0; atomic_set(&s->pending_exceptions_count, 0); @@ -723,12 +742,15 @@ bad_hash_tables: dm_put_device(ti, s->origin); bad_origin: - kfree(s); + dm_exception_store_destroy(s->store); -bad_snap: - dm_exception_store_destroy(store); +bad_store: + dm_put_device(ti, s->cow); -bad_args: +bad_cow: + kfree(s); + +bad: return r; } @@ -777,6 +799,8 @@ static void snapshot_dtr(struct dm_target *ti) dm_exception_store_destroy(s->store); + dm_put_device(ti, s->cow); + kfree(s); } @@ -839,7 +863,7 @@ static void __invalidate_snapshot(struct dm_snapshot *s, int err) s->valid = 0; - dm_table_event(s->store->ti->table); + dm_table_event(s->ti->table); } static void get_pending_exception(struct dm_snap_pending_exception *pe) @@ -977,7 +1001,7 @@ static void start_copy(struct dm_snap_pending_exception *pe) src.sector = chunk_to_sector(s->store, pe->e.old_chunk); src.count = min((sector_t)s->store->chunk_size, dev_size - src.sector); - dest.bdev = s->store->cow->bdev; + dest.bdev = s->cow->bdev; dest.sector = chunk_to_sector(s->store, pe->e.new_chunk); dest.count = src.count; @@ -1038,7 +1062,7 @@ __find_pending_exception(struct dm_snapshot *s, static void remap_exception(struct dm_snapshot *s, struct dm_exception *e, struct bio *bio, chunk_t chunk) { - bio->bi_bdev = s->store->cow->bdev; + bio->bi_bdev = s->cow->bdev; bio->bi_sector = chunk_to_sector(s->store, dm_chunk_number(e->new_chunk) + (chunk - e->old_chunk)) + @@ -1056,7 +1080,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, struct dm_snap_pending_exception *pe = NULL; if (unlikely(bio_empty_barrier(bio))) { - bio->bi_bdev = s->store->cow->bdev; + bio->bi_bdev = s->cow->bdev; return DM_MAPIO_REMAPPED; } @@ -1200,7 +1224,7 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, * to make private copies if the output is to * make sense. */ - DMEMIT("%s", snap->origin->name); + DMEMIT("%s %s", snap->origin->name, snap->cow->name); snap->store->type->status(snap->store, type, result + sz, maxlen - sz); break; @@ -1240,7 +1264,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) goto next_snapshot; /* Nothing to do if writing beyond end of snapshot */ - if (bio->bi_sector >= dm_table_get_size(snap->store->ti->table)) + if (bio->bi_sector >= dm_table_get_size(snap->ti->table)) goto next_snapshot; /* -- cgit v0.10.2 From c26655ca3ca7550740a63820ee981e5c7c797523 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 10 Dec 2009 23:52:12 +0000 Subject: dm snapshot: track suspended state in target Keep track of whether or not the device is suspended within the snapshot target module, the same as we do in dm-raid1. We will use this later to enforce the correct sequence of ioctls to transfer the in-core exceptions from a snapshot target instance in one table to a replacement one capable of merging them back into the origin. Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index dc500a6..fd04caa9 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -72,6 +72,9 @@ struct dm_snapshot { /* Origin writes don't trigger exceptions until this is set */ int active; + /* Whether or not owning mapped_device is suspended */ + int suspended; + mempool_t *pending_pool; atomic_t pending_exceptions_count; @@ -656,6 +659,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) s->ti = ti; s->valid = 1; s->active = 0; + s->suspended = 0; atomic_set(&s->pending_exceptions_count, 0); init_rwsem(&s->lock); spin_lock_init(&s->pe_lock); @@ -1175,12 +1179,22 @@ static int snapshot_end_io(struct dm_target *ti, struct bio *bio, return 0; } +static void snapshot_postsuspend(struct dm_target *ti) +{ + struct dm_snapshot *s = ti->private; + + down_write(&s->lock); + s->suspended = 1; + up_write(&s->lock); +} + static void snapshot_resume(struct dm_target *ti) { struct dm_snapshot *s = ti->private; down_write(&s->lock); s->active = 1; + s->suspended = 0; up_write(&s->lock); } @@ -1489,12 +1503,13 @@ static struct target_type origin_target = { static struct target_type snapshot_target = { .name = "snapshot", - .version = {1, 8, 0}, + .version = {1, 9, 0}, .module = THIS_MODULE, .ctr = snapshot_ctr, .dtr = snapshot_dtr, .map = snapshot_map, .end_io = snapshot_end_io, + .postsuspend = snapshot_postsuspend, .resume = snapshot_resume, .status = snapshot_status, .iterate_devices = snapshot_iterate_devices, -- cgit v0.10.2 From 9ca170a3c0cbb0d5251cef6f5a3300fa436ba8ec Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:13 +0000 Subject: dm kcopyd: accept zero size jobs dm-kcopyd: accept zero-size jobs This patch changes dm-kcopyd so that it accepts zero-size jobs and completes them immediatelly via its completion thread. It is needed for multisnapshots snapshot resizing. When we are writing to a chunk beyond origin end, no copying is done. To simplify the code, we submit an empty request to kcopyd and let kcopyd complete it. If we didn't submit a request to kcopyd and called the completion routine immediatelly, it would violate the principle that completion is called only from one thread and it would need additional locking. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c index 3e3fc06..addf834 100644 --- a/drivers/md/dm-kcopyd.c +++ b/drivers/md/dm-kcopyd.c @@ -450,7 +450,10 @@ static void dispatch_job(struct kcopyd_job *job) { struct dm_kcopyd_client *kc = job->kc; atomic_inc(&kc->nr_jobs); - push(&kc->pages_jobs, job); + if (unlikely(!job->source.count)) + push(&kc->complete_jobs, job); + else + push(&kc->pages_jobs, job); wake(kc); } -- cgit v0.10.2 From 90abb8c4cec8f0aa4ce58790542e3cf13071601a Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 10 Dec 2009 23:52:13 +0000 Subject: dm: abstract dm_in_flight function This patch adds md_in_flight() to get the number of in_flight I/Os. No functional change. This patch is a preparation for a later patch in this series, which changes I/O counter to md->pending from q->in_flight in request-based dm. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 473f0c3..73b89af 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -452,6 +452,12 @@ static void free_bio_info(struct dm_rq_clone_bio_info *info) mempool_free(info, info->tio->md->io_pool); } +static int md_in_flight(struct mapped_device *md) +{ + return atomic_read(&md->pending[READ]) + + atomic_read(&md->pending[WRITE]); +} + static void start_io_acct(struct dm_io *io) { struct mapped_device *md = io->md; @@ -2100,8 +2106,7 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible) break; } spin_unlock_irqrestore(q->queue_lock, flags); - } else if (!atomic_read(&md->pending[0]) && - !atomic_read(&md->pending[1])) + } else if (!md_in_flight(md)) break; if (interruptible == TASK_INTERRUPTIBLE && -- cgit v0.10.2 From 598de40947909e6b948569710383661ecc0ddc8e Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 10 Dec 2009 23:52:14 +0000 Subject: dm: use clone in map_request function This patch changes the argument of map_request() to clone request from original request. No functional change. This patch is a preparation for PATCH 9, which needs to use map_request() for clones sharing an original barrier request. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 73b89af..cf0b455 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1495,11 +1495,10 @@ static int dm_prep_fn(struct request_queue *q, struct request *rq) return BLKPREP_OK; } -static void map_request(struct dm_target *ti, struct request *rq, +static void map_request(struct dm_target *ti, struct request *clone, struct mapped_device *md) { int r; - struct request *clone = rq->special; struct dm_rq_target_io *tio = clone->end_io_data; /* @@ -1576,7 +1575,7 @@ static void dm_request_fn(struct request_queue *q) blk_start_request(rq); spin_unlock(q->queue_lock); - map_request(ti, rq, md); + map_request(ti, rq->special, md); spin_lock_irq(q->queue_lock); } -- cgit v0.10.2 From 0888564393a1277ce2d0564d819e1bcff1120343 Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 10 Dec 2009 23:52:15 +0000 Subject: dm: pass gfp_mask to alloc_rq_tio This patch adds the gfp_mask argument to alloc_rq_tio(). No functional change. This patch is a preparation for a later patch in this series which needs to allocate tio (for barrier I/O) with different allocation flag (GFP_NOIO) from the one in the normal I/O code path. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm.c b/drivers/md/dm.c index cf0b455..a42dfb7 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -432,9 +432,10 @@ static void free_tio(struct mapped_device *md, struct dm_target_io *tio) mempool_free(tio, md->tio_pool); } -static struct dm_rq_target_io *alloc_rq_tio(struct mapped_device *md) +static struct dm_rq_target_io *alloc_rq_tio(struct mapped_device *md, + gfp_t gfp_mask) { - return mempool_alloc(md->tio_pool, GFP_ATOMIC); + return mempool_alloc(md->tio_pool, gfp_mask); } static void free_rq_tio(struct dm_rq_target_io *tio) @@ -1471,7 +1472,7 @@ static int dm_prep_fn(struct request_queue *q, struct request *rq) return BLKPREP_KILL; } - tio = alloc_rq_tio(md); /* Only one for each original request */ + tio = alloc_rq_tio(md, GFP_ATOMIC); if (!tio) /* -ENOMEM */ return BLKPREP_DEFER; -- cgit v0.10.2 From 6facdaff229f2b25d0de82be9be99b9f562e72ba Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 10 Dec 2009 23:52:15 +0000 Subject: dm: abstract clone_rq This patch factors out the request cloning code in dm_prep_fn() as clone_rq(). No functional change. This patch is a preparation for a later patch in this series which needs to make clones from an original barrier request. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm.c b/drivers/md/dm.c index a42dfb7..30f5dc8 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1445,6 +1445,32 @@ static int setup_clone(struct request *clone, struct request *rq, return 0; } +static struct request *clone_rq(struct request *rq, struct mapped_device *md, + gfp_t gfp_mask) +{ + struct request *clone; + struct dm_rq_target_io *tio; + + tio = alloc_rq_tio(md, gfp_mask); + if (!tio) + return NULL; + + tio->md = md; + tio->ti = NULL; + tio->orig = rq; + tio->error = 0; + memset(&tio->info, 0, sizeof(tio->info)); + + clone = &tio->clone; + if (setup_clone(clone, rq, tio)) { + /* -ENOMEM */ + free_rq_tio(tio); + return NULL; + } + + return clone; +} + static int dm_rq_flush_suspending(struct mapped_device *md) { return !md->suspend_rq.special; @@ -1456,7 +1482,6 @@ static int dm_rq_flush_suspending(struct mapped_device *md) static int dm_prep_fn(struct request_queue *q, struct request *rq) { struct mapped_device *md = q->queuedata; - struct dm_rq_target_io *tio; struct request *clone; if (unlikely(rq == &md->suspend_rq)) { @@ -1472,24 +1497,10 @@ static int dm_prep_fn(struct request_queue *q, struct request *rq) return BLKPREP_KILL; } - tio = alloc_rq_tio(md, GFP_ATOMIC); - if (!tio) - /* -ENOMEM */ + clone = clone_rq(rq, md, GFP_ATOMIC); + if (!clone) return BLKPREP_DEFER; - tio->md = md; - tio->ti = NULL; - tio->orig = rq; - tio->error = 0; - memset(&tio->info, 0, sizeof(tio->info)); - - clone = &tio->clone; - if (setup_clone(clone, rq, tio)) { - /* -ENOMEM */ - free_rq_tio(tio); - return BLKPREP_DEFER; - } - rq->special = clone; rq->cmd_flags |= REQ_DONTPREP; -- cgit v0.10.2 From 9f518b27cf682dd5155a4c1679d52cd4b5be82f2 Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 10 Dec 2009 23:52:16 +0000 Subject: dm: simplify request based suspend The semantics of bio-based dm were changed recently in the case of suspend with "--nolockfs" but without "--noflush". Before 2.6.30, I/Os submitted before the suspend invocation were always flushed. From 2.6.30 onwards, I/Os submitted before the suspend invocation might not be flushed. (For details, see http://marc.info/?t=123994433400003&r=1&w=2) This patch brings the behaviour of request-based dm into line with bio-based dm, simplifying the code and preparing for a subsequent patch that will wait for all in_flight I/Os to complete without stopping request_queue and use dm_wait_for_completion() for it. This change in semantics simplifies the suspend code as follows: o Suspend is implemented as stopping request_queue in request-based dm, and all I/Os are queued in the request_queue even after suspend is invoked. o In the old semantics, we had to track whether I/Os were queued before or after the suspend invocation, so a special barrier-like request called 'suspend marker' was introduced. o With the new semantics, we don't need to flush any I/O so we can remove the marker and the code related to the marker handling and I/O flushing. After removing this codes, the suspend sequence is now: 1. Flush all I/Os by lock_fs() if needed. 2. Stop dispatching any I/O by stopping the request_queue. 3. Wait for all in-flight I/Os to be completed or requeued. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 30f5dc8..634b1da 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -178,9 +178,6 @@ struct mapped_device { /* forced geometry settings */ struct hd_geometry geometry; - /* marker of flush suspend for request-based dm */ - struct request suspend_rq; - /* For saving the address of __make_request for request based dm */ make_request_fn *saved_make_request_fn; @@ -1471,11 +1468,6 @@ static struct request *clone_rq(struct request *rq, struct mapped_device *md, return clone; } -static int dm_rq_flush_suspending(struct mapped_device *md) -{ - return !md->suspend_rq.special; -} - /* * Called with the queue lock held. */ @@ -1484,14 +1476,6 @@ static int dm_prep_fn(struct request_queue *q, struct request *rq) struct mapped_device *md = q->queuedata; struct request *clone; - if (unlikely(rq == &md->suspend_rq)) { - if (dm_rq_flush_suspending(md)) - return BLKPREP_OK; - else - /* The flush suspend was interrupted */ - return BLKPREP_KILL; - } - if (unlikely(rq->special)) { DMWARN("Already has something in rq->special."); return BLKPREP_KILL; @@ -1560,27 +1544,15 @@ static void dm_request_fn(struct request_queue *q) struct request *rq; /* - * For noflush suspend, check blk_queue_stopped() to immediately - * quit I/O dispatching. + * For suspend, check blk_queue_stopped() and don't increment + * the number of in-flight I/Os after the queue is stopped + * in dm_suspend(). */ while (!blk_queue_plugged(q) && !blk_queue_stopped(q)) { rq = blk_peek_request(q); if (!rq) goto plug_and_out; - if (unlikely(rq == &md->suspend_rq)) { /* Flush suspend maker */ - if (queue_in_flight(q)) - /* Not quiet yet. Wait more */ - goto plug_and_out; - - /* This device should be quiet now */ - __stop_queue(q); - blk_start_request(rq); - __blk_end_request_all(rq, 0); - wake_up(&md->wait); - goto out; - } - ti = dm_table_find_target(map, blk_rq_pos(rq)); if (ti->type->busy && ti->type->busy(ti)) goto plug_and_out; @@ -2112,7 +2084,7 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible) smp_mb(); if (dm_request_based(md)) { spin_lock_irqsave(q->queue_lock, flags); - if (!queue_in_flight(q) && blk_queue_stopped(q)) { + if (!queue_in_flight(q)) { spin_unlock_irqrestore(q->queue_lock, flags); break; } @@ -2245,67 +2217,6 @@ out: return r; } -static void dm_rq_invalidate_suspend_marker(struct mapped_device *md) -{ - md->suspend_rq.special = (void *)0x1; -} - -static void dm_rq_abort_suspend(struct mapped_device *md, int noflush) -{ - struct request_queue *q = md->queue; - unsigned long flags; - - spin_lock_irqsave(q->queue_lock, flags); - if (!noflush) - dm_rq_invalidate_suspend_marker(md); - __start_queue(q); - spin_unlock_irqrestore(q->queue_lock, flags); -} - -static void dm_rq_start_suspend(struct mapped_device *md, int noflush) -{ - struct request *rq = &md->suspend_rq; - struct request_queue *q = md->queue; - - if (noflush) - stop_queue(q); - else { - blk_rq_init(q, rq); - blk_insert_request(q, rq, 0, NULL); - } -} - -static int dm_rq_suspend_available(struct mapped_device *md, int noflush) -{ - int r = 1; - struct request *rq = &md->suspend_rq; - struct request_queue *q = md->queue; - unsigned long flags; - - if (noflush) - return r; - - /* The marker must be protected by queue lock if it is in use */ - spin_lock_irqsave(q->queue_lock, flags); - if (unlikely(rq->ref_count)) { - /* - * This can happen, when the previous flush suspend was - * interrupted, the marker is still in the queue and - * this flush suspend has been invoked, because we don't - * remove the marker at the time of suspend interruption. - * We have only one marker per mapped_device, so we can't - * start another flush suspend while it is in use. - */ - BUG_ON(!rq->special); /* The marker should be invalidated */ - DMWARN("Invalidating the previous flush suspend is still in" - " progress. Please retry later."); - r = 0; - } - spin_unlock_irqrestore(q->queue_lock, flags); - - return r; -} - /* * Functions to lock and unlock any filesystem running on the * device. @@ -2348,49 +2259,11 @@ static void unlock_fs(struct mapped_device *md) /* * Suspend mechanism in request-based dm. * - * After the suspend starts, further incoming requests are kept in - * the request_queue and deferred. - * Remaining requests in the request_queue at the start of suspend are flushed - * if it is flush suspend. - * The suspend completes when the following conditions have been satisfied, - * so wait for it: - * 1. q->in_flight is 0 (which means no in_flight request) - * 2. queue has been stopped (which means no request dispatching) - * - * - * Noflush suspend - * --------------- - * Noflush suspend doesn't need to dispatch remaining requests. - * So stop the queue immediately. Then, wait for all in_flight requests - * to be completed or requeued. - * - * To abort noflush suspend, start the queue. + * 1. Flush all I/Os by lock_fs() if needed. + * 2. Stop dispatching any I/O by stopping the request_queue. + * 3. Wait for all in-flight I/Os to be completed or requeued. * - * - * Flush suspend - * ------------- - * Flush suspend needs to dispatch remaining requests. So stop the queue - * after the remaining requests are completed. (Requeued request must be also - * re-dispatched and completed. Until then, we can't stop the queue.) - * - * During flushing the remaining requests, further incoming requests are also - * inserted to the same queue. To distinguish which requests are to be - * flushed, we insert a marker request to the queue at the time of starting - * flush suspend, like a barrier. - * The dispatching is blocked when the marker is found on the top of the queue. - * And the queue is stopped when all in_flight requests are completed, since - * that means the remaining requests are completely flushed. - * Then, the marker is removed from the queue. - * - * To abort flush suspend, we also need to take care of the marker, not only - * starting the queue. - * We don't remove the marker forcibly from the queue since it's against - * the block-layer manner. Instead, we put a invalidated mark on the marker. - * When the invalidated marker is found on the top of the queue, it is - * immediately removed from the queue, so it doesn't block dispatching. - * Because we have only one marker per mapped_device, we can't start another - * flush suspend until the invalidated marker is removed from the queue. - * So fail and return with -EBUSY in such a case. + * To abort suspend, start the request_queue. */ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) { @@ -2406,11 +2279,6 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) goto out_unlock; } - if (dm_request_based(md) && !dm_rq_suspend_available(md, noflush)) { - r = -EBUSY; - goto out_unlock; - } - map = dm_get_table(md); /* @@ -2424,8 +2292,10 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) dm_table_presuspend_targets(map); /* - * Flush I/O to the device. noflush supersedes do_lockfs, - * because lock_fs() needs to flush I/Os. + * Flush I/O to the device. + * Any I/O submitted after lock_fs() may not be flushed. + * noflush takes precedence over do_lockfs. + * (lock_fs() flushes I/Os and waits for them to complete.) */ if (!noflush && do_lockfs) { r = lock_fs(md); @@ -2457,7 +2327,7 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) flush_workqueue(md->wq); if (dm_request_based(md)) - dm_rq_start_suspend(md, noflush); + stop_queue(md->queue); /* * At this point no more requests are entering target request routines. @@ -2476,7 +2346,7 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) dm_queue_flush(md); if (dm_request_based(md)) - dm_rq_abort_suspend(md, noflush); + start_queue(md->queue); unlock_fs(md); goto out; /* pushback list is already flushed, so skip flush */ -- cgit v0.10.2 From b4324feeae304ae39e631a254d238a7d63be004b Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 10 Dec 2009 23:52:16 +0000 Subject: dm: use md pending for in flight IO counting This patch changes the counter for the number of in_flight I/Os to md->pending from q->in_flight in preparation for a later patch. No functional change. Request-based dm used q->in_flight to count the number of in-flight clones assuming the counter is always incremented for an in-flight original request and original:clone is 1:1 relationship. However, it this no longer true for barrier requests. So use md->pending to count the number of in-flight clones. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 634b1da..01d741a 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -727,23 +727,16 @@ static void end_clone_bio(struct bio *clone, int error) * the md may be freed in dm_put() at the end of this function. * Or do dm_get() before calling this function and dm_put() later. */ -static void rq_completed(struct mapped_device *md, int run_queue) +static void rq_completed(struct mapped_device *md, int rw, int run_queue) { - int wakeup_waiters = 0; - struct request_queue *q = md->queue; - unsigned long flags; - - spin_lock_irqsave(q->queue_lock, flags); - if (!queue_in_flight(q)) - wakeup_waiters = 1; - spin_unlock_irqrestore(q->queue_lock, flags); + atomic_dec(&md->pending[rw]); /* nudge anyone waiting on suspend queue */ - if (wakeup_waiters) + if (!md_in_flight(md)) wake_up(&md->wait); if (run_queue) - blk_run_queue(q); + blk_run_queue(md->queue); /* * dm_put() must be at the end of this function. See the comment above @@ -774,6 +767,7 @@ static void dm_unprep_request(struct request *rq) */ void dm_requeue_unmapped_request(struct request *clone) { + int rw = rq_data_dir(clone); struct dm_rq_target_io *tio = clone->end_io_data; struct mapped_device *md = tio->md; struct request *rq = tio->orig; @@ -788,7 +782,7 @@ void dm_requeue_unmapped_request(struct request *clone) blk_requeue_request(q, rq); spin_unlock_irqrestore(q->queue_lock, flags); - rq_completed(md, 0); + rq_completed(md, rw, 0); } EXPORT_SYMBOL_GPL(dm_requeue_unmapped_request); @@ -827,6 +821,7 @@ static void start_queue(struct request_queue *q) */ static void dm_end_request(struct request *clone, int error) { + int rw = rq_data_dir(clone); struct dm_rq_target_io *tio = clone->end_io_data; struct mapped_device *md = tio->md; struct request *rq = tio->orig; @@ -848,7 +843,7 @@ static void dm_end_request(struct request *clone, int error) blk_end_request_all(rq, error); - rq_completed(md, 1); + rq_completed(md, rw, 1); } /* @@ -1541,12 +1536,13 @@ static void dm_request_fn(struct request_queue *q) struct mapped_device *md = q->queuedata; struct dm_table *map = dm_get_table(md); struct dm_target *ti; - struct request *rq; + struct request *rq, *clone; /* - * For suspend, check blk_queue_stopped() and don't increment - * the number of in-flight I/Os after the queue is stopped - * in dm_suspend(). + * For suspend, check blk_queue_stopped() and increment + * ->pending within a single queue_lock not to increment the + * number of in-flight I/Os after the queue is stopped in + * dm_suspend(). */ while (!blk_queue_plugged(q) && !blk_queue_stopped(q)) { rq = blk_peek_request(q); @@ -1558,8 +1554,11 @@ static void dm_request_fn(struct request_queue *q) goto plug_and_out; blk_start_request(rq); + clone = rq->special; + atomic_inc(&md->pending[rq_data_dir(clone)]); + spin_unlock(q->queue_lock); - map_request(ti, rq->special, md); + map_request(ti, clone, md); spin_lock_irq(q->queue_lock); } @@ -2071,8 +2070,6 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible) { int r = 0; DECLARE_WAITQUEUE(wait, current); - struct request_queue *q = md->queue; - unsigned long flags; dm_unplug_all(md->queue); @@ -2082,14 +2079,7 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible) set_current_state(interruptible); smp_mb(); - if (dm_request_based(md)) { - spin_lock_irqsave(q->queue_lock, flags); - if (!queue_in_flight(q)) { - spin_unlock_irqrestore(q->queue_lock, flags); - break; - } - spin_unlock_irqrestore(q->queue_lock, flags); - } else if (!md_in_flight(md)) + if (!md_in_flight(md)) break; if (interruptible == TASK_INTERRUPTIBLE && -- cgit v0.10.2 From 11a68244e16b0c35e122dd55b4e7c595e0fb67a1 Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 10 Dec 2009 23:52:17 +0000 Subject: dm: refactor request based completion functions This patch factors out the clone completion code, dm_done(), from dm_softirq_done() in preparation for a subsequent patch. No functional change. dm_done() will be used in barrier completion, which can't use and doesn't need softirq. The softirq_done callback needs to get a clone from an original request but it can't in the case of barrier, where an original request is shared by multiple clones. On the other hand, the completion of barrier clones doesn't involve re-submitting requests, which was the primary reason of the need for softirq. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 01d741a..c65be45 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -846,35 +846,46 @@ static void dm_end_request(struct request *clone, int error) rq_completed(md, rw, 1); } -/* - * Request completion handler for request-based dm - */ -static void dm_softirq_done(struct request *rq) +static void dm_done(struct request *clone, int error, bool mapped) { - struct request *clone = rq->completion_data; + int r = error; struct dm_rq_target_io *tio = clone->end_io_data; dm_request_endio_fn rq_end_io = tio->ti->type->rq_end_io; - int error = tio->error; - if (!(rq->cmd_flags & REQ_FAILED) && rq_end_io) - error = rq_end_io(tio->ti, clone, error, &tio->info); + if (mapped && rq_end_io) + r = rq_end_io(tio->ti, clone, error, &tio->info); - if (error <= 0) + if (r <= 0) /* The target wants to complete the I/O */ - dm_end_request(clone, error); - else if (error == DM_ENDIO_INCOMPLETE) + dm_end_request(clone, r); + else if (r == DM_ENDIO_INCOMPLETE) /* The target will handle the I/O */ return; - else if (error == DM_ENDIO_REQUEUE) + else if (r == DM_ENDIO_REQUEUE) /* The target wants to requeue the I/O */ dm_requeue_unmapped_request(clone); else { - DMWARN("unimplemented target endio return value: %d", error); + DMWARN("unimplemented target endio return value: %d", r); BUG(); } } /* + * Request completion handler for request-based dm + */ +static void dm_softirq_done(struct request *rq) +{ + bool mapped = true; + struct request *clone = rq->completion_data; + struct dm_rq_target_io *tio = clone->end_io_data; + + if (rq->cmd_flags & REQ_FAILED) + mapped = false; + + dm_done(clone, tio->error, mapped); +} + +/* * Complete the clone and the original request with the error status * through softirq context. */ -- cgit v0.10.2 From 980691e5f3a1b5ebbb2d34014e028fd7f1c6e4fb Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 10 Dec 2009 23:52:17 +0000 Subject: dm: move dm_end_request This patch moves dm_end_request() to make the next patch more readable. No functional change. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm.c b/drivers/md/dm.c index c65be45..821a5dd 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -752,6 +752,37 @@ static void free_rq_clone(struct request *clone) free_rq_tio(tio); } +/* + * Complete the clone and the original request. + * Must be called without queue lock. + */ +static void dm_end_request(struct request *clone, int error) +{ + int rw = rq_data_dir(clone); + struct dm_rq_target_io *tio = clone->end_io_data; + struct mapped_device *md = tio->md; + struct request *rq = tio->orig; + + if (blk_pc_request(rq)) { + rq->errors = clone->errors; + rq->resid_len = clone->resid_len; + + if (rq->sense) + /* + * We are using the sense buffer of the original + * request. + * So setting the length of the sense data is enough. + */ + rq->sense_len = clone->sense_len; + } + + free_rq_clone(clone); + + blk_end_request_all(rq, error); + + rq_completed(md, rw, 1); +} + static void dm_unprep_request(struct request *rq) { struct request *clone = rq->special; @@ -815,37 +846,6 @@ static void start_queue(struct request_queue *q) spin_unlock_irqrestore(q->queue_lock, flags); } -/* - * Complete the clone and the original request. - * Must be called without queue lock. - */ -static void dm_end_request(struct request *clone, int error) -{ - int rw = rq_data_dir(clone); - struct dm_rq_target_io *tio = clone->end_io_data; - struct mapped_device *md = tio->md; - struct request *rq = tio->orig; - - if (blk_pc_request(rq)) { - rq->errors = clone->errors; - rq->resid_len = clone->resid_len; - - if (rq->sense) - /* - * We are using the sense buffer of the original - * request. - * So setting the length of the sense data is enough. - */ - rq->sense_len = clone->sense_len; - } - - free_rq_clone(clone); - - blk_end_request_all(rq, error); - - rq_completed(md, rw, 1); -} - static void dm_done(struct request *clone, int error, bool mapped) { int r = error; -- cgit v0.10.2 From d0bcb8786532b01206f04258eb6b7d4ac858436a Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 10 Dec 2009 23:52:18 +0000 Subject: dm: add request based barrier support This patch adds barrier support for request-based dm. CORE DESIGN The design is basically same as bio-based dm, which emulates barrier by mapping empty barrier bios before/after a barrier I/O. But request-based dm has been using struct request_queue for I/O queueing, so the block-layer's barrier mechanism can be used. o Summary of the block-layer's behavior (which is depended by dm-core) Request-based dm uses QUEUE_ORDERED_DRAIN_FLUSH ordered mode for I/O barrier. It means that when an I/O requiring barrier is found in the request_queue, the block-layer makes pre-flush request and post-flush request just before and just after the I/O respectively. After the ordered sequence starts, the block-layer waits for all in-flight I/Os to complete, then gives drivers the pre-flush request, the barrier I/O and the post-flush request one by one. It means that the request_queue is stopped automatically by the block-layer until drivers complete each sequence. o dm-core For the barrier I/O, treats it as a normal I/O, so no additional code is needed. For the pre/post-flush request, flushes caches by the followings: 1. Make the number of empty barrier requests required by target's num_flush_requests, and map them (dm_rq_barrier()). 2. Waits for the mapped barriers to complete (dm_rq_barrier()). If error has occurred, save the error value to md->barrier_error (dm_end_request()). (*) Basically, the first reported error is taken. But -EOPNOTSUPP supersedes any error and DM_ENDIO_REQUEUE follows. 3. Requeue the pre/post-flush request if the error value is DM_ENDIO_REQUEUE. Otherwise, completes with the error value (dm_rq_barrier_work()). The pre/post-flush work above is done in the kernel thread (kdmflush) context, since memory allocation which might sleep is needed in dm_rq_barrier() but sleep is not allowed in dm_request_fn(), which is an irq-disabled context. Also, clones of the pre/post-flush request share an original, so such clones can't be completed using the softirq context. Instead, complete them in the context of underlying device drivers. It should be safe since there is no I/O dispatching during the completion of such clones. For suspend, the workqueue of kdmflush needs to be flushed after the request_queue has been stopped. Otherwise, the next flush work can be kicked even after the suspend completes. TARGET INTERFACE No new interface is added. Just use the existing num_flush_requests in struct target_type as same as bio-based dm. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 821a5dd..3de8d6d 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -143,9 +143,19 @@ struct mapped_device { int barrier_error; /* + * Protect barrier_error from concurrent endio processing + * in request-based dm. + */ + spinlock_t barrier_error_lock; + + /* * Processing queue (flush/barriers) */ struct workqueue_struct *wq; + struct work_struct barrier_work; + + /* A pointer to the currently processing pre/post flush request */ + struct request *flush_request; /* * The current mapping. @@ -722,6 +732,23 @@ static void end_clone_bio(struct bio *clone, int error) blk_update_request(tio->orig, 0, nr_bytes); } +static void store_barrier_error(struct mapped_device *md, int error) +{ + unsigned long flags; + + spin_lock_irqsave(&md->barrier_error_lock, flags); + /* + * Basically, the first error is taken, but: + * -EOPNOTSUPP supersedes any I/O error. + * Requeue request supersedes any I/O error but -EOPNOTSUPP. + */ + if (!md->barrier_error || error == -EOPNOTSUPP || + (md->barrier_error != -EOPNOTSUPP && + error == DM_ENDIO_REQUEUE)) + md->barrier_error = error; + spin_unlock_irqrestore(&md->barrier_error_lock, flags); +} + /* * Don't touch any member of the md after calling this function because * the md may be freed in dm_put() at the end of this function. @@ -759,11 +786,13 @@ static void free_rq_clone(struct request *clone) static void dm_end_request(struct request *clone, int error) { int rw = rq_data_dir(clone); + int run_queue = 1; + bool is_barrier = blk_barrier_rq(clone); struct dm_rq_target_io *tio = clone->end_io_data; struct mapped_device *md = tio->md; struct request *rq = tio->orig; - if (blk_pc_request(rq)) { + if (blk_pc_request(rq) && !is_barrier) { rq->errors = clone->errors; rq->resid_len = clone->resid_len; @@ -778,9 +807,14 @@ static void dm_end_request(struct request *clone, int error) free_rq_clone(clone); - blk_end_request_all(rq, error); + if (unlikely(is_barrier)) { + if (unlikely(error)) + store_barrier_error(md, error); + run_queue = 0; + } else + blk_end_request_all(rq, error); - rq_completed(md, rw, 1); + rq_completed(md, rw, run_queue); } static void dm_unprep_request(struct request *rq) @@ -805,6 +839,16 @@ void dm_requeue_unmapped_request(struct request *clone) struct request_queue *q = rq->q; unsigned long flags; + if (unlikely(blk_barrier_rq(clone))) { + /* + * Barrier clones share an original request. + * Leave it to dm_end_request(), which handles this special + * case. + */ + dm_end_request(clone, DM_ENDIO_REQUEUE); + return; + } + dm_unprep_request(rq); spin_lock_irqsave(q->queue_lock, flags); @@ -894,6 +938,19 @@ static void dm_complete_request(struct request *clone, int error) struct dm_rq_target_io *tio = clone->end_io_data; struct request *rq = tio->orig; + if (unlikely(blk_barrier_rq(clone))) { + /* + * Barrier clones share an original request. So can't use + * softirq_done with the original. + * Pass the clone to dm_done() directly in this special case. + * It is safe (even if clone->q->queue_lock is held here) + * because there is no I/O dispatching during the completion + * of barrier clone. + */ + dm_done(clone, error, true); + return; + } + tio->error = error; rq->completion_data = clone; blk_complete_request(rq); @@ -910,6 +967,17 @@ void dm_kill_unmapped_request(struct request *clone, int error) struct dm_rq_target_io *tio = clone->end_io_data; struct request *rq = tio->orig; + if (unlikely(blk_barrier_rq(clone))) { + /* + * Barrier clones share an original request. + * Leave it to dm_end_request(), which handles this special + * case. + */ + BUG_ON(error > 0); + dm_end_request(clone, error); + return; + } + rq->cmd_flags |= REQ_FAILED; dm_complete_request(clone, error); } @@ -1364,11 +1432,6 @@ static int dm_make_request(struct request_queue *q, struct bio *bio) { struct mapped_device *md = q->queuedata; - if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { - bio_endio(bio, -EOPNOTSUPP); - return 0; - } - return md->saved_make_request_fn(q, bio); /* call __make_request() */ } @@ -1387,6 +1450,25 @@ static int dm_request(struct request_queue *q, struct bio *bio) return _dm_request(q, bio); } +/* + * Mark this request as flush request, so that dm_request_fn() can + * recognize. + */ +static void dm_rq_prepare_flush(struct request_queue *q, struct request *rq) +{ + rq->cmd_type = REQ_TYPE_LINUX_BLOCK; + rq->cmd[0] = REQ_LB_OP_FLUSH; +} + +static bool dm_rq_is_flush_request(struct request *rq) +{ + if (rq->cmd_type == REQ_TYPE_LINUX_BLOCK && + rq->cmd[0] == REQ_LB_OP_FLUSH) + return true; + else + return false; +} + void dm_dispatch_request(struct request *rq) { int r; @@ -1432,16 +1514,24 @@ static int dm_rq_bio_constructor(struct bio *bio, struct bio *bio_orig, static int setup_clone(struct request *clone, struct request *rq, struct dm_rq_target_io *tio) { - int r = blk_rq_prep_clone(clone, rq, tio->md->bs, GFP_ATOMIC, - dm_rq_bio_constructor, tio); + int r; - if (r) - return r; + if (dm_rq_is_flush_request(rq)) { + blk_rq_init(NULL, clone); + clone->cmd_type = REQ_TYPE_FS; + clone->cmd_flags |= (REQ_HARDBARRIER | WRITE); + } else { + r = blk_rq_prep_clone(clone, rq, tio->md->bs, GFP_ATOMIC, + dm_rq_bio_constructor, tio); + if (r) + return r; + + clone->cmd = rq->cmd; + clone->cmd_len = rq->cmd_len; + clone->sense = rq->sense; + clone->buffer = rq->buffer; + } - clone->cmd = rq->cmd; - clone->cmd_len = rq->cmd_len; - clone->sense = rq->sense; - clone->buffer = rq->buffer; clone->end_io = end_clone_request; clone->end_io_data = tio; @@ -1482,6 +1572,9 @@ static int dm_prep_fn(struct request_queue *q, struct request *rq) struct mapped_device *md = q->queuedata; struct request *clone; + if (unlikely(dm_rq_is_flush_request(rq))) + return BLKPREP_OK; + if (unlikely(rq->special)) { DMWARN("Already has something in rq->special."); return BLKPREP_KILL; @@ -1560,6 +1653,14 @@ static void dm_request_fn(struct request_queue *q) if (!rq) goto plug_and_out; + if (unlikely(dm_rq_is_flush_request(rq))) { + BUG_ON(md->flush_request); + md->flush_request = rq; + blk_start_request(rq); + queue_work(md->wq, &md->barrier_work); + goto out; + } + ti = dm_table_find_target(map, blk_rq_pos(rq)); if (ti->type->busy && ti->type->busy(ti)) goto plug_and_out; @@ -1726,6 +1827,7 @@ out: static const struct block_device_operations dm_blk_dops; static void dm_wq_work(struct work_struct *work); +static void dm_rq_barrier_work(struct work_struct *work); /* * Allocate and initialise a blank device with a given minor. @@ -1755,6 +1857,7 @@ static struct mapped_device *alloc_dev(int minor) init_rwsem(&md->io_lock); mutex_init(&md->suspend_lock); spin_lock_init(&md->deferred_lock); + spin_lock_init(&md->barrier_error_lock); rwlock_init(&md->map_lock); atomic_set(&md->holders, 1); atomic_set(&md->open_count, 0); @@ -1789,6 +1892,8 @@ static struct mapped_device *alloc_dev(int minor) blk_queue_softirq_done(md->queue, dm_softirq_done); blk_queue_prep_rq(md->queue, dm_prep_fn); blk_queue_lld_busy(md->queue, dm_lld_busy); + blk_queue_ordered(md->queue, QUEUE_ORDERED_DRAIN_FLUSH, + dm_rq_prepare_flush); md->disk = alloc_disk(1); if (!md->disk) @@ -1798,6 +1903,7 @@ static struct mapped_device *alloc_dev(int minor) atomic_set(&md->pending[1], 0); init_waitqueue_head(&md->wait); INIT_WORK(&md->work, dm_wq_work); + INIT_WORK(&md->barrier_work, dm_rq_barrier_work); init_waitqueue_head(&md->eventq); md->disk->major = _major; @@ -2185,6 +2291,73 @@ static void dm_queue_flush(struct mapped_device *md) queue_work(md->wq, &md->work); } +static void dm_rq_set_flush_nr(struct request *clone, unsigned flush_nr) +{ + struct dm_rq_target_io *tio = clone->end_io_data; + + tio->info.flush_request = flush_nr; +} + +/* Issue barrier requests to targets and wait for their completion. */ +static int dm_rq_barrier(struct mapped_device *md) +{ + int i, j; + struct dm_table *map = dm_get_table(md); + unsigned num_targets = dm_table_get_num_targets(map); + struct dm_target *ti; + struct request *clone; + + md->barrier_error = 0; + + for (i = 0; i < num_targets; i++) { + ti = dm_table_get_target(map, i); + for (j = 0; j < ti->num_flush_requests; j++) { + clone = clone_rq(md->flush_request, md, GFP_NOIO); + dm_rq_set_flush_nr(clone, j); + atomic_inc(&md->pending[rq_data_dir(clone)]); + map_request(ti, clone, md); + } + } + + dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE); + dm_table_put(map); + + return md->barrier_error; +} + +static void dm_rq_barrier_work(struct work_struct *work) +{ + int error; + struct mapped_device *md = container_of(work, struct mapped_device, + barrier_work); + struct request_queue *q = md->queue; + struct request *rq; + unsigned long flags; + + /* + * Hold the md reference here and leave it at the last part so that + * the md can't be deleted by device opener when the barrier request + * completes. + */ + dm_get(md); + + error = dm_rq_barrier(md); + + rq = md->flush_request; + md->flush_request = NULL; + + if (error == DM_ENDIO_REQUEUE) { + spin_lock_irqsave(q->queue_lock, flags); + blk_requeue_request(q, rq); + spin_unlock_irqrestore(q->queue_lock, flags); + } else + blk_end_request_all(rq, error); + + blk_run_queue(q); + + dm_put(md); +} + /* * Swap in a new table (destroying old one). */ @@ -2325,11 +2498,16 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) set_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags); up_write(&md->io_lock); - flush_workqueue(md->wq); - + /* + * Request-based dm uses md->wq for barrier (dm_rq_barrier_work) which + * can be kicked until md->queue is stopped. So stop md->queue before + * flushing md->wq. + */ if (dm_request_based(md)) stop_queue(md->queue); + flush_workqueue(md->wq); + /* * At this point no more requests are entering target request routines. * We call dm_wait_for_completion to wait for all existing requests -- cgit v0.10.2 From 7c6664114b7342a36f14a6836564e865669b3cea Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Thu, 10 Dec 2009 23:52:19 +0000 Subject: dm: rename dm_get_table to dm_get_live_table Rename dm_get_table to dm_get_live_table. Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 99de0e4..bf3d19a 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -235,7 +235,7 @@ static void __hash_remove(struct hash_cell *hc) dm_set_mdptr(hc->md, NULL); mutex_unlock(&dm_hash_cells_mutex); - table = dm_get_table(hc->md); + table = dm_get_live_table(hc->md); if (table) { dm_table_event(table); dm_table_put(table); @@ -338,7 +338,7 @@ static int dm_hash_rename(uint32_t cookie, const char *old, const char *new) /* * Wake up any dm event waiters. */ - table = dm_get_table(hc->md); + table = dm_get_live_table(hc->md); if (table) { dm_table_event(table); dm_table_put(table); @@ -564,7 +564,7 @@ static int __dev_status(struct mapped_device *md, struct dm_ioctl *param) param->event_nr = dm_get_event_nr(md); - table = dm_get_table(md); + table = dm_get_live_table(md); if (table) { param->flags |= DM_ACTIVE_PRESENT_FLAG; param->target_count = dm_table_get_num_targets(table); @@ -993,7 +993,7 @@ static int dev_wait(struct dm_ioctl *param, size_t param_size) if (r) goto out; - table = dm_get_table(md); + table = dm_get_live_table(md); if (table) { retrieve_status(table, param, param_size); dm_table_put(table); @@ -1226,7 +1226,7 @@ static int table_deps(struct dm_ioctl *param, size_t param_size) if (r) goto out; - table = dm_get_table(md); + table = dm_get_live_table(md); if (table) { retrieve_deps(table, param, param_size); dm_table_put(table); @@ -1255,7 +1255,7 @@ static int table_status(struct dm_ioctl *param, size_t param_size) if (r) goto out; - table = dm_get_table(md); + table = dm_get_live_table(md); if (table) { retrieve_status(table, param, param_size); dm_table_put(table); @@ -1299,7 +1299,7 @@ static int target_message(struct dm_ioctl *param, size_t param_size) goto out; } - table = dm_get_table(md); + table = dm_get_live_table(md); if (!table) goto out_argv; diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 3de8d6d..233a2e9 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -397,7 +397,7 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { struct mapped_device *md = bdev->bd_disk->private_data; - struct dm_table *map = dm_get_table(md); + struct dm_table *map = dm_get_live_table(md); struct dm_target *tgt; int r = -ENOTTY; @@ -528,7 +528,7 @@ static void queue_io(struct mapped_device *md, struct bio *bio) * function to access the md->map field, and make sure they call * dm_table_put() when finished. */ -struct dm_table *dm_get_table(struct mapped_device *md) +struct dm_table *dm_get_live_table(struct mapped_device *md) { struct dm_table *t; unsigned long flags; @@ -1294,7 +1294,7 @@ static void __split_and_process_bio(struct mapped_device *md, struct bio *bio) struct clone_info ci; int error = 0; - ci.map = dm_get_table(md); + ci.map = dm_get_live_table(md); if (unlikely(!ci.map)) { if (!bio_rw_flagged(bio, BIO_RW_BARRIER)) bio_io_error(bio); @@ -1335,7 +1335,7 @@ static int dm_merge_bvec(struct request_queue *q, struct bio_vec *biovec) { struct mapped_device *md = q->queuedata; - struct dm_table *map = dm_get_table(md); + struct dm_table *map = dm_get_live_table(md); struct dm_target *ti; sector_t max_sectors; int max_size = 0; @@ -1638,7 +1638,7 @@ static void map_request(struct dm_target *ti, struct request *clone, static void dm_request_fn(struct request_queue *q) { struct mapped_device *md = q->queuedata; - struct dm_table *map = dm_get_table(md); + struct dm_table *map = dm_get_live_table(md); struct dm_target *ti; struct request *rq, *clone; @@ -1697,7 +1697,7 @@ static int dm_lld_busy(struct request_queue *q) { int r; struct mapped_device *md = q->queuedata; - struct dm_table *map = dm_get_table(md); + struct dm_table *map = dm_get_live_table(md); if (!map || test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) r = 1; @@ -1712,7 +1712,7 @@ static int dm_lld_busy(struct request_queue *q) static void dm_unplug_all(struct request_queue *q) { struct mapped_device *md = q->queuedata; - struct dm_table *map = dm_get_table(md); + struct dm_table *map = dm_get_live_table(md); if (map) { if (dm_request_based(md)) @@ -1730,7 +1730,7 @@ static int dm_any_congested(void *congested_data, int bdi_bits) struct dm_table *map; if (!test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) { - map = dm_get_table(md); + map = dm_get_live_table(md); if (map) { /* * Request-based dm cares about only own queue for @@ -2166,7 +2166,7 @@ void dm_put(struct mapped_device *md) BUG_ON(test_bit(DMF_FREEING, &md->flags)); if (atomic_dec_and_lock(&md->holders, &_minor_lock)) { - map = dm_get_table(md); + map = dm_get_live_table(md); idr_replace(&_minor_idr, MINOR_ALLOCED, MINOR(disk_devt(dm_disk(md)))); set_bit(DMF_FREEING, &md->flags); @@ -2302,7 +2302,7 @@ static void dm_rq_set_flush_nr(struct request *clone, unsigned flush_nr) static int dm_rq_barrier(struct mapped_device *md) { int i, j; - struct dm_table *map = dm_get_table(md); + struct dm_table *map = dm_get_live_table(md); unsigned num_targets = dm_table_get_num_targets(map); struct dm_target *ti; struct request *clone; @@ -2453,7 +2453,7 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) goto out_unlock; } - map = dm_get_table(md); + map = dm_get_live_table(md); /* * DMF_NOFLUSH_SUSPENDING must be set before presuspend. @@ -2558,7 +2558,7 @@ int dm_resume(struct mapped_device *md) if (!dm_suspended(md)) goto out; - map = dm_get_table(md); + map = dm_get_live_table(md); if (!map || !dm_table_get_size(map)) goto out; diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index df7607e..fc16a35 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -276,7 +276,7 @@ void dm_table_unplug_all(struct dm_table *t); /* * Table reference counting. */ -struct dm_table *dm_get_table(struct mapped_device *md); +struct dm_table *dm_get_live_table(struct mapped_device *md); void dm_table_get(struct dm_table *t); void dm_table_put(struct dm_table *t); -- cgit v0.10.2 From 6df400ab64c68fc4072a13019fc20fd7e3d51303 Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 10 Dec 2009 23:52:19 +0000 Subject: dm mpath: flush workqueues before suspend completes This patch stops the remaining dm-mpath activity during the suspend sequence by flushing workqueues in postsuspend function. The current dm-mpath target may not be quiet even after suspend completes because some workqueues (e.g. device_handler's work, event handling) are not flushed during the suspend sequence, even though suspended devices/targets are supposed to be quiet in this state. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index dce971d..5b23f2d 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -885,13 +885,18 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc, return r; } -static void multipath_dtr(struct dm_target *ti) +static void flush_multipath_work(void) { - struct multipath *m = (struct multipath *) ti->private; - flush_workqueue(kmpath_handlerd); flush_workqueue(kmultipathd); flush_scheduled_work(); +} + +static void multipath_dtr(struct dm_target *ti) +{ + struct multipath *m = ti->private; + + flush_multipath_work(); free_multipath(m); } @@ -1261,6 +1266,11 @@ static void multipath_presuspend(struct dm_target *ti) queue_if_no_path(m, 0, 1); } +static void multipath_postsuspend(struct dm_target *ti) +{ + flush_multipath_work(); +} + /* * Restore the queue_if_no_path setting. */ @@ -1567,13 +1577,14 @@ out: *---------------------------------------------------------------*/ static struct target_type multipath_target = { .name = "multipath", - .version = {1, 1, 0}, + .version = {1, 1, 1}, .module = THIS_MODULE, .ctr = multipath_ctr, .dtr = multipath_dtr, .map_rq = multipath_map, .rq_end_io = multipath_end_io, .presuspend = multipath_presuspend, + .postsuspend = multipath_postsuspend, .resume = multipath_resume, .status = multipath_status, .message = multipath_message, -- cgit v0.10.2 From 432a212c0dd0f4ca386cf37c5b740ac9dbda4479 Mon Sep 17 00:00:00 2001 From: Mike Anderson Date: Thu, 10 Dec 2009 23:52:20 +0000 Subject: dm: add dm_deleting_md function Add dm_deleting_md to check whether or not a given mapped device is currently being deleted. Signed-off-by: Mike Anderson Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 233a2e9..16f759f 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -329,6 +329,11 @@ static void __exit dm_exit(void) /* * Block device functions */ +int dm_deleting_md(struct mapped_device *md) +{ + return test_bit(DMF_DELETING, &md->flags); +} + static int dm_blk_open(struct block_device *bdev, fmode_t mode) { struct mapped_device *md; @@ -340,7 +345,7 @@ static int dm_blk_open(struct block_device *bdev, fmode_t mode) goto out; if (test_bit(DMF_FREEING, &md->flags) || - test_bit(DMF_DELETING, &md->flags)) { + dm_deleting_md(md)) { md = NULL; goto out; } @@ -2659,7 +2664,7 @@ struct mapped_device *dm_get_from_kobject(struct kobject *kobj) return NULL; if (test_bit(DMF_FREEING, &md->flags) || - test_bit(DMF_DELETING, &md->flags)) + dm_deleting_md(md)) return NULL; dm_get(md); diff --git a/drivers/md/dm.h b/drivers/md/dm.h index 4a95e8f..604a5f2 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -89,6 +89,11 @@ int dm_target_iterate(void (*iter_func)(struct target_type *tt, int dm_split_args(int *argc, char ***argvp, char *input); /* + * Is this mapped_device being deleted? + */ +int dm_deleting_md(struct mapped_device *md); + +/* * The device-mapper can be driven through one of two interfaces; * ioctl or filesystem, depending which patch you have applied. */ -- cgit v0.10.2 From c50abeb38026ea721a812cf8a9b2fac5d3b7684b Mon Sep 17 00:00:00 2001 From: Mike Anderson Date: Thu, 10 Dec 2009 23:52:20 +0000 Subject: dm ioctl: forbid messages to devices being deleted Once we begin deleting a device, prevent any further messages being sent to targets of its table (to avoid races). Signed-off-by: Mike Anderson Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index bf3d19a..d06dd39 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -1303,6 +1303,11 @@ static int target_message(struct dm_ioctl *param, size_t param_size) if (!table) goto out_argv; + if (dm_deleting_md(md)) { + r = -ENXIO; + goto out_table; + } + ti = dm_table_find_target(table, tmsg->sector); if (!dm_target_is_valid(ti)) { DMWARN("Target message sector outside device."); @@ -1314,6 +1319,7 @@ static int target_message(struct dm_ioctl *param, size_t param_size) r = -EINVAL; } + out_table: dm_table_put(table); out_argv: kfree(argv); -- cgit v0.10.2 From 6380f26f0424034345461cabaab9a7030d905b59 Mon Sep 17 00:00:00 2001 From: Mike Anderson Date: Thu, 10 Dec 2009 23:52:21 +0000 Subject: dm mpath: add mutex to synchronize adding and flushing work Add a mutex to allow possible creators of new work to synchronize with flushing work queues. Signed-off-by: Mike Anderson Acked-by: Kiyoshi Ueda Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 5b23f2d..700154e 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -93,6 +93,8 @@ struct multipath { * can resubmit bios on error. */ mempool_t *mpio_pool; + + struct mutex work_mutex; }; /* @@ -198,6 +200,7 @@ static struct multipath *alloc_multipath(struct dm_target *ti) m->queue_io = 1; INIT_WORK(&m->process_queued_ios, process_queued_ios); INIT_WORK(&m->trigger_event, trigger_event); + mutex_init(&m->work_mutex); m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache); if (!m->mpio_pool) { kfree(m); @@ -1268,7 +1271,11 @@ static void multipath_presuspend(struct dm_target *ti) static void multipath_postsuspend(struct dm_target *ti) { + struct multipath *m = ti->private; + + mutex_lock(&m->work_mutex); flush_multipath_work(); + mutex_unlock(&m->work_mutex); } /* @@ -1407,51 +1414,61 @@ static int multipath_status(struct dm_target *ti, status_type_t type, static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) { - int r; + int r = -EINVAL; struct dm_dev *dev; struct multipath *m = (struct multipath *) ti->private; action_fn action; + mutex_lock(&m->work_mutex); + if (argc == 1) { - if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) - return queue_if_no_path(m, 1, 0); - else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path"))) - return queue_if_no_path(m, 0, 0); + if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) { + r = queue_if_no_path(m, 1, 0); + goto out; + } else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path"))) { + r = queue_if_no_path(m, 0, 0); + goto out; + } } - if (argc != 2) - goto error; + if (argc != 2) { + DMWARN("Unrecognised multipath message received."); + goto out; + } - if (!strnicmp(argv[0], MESG_STR("disable_group"))) - return bypass_pg_num(m, argv[1], 1); - else if (!strnicmp(argv[0], MESG_STR("enable_group"))) - return bypass_pg_num(m, argv[1], 0); - else if (!strnicmp(argv[0], MESG_STR("switch_group"))) - return switch_pg_num(m, argv[1]); - else if (!strnicmp(argv[0], MESG_STR("reinstate_path"))) + if (!strnicmp(argv[0], MESG_STR("disable_group"))) { + r = bypass_pg_num(m, argv[1], 1); + goto out; + } else if (!strnicmp(argv[0], MESG_STR("enable_group"))) { + r = bypass_pg_num(m, argv[1], 0); + goto out; + } else if (!strnicmp(argv[0], MESG_STR("switch_group"))) { + r = switch_pg_num(m, argv[1]); + goto out; + } else if (!strnicmp(argv[0], MESG_STR("reinstate_path"))) action = reinstate_path; else if (!strnicmp(argv[0], MESG_STR("fail_path"))) action = fail_path; - else - goto error; + else { + DMWARN("Unrecognised multipath message received."); + goto out; + } r = dm_get_device(ti, argv[1], ti->begin, ti->len, dm_table_get_mode(ti->table), &dev); if (r) { DMWARN("message: error getting device %s", argv[1]); - return -EINVAL; + goto out; } r = action_dev(m, dev, action); dm_put_device(ti, dev); +out: + mutex_unlock(&m->work_mutex); return r; - -error: - DMWARN("Unrecognised multipath message received."); - return -EINVAL; } static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, -- cgit v0.10.2 From 67a46dad25ccc8910995d8671f7ec17a6bc823cb Mon Sep 17 00:00:00 2001 From: Mike Anderson Date: Thu, 10 Dec 2009 23:52:21 +0000 Subject: dm mpath: prevent io from work queue while suspended Reject messages that can generate I/O while the device itself is suspended. Signed-off-by: Mike Anderson Acked-by: Kiyoshi Ueda Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 700154e..45d9bf1 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -95,6 +95,8 @@ struct multipath { mempool_t *mpio_pool; struct mutex work_mutex; + + unsigned suspended; /* Don't create new I/O internally when set. */ }; /* @@ -1274,6 +1276,7 @@ static void multipath_postsuspend(struct dm_target *ti) struct multipath *m = ti->private; mutex_lock(&m->work_mutex); + m->suspended = 1; flush_multipath_work(); mutex_unlock(&m->work_mutex); } @@ -1286,6 +1289,10 @@ static void multipath_resume(struct dm_target *ti) struct multipath *m = (struct multipath *) ti->private; unsigned long flags; + mutex_lock(&m->work_mutex); + m->suspended = 0; + mutex_unlock(&m->work_mutex); + spin_lock_irqsave(&m->lock, flags); m->queue_if_no_path = m->saved_queue_if_no_path; spin_unlock_irqrestore(&m->lock, flags); @@ -1421,6 +1428,11 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) mutex_lock(&m->work_mutex); + if (m->suspended) { + r = -EBUSY; + goto out; + } + if (argc == 1) { if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) { r = queue_if_no_path(m, 1, 0); -- cgit v0.10.2 From 12fc0f49dc994d8d90dcf3df13f5b1ee5441288d Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:22 +0000 Subject: dm io: handle empty barriers Accept empty barriers in dm-io. dm-io will process empty write barrier requests just like the other read/write requests. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index f6a714c..10f457c 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -309,7 +309,11 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, unsigned num_bvecs; sector_t remaining = where->count; - while (remaining) { + /* + * where->count may be zero if rw holds a write barrier and we + * need to send a zero-sized barrier. + */ + do { /* * Allocate a suitably sized-bio. */ @@ -339,7 +343,7 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, atomic_inc(&io->count); submit_bio(rw, bio); - } + } while (remaining); } static void dispatch_io(int rw, unsigned int num_regions, @@ -360,7 +364,7 @@ static void dispatch_io(int rw, unsigned int num_regions, */ for (i = 0; i < num_regions; i++) { *dp = old_pages; - if (where[i].count) + if (where[i].count || (rw & (1 << BIO_RW_BARRIER))) do_region(rw, i, where + i, dp, io); } -- cgit v0.10.2 From 1d0f3ce83200edc5d43723c77c62b09ad6560294 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 10 Dec 2009 23:52:22 +0000 Subject: dm ioctl: retrieve status from inactive table Add the flag DM_QUERY_INACTIVE_TABLE_FLAG to the ioctls to return infomation about the loaded-but-not-yet-active table instead of the live table. Prior to this patch it was impossible to obtain this information until the device had been 'resumed'. Userspace dmsetup and libdevmapper support the flag as of version 1.02.40. e.g. dmsetup info --inactive vg1-lv1 Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index d06dd39..a3d2026 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -523,8 +523,6 @@ static int list_versions(struct dm_ioctl *param, size_t param_size) return 0; } - - static int check_name(const char *name) { if (strchr(name, '/')) { @@ -536,6 +534,40 @@ static int check_name(const char *name) } /* + * On successful return, the caller must not attempt to acquire + * _hash_lock without first calling dm_table_put, because dm_table_destroy + * waits for this dm_table_put and could be called under this lock. + */ +static struct dm_table *dm_get_inactive_table(struct mapped_device *md) +{ + struct hash_cell *hc; + struct dm_table *table = NULL; + + down_read(&_hash_lock); + hc = dm_get_mdptr(md); + if (!hc || hc->md != md) { + DMWARN("device has been removed from the dev hash table."); + goto out; + } + + table = hc->new_map; + if (table) + dm_table_get(table); + +out: + up_read(&_hash_lock); + + return table; +} + +static struct dm_table *dm_get_live_or_inactive_table(struct mapped_device *md, + struct dm_ioctl *param) +{ + return (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) ? + dm_get_inactive_table(md) : dm_get_live_table(md); +} + +/* * Fills in a dm_ioctl structure, ready for sending back to * userland. */ @@ -559,18 +591,30 @@ static int __dev_status(struct mapped_device *md, struct dm_ioctl *param) */ param->open_count = dm_open_count(md); - if (get_disk_ro(disk)) - param->flags |= DM_READONLY_FLAG; - param->event_nr = dm_get_event_nr(md); + param->target_count = 0; table = dm_get_live_table(md); if (table) { - param->flags |= DM_ACTIVE_PRESENT_FLAG; - param->target_count = dm_table_get_num_targets(table); + if (!(param->flags & DM_QUERY_INACTIVE_TABLE_FLAG)) { + if (get_disk_ro(disk)) + param->flags |= DM_READONLY_FLAG; + param->target_count = dm_table_get_num_targets(table); + } dm_table_put(table); - } else - param->target_count = 0; + + param->flags |= DM_ACTIVE_PRESENT_FLAG; + } + + if (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) { + table = dm_get_inactive_table(md); + if (table) { + if (!(dm_table_get_mode(table) & FMODE_WRITE)) + param->flags |= DM_READONLY_FLAG; + param->target_count = dm_table_get_num_targets(table); + dm_table_put(table); + } + } return 0; } @@ -993,7 +1037,7 @@ static int dev_wait(struct dm_ioctl *param, size_t param_size) if (r) goto out; - table = dm_get_live_table(md); + table = dm_get_live_or_inactive_table(md, param); if (table) { retrieve_status(table, param, param_size); dm_table_put(table); @@ -1226,7 +1270,7 @@ static int table_deps(struct dm_ioctl *param, size_t param_size) if (r) goto out; - table = dm_get_live_table(md); + table = dm_get_live_or_inactive_table(md, param); if (table) { retrieve_deps(table, param, param_size); dm_table_put(table); @@ -1255,13 +1299,13 @@ static int table_status(struct dm_ioctl *param, size_t param_size) if (r) goto out; - table = dm_get_live_table(md); + table = dm_get_live_or_inactive_table(md, param); if (table) { retrieve_status(table, param, param_size); dm_table_put(table); } - out: +out: dm_put(md); return r; } diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h index 2ab84c8..aa95508 100644 --- a/include/linux/dm-ioctl.h +++ b/include/linux/dm-ioctl.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2001 - 2003 Sistina Software (UK) Limited. - * Copyright (C) 2004 - 2005 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004 - 2009 Red Hat, Inc. All rights reserved. * * This file is released under the LGPL. */ @@ -266,9 +266,9 @@ enum { #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl) #define DM_VERSION_MAJOR 4 -#define DM_VERSION_MINOR 15 +#define DM_VERSION_MINOR 16 #define DM_VERSION_PATCHLEVEL 0 -#define DM_VERSION_EXTRA "-ioctl (2009-04-01)" +#define DM_VERSION_EXTRA "-ioctl (2009-11-05)" /* Status bits */ #define DM_READONLY_FLAG (1 << 0) /* In/Out */ @@ -309,4 +309,11 @@ enum { */ #define DM_NOFLUSH_FLAG (1 << 11) /* In */ +/* + * If set, any table information returned will relate to the inactive + * table instead of the live one. Always check DM_INACTIVE_PRESENT_FLAG + * is set before using the data returned. + */ +#define DM_QUERY_INACTIVE_TABLE_FLAG (1 << 12) /* In */ + #endif /* _LINUX_DM_IOCTL_H */ -- cgit v0.10.2 From a794015597a2d9b437470c7692aac77e5fc08cd2 Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Thu, 10 Dec 2009 23:52:23 +0000 Subject: dm: bind new table before destroying old When replacing a mapped device's table during a 'resume', delay the destruction of the old table until the new one is successfully in place. This will make it easier for a later patch to transfer internal state information from the old table to the new one (something we do not currently support) while giving us more options for reversion if a later part of the operation fails. Devices are always in the suspended state during dm_swap_table(). This patch reinforces the requirement that all I/O must have been flushed from the table targets while in this state (including any in workqueues). In the case of 'noflush' suspending, unprocessed I/O should have been 'pushed back' to the dm core prior to this point, for resubmission after the new table is in place. Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 1a6cb3c..3162b9c 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -237,6 +237,9 @@ void dm_table_destroy(struct dm_table *t) { unsigned int i; + if (!t) + return; + while (atomic_read(&t->holders)) msleep(1); smp_mb(); diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 16f759f..255b75c 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -2077,19 +2077,23 @@ static int __bind(struct mapped_device *md, struct dm_table *t, return 0; } -static void __unbind(struct mapped_device *md) +/* + * Returns unbound table for the caller to free. + */ +static struct dm_table *__unbind(struct mapped_device *md) { struct dm_table *map = md->map; unsigned long flags; if (!map) - return; + return NULL; dm_table_event_callback(map, NULL, NULL); write_lock_irqsave(&md->map_lock, flags); md->map = NULL; write_unlock_irqrestore(&md->map_lock, flags); - dm_table_destroy(map); + + return map; } /* @@ -2182,7 +2186,7 @@ void dm_put(struct mapped_device *md) } dm_sysfs_exit(md); dm_table_put(map); - __unbind(md); + dm_table_destroy(__unbind(md)); free_dev(md); } } @@ -2368,6 +2372,7 @@ static void dm_rq_barrier_work(struct work_struct *work) */ int dm_swap_table(struct mapped_device *md, struct dm_table *table) { + struct dm_table *map; struct queue_limits limits; int r = -EINVAL; @@ -2388,8 +2393,9 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) goto out; } - __unbind(md); + map = __unbind(md); r = __bind(md, table, &limits); + dm_table_destroy(map); out: mutex_unlock(&md->suspend_lock); -- cgit v0.10.2 From 042d2a9bcd80fe12d4b0871706aa9dd2231e8238 Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Thu, 10 Dec 2009 23:52:24 +0000 Subject: dm: keep old table until after resume succeeded When swapping a new table into place, retain the old table until its replacement is in place. An old check for an empty table is removed because this is enforced in populate_table(). __unbind() becomes redundant when followed by __bind(). Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index a3d2026..63fd4de 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -855,7 +855,7 @@ static int do_resume(struct dm_ioctl *param) unsigned suspend_flags = DM_SUSPEND_LOCKFS_FLAG; struct hash_cell *hc; struct mapped_device *md; - struct dm_table *new_map; + struct dm_table *new_map, *old_map = NULL; down_write(&_hash_lock); @@ -884,11 +884,11 @@ static int do_resume(struct dm_ioctl *param) if (!dm_suspended(md)) dm_suspend(md, suspend_flags); - r = dm_swap_table(md, new_map); - if (r) { + old_map = dm_swap_table(md, new_map); + if (IS_ERR(old_map)) { dm_table_destroy(new_map); dm_put(md); - return r; + return PTR_ERR(old_map); } if (dm_table_get_mode(new_map) & FMODE_WRITE) @@ -900,6 +900,8 @@ static int do_resume(struct dm_ioctl *param) if (dm_suspended(md)) r = dm_resume(md); + if (old_map) + dm_table_destroy(old_map); if (!r) { dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr); diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 255b75c..c254c6c 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -2033,9 +2033,13 @@ static void __set_size(struct mapped_device *md, sector_t size) mutex_unlock(&md->bdev->bd_inode->i_mutex); } -static int __bind(struct mapped_device *md, struct dm_table *t, - struct queue_limits *limits) +/* + * Returns old map, which caller must destroy. + */ +static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t, + struct queue_limits *limits) { + struct dm_table *old_map; struct request_queue *q = md->queue; sector_t size; unsigned long flags; @@ -2050,11 +2054,6 @@ static int __bind(struct mapped_device *md, struct dm_table *t, __set_size(md, size); - if (!size) { - dm_table_destroy(t); - return 0; - } - dm_table_event_callback(t, event_callback, md); /* @@ -2070,11 +2069,12 @@ static int __bind(struct mapped_device *md, struct dm_table *t, __bind_mempools(md, t); write_lock_irqsave(&md->map_lock, flags); + old_map = md->map; md->map = t; dm_table_set_restrictions(t, q, limits); write_unlock_irqrestore(&md->map_lock, flags); - return 0; + return old_map; } /* @@ -2368,13 +2368,13 @@ static void dm_rq_barrier_work(struct work_struct *work) } /* - * Swap in a new table (destroying old one). + * Swap in a new table, returning the old one for the caller to destroy. */ -int dm_swap_table(struct mapped_device *md, struct dm_table *table) +struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table) { - struct dm_table *map; + struct dm_table *map = ERR_PTR(-EINVAL); struct queue_limits limits; - int r = -EINVAL; + int r; mutex_lock(&md->suspend_lock); @@ -2383,8 +2383,10 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) goto out; r = dm_calculate_queue_limits(table, &limits); - if (r) + if (r) { + map = ERR_PTR(r); goto out; + } /* cannot change the device type, once a table is bound */ if (md->map && @@ -2393,13 +2395,11 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) goto out; } - map = __unbind(md); - r = __bind(md, table, &limits); - dm_table_destroy(map); + map = __bind(md, table, &limits); out: mutex_unlock(&md->suspend_lock); - return r; + return map; } /* diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index fc16a35..b9c6c8c 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -295,8 +295,10 @@ void dm_table_event(struct dm_table *t); /* * The device must be suspended before calling this method. + * Returns the previous table, which the caller must destroy. */ -int dm_swap_table(struct mapped_device *md, struct dm_table *t); +struct dm_table *dm_swap_table(struct mapped_device *md, + struct dm_table *t); /* * A wrapper around vmalloc. -- cgit v0.10.2 From c1f0c183f6acc6d32c5a1d0249ec68bf783af7b1 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 10 Dec 2009 23:52:24 +0000 Subject: dm snapshot: allow live exception store handover between tables Permit in-use snapshot exception data to be 'handed over' from one snapshot instance to another. This is a pre-requisite for patches that allow the changes made in a snapshot device to be merged back into its origin device and also allows device resizing. The basic call sequence is: dmsetup load new_snapshot (referencing the existing in-use cow device) - the ctr code detects that the cow is already in use and allows the two snapshot target instances to be linked together dmsetup suspend original_snapshot dmsetup resume new_snapshot - the new_snapshot becomes live, and if anything now tries to access the original one it will receive -EIO dmsetup remove original_snapshot (There can only be two snapshot targets referencing the same cow device simultaneously.) Signed-off-by: Mike Snitzer Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index fd04caa9..b5b9118 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -303,22 +303,116 @@ static void __insert_origin(struct origin *o) } /* + * _origins_lock must be held when calling this function. + * Returns number of snapshots registered using the supplied cow device, plus: + * snap_src - a snapshot suitable for use as a source of exception handover + * snap_dest - a snapshot capable of receiving exception handover. + * + * Possible return values and states: + * 0: NULL, NULL - first new snapshot + * 1: snap_src, NULL - normal snapshot + * 2: snap_src, snap_dest - waiting for handover + * 2: snap_src, NULL - handed over, waiting for old to be deleted + * 1: NULL, snap_dest - source got destroyed without handover + */ +static int __find_snapshots_sharing_cow(struct dm_snapshot *snap, + struct dm_snapshot **snap_src, + struct dm_snapshot **snap_dest) +{ + struct dm_snapshot *s; + struct origin *o; + int count = 0; + int active; + + o = __lookup_origin(snap->origin->bdev); + if (!o) + goto out; + + list_for_each_entry(s, &o->snapshots, list) { + if (!bdev_equal(s->cow->bdev, snap->cow->bdev)) + continue; + + down_read(&s->lock); + active = s->active; + up_read(&s->lock); + + if (active) { + if (snap_src) + *snap_src = s; + } else if (snap_dest) + *snap_dest = s; + + count++; + } + +out: + return count; +} + +/* + * On success, returns 1 if this snapshot is a handover destination, + * otherwise returns 0. + */ +static int __validate_exception_handover(struct dm_snapshot *snap) +{ + struct dm_snapshot *snap_src = NULL, *snap_dest = NULL; + + /* Does snapshot need exceptions handed over to it? */ + if ((__find_snapshots_sharing_cow(snap, &snap_src, &snap_dest) == 2) || + snap_dest) { + snap->ti->error = "Snapshot cow pairing for exception " + "table handover failed"; + return -EINVAL; + } + + /* + * If no snap_src was found, snap cannot become a handover + * destination. + */ + if (!snap_src) + return 0; + + return 1; +} + +static void __insert_snapshot(struct origin *o, struct dm_snapshot *s) +{ + struct dm_snapshot *l; + + /* Sort the list according to chunk size, largest-first smallest-last */ + list_for_each_entry(l, &o->snapshots, list) + if (l->store->chunk_size < s->store->chunk_size) + break; + list_add_tail(&s->list, &l->list); +} + +/* * Make a note of the snapshot and its origin so we can look it * up when the origin has a write on it. + * + * Also validate snapshot exception store handovers. + * On success, returns 1 if this registration is a handover destination, + * otherwise returns 0. */ static int register_snapshot(struct dm_snapshot *snap) { - struct dm_snapshot *l; - struct origin *o, *new_o; + struct origin *o, *new_o = NULL; struct block_device *bdev = snap->origin->bdev; + int r = 0; new_o = kmalloc(sizeof(*new_o), GFP_KERNEL); if (!new_o) return -ENOMEM; down_write(&_origins_lock); - o = __lookup_origin(bdev); + r = __validate_exception_handover(snap); + if (r < 0) { + kfree(new_o); + goto out; + } + + o = __lookup_origin(bdev); if (o) kfree(new_o); else { @@ -332,14 +426,27 @@ static int register_snapshot(struct dm_snapshot *snap) __insert_origin(o); } - /* Sort the list according to chunk size, largest-first smallest-last */ - list_for_each_entry(l, &o->snapshots, list) - if (l->store->chunk_size < snap->store->chunk_size) - break; - list_add_tail(&snap->list, &l->list); + __insert_snapshot(o, snap); + +out: + up_write(&_origins_lock); + + return r; +} + +/* + * Move snapshot to correct place in list according to chunk size. + */ +static void reregister_snapshot(struct dm_snapshot *s) +{ + struct block_device *bdev = s->origin->bdev; + + down_write(&_origins_lock); + + list_del(&s->list); + __insert_snapshot(__lookup_origin(bdev), s); up_write(&_origins_lock); - return 0; } static void unregister_snapshot(struct dm_snapshot *s) @@ -350,7 +457,7 @@ static void unregister_snapshot(struct dm_snapshot *s) o = __lookup_origin(s->origin->bdev); list_del(&s->list); - if (list_empty(&o->snapshots)) { + if (o && list_empty(&o->snapshots)) { list_del(&o->hash_list); kfree(o); } @@ -662,6 +769,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) s->suspended = 0; atomic_set(&s->pending_exceptions_count, 0); init_rwsem(&s->lock); + INIT_LIST_HEAD(&s->list); spin_lock_init(&s->pe_lock); /* Allocate hash table for COW data */ @@ -696,39 +804,55 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) spin_lock_init(&s->tracked_chunk_lock); - /* Metadata must only be loaded into one table at once */ + bio_list_init(&s->queued_bios); + INIT_WORK(&s->queued_bios_work, flush_queued_bios); + + ti->private = s; + ti->num_flush_requests = 1; + + /* Add snapshot to the list of snapshots for this origin */ + /* Exceptions aren't triggered till snapshot_resume() is called */ + r = register_snapshot(s); + if (r == -ENOMEM) { + ti->error = "Snapshot origin struct allocation failed"; + goto bad_load_and_register; + } else if (r < 0) { + /* invalid handover, register_snapshot has set ti->error */ + goto bad_load_and_register; + } + + /* + * Metadata must only be loaded into one table at once, so skip this + * if metadata will be handed over during resume. + * Chunk size will be set during the handover - set it to zero to + * ensure it's ignored. + */ + if (r > 0) { + s->store->chunk_size = 0; + return 0; + } + r = s->store->type->read_metadata(s->store, dm_add_exception, (void *)s); if (r < 0) { ti->error = "Failed to read snapshot metadata"; - goto bad_load_and_register; + goto bad_read_metadata; } else if (r > 0) { s->valid = 0; DMWARN("Snapshot is marked invalid."); } - bio_list_init(&s->queued_bios); - INIT_WORK(&s->queued_bios_work, flush_queued_bios); - if (!s->store->chunk_size) { ti->error = "Chunk size not set"; - goto bad_load_and_register; - } - - /* Add snapshot to the list of snapshots for this origin */ - /* Exceptions aren't triggered till snapshot_resume() is called */ - if (register_snapshot(s)) { - r = -EINVAL; - ti->error = "Cannot register snapshot origin"; - goto bad_load_and_register; + goto bad_read_metadata; } - - ti->private = s; ti->split_io = s->store->chunk_size; - ti->num_flush_requests = 1; return 0; +bad_read_metadata: + unregister_snapshot(s); + bad_load_and_register: mempool_destroy(s->tracked_chunk_pool); @@ -767,15 +891,58 @@ static void __free_exceptions(struct dm_snapshot *s) dm_exception_table_exit(&s->complete, exception_cache); } +static void __handover_exceptions(struct dm_snapshot *snap_src, + struct dm_snapshot *snap_dest) +{ + union { + struct dm_exception_table table_swap; + struct dm_exception_store *store_swap; + } u; + + /* + * Swap all snapshot context information between the two instances. + */ + u.table_swap = snap_dest->complete; + snap_dest->complete = snap_src->complete; + snap_src->complete = u.table_swap; + + u.store_swap = snap_dest->store; + snap_dest->store = snap_src->store; + snap_src->store = u.store_swap; + + snap_dest->store->snap = snap_dest; + snap_src->store->snap = snap_src; + + snap_dest->ti->split_io = snap_dest->store->chunk_size; + snap_dest->valid = snap_src->valid; + + /* + * Set source invalid to ensure it receives no further I/O. + */ + snap_src->valid = 0; +} + static void snapshot_dtr(struct dm_target *ti) { #ifdef CONFIG_DM_DEBUG int i; #endif struct dm_snapshot *s = ti->private; + struct dm_snapshot *snap_src = NULL, *snap_dest = NULL; flush_workqueue(ksnapd); + down_read(&_origins_lock); + /* Check whether exception handover must be cancelled */ + (void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest); + if (snap_src && snap_dest && (s == snap_src)) { + down_write(&snap_dest->lock); + snap_dest->valid = 0; + up_write(&snap_dest->lock); + DMERR("Cancelling snapshot handover."); + } + up_read(&_origins_lock); + /* Prevent further origin writes from using this snapshot. */ /* After this returns there can be no new kcopyd jobs. */ unregister_snapshot(s); @@ -1188,9 +1355,50 @@ static void snapshot_postsuspend(struct dm_target *ti) up_write(&s->lock); } +static int snapshot_preresume(struct dm_target *ti) +{ + int r = 0; + struct dm_snapshot *s = ti->private; + struct dm_snapshot *snap_src = NULL, *snap_dest = NULL; + + down_read(&_origins_lock); + (void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest); + if (snap_src && snap_dest) { + down_read(&snap_src->lock); + if (s == snap_src) { + DMERR("Unable to resume snapshot source until " + "handover completes."); + r = -EINVAL; + } else if (!snap_src->suspended) { + DMERR("Unable to perform snapshot handover until " + "source is suspended."); + r = -EINVAL; + } + up_read(&snap_src->lock); + } + up_read(&_origins_lock); + + return r; +} + static void snapshot_resume(struct dm_target *ti) { struct dm_snapshot *s = ti->private; + struct dm_snapshot *snap_src = NULL, *snap_dest = NULL; + + down_read(&_origins_lock); + (void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest); + if (snap_src && snap_dest) { + down_write(&snap_src->lock); + down_write_nested(&snap_dest->lock, SINGLE_DEPTH_NESTING); + __handover_exceptions(snap_src, snap_dest); + up_write(&snap_dest->lock); + up_write(&snap_src->lock); + } + up_read(&_origins_lock); + + /* Now we have correct chunk size, reregister */ + reregister_snapshot(s); down_write(&s->lock); s->active = 1; @@ -1510,6 +1718,7 @@ static struct target_type snapshot_target = { .map = snapshot_map, .end_io = snapshot_end_io, .postsuspend = snapshot_postsuspend, + .preresume = snapshot_preresume, .resume = snapshot_resume, .status = snapshot_status, .iterate_devices = snapshot_iterate_devices, -- cgit v0.10.2 From 6db4ccd6357f28c9ef7058b3bc48904c4b2ac419 Mon Sep 17 00:00:00 2001 From: Jun'ichi Nomura Date: Thu, 10 Dec 2009 23:52:25 +0000 Subject: dm: trace request based remapping This patch adds a remapping trace to request-based dm. BIO-based dm already has the equivalent tracepoint. For example, under this dm stack (linear LV on multipath): # dmsetup ls --tree -o ascii vg-lv0 (253:1) `-mpath0 (253:0) |- (8:160) |- (66:80) |- (65:176) `- (65:160) Trace of 'dd of=/dev/vg/lv0 bs=128k count=1 oflag=direct' looks like this: without the patch: dd-6674 [000] 539.727384: block_bio_queue: 253,1 WS 0 + 256 [dd] dd-6674 [000] 539.727392: block_remap: 253,0 WS 384 + 256 <- (253,1) 0 dd-6674 [000] 539.727394: block_bio_queue: 253,0 WS 384 + 256 [dd] dd-6674 [000] 539.727405: block_getrq: 253,0 WS 384 + 256 [dd] dd-6674 [000] 539.727409: block_plug: [dd] dd-6674 [000] 539.727410: block_rq_insert: 253,0 W 0 () 384 + 256 [dd] dd-6674 [000] 539.727416: block_rq_issue: 253,0 W 0 () 384 + 256 [dd] dd-6674 [000] 539.727426: block_rq_insert: 65,176 W 0 () 384 + 256 [dd] dd-6674 [000] 539.727427: block_rq_issue: 65,176 W 0 () 384 + 256 [dd] ... and with the patch: (the line with '**' is the trace added by this patch) dd-6617 [002] 162.914301: block_bio_queue: 253,1 WS 0 + 256 [dd] dd-6617 [002] 162.914314: block_remap: 253,0 WS 384 + 256 <- (253,1) 0 dd-6617 [002] 162.914316: block_bio_queue: 253,0 WS 384 + 256 [dd] dd-6617 [002] 162.914331: block_getrq: 253,0 WS 384 + 256 [dd] dd-6617 [002] 162.914335: block_plug: [dd] dd-6617 [002] 162.914337: block_rq_insert: 253,0 W 0 () 384 + 256 [dd] dd-6617 [002] 162.914347: block_rq_issue: 253,0 W 0 () 384 + 256 [dd] **dd-6617 [002] 162.914356: block_rq_remap: 65,176 W 384 + 256 <- (253,0) 384 dd-6617 [002] 162.914358: block_rq_insert: 65,176 W 0 () 384 + 256 [dd] dd-6617 [002] 162.914359: block_rq_issue: 65,176 W 0 () 384 + 256 [dd] ... Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Cc: Jens Axboe Cc: Li Zefan Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm.c b/drivers/md/dm.c index c254c6c..40e257f 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1618,6 +1618,8 @@ static void map_request(struct dm_target *ti, struct request *clone, break; case DM_MAPIO_REMAPPED: /* The target has remapped the I/O so dispatch it */ + trace_block_rq_remap(clone->q, clone, disk_devt(dm_disk(md)), + blk_rq_pos(tio->orig)); dm_dispatch_request(clone); break; case DM_MAPIO_REQUEUE: -- cgit v0.10.2 From 61afef614b013ee1b767cdd10325acae1db1f4d2 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Thu, 10 Dec 2009 23:52:25 +0000 Subject: dm crypt: add plain64 iv The default plain IV is 32-bit only. This plain64 IV provides a compatible mode for encrypted devices bigger than 4TB. Signed-off-by: Milan Broz Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 91e1bf9..a936372 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -158,6 +158,9 @@ static void kcryptd_queue_crypt(struct dm_crypt_io *io); * plain: the initial vector is the 32-bit little-endian version of the sector * number, padded with zeros if necessary. * + * plain64: the initial vector is the 64-bit little-endian version of the sector + * number, padded with zeros if necessary. + * * essiv: "encrypted sector|salt initial vector", the sector number is * encrypted with the bulk cipher using a salt as key. The salt * should be derived from the bulk cipher's key via hashing. @@ -180,6 +183,15 @@ static int crypt_iv_plain_gen(struct crypt_config *cc, u8 *iv, sector_t sector) return 0; } +static int crypt_iv_plain64_gen(struct crypt_config *cc, u8 *iv, + sector_t sector) +{ + memset(iv, 0, cc->iv_size); + *(u64 *)iv = cpu_to_le64(sector); + + return 0; +} + /* Initialise ESSIV - compute salt but no local memory allocations */ static int crypt_iv_essiv_init(struct crypt_config *cc) { @@ -342,6 +354,10 @@ static struct crypt_iv_operations crypt_iv_plain_ops = { .generator = crypt_iv_plain_gen }; +static struct crypt_iv_operations crypt_iv_plain64_ops = { + .generator = crypt_iv_plain64_gen +}; + static struct crypt_iv_operations crypt_iv_essiv_ops = { .ctr = crypt_iv_essiv_ctr, .dtr = crypt_iv_essiv_dtr, @@ -1063,6 +1079,8 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) cc->iv_gen_ops = NULL; else if (strcmp(ivmode, "plain") == 0) cc->iv_gen_ops = &crypt_iv_plain_ops; + else if (strcmp(ivmode, "plain64") == 0) + cc->iv_gen_ops = &crypt_iv_plain64_ops; else if (strcmp(ivmode, "essiv") == 0) cc->iv_gen_ops = &crypt_iv_essiv_ops; else if (strcmp(ivmode, "benbi") == 0) -- cgit v0.10.2 From 4d4471cb5c1ec426c0f24818b270dc7b3ad7e655 Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 10 Dec 2009 23:52:26 +0000 Subject: dm: swap target postsuspend call and setting suspended flag This patch moves DMF_SUSPENDED flag set before postsuspend. No one should care about the ordering, because the flag set and the postsuspend are protected by a single lock, md->suspend_lock, and all strict flag-checkers take the lock. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Cc: Mike Anderson Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 40e257f..f2b993c 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -2550,10 +2550,10 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) * requests are being added to md->deferred list. */ - dm_table_postsuspend_targets(map); - set_bit(DMF_SUSPENDED, &md->flags); + dm_table_postsuspend_targets(map); + out: dm_table_put(map); -- cgit v0.10.2 From 4f186f8bbfa92bf1a2b39f7a8674348bfdba9437 Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 10 Dec 2009 23:52:26 +0000 Subject: dm: rename dm_suspended to dm_suspended_md This patch renames dm_suspended() to dm_suspended_md() and keeps it internal to dm. No functional change. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Cc: Mike Anderson Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 63fd4de..1d66932 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -579,7 +579,7 @@ static int __dev_status(struct mapped_device *md, struct dm_ioctl *param) param->flags &= ~(DM_SUSPEND_FLAG | DM_READONLY_FLAG | DM_ACTIVE_PRESENT_FLAG); - if (dm_suspended(md)) + if (dm_suspended_md(md)) param->flags |= DM_SUSPEND_FLAG; param->dev = huge_encode_dev(disk_devt(disk)); @@ -839,7 +839,7 @@ static int do_suspend(struct dm_ioctl *param) if (param->flags & DM_NOFLUSH_FLAG) suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG; - if (!dm_suspended(md)) + if (!dm_suspended_md(md)) r = dm_suspend(md, suspend_flags); if (!r) @@ -881,7 +881,7 @@ static int do_resume(struct dm_ioctl *param) suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG; if (param->flags & DM_NOFLUSH_FLAG) suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG; - if (!dm_suspended(md)) + if (!dm_suspended_md(md)) dm_suspend(md, suspend_flags); old_map = dm_swap_table(md, new_map); @@ -897,7 +897,7 @@ static int do_resume(struct dm_ioctl *param) set_disk_ro(dm_disk(md), 1); } - if (dm_suspended(md)) + if (dm_suspended_md(md)) r = dm_resume(md); if (old_map) diff --git a/drivers/md/dm-sysfs.c b/drivers/md/dm-sysfs.c index b000de3..f53392d 100644 --- a/drivers/md/dm-sysfs.c +++ b/drivers/md/dm-sysfs.c @@ -59,7 +59,7 @@ static ssize_t dm_attr_uuid_show(struct mapped_device *md, char *buf) static ssize_t dm_attr_suspended_show(struct mapped_device *md, char *buf) { - sprintf(buf, "%d\n", dm_suspended(md)); + sprintf(buf, "%d\n", dm_suspended_md(md)); return strlen(buf); } diff --git a/drivers/md/dm.c b/drivers/md/dm.c index f2b993c..e0702bf 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -415,7 +415,7 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode, tgt = dm_table_get_target(map, 0); - if (dm_suspended(md)) { + if (dm_suspended_md(md)) { r = -EAGAIN; goto out; } @@ -2182,7 +2182,7 @@ void dm_put(struct mapped_device *md) MINOR(disk_devt(dm_disk(md)))); set_bit(DMF_FREEING, &md->flags); spin_unlock(&_minor_lock); - if (!dm_suspended(md)) { + if (!dm_suspended_md(md)) { dm_table_presuspend_targets(map); dm_table_postsuspend_targets(map); } @@ -2381,7 +2381,7 @@ struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table) mutex_lock(&md->suspend_lock); /* device must be suspended */ - if (!dm_suspended(md)) + if (!dm_suspended_md(md)) goto out; r = dm_calculate_queue_limits(table, &limits); @@ -2461,7 +2461,7 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) mutex_lock(&md->suspend_lock); - if (dm_suspended(md)) { + if (dm_suspended_md(md)) { r = -EINVAL; goto out_unlock; } @@ -2568,7 +2568,7 @@ int dm_resume(struct mapped_device *md) struct dm_table *map = NULL; mutex_lock(&md->suspend_lock); - if (!dm_suspended(md)) + if (!dm_suspended_md(md)) goto out; map = dm_get_live_table(md); @@ -2679,7 +2679,7 @@ struct mapped_device *dm_get_from_kobject(struct kobject *kobj) return md; } -int dm_suspended(struct mapped_device *md) +int dm_suspended_md(struct mapped_device *md) { return test_bit(DMF_SUSPENDED, &md->flags); } diff --git a/drivers/md/dm.h b/drivers/md/dm.h index 604a5f2..8dadaa5 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -94,6 +94,11 @@ int dm_split_args(int *argc, char ***argvp, char *input); int dm_deleting_md(struct mapped_device *md); /* + * Is this mapped_device suspended? + */ +int dm_suspended_md(struct mapped_device *md); + +/* * The device-mapper can be driven through one of two interfaces; * ioctl or filesystem, depending which patch you have applied. */ diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index b9c6c8c..fca0d31b 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -235,7 +235,6 @@ void dm_uevent_add(struct mapped_device *md, struct list_head *elist); const char *dm_device_name(struct mapped_device *md); int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid); struct gendisk *dm_disk(struct mapped_device *md); -int dm_suspended(struct mapped_device *md); int dm_noflush_suspending(struct dm_target *ti); union map_info *dm_get_mapinfo(struct bio *bio); union map_info *dm_get_rq_mapinfo(struct request *rq); -- cgit v0.10.2 From 64dbce580d5a7e89e8de20b91f80c7267cdad91d Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 10 Dec 2009 23:52:27 +0000 Subject: dm: export suspended state to targets This patch adds the exported dm_suspended() function so that targets can check whether or not they are suspended. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Cc: Mike Anderson Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm.c b/drivers/md/dm.c index e0702bf..3167480 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -2684,6 +2684,17 @@ int dm_suspended_md(struct mapped_device *md) return test_bit(DMF_SUSPENDED, &md->flags); } +int dm_suspended(struct dm_target *ti) +{ + struct mapped_device *md = dm_table_get_md(ti->table); + int r = dm_suspended_md(md); + + dm_put(md); + + return r; +} +EXPORT_SYMBOL_GPL(dm_suspended); + int dm_noflush_suspending(struct dm_target *ti) { struct mapped_device *md = dm_table_get_md(ti->table); diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index fca0d31b..d4c9c0b 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -235,6 +235,7 @@ void dm_uevent_add(struct mapped_device *md, struct list_head *elist); const char *dm_device_name(struct mapped_device *md); int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid); struct gendisk *dm_disk(struct mapped_device *md); +int dm_suspended(struct dm_target *ti); int dm_noflush_suspending(struct dm_target *ti); union map_info *dm_get_mapinfo(struct bio *bio); union map_info *dm_get_rq_mapinfo(struct request *rq); -- cgit v0.10.2 From c2f3d24b783fda20618b73d65678eb5dfae31a5d Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 10 Dec 2009 23:52:27 +0000 Subject: dm mpath: reject messages when device is suspended This patch rejects messages that can generate I/O while the device itself is suspended. Signed-off-by: Kiyoshi Ueda Cc: Mike Anderson Signed-off-by: Jun'ichi Nomura Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 45d9bf1..e81345a 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -1433,6 +1433,11 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) goto out; } + if (dm_suspended(ti)) { + r = -EBUSY; + goto out; + } + if (argc == 1) { if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) { r = queue_if_no_path(m, 1, 0); -- cgit v0.10.2 From 9eaae8ffbc340fc034fed1e5d0dc9ca0e943f817 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:28 +0000 Subject: dm snapshot: make bio optional in __origin_write To support the merging of snapshots back into their origin we need to trigger exceptions in other snapshots not being merged without any incoming bio on the origin device. The bio parameter to __origin_write() becomes optional and the sector needs supplying separately. Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index b5b9118..5e553c5 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -1467,7 +1467,19 @@ static int snapshot_iterate_devices(struct dm_target *ti, /*----------------------------------------------------------------- * Origin methods *---------------------------------------------------------------*/ -static int __origin_write(struct list_head *snapshots, struct bio *bio) + +/* + * If no exceptions need creating, DM_MAPIO_REMAPPED is returned and any + * supplied bio was ignored. The caller may submit it immediately. + * (No remapping actually occurs as the origin is always a direct linear + * map.) + * + * If further exceptions are required, DM_MAPIO_SUBMITTED is returned + * and any supplied bio is added to a list to be submitted once all + * the necessary exceptions exist. + */ +static int __origin_write(struct list_head *snapshots, sector_t sector, + struct bio *bio) { int r = DM_MAPIO_REMAPPED, first = 0; struct dm_snapshot *snap; @@ -1486,14 +1498,14 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) goto next_snapshot; /* Nothing to do if writing beyond end of snapshot */ - if (bio->bi_sector >= dm_table_get_size(snap->ti->table)) + if (sector >= dm_table_get_size(snap->ti->table)) goto next_snapshot; /* * Remember, different snapshots can have * different chunk sizes. */ - chunk = sector_to_chunk(snap->store, bio->bi_sector); + chunk = sector_to_chunk(snap->store, sector); /* * Check exception table to see if block @@ -1543,7 +1555,8 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) first = 1; } - bio_list_add(&primary_pe->origin_bios, bio); + if (bio) + bio_list_add(&primary_pe->origin_bios, bio); r = DM_MAPIO_SUBMITTED; } @@ -1599,7 +1612,7 @@ static int do_origin(struct dm_dev *origin, struct bio *bio) down_read(&_origins_lock); o = __lookup_origin(origin->bdev); if (o) - r = __origin_write(&o->snapshots, bio); + r = __origin_write(&o->snapshots, bio->bi_sector, bio); up_read(&_origins_lock); return r; -- cgit v0.10.2 From 615d1eb9cad9b34ed17c18c604254e8db533ac6f Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 10 Dec 2009 23:52:29 +0000 Subject: dm snapshot: create function for chunk_is_tracked wait Move the __chunk_is_tracked() loop into a separate function as we will also need to call it from the write path in the rare case of conflicting writes to the same chunk. Originally introduced in commit a8d41b59f3f5a7ac19452ef442a7fc1b5fa17366 ("dm snapshot: fix race during exception creation"). Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 5e553c5..288994e 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -234,6 +234,16 @@ static int __chunk_is_tracked(struct dm_snapshot *s, chunk_t chunk) } /* + * This conflicting I/O is extremely improbable in the caller, + * so msleep(1) is sufficient and there is no need for a wait queue. + */ +static void __check_for_conflicting_io(struct dm_snapshot *s, chunk_t chunk) +{ + while (__chunk_is_tracked(s, chunk)) + msleep(1); +} + +/* * One of these per registered origin, held in the snapshot_origins hash */ struct origin { @@ -1102,12 +1112,8 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) goto out; } - /* - * Check for conflicting reads. This is extremely improbable, - * so msleep(1) is sufficient and there is no need for a wait queue. - */ - while (__chunk_is_tracked(s, pe->e.old_chunk)) - msleep(1); + /* Check for conflicting reads */ + __check_for_conflicting_io(s, pe->e.old_chunk); /* * Add a proper exception, and remove the -- cgit v0.10.2 From 4454a6216f75a9ef8c4bd0a65e34b101f725ef1e Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:29 +0000 Subject: dm exception store: add merge specific methods Add functions that decide how many consecutive chunks of snapshot to merge back into the origin next and to update the metadata afterwards. prepare_merge provides a pointer to the most recent still-to-be-merged chunk and returns how many previous ones are consecutive and can be processed together. commit_merge removes the nr_merged most-recent chunks permanently from the exception store. The number must not exceed that returned by prepare_merge. Introduce NUM_SNAPSHOT_HDR_CHUNKS to show where the snapshot header chunk is accounted for. Signed-off-by: Mikulas Patocka Reviewed-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h index bb88746..c53e089 100644 --- a/drivers/md/dm-exception-store.h +++ b/drivers/md/dm-exception-store.h @@ -75,6 +75,23 @@ struct dm_exception_store_type { void *callback_context); /* + * Returns 0 if the exception store is empty. + * + * If there are exceptions still to be merged, sets + * *last_old_chunk and *last_new_chunk to the most recent + * still-to-be-merged chunk and returns the number of + * consecutive previous ones. + */ + int (*prepare_merge) (struct dm_exception_store *store, + chunk_t *last_old_chunk, chunk_t *last_new_chunk); + + /* + * Clear the last n exceptions. + * nr_merged must be <= the value returned by prepare_merge. + */ + int (*commit_merge) (struct dm_exception_store *store, int nr_merged); + + /* * The snapshot is invalid, note this in the metadata. */ void (*drop_snapshot) (struct dm_exception_store *store); diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 157999e..7d08879 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c @@ -55,6 +55,8 @@ */ #define SNAPSHOT_DISK_VERSION 1 +#define NUM_SNAPSHOT_HDR_CHUNKS 1 + struct disk_header { uint32_t magic; @@ -120,7 +122,22 @@ struct pstore { /* * The next free chunk for an exception. + * + * When creating exceptions, all the chunks here and above are + * free. It holds the next chunk to be allocated. On rare + * occasions (e.g. after a system crash) holes can be left in + * the exception store because chunks can be committed out of + * order. + * + * When merging exceptions, it does not necessarily mean all the + * chunks here and above are free. It holds the value it would + * have held if all chunks had been committed in order of + * allocation. Consequently the value may occasionally be + * slightly too low, but since it's only used for 'status' and + * it can never reach its minimum value too early this doesn't + * matter. */ + chunk_t next_free; /* @@ -409,6 +426,15 @@ static void write_exception(struct pstore *ps, e->new_chunk = cpu_to_le64(de->new_chunk); } +static void clear_exception(struct pstore *ps, uint32_t index) +{ + struct disk_exception *e = get_exception(ps, index); + + /* clear it */ + e->old_chunk = 0; + e->new_chunk = 0; +} + /* * Registers the exceptions that are present in the current area. * 'full' is filled in to indicate if the area has been @@ -505,7 +531,8 @@ static void persistent_usage(struct dm_exception_store *store, * Then there are (ps->current_area + 1) metadata chunks, each one * separated from the next by ps->exceptions_per_area data chunks. */ - *metadata_sectors = (ps->current_area + 2) * store->chunk_size; + *metadata_sectors = (ps->current_area + 1 + NUM_SNAPSHOT_HDR_CHUNKS) * + store->chunk_size; } static void persistent_dtr(struct dm_exception_store *store) @@ -680,6 +707,85 @@ static void persistent_commit_exception(struct dm_exception_store *store, ps->callback_count = 0; } +static int persistent_prepare_merge(struct dm_exception_store *store, + chunk_t *last_old_chunk, + chunk_t *last_new_chunk) +{ + struct pstore *ps = get_info(store); + struct disk_exception de; + int nr_consecutive; + int r; + + /* + * When current area is empty, move back to preceding area. + */ + if (!ps->current_committed) { + /* + * Have we finished? + */ + if (!ps->current_area) + return 0; + + ps->current_area--; + r = area_io(ps, READ); + if (r < 0) + return r; + ps->current_committed = ps->exceptions_per_area; + } + + read_exception(ps, ps->current_committed - 1, &de); + *last_old_chunk = de.old_chunk; + *last_new_chunk = de.new_chunk; + + /* + * Find number of consecutive chunks within the current area, + * working backwards. + */ + for (nr_consecutive = 1; nr_consecutive < ps->current_committed; + nr_consecutive++) { + read_exception(ps, ps->current_committed - 1 - nr_consecutive, + &de); + if (de.old_chunk != *last_old_chunk - nr_consecutive || + de.new_chunk != *last_new_chunk - nr_consecutive) + break; + } + + return nr_consecutive; +} + +static int persistent_commit_merge(struct dm_exception_store *store, + int nr_merged) +{ + int r, i; + struct pstore *ps = get_info(store); + + BUG_ON(nr_merged > ps->current_committed); + + for (i = 0; i < nr_merged; i++) + clear_exception(ps, ps->current_committed - 1 - i); + + r = area_io(ps, WRITE); + if (r < 0) + return r; + + ps->current_committed -= nr_merged; + + /* + * At this stage, only persistent_usage() uses ps->next_free, so + * we make no attempt to keep ps->next_free strictly accurate + * as exceptions may have been committed out-of-order originally. + * Once a snapshot has become merging, we set it to the value it + * would have held had all the exceptions been committed in order. + * + * ps->current_area does not get reduced by prepare_merge() until + * after commit_merge() has removed the nr_merged previous exceptions. + */ + ps->next_free = (area_location(ps, ps->current_area) - 1) + + (ps->current_committed + 1) + NUM_SNAPSHOT_HDR_CHUNKS; + + return 0; +} + static void persistent_drop_snapshot(struct dm_exception_store *store) { struct pstore *ps = get_info(store); @@ -705,7 +811,7 @@ static int persistent_ctr(struct dm_exception_store *store, ps->area = NULL; ps->zero_area = NULL; ps->header_area = NULL; - ps->next_free = 2; /* skipping the header and first area */ + ps->next_free = NUM_SNAPSHOT_HDR_CHUNKS + 1; /* header and 1st area */ ps->current_committed = 0; ps->callback_count = 0; @@ -748,6 +854,8 @@ static struct dm_exception_store_type _persistent_type = { .read_metadata = persistent_read_metadata, .prepare_exception = persistent_prepare_exception, .commit_exception = persistent_commit_exception, + .prepare_merge = persistent_prepare_merge, + .commit_merge = persistent_commit_merge, .drop_snapshot = persistent_drop_snapshot, .usage = persistent_usage, .status = persistent_status, @@ -761,6 +869,8 @@ static struct dm_exception_store_type _persistent_compat_type = { .read_metadata = persistent_read_metadata, .prepare_exception = persistent_prepare_exception, .commit_exception = persistent_commit_exception, + .prepare_merge = persistent_prepare_merge, + .commit_merge = persistent_commit_merge, .drop_snapshot = persistent_drop_snapshot, .usage = persistent_usage, .status = persistent_status, -- cgit v0.10.2 From d698aa4500aa3ca9559142060caf0f79da998744 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:30 +0000 Subject: dm snapshot: add merge target The snapshot-merge target allows a snapshot to be merged back into the snapshot's origin device. One anticipated use of snapshot merging is the rollback of filesystems to back out problematic system upgrades. This patch adds snapshot-merge target management to both dm_snapshot_init() and dm_snapshot_exit(). As an initial place-holder, snapshot-merge is identical to the snapshot target. Documentation is provided. Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/Documentation/device-mapper/snapshot.txt b/Documentation/device-mapper/snapshot.txt index a5009c8..e3a77b2 100644 --- a/Documentation/device-mapper/snapshot.txt +++ b/Documentation/device-mapper/snapshot.txt @@ -8,13 +8,19 @@ the block device which are also writable without interfering with the original content; *) To create device "forks", i.e. multiple different versions of the same data stream. +*) To merge a snapshot of a block device back into the snapshot's origin +device. +In the first two cases, dm copies only the chunks of data that get +changed and uses a separate copy-on-write (COW) block device for +storage. -In both cases, dm copies only the chunks of data that get changed and -uses a separate copy-on-write (COW) block device for storage. +For snapshot merge the contents of the COW storage are merged back into +the origin device. -There are two dm targets available: snapshot and snapshot-origin. +There are three dm targets available: +snapshot, snapshot-origin, and snapshot-merge. *) snapshot-origin @@ -40,8 +46,25 @@ The difference is that for transient snapshots less metadata must be saved on disk - they can be kept in memory by the kernel. -How this is used by LVM2 -======================== +* snapshot-merge + +takes the same table arguments as the snapshot target except it only +works with persistent snapshots. This target assumes the role of the +"snapshot-origin" target and must not be loaded if the "snapshot-origin" +is still present for . + +Creates a merging snapshot that takes control of the changed chunks +stored in the of an existing snapshot, through a handover +procedure, and merges these chunks back into the . Once merging +has started (in the background) the may be opened and the merge +will continue while I/O is flowing to it. Changes to the are +deferred until the merging snapshot's corresponding chunk(s) have been +merged. Once merging has started the snapshot device, associated with +the "snapshot" target, will return -EIO when accessed. + + +How snapshot is used by LVM2 +============================ When you create the first LVM2 snapshot of a volume, four dm devices are used: 1) a device containing the original mapping table of the source volume; @@ -72,3 +95,30 @@ brw------- 1 root root 254, 12 29 ago 18:15 /dev/mapper/volumeGroup-snap-cow brw------- 1 root root 254, 13 29 ago 18:15 /dev/mapper/volumeGroup-snap brw------- 1 root root 254, 10 29 ago 18:14 /dev/mapper/volumeGroup-base + +How snapshot-merge is used by LVM2 +================================== +A merging snapshot assumes the role of the "snapshot-origin" while +merging. As such the "snapshot-origin" is replaced with +"snapshot-merge". The "-real" device is not changed and the "-cow" +device is renamed to -cow to aid LVM2's cleanup of the +merging snapshot after it completes. The "snapshot" that hands over its +COW device to the "snapshot-merge" is deactivated (unless using lvchange +--refresh); but if it is left active it will simply return I/O errors. + +A snapshot will merge into its origin with the following command: + +lvconvert --merge volumeGroup/snap + +we'll now have this situation: + +# dmsetup table|grep volumeGroup + +volumeGroup-base-real: 0 2097152 linear 8:19 384 +volumeGroup-base-cow: 0 204800 linear 8:19 2097536 +volumeGroup-base: 0 2097152 snapshot-merge 254:11 254:12 P 16 + +# ls -lL /dev/mapper/volumeGroup-* +brw------- 1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real +brw------- 1 root root 254, 12 29 ago 18:16 /dev/mapper/volumeGroup-base-cow +brw------- 1 root root 254, 10 29 ago 18:16 /dev/mapper/volumeGroup-base diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 288994e..446827f 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -25,6 +25,11 @@ #define DM_MSG_PREFIX "snapshots" +static const char dm_snapshot_merge_target_name[] = "snapshot-merge"; + +#define dm_target_is_snapshot_merge(ti) \ + ((ti)->type->name == dm_snapshot_merge_target_name) + /* * The percentage increment we will wake up users at */ @@ -1743,6 +1748,21 @@ static struct target_type snapshot_target = { .iterate_devices = snapshot_iterate_devices, }; +static struct target_type merge_target = { + .name = dm_snapshot_merge_target_name, + .version = {1, 0, 0}, + .module = THIS_MODULE, + .ctr = snapshot_ctr, + .dtr = snapshot_dtr, + .map = snapshot_map, + .end_io = snapshot_end_io, + .postsuspend = snapshot_postsuspend, + .preresume = snapshot_preresume, + .resume = snapshot_resume, + .status = snapshot_status, + .iterate_devices = snapshot_iterate_devices, +}; + static int __init dm_snapshot_init(void) { int r; @@ -1754,7 +1774,7 @@ static int __init dm_snapshot_init(void) } r = dm_register_target(&snapshot_target); - if (r) { + if (r < 0) { DMERR("snapshot target register failed %d", r); goto bad_register_snapshot_target; } @@ -1762,34 +1782,40 @@ static int __init dm_snapshot_init(void) r = dm_register_target(&origin_target); if (r < 0) { DMERR("Origin target register failed %d", r); - goto bad1; + goto bad_register_origin_target; + } + + r = dm_register_target(&merge_target); + if (r < 0) { + DMERR("Merge target register failed %d", r); + goto bad_register_merge_target; } r = init_origin_hash(); if (r) { DMERR("init_origin_hash failed."); - goto bad2; + goto bad_origin_hash; } exception_cache = KMEM_CACHE(dm_exception, 0); if (!exception_cache) { DMERR("Couldn't create exception cache."); r = -ENOMEM; - goto bad3; + goto bad_exception_cache; } pending_cache = KMEM_CACHE(dm_snap_pending_exception, 0); if (!pending_cache) { DMERR("Couldn't create pending cache."); r = -ENOMEM; - goto bad4; + goto bad_pending_cache; } tracked_chunk_cache = KMEM_CACHE(dm_snap_tracked_chunk, 0); if (!tracked_chunk_cache) { DMERR("Couldn't create cache to track chunks in use."); r = -ENOMEM; - goto bad5; + goto bad_tracked_chunk_cache; } ksnapd = create_singlethread_workqueue("ksnapd"); @@ -1803,19 +1829,21 @@ static int __init dm_snapshot_init(void) bad_pending_pool: kmem_cache_destroy(tracked_chunk_cache); -bad5: +bad_tracked_chunk_cache: kmem_cache_destroy(pending_cache); -bad4: +bad_pending_cache: kmem_cache_destroy(exception_cache); -bad3: +bad_exception_cache: exit_origin_hash(); -bad2: +bad_origin_hash: + dm_unregister_target(&merge_target); +bad_register_merge_target: dm_unregister_target(&origin_target); -bad1: +bad_register_origin_target: dm_unregister_target(&snapshot_target); - bad_register_snapshot_target: dm_exception_store_exit(); + return r; } @@ -1825,6 +1853,7 @@ static void __exit dm_snapshot_exit(void) dm_unregister_target(&snapshot_target); dm_unregister_target(&origin_target); + dm_unregister_target(&merge_target); exit_origin_hash(); kmem_cache_destroy(pending_cache); -- cgit v0.10.2 From 515ad66cc4c82f210d726340349c8f7c1ec6b125 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:30 +0000 Subject: dm snapshot: rework writing to origin To track the completion of exceptions relating to the same location on the device, the current code selects one exception as primary_pe, links the other exceptions to it and uses reference counting to wait until all the reallocations are complete. It is considered too complicated to extend this code to handle the new snapshot-merge target, where sets of non-overlapping chunks would also need to become linked. Instead, a simpler (but less efficient) approach is taken. Bios are linked to one exception. When it completes, bios are simply retried, and if other related exceptions are still outstanding, they'll get queued again to wait for another one. Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 446827f..c01e0da 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -142,28 +142,6 @@ struct dm_snap_pending_exception { struct bio_list origin_bios; struct bio_list snapshot_bios; - /* - * Short-term queue of pending exceptions prior to submission. - */ - struct list_head list; - - /* - * The primary pending_exception is the one that holds - * the ref_count and the list of origin_bios for a - * group of pending_exceptions. It is always last to get freed. - * These fields get set up when writing to the origin. - */ - struct dm_snap_pending_exception *primary_pe; - - /* - * Number of pending_exceptions processing this chunk. - * When this drops to zero we must complete the origin bios. - * If incrementing or decrementing this, hold pe->snap->lock for - * the sibling concerned and not pe->primary_pe->snap->lock unless - * they are the same. - */ - atomic_t ref_count; - /* Pointer back to snapshot context */ struct dm_snapshot *snap; @@ -1019,6 +997,26 @@ static void flush_queued_bios(struct work_struct *work) flush_bios(queued_bios); } +static int do_origin(struct dm_dev *origin, struct bio *bio); + +/* + * Flush a list of buffers. + */ +static void retry_origin_bios(struct dm_snapshot *s, struct bio *bio) +{ + struct bio *n; + int r; + + while (bio) { + n = bio->bi_next; + bio->bi_next = NULL; + r = do_origin(s->origin, bio); + if (r == DM_MAPIO_REMAPPED) + generic_make_request(bio); + bio = n; + } +} + /* * Error a list of buffers. */ @@ -1052,39 +1050,6 @@ static void __invalidate_snapshot(struct dm_snapshot *s, int err) dm_table_event(s->ti->table); } -static void get_pending_exception(struct dm_snap_pending_exception *pe) -{ - atomic_inc(&pe->ref_count); -} - -static struct bio *put_pending_exception(struct dm_snap_pending_exception *pe) -{ - struct dm_snap_pending_exception *primary_pe; - struct bio *origin_bios = NULL; - - primary_pe = pe->primary_pe; - - /* - * If this pe is involved in a write to the origin and - * it is the last sibling to complete then release - * the bios for the original write to the origin. - */ - if (primary_pe && - atomic_dec_and_test(&primary_pe->ref_count)) { - origin_bios = bio_list_get(&primary_pe->origin_bios); - free_pending_exception(primary_pe); - } - - /* - * Free the pe if it's not linked to an origin write or if - * it's not itself a primary pe. - */ - if (!primary_pe || primary_pe != pe) - free_pending_exception(pe); - - return origin_bios; -} - static void pending_complete(struct dm_snap_pending_exception *pe, int success) { struct dm_exception *e; @@ -1129,7 +1094,8 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) out: dm_remove_exception(&pe->e); snapshot_bios = bio_list_get(&pe->snapshot_bios); - origin_bios = put_pending_exception(pe); + origin_bios = bio_list_get(&pe->origin_bios); + free_pending_exception(pe); up_write(&s->lock); @@ -1139,7 +1105,7 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) else flush_bios(snapshot_bios); - flush_bios(origin_bios); + retry_origin_bios(s, origin_bios); } static void commit_callback(void *context, int success) @@ -1226,8 +1192,6 @@ __find_pending_exception(struct dm_snapshot *s, pe->e.old_chunk = chunk; bio_list_init(&pe->origin_bios); bio_list_init(&pe->snapshot_bios); - pe->primary_pe = NULL; - atomic_set(&pe->ref_count, 0); pe->started = 0; if (s->store->type->prepare_exception(s->store, &pe->e)) { @@ -1235,7 +1199,6 @@ __find_pending_exception(struct dm_snapshot *s, return NULL; } - get_pending_exception(pe); dm_insert_exception(&s->pending, &pe->e); return pe; @@ -1492,16 +1455,16 @@ static int snapshot_iterate_devices(struct dm_target *ti, static int __origin_write(struct list_head *snapshots, sector_t sector, struct bio *bio) { - int r = DM_MAPIO_REMAPPED, first = 0; + int r = DM_MAPIO_REMAPPED; struct dm_snapshot *snap; struct dm_exception *e; - struct dm_snap_pending_exception *pe, *next_pe, *primary_pe = NULL; + struct dm_snap_pending_exception *pe; + struct dm_snap_pending_exception *pe_to_start_now = NULL; + struct dm_snap_pending_exception *pe_to_start_last = NULL; chunk_t chunk; - LIST_HEAD(pe_queue); /* Do all the snapshots on this origin */ list_for_each_entry (snap, snapshots, list) { - down_write(&snap->lock); /* Only deal with valid and active snapshots */ @@ -1522,9 +1485,6 @@ static int __origin_write(struct list_head *snapshots, sector_t sector, * Check exception table to see if block * is already remapped in this snapshot * and trigger an exception if not. - * - * ref_count is initialised to 1 so pending_complete() - * won't destroy the primary_pe while we're inside this loop. */ e = dm_lookup_exception(&snap->complete, chunk); if (e) @@ -1554,60 +1514,43 @@ static int __origin_write(struct list_head *snapshots, sector_t sector, } } - if (!primary_pe) { - /* - * Either every pe here has same - * primary_pe or none has one yet. - */ - if (pe->primary_pe) - primary_pe = pe->primary_pe; - else { - primary_pe = pe; - first = 1; - } - - if (bio) - bio_list_add(&primary_pe->origin_bios, bio); + r = DM_MAPIO_SUBMITTED; - r = DM_MAPIO_SUBMITTED; - } + /* + * If an origin bio was supplied, queue it to wait for the + * completion of this exception, and start this one last, + * at the end of the function. + */ + if (bio) { + bio_list_add(&pe->origin_bios, bio); + bio = NULL; - if (!pe->primary_pe) { - pe->primary_pe = primary_pe; - get_pending_exception(primary_pe); + if (!pe->started) { + pe->started = 1; + pe_to_start_last = pe; + } } if (!pe->started) { pe->started = 1; - list_add_tail(&pe->list, &pe_queue); + pe_to_start_now = pe; } next_snapshot: up_write(&snap->lock); - } - if (!primary_pe) - return r; - - /* - * If this is the first time we're processing this chunk and - * ref_count is now 1 it means all the pending exceptions - * got completed while we were in the loop above, so it falls to - * us here to remove the primary_pe and submit any origin_bios. - */ - - if (first && atomic_dec_and_test(&primary_pe->ref_count)) { - flush_bios(bio_list_get(&primary_pe->origin_bios)); - free_pending_exception(primary_pe); - /* If we got here, pe_queue is necessarily empty. */ - return r; + if (pe_to_start_now) { + start_copy(pe_to_start_now); + pe_to_start_now = NULL; + } } /* - * Now that we have a complete pe list we can start the copying. + * Submit the exception against which the bio is queued last, + * to give the other exceptions a head start. */ - list_for_each_entry_safe(pe, next_pe, &pe_queue, list) - start_copy(pe); + if (pe_to_start_last) + start_copy(pe_to_start_last); return r; } -- cgit v0.10.2 From 3452c2a1eb5b93c1b9fb0d22bd5b07c0cee4dc29 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:31 +0000 Subject: dm snapshot: avoid allocating exceptions in merge The snapshot-merge target should not allocate new exceptions because the intent is to merge all of its exceptions as quickly and safely as possible. This patch introduces the snapshot-merge mapping function and updates __origin_write() so that it doesn't allocate exceptions on any snapshots that are being merged. If a write request to a merging snapshot device is to be dispatched directly to the origin (because the chunk is not remapped or was already merged), snapshot_merge_map() must make exceptions in other snapshots so calls do_origin(). Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index c01e0da..59d9ef6 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -1308,6 +1308,54 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, return r; } +/* + * A snapshot-merge target behaves like a combination of a snapshot + * target and a snapshot-origin target. It only generates new + * exceptions in other snapshots and not in the one that is being + * merged. + * + * For each chunk, if there is an existing exception, it is used to + * redirect I/O to the cow device. Otherwise I/O is sent to the origin, + * which in turn might generate exceptions in other snapshots. + */ +static int snapshot_merge_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) +{ + struct dm_exception *e; + struct dm_snapshot *s = ti->private; + int r = DM_MAPIO_REMAPPED; + chunk_t chunk; + + chunk = sector_to_chunk(s->store, bio->bi_sector); + + down_read(&s->lock); + + /* Full snapshots are not usable */ + if (!s->valid) { + r = -EIO; + goto out_unlock; + } + + /* If the block is already remapped - use that */ + e = dm_lookup_exception(&s->complete, chunk); + if (e) { + remap_exception(s, e, bio, chunk); + goto out_unlock; + } + + bio->bi_bdev = s->origin->bdev; + + if (bio_rw(bio) == WRITE) { + up_read(&s->lock); + return do_origin(s->origin, bio); + } + +out_unlock: + up_read(&s->lock); + + return r; +} + static int snapshot_end_io(struct dm_target *ti, struct bio *bio, int error, union map_info *map_context) { @@ -1465,6 +1513,13 @@ static int __origin_write(struct list_head *snapshots, sector_t sector, /* Do all the snapshots on this origin */ list_for_each_entry (snap, snapshots, list) { + /* + * Don't make new exceptions in a merging snapshot + * because it has effectively been deleted + */ + if (dm_target_is_snapshot_merge(snap->ti)) + continue; + down_write(&snap->lock); /* Only deal with valid and active snapshots */ @@ -1697,7 +1752,7 @@ static struct target_type merge_target = { .module = THIS_MODULE, .ctr = snapshot_ctr, .dtr = snapshot_dtr, - .map = snapshot_map, + .map = snapshot_merge_map, .end_io = snapshot_end_io, .postsuspend = snapshot_postsuspend, .preresume = snapshot_preresume, -- cgit v0.10.2 From 10b8106a70433e14153469ebbdd189776500e238 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 10 Dec 2009 23:52:31 +0000 Subject: dm snapshot: support barriers in snapshot merge target Sets num_flush_requests=2 to support flushing both the origin and cow devices used by the snapshot-merge target. Also, snapshot_ctr() now gets the origin device using FMODE_WRITE if the target is snapshot-merge (which writes to the origin device). Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 59d9ef6..23e3396 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -709,7 +709,8 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) int i; int r = -EINVAL; char *origin_path, *cow_path; - unsigned args_used; + unsigned args_used, num_flush_requests = 1; + fmode_t origin_mode = FMODE_READ; if (argc != 4) { ti->error = "requires exactly 4 arguments"; @@ -717,6 +718,11 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad; } + if (dm_target_is_snapshot_merge(ti)) { + num_flush_requests = 2; + origin_mode = FMODE_WRITE; + } + origin_path = argv[0]; argv++; argc--; @@ -750,7 +756,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) argv += args_used; argc -= args_used; - r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin); + r = dm_get_device(ti, origin_path, 0, ti->len, origin_mode, &s->origin); if (r) { ti->error = "Cannot get origin device"; goto bad_origin; @@ -801,7 +807,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) INIT_WORK(&s->queued_bios_work, flush_queued_bios); ti->private = s; - ti->num_flush_requests = 1; + ti->num_flush_requests = num_flush_requests; /* Add snapshot to the list of snapshots for this origin */ /* Exceptions aren't triggered till snapshot_resume() is called */ @@ -1326,6 +1332,15 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio, int r = DM_MAPIO_REMAPPED; chunk_t chunk; + if (unlikely(bio_empty_barrier(bio))) { + if (!map_context->flush_request) + bio->bi_bdev = s->origin->bdev; + else + bio->bi_bdev = s->cow->bdev; + map_context->ptr = NULL; + return DM_MAPIO_REMAPPED; + } + chunk = sector_to_chunk(s->store, bio->bi_sector); down_read(&s->lock); -- cgit v0.10.2 From 9d3b15c4c776b041f9ee81810cbd375275411829 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:32 +0000 Subject: dm snapshot: permit only one merge at once Merging more than one snapshot is not supported, so prevent this happening. Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 23e3396..7ddee7c 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -300,8 +300,10 @@ static void __insert_origin(struct origin *o) * Returns number of snapshots registered using the supplied cow device, plus: * snap_src - a snapshot suitable for use as a source of exception handover * snap_dest - a snapshot capable of receiving exception handover. + * snap_merge - an existing snapshot-merge target linked to the same origin. + * There can be at most one snapshot-merge target. The parameter is optional. * - * Possible return values and states: + * Possible return values and states of snap_src and snap_dest. * 0: NULL, NULL - first new snapshot * 1: snap_src, NULL - normal snapshot * 2: snap_src, snap_dest - waiting for handover @@ -310,7 +312,8 @@ static void __insert_origin(struct origin *o) */ static int __find_snapshots_sharing_cow(struct dm_snapshot *snap, struct dm_snapshot **snap_src, - struct dm_snapshot **snap_dest) + struct dm_snapshot **snap_dest, + struct dm_snapshot **snap_merge) { struct dm_snapshot *s; struct origin *o; @@ -322,6 +325,8 @@ static int __find_snapshots_sharing_cow(struct dm_snapshot *snap, goto out; list_for_each_entry(s, &o->snapshots, list) { + if (dm_target_is_snapshot_merge(s->ti) && snap_merge) + *snap_merge = s; if (!bdev_equal(s->cow->bdev, snap->cow->bdev)) continue; @@ -349,9 +354,11 @@ out: static int __validate_exception_handover(struct dm_snapshot *snap) { struct dm_snapshot *snap_src = NULL, *snap_dest = NULL; + struct dm_snapshot *snap_merge = NULL; /* Does snapshot need exceptions handed over to it? */ - if ((__find_snapshots_sharing_cow(snap, &snap_src, &snap_dest) == 2) || + if ((__find_snapshots_sharing_cow(snap, &snap_src, &snap_dest, + &snap_merge) == 2) || snap_dest) { snap->ti->error = "Snapshot cow pairing for exception " "table handover failed"; @@ -365,6 +372,20 @@ static int __validate_exception_handover(struct dm_snapshot *snap) if (!snap_src) return 0; + /* + * Non-snapshot-merge handover? + */ + if (!dm_target_is_snapshot_merge(snap->ti)) + return 1; + + /* + * Do not allow more than one merging snapshot. + */ + if (snap_merge) { + snap->ti->error = "A snapshot is already merging."; + return -EINVAL; + } + return 1; } @@ -933,7 +954,7 @@ static void snapshot_dtr(struct dm_target *ti) down_read(&_origins_lock); /* Check whether exception handover must be cancelled */ - (void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest); + (void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL); if (snap_src && snap_dest && (s == snap_src)) { down_write(&snap_dest->lock); snap_dest->valid = 0; @@ -1399,7 +1420,7 @@ static int snapshot_preresume(struct dm_target *ti) struct dm_snapshot *snap_src = NULL, *snap_dest = NULL; down_read(&_origins_lock); - (void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest); + (void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL); if (snap_src && snap_dest) { down_read(&snap_src->lock); if (s == snap_src) { @@ -1424,7 +1445,7 @@ static void snapshot_resume(struct dm_target *ti) struct dm_snapshot *snap_src = NULL, *snap_dest = NULL; down_read(&_origins_lock); - (void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest); + (void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL); if (snap_src && snap_dest) { down_write(&snap_src->lock); down_write_nested(&snap_dest->lock, SINGLE_DEPTH_NESTING); -- cgit v0.10.2 From 1e03f97e4301f75a2f3b649787f7876516764929 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:32 +0000 Subject: dm snapshot: add merging Merging is started when origin is resumed and it is stopped when origin is suspended or when the merging snapshot is destroyed or errors are detected. Merging is not yet interlocked with writes: this will be handled in subsequent patches. The code relies on callbacks from a private kcopyd thread. Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h index c53e089..e8dfa06 100644 --- a/drivers/md/dm-exception-store.h +++ b/drivers/md/dm-exception-store.h @@ -154,6 +154,13 @@ static inline void dm_consecutive_chunk_count_inc(struct dm_exception *e) BUG_ON(!dm_consecutive_chunk_count(e)); } +static inline void dm_consecutive_chunk_count_dec(struct dm_exception *e) +{ + BUG_ON(!dm_consecutive_chunk_count(e)); + + e->new_chunk -= (1ULL << DM_CHUNK_NUMBER_BITS); +} + # else # define DM_CHUNK_CONSECUTIVE_BITS 0 @@ -171,6 +178,10 @@ static inline void dm_consecutive_chunk_count_inc(struct dm_exception *e) { } +static inline void dm_consecutive_chunk_count_dec(struct dm_exception *e) +{ +} + # endif /* diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 7ddee7c..dc2412e 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -106,8 +106,20 @@ struct dm_snapshot { mempool_t *tracked_chunk_pool; spinlock_t tracked_chunk_lock; struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE]; + + /* Wait for events based on state_bits */ + unsigned long state_bits; }; +/* + * state_bits: + * RUNNING_MERGE - Merge operation is in progress. + * SHUTDOWN_MERGE - Set to signal that merge needs to be stopped; + * cleared afterwards. + */ +#define RUNNING_MERGE 0 +#define SHUTDOWN_MERGE 1 + struct dm_dev *dm_snap_cow(struct dm_snapshot *s) { return s->cow; @@ -386,6 +398,13 @@ static int __validate_exception_handover(struct dm_snapshot *snap) return -EINVAL; } + if (!snap_src->store->type->prepare_merge || + !snap_src->store->type->commit_merge) { + snap->ti->error = "Snapshot exception store does not " + "support snapshot-merge."; + return -EINVAL; + } + return 1; } @@ -721,6 +740,178 @@ static int init_hash_tables(struct dm_snapshot *s) return 0; } +static void merge_shutdown(struct dm_snapshot *s) +{ + clear_bit_unlock(RUNNING_MERGE, &s->state_bits); + smp_mb__after_clear_bit(); + wake_up_bit(&s->state_bits, RUNNING_MERGE); +} + +/* + * Remove one chunk from the index of completed exceptions. + */ +static int __remove_single_exception_chunk(struct dm_snapshot *s, + chunk_t old_chunk) +{ + struct dm_exception *e; + + /* FIXME: interlock writes to this chunk */ + + e = dm_lookup_exception(&s->complete, old_chunk); + if (!e) { + DMERR("Corruption detected: exception for block %llu is " + "on disk but not in memory", + (unsigned long long)old_chunk); + return -EINVAL; + } + + /* + * If this is the only chunk using this exception, remove exception. + */ + if (!dm_consecutive_chunk_count(e)) { + dm_remove_exception(e); + free_completed_exception(e); + return 0; + } + + /* + * The chunk may be either at the beginning or the end of a + * group of consecutive chunks - never in the middle. We are + * removing chunks in the opposite order to that in which they + * were added, so this should always be true. + * Decrement the consecutive chunk counter and adjust the + * starting point if necessary. + */ + if (old_chunk == e->old_chunk) { + e->old_chunk++; + e->new_chunk++; + } else if (old_chunk != e->old_chunk + + dm_consecutive_chunk_count(e)) { + DMERR("Attempt to merge block %llu from the " + "middle of a chunk range [%llu - %llu]", + (unsigned long long)old_chunk, + (unsigned long long)e->old_chunk, + (unsigned long long) + e->old_chunk + dm_consecutive_chunk_count(e)); + return -EINVAL; + } + + dm_consecutive_chunk_count_dec(e); + + return 0; +} + +static int remove_single_exception_chunk(struct dm_snapshot *s, + chunk_t old_chunk) +{ + int r = 0; + + down_write(&s->lock); + r = __remove_single_exception_chunk(s, old_chunk); + up_write(&s->lock); + + return r; +} + +static void merge_callback(int read_err, unsigned long write_err, + void *context); + +static void snapshot_merge_next_chunks(struct dm_snapshot *s) +{ + int r; + chunk_t old_chunk, new_chunk; + struct dm_io_region src, dest; + + BUG_ON(!test_bit(RUNNING_MERGE, &s->state_bits)); + if (unlikely(test_bit(SHUTDOWN_MERGE, &s->state_bits))) + goto shut; + + /* + * valid flag never changes during merge, so no lock required. + */ + if (!s->valid) { + DMERR("Snapshot is invalid: can't merge"); + goto shut; + } + + r = s->store->type->prepare_merge(s->store, &old_chunk, &new_chunk); + if (r <= 0) { + if (r < 0) + DMERR("Read error in exception store: " + "shutting down merge"); + goto shut; + } + + /* TODO: use larger I/O size once we verify that kcopyd handles it */ + + if (remove_single_exception_chunk(s, old_chunk) < 0) + goto shut; + + dest.bdev = s->origin->bdev; + dest.sector = chunk_to_sector(s->store, old_chunk); + dest.count = min((sector_t)s->store->chunk_size, + get_dev_size(dest.bdev) - dest.sector); + + src.bdev = s->cow->bdev; + src.sector = chunk_to_sector(s->store, new_chunk); + src.count = dest.count; + + dm_kcopyd_copy(s->kcopyd_client, &src, 1, &dest, 0, merge_callback, s); + return; + +shut: + merge_shutdown(s); +} + +static void merge_callback(int read_err, unsigned long write_err, void *context) +{ + struct dm_snapshot *s = context; + + if (read_err || write_err) { + if (read_err) + DMERR("Read error: shutting down merge."); + else + DMERR("Write error: shutting down merge."); + goto shut; + } + + if (s->store->type->commit_merge(s->store, 1) < 0) { + DMERR("Write error in exception store: shutting down merge"); + goto shut; + } + + snapshot_merge_next_chunks(s); + + return; + +shut: + merge_shutdown(s); +} + +static void start_merge(struct dm_snapshot *s) +{ + if (!test_and_set_bit(RUNNING_MERGE, &s->state_bits)) + snapshot_merge_next_chunks(s); +} + +static int wait_schedule(void *ptr) +{ + schedule(); + + return 0; +} + +/* + * Stop the merging process and wait until it finishes. + */ +static void stop_merge(struct dm_snapshot *s) +{ + set_bit(SHUTDOWN_MERGE, &s->state_bits); + wait_on_bit(&s->state_bits, RUNNING_MERGE, wait_schedule, + TASK_UNINTERRUPTIBLE); + clear_bit(SHUTDOWN_MERGE, &s->state_bits); +} + /* * Construct a snapshot mapping:

*/ @@ -791,6 +982,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) init_rwsem(&s->lock); INIT_LIST_HEAD(&s->list); spin_lock_init(&s->pe_lock); + s->state_bits = 0; /* Allocate hash table for COW data */ if (init_hash_tables(s)) { @@ -963,6 +1155,9 @@ static void snapshot_dtr(struct dm_target *ti) } up_read(&_origins_lock); + if (dm_target_is_snapshot_merge(ti)) + stop_merge(s); + /* Prevent further origin writes from using this snapshot. */ /* After this returns there can be no new kcopyd jobs. */ unregister_snapshot(s); @@ -1404,6 +1599,13 @@ static int snapshot_end_io(struct dm_target *ti, struct bio *bio, return 0; } +static void snapshot_merge_presuspend(struct dm_target *ti) +{ + struct dm_snapshot *s = ti->private; + + stop_merge(s); +} + static void snapshot_postsuspend(struct dm_target *ti) { struct dm_snapshot *s = ti->private; @@ -1464,6 +1666,34 @@ static void snapshot_resume(struct dm_target *ti) up_write(&s->lock); } +static sector_t get_origin_minimum_chunksize(struct block_device *bdev) +{ + sector_t min_chunksize; + + down_read(&_origins_lock); + min_chunksize = __minimum_chunk_size(__lookup_origin(bdev)); + up_read(&_origins_lock); + + return min_chunksize; +} + +static void snapshot_merge_resume(struct dm_target *ti) +{ + struct dm_snapshot *s = ti->private; + + /* + * Handover exceptions from existing snapshot. + */ + snapshot_resume(ti); + + /* + * snapshot-merge acts as an origin, so set ti->split_io + */ + ti->split_io = get_origin_minimum_chunksize(s->origin->bdev); + + start_merge(s); +} + static int snapshot_status(struct dm_target *ti, status_type_t type, char *result, unsigned int maxlen) { @@ -1722,11 +1952,7 @@ static void origin_resume(struct dm_target *ti) { struct dm_dev *dev = ti->private; - down_read(&_origins_lock); - - ti->split_io = __minimum_chunk_size(__lookup_origin(dev->bdev)); - - up_read(&_origins_lock); + ti->split_io = get_origin_minimum_chunksize(dev->bdev); } static int origin_status(struct dm_target *ti, status_type_t type, char *result, @@ -1790,9 +2016,10 @@ static struct target_type merge_target = { .dtr = snapshot_dtr, .map = snapshot_merge_map, .end_io = snapshot_end_io, + .presuspend = snapshot_merge_presuspend, .postsuspend = snapshot_postsuspend, .preresume = snapshot_preresume, - .resume = snapshot_resume, + .resume = snapshot_merge_resume, .status = snapshot_status, .iterate_devices = snapshot_iterate_devices, }; -- cgit v0.10.2 From 9fe862548821b0c206c58e8057b782530a173703 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:33 +0000 Subject: dm snapshot: queue writes to chunks being merged While a set of chunks is being merged, any overlapping writes need to be queued. Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index dc2412e..91a47c5 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -109,6 +109,16 @@ struct dm_snapshot { /* Wait for events based on state_bits */ unsigned long state_bits; + + /* Range of chunks currently being merged. */ + chunk_t first_merging_chunk; + int num_merging_chunks; + + /* + * Incoming bios that overlap with chunks being merged must wait + * for them to be committed. + */ + struct bio_list bios_queued_during_merge; }; /* @@ -747,6 +757,14 @@ static void merge_shutdown(struct dm_snapshot *s) wake_up_bit(&s->state_bits, RUNNING_MERGE); } +static struct bio *__release_queued_bios_after_merge(struct dm_snapshot *s) +{ + s->first_merging_chunk = 0; + s->num_merging_chunks = 0; + + return bio_list_get(&s->bios_queued_during_merge); +} + /* * Remove one chunk from the index of completed exceptions. */ @@ -755,8 +773,6 @@ static int __remove_single_exception_chunk(struct dm_snapshot *s, { struct dm_exception *e; - /* FIXME: interlock writes to this chunk */ - e = dm_lookup_exception(&s->complete, old_chunk); if (!e) { DMERR("Corruption detected: exception for block %llu is " @@ -801,14 +817,32 @@ static int __remove_single_exception_chunk(struct dm_snapshot *s, return 0; } -static int remove_single_exception_chunk(struct dm_snapshot *s, - chunk_t old_chunk) +static void flush_bios(struct bio *bio); + +static int remove_single_exception_chunk(struct dm_snapshot *s) { - int r = 0; + struct bio *b = NULL; + int r; + chunk_t old_chunk = s->first_merging_chunk + s->num_merging_chunks - 1; down_write(&s->lock); - r = __remove_single_exception_chunk(s, old_chunk); + + /* + * Process chunks (and associated exceptions) in reverse order + * so that dm_consecutive_chunk_count_dec() accounting works. + */ + do { + r = __remove_single_exception_chunk(s, old_chunk); + if (r) + goto out; + } while (old_chunk-- > s->first_merging_chunk); + + b = __release_queued_bios_after_merge(s); + +out: up_write(&s->lock); + if (b) + flush_bios(b); return r; } @@ -844,9 +878,6 @@ static void snapshot_merge_next_chunks(struct dm_snapshot *s) /* TODO: use larger I/O size once we verify that kcopyd handles it */ - if (remove_single_exception_chunk(s, old_chunk) < 0) - goto shut; - dest.bdev = s->origin->bdev; dest.sector = chunk_to_sector(s->store, old_chunk); dest.count = min((sector_t)s->store->chunk_size, @@ -856,6 +887,13 @@ static void snapshot_merge_next_chunks(struct dm_snapshot *s) src.sector = chunk_to_sector(s->store, new_chunk); src.count = dest.count; + down_write(&s->lock); + s->first_merging_chunk = old_chunk; + s->num_merging_chunks = 1; + up_write(&s->lock); + + /* !!! FIXME: wait until writes to this chunk drain */ + dm_kcopyd_copy(s->kcopyd_client, &src, 1, &dest, 0, merge_callback, s); return; @@ -863,9 +901,12 @@ shut: merge_shutdown(s); } +static void error_bios(struct bio *bio); + static void merge_callback(int read_err, unsigned long write_err, void *context) { struct dm_snapshot *s = context; + struct bio *b = NULL; if (read_err || write_err) { if (read_err) @@ -875,16 +916,25 @@ static void merge_callback(int read_err, unsigned long write_err, void *context) goto shut; } - if (s->store->type->commit_merge(s->store, 1) < 0) { + if (s->store->type->commit_merge(s->store, + s->num_merging_chunks) < 0) { DMERR("Write error in exception store: shutting down merge"); goto shut; } + if (remove_single_exception_chunk(s) < 0) + goto shut; + snapshot_merge_next_chunks(s); return; shut: + down_write(&s->lock); + b = __release_queued_bios_after_merge(s); + up_write(&s->lock); + error_bios(b); + merge_shutdown(s); } @@ -983,6 +1033,9 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) INIT_LIST_HEAD(&s->list); spin_lock_init(&s->pe_lock); s->state_bits = 0; + s->first_merging_chunk = 0; + s->num_merging_chunks = 0; + bio_list_init(&s->bios_queued_during_merge); /* Allocate hash table for COW data */ if (init_hash_tables(s)) { @@ -1539,6 +1592,8 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, * For each chunk, if there is an existing exception, it is used to * redirect I/O to the cow device. Otherwise I/O is sent to the origin, * which in turn might generate exceptions in other snapshots. + * If merging is currently taking place on the chunk in question, the + * I/O is deferred by adding it to s->bios_queued_during_merge. */ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio, union map_info *map_context) @@ -1559,7 +1614,7 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio, chunk = sector_to_chunk(s->store, bio->bi_sector); - down_read(&s->lock); + down_write(&s->lock); /* Full snapshots are not usable */ if (!s->valid) { @@ -1570,6 +1625,16 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio, /* If the block is already remapped - use that */ e = dm_lookup_exception(&s->complete, chunk); if (e) { + /* Queue writes overlapping with chunks being merged */ + if (bio_rw(bio) == WRITE && + chunk >= s->first_merging_chunk && + chunk < (s->first_merging_chunk + + s->num_merging_chunks)) { + bio->bi_bdev = s->origin->bdev; + bio_list_add(&s->bios_queued_during_merge, bio); + r = DM_MAPIO_SUBMITTED; + goto out_unlock; + } remap_exception(s, e, bio, chunk); goto out_unlock; } @@ -1577,12 +1642,12 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio, bio->bi_bdev = s->origin->bdev; if (bio_rw(bio) == WRITE) { - up_read(&s->lock); + up_write(&s->lock); return do_origin(s->origin, bio); } out_unlock: - up_read(&s->lock); + up_write(&s->lock); return r; } -- cgit v0.10.2 From 17aa03326d40614db94bc51fbbc92df628a5c97c Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:33 +0000 Subject: dm snapshot: delay merging a chunk until writes to it complete Track writes to chunks that are currently being merged and delay merging a chunk until all writes to that chunk finish. Signed-off-by: Mikulas Patocka Reviewed-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 91a47c5..bc52776 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -892,7 +892,7 @@ static void snapshot_merge_next_chunks(struct dm_snapshot *s) s->num_merging_chunks = 1; up_write(&s->lock); - /* !!! FIXME: wait until writes to this chunk drain */ + __check_for_conflicting_io(s, old_chunk); dm_kcopyd_copy(s->kcopyd_client, &src, 1, &dest, 0, merge_callback, s); return; @@ -1635,7 +1635,11 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio, r = DM_MAPIO_SUBMITTED; goto out_unlock; } + remap_exception(s, e, bio, chunk); + + if (bio_rw(bio) == WRITE) + map_context->ptr = track_chunk(s, chunk); goto out_unlock; } -- cgit v0.10.2 From 73dfd078cf8bfee4018fb22f1e2a24f2e05b69dc Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:34 +0000 Subject: dm snapshot: trigger exceptions in remaining snapshots during merge When there is one merging snapshot and other non-merging snapshots, snapshot_merge_process() must make exceptions in the non-merging snapshots. Use a sequence count to resolve the race between I/O to chunks that are about to be merged. The count increases each time an exception reallocation finishes. Use wait_event() to wait until the count changes. Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index bc52776..1498704 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -270,6 +270,10 @@ struct origin { static struct list_head *_origins; static struct rw_semaphore _origins_lock; +static DECLARE_WAIT_QUEUE_HEAD(_pending_exceptions_done); +static DEFINE_SPINLOCK(_pending_exceptions_done_spinlock); +static uint64_t _pending_exceptions_done_count; + static int init_origin_hash(void) { int i; @@ -847,14 +851,38 @@ out: return r; } +static int origin_write_extent(struct dm_snapshot *merging_snap, + sector_t sector, unsigned chunk_size); + static void merge_callback(int read_err, unsigned long write_err, void *context); +static uint64_t read_pending_exceptions_done_count(void) +{ + uint64_t pending_exceptions_done; + + spin_lock(&_pending_exceptions_done_spinlock); + pending_exceptions_done = _pending_exceptions_done_count; + spin_unlock(&_pending_exceptions_done_spinlock); + + return pending_exceptions_done; +} + +static void increment_pending_exceptions_done_count(void) +{ + spin_lock(&_pending_exceptions_done_spinlock); + _pending_exceptions_done_count++; + spin_unlock(&_pending_exceptions_done_spinlock); + + wake_up_all(&_pending_exceptions_done); +} + static void snapshot_merge_next_chunks(struct dm_snapshot *s) { int r; chunk_t old_chunk, new_chunk; struct dm_io_region src, dest; + uint64_t previous_count; BUG_ON(!test_bit(RUNNING_MERGE, &s->state_bits)); if (unlikely(test_bit(SHUTDOWN_MERGE, &s->state_bits))) @@ -887,6 +915,24 @@ static void snapshot_merge_next_chunks(struct dm_snapshot *s) src.sector = chunk_to_sector(s->store, new_chunk); src.count = dest.count; + /* + * Reallocate any exceptions needed in other snapshots then + * wait for the pending exceptions to complete. + * Each time any pending exception (globally on the system) + * completes we are woken and repeat the process to find out + * if we can proceed. While this may not seem a particularly + * efficient algorithm, it is not expected to have any + * significant impact on performance. + */ + previous_count = read_pending_exceptions_done_count(); + while (origin_write_extent(s, dest.sector, s->store->chunk_size)) { + wait_event(_pending_exceptions_done, + (read_pending_exceptions_done_count() != + previous_count)); + /* Retry after the wait, until all exceptions are done. */ + previous_count = read_pending_exceptions_done_count(); + } + down_write(&s->lock); s->first_merging_chunk = old_chunk; s->num_merging_chunks = 1; @@ -1372,6 +1418,8 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) origin_bios = bio_list_get(&pe->origin_bios); free_pending_exception(pe); + increment_pending_exceptions_done_count(); + up_write(&s->lock); /* Submit any pending write bios */ @@ -1963,6 +2011,41 @@ static int do_origin(struct dm_dev *origin, struct bio *bio) } /* + * Trigger exceptions in all non-merging snapshots. + * + * The chunk size of the merging snapshot may be larger than the chunk + * size of some other snapshot so we may need to reallocate multiple + * chunks in other snapshots. + * + * We scan all the overlapping exceptions in the other snapshots. + * Returns 1 if anything was reallocated and must be waited for, + * otherwise returns 0. + * + * size must be a multiple of merging_snap's chunk_size. + */ +static int origin_write_extent(struct dm_snapshot *merging_snap, + sector_t sector, unsigned size) +{ + int must_wait = 0; + sector_t n; + struct origin *o; + + /* + * The origin's __minimum_chunk_size() got stored in split_io + * by snapshot_merge_resume(). + */ + down_read(&_origins_lock); + o = __lookup_origin(merging_snap->origin->bdev); + for (n = 0; n < size; n += merging_snap->ti->split_io) + if (__origin_write(&o->snapshots, sector + n, NULL) == + DM_MAPIO_SUBMITTED) + must_wait = 1; + up_read(&_origins_lock); + + return must_wait; +} + +/* * Origin: maps a linear range of a device, with hooks for snapshotting. */ -- cgit v0.10.2 From 8a2d528620e228ddfd0df9cec0a16e034ff8db1d Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 10 Dec 2009 23:52:34 +0000 Subject: dm snapshot: merge consecutive chunks together s->store->type->prepare_merge returns the number of chunks that can be copied linearly working backwards from the returned chunk number. For example, if it returns 3 chunks with old_chunk == 10 and new_chunk == 20, then chunk 20 can be copied to 10, chunk 19 to 9 and 18 to 8. Until now kcopyd only copied one chunk at a time. This patch now copies the full set at once. Consequently, snapshot_merge_process() needs to delay the merging of all chunks if any have writes in progress, not just the first chunk in the region that is to be merged. snapshot-merge's performance is now comparable to the original snapshot-origin target. Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 1498704..bb4b733 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -879,9 +879,10 @@ static void increment_pending_exceptions_done_count(void) static void snapshot_merge_next_chunks(struct dm_snapshot *s) { - int r; + int i, linear_chunks; chunk_t old_chunk, new_chunk; struct dm_io_region src, dest; + sector_t io_size; uint64_t previous_count; BUG_ON(!test_bit(RUNNING_MERGE, &s->state_bits)); @@ -896,20 +897,28 @@ static void snapshot_merge_next_chunks(struct dm_snapshot *s) goto shut; } - r = s->store->type->prepare_merge(s->store, &old_chunk, &new_chunk); - if (r <= 0) { - if (r < 0) + linear_chunks = s->store->type->prepare_merge(s->store, &old_chunk, + &new_chunk); + if (linear_chunks <= 0) { + if (linear_chunks < 0) DMERR("Read error in exception store: " "shutting down merge"); goto shut; } - /* TODO: use larger I/O size once we verify that kcopyd handles it */ + /* Adjust old_chunk and new_chunk to reflect start of linear region */ + old_chunk = old_chunk + 1 - linear_chunks; + new_chunk = new_chunk + 1 - linear_chunks; + + /* + * Use one (potentially large) I/O to copy all 'linear_chunks' + * from the exception store to the origin + */ + io_size = linear_chunks * s->store->chunk_size; dest.bdev = s->origin->bdev; dest.sector = chunk_to_sector(s->store, old_chunk); - dest.count = min((sector_t)s->store->chunk_size, - get_dev_size(dest.bdev) - dest.sector); + dest.count = min(io_size, get_dev_size(dest.bdev) - dest.sector); src.bdev = s->cow->bdev; src.sector = chunk_to_sector(s->store, new_chunk); @@ -925,7 +934,7 @@ static void snapshot_merge_next_chunks(struct dm_snapshot *s) * significant impact on performance. */ previous_count = read_pending_exceptions_done_count(); - while (origin_write_extent(s, dest.sector, s->store->chunk_size)) { + while (origin_write_extent(s, dest.sector, io_size)) { wait_event(_pending_exceptions_done, (read_pending_exceptions_done_count() != previous_count)); @@ -935,10 +944,12 @@ static void snapshot_merge_next_chunks(struct dm_snapshot *s) down_write(&s->lock); s->first_merging_chunk = old_chunk; - s->num_merging_chunks = 1; + s->num_merging_chunks = linear_chunks; up_write(&s->lock); - __check_for_conflicting_io(s, old_chunk); + /* Wait until writes to all 'linear_chunks' drain */ + for (i = 0; i < linear_chunks; i++) + __check_for_conflicting_io(s, old_chunk + i); dm_kcopyd_copy(s->kcopyd_client, &src, 1, &dest, 0, merge_callback, s); return; -- cgit v0.10.2 From d8ddb1cfff0070479c1f4a07c1d4a48ef8cb188e Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 10 Dec 2009 23:52:35 +0000 Subject: dm snapshot: report merge failure in status Set 'merge_failed' flag if a snapshot fails to merge. Update snapshot_status() to report "Merge failed" if 'merge_failed' is set. Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index bb4b733..4c80e82 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -71,7 +71,10 @@ struct dm_snapshot { /* List of snapshots per Origin */ struct list_head list; - /* You can't use a snapshot if this is 0 (e.g. if full) */ + /* + * You can't use a snapshot if this is 0 (e.g. if full). + * A snapshot-merge target never clears this. + */ int valid; /* Origin writes don't trigger exceptions until this is set */ @@ -107,6 +110,21 @@ struct dm_snapshot { spinlock_t tracked_chunk_lock; struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE]; + /* + * The merge operation failed if this flag is set. + * Failure modes are handled as follows: + * - I/O error reading the header + * => don't load the target; abort. + * - Header does not have "valid" flag set + * => use the origin; forget about the snapshot. + * - I/O error when reading exceptions + * => don't load the target; abort. + * (We can't use the intermediate origin state.) + * - I/O error while merging + * => stop merging; set merge_failed; process I/O normally. + */ + int merge_failed; + /* Wait for events based on state_bits */ unsigned long state_bits; @@ -900,9 +918,13 @@ static void snapshot_merge_next_chunks(struct dm_snapshot *s) linear_chunks = s->store->type->prepare_merge(s->store, &old_chunk, &new_chunk); if (linear_chunks <= 0) { - if (linear_chunks < 0) + if (linear_chunks < 0) { DMERR("Read error in exception store: " "shutting down merge"); + down_write(&s->lock); + s->merge_failed = 1; + up_write(&s->lock); + } goto shut; } @@ -988,6 +1010,7 @@ static void merge_callback(int read_err, unsigned long write_err, void *context) shut: down_write(&s->lock); + s->merge_failed = 1; b = __release_queued_bios_after_merge(s); up_write(&s->lock); error_bios(b); @@ -1090,6 +1113,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) INIT_LIST_HEAD(&s->list); spin_lock_init(&s->pe_lock); s->state_bits = 0; + s->merge_failed = 0; s->first_merging_chunk = 0; s->num_merging_chunks = 0; bio_list_init(&s->bios_queued_during_merge); @@ -1835,6 +1859,8 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, if (!snap->valid) DMEMIT("Invalid"); + else if (snap->merge_failed) + DMEMIT("Merge failed"); else { if (snap->store->type->usage) { sector_t total_sectors, sectors_allocated, -- cgit v0.10.2 From d2fdb776e08d4231d7e86a879cc663a93913c202 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Thu, 10 Dec 2009 23:52:36 +0000 Subject: dm snapshot: use merge origin if snapshot invalid If the snapshot we are merging became invalid (e.g. it ran out of space) redirect all I/O directly to the origin device. Signed-off-by: Mikulas Patocka Reviewed-by: Mike Snitzer Signed-off-by: Alasdair G Kergon diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 4c80e82..ee8eb28 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -1699,11 +1699,9 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio, down_write(&s->lock); - /* Full snapshots are not usable */ - if (!s->valid) { - r = -EIO; - goto out_unlock; - } + /* Full merging snapshots are redirected to the origin */ + if (!s->valid) + goto redirect_to_origin; /* If the block is already remapped - use that */ e = dm_lookup_exception(&s->complete, chunk); @@ -1726,6 +1724,7 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio, goto out_unlock; } +redirect_to_origin: bio->bi_bdev = s->origin->bdev; if (bio_rw(bio) == WRITE) { -- cgit v0.10.2 From 3bd95dfb182969dc6d2a317c150e0df7107608d3 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 9 Dec 2009 12:34:40 -0500 Subject: x86, 64-bit: Move kernel_thread to C Prepare for merging with 32-bit. Signed-off-by: Brian Gerst LKML-Reference: <1260380084-3707-2-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 63bca79..73d9b2c 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -1166,63 +1166,20 @@ bad_gs: jmp 2b .previous -/* - * Create a kernel thread. - * - * C extern interface: - * extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) - * - * asm input arguments: - * rdi: fn, rsi: arg, rdx: flags - */ -ENTRY(kernel_thread) - CFI_STARTPROC - FAKE_STACK_FRAME $child_rip - SAVE_ALL - - # rdi: flags, rsi: usp, rdx: will be &pt_regs - movq %rdx,%rdi - orq kernel_thread_flags(%rip),%rdi - movq $-1, %rsi - movq %rsp, %rdx - - xorl %r8d,%r8d - xorl %r9d,%r9d - - # clone now - call do_fork - movq %rax,RAX(%rsp) - xorl %edi,%edi - - /* - * It isn't worth to check for reschedule here, - * so internally to the x86_64 port you can rely on kernel_thread() - * not to reschedule the child before returning, this avoids the need - * of hacks for example to fork off the per-CPU idle tasks. - * [Hopefully no generic code relies on the reschedule -AK] - */ - RESTORE_ALL - UNFAKE_STACK_FRAME - ret - CFI_ENDPROC -END(kernel_thread) - -ENTRY(child_rip) +ENTRY(kernel_thread_helper) pushq $0 # fake return address CFI_STARTPROC /* * Here we are in the child and the registers are set as they were * at kernel_thread() invocation in the parent. */ - movq %rdi, %rax - movq %rsi, %rdi - call *%rax + call *%rsi # exit mov %eax, %edi call do_exit ud2 # padding for call trace CFI_ENDPROC -END(child_rip) +END(kernel_thread_helper) /* * execve(). This function needs to use IRET, not SYSRET, to set up all state properly. diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 83019f9..92484c2 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -59,8 +59,6 @@ asmlinkage extern void ret_from_fork(void); DEFINE_PER_CPU(unsigned long, old_rsp); static DEFINE_PER_CPU(unsigned char, is_idle); -unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED; - static ATOMIC_NOTIFIER_HEAD(idle_notifier); void idle_notifier_register(struct notifier_block *n) @@ -231,6 +229,35 @@ void show_regs(struct pt_regs *regs) show_trace(NULL, regs, (void *)(regs + 1), regs->bp); } +/* + * This gets run with %si containing the + * function to call, and %di containing + * the "args". + */ +extern void kernel_thread_helper(void); + +/* + * Create a kernel thread + */ +int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) +{ + struct pt_regs regs; + + memset(®s, 0, sizeof(regs)); + + regs.si = (unsigned long) fn; + regs.di = (unsigned long) arg; + + regs.orig_ax = -1; + regs.ip = (unsigned long) kernel_thread_helper; + regs.cs = __KERNEL_CS; + regs.flags = X86_EFLAGS_IF; + + /* Ok, create the new process.. */ + return do_fork(flags | CLONE_VM | CLONE_UNTRACED, ~0UL, ®s, 0, NULL, NULL); +} +EXPORT_SYMBOL(kernel_thread); + void release_thread(struct task_struct *dead_task) { if (dead_task->mm) { diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index a102976..9fafaf8 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c @@ -17,8 +17,6 @@ EXPORT_SYMBOL(mcount); #endif -EXPORT_SYMBOL(kernel_thread); - EXPORT_SYMBOL(__get_user_1); EXPORT_SYMBOL(__get_user_2); EXPORT_SYMBOL(__get_user_4); -- cgit v0.10.2 From fa4b8f84383ae197e643a46c36bf58ab8dffc95c Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 9 Dec 2009 12:34:41 -0500 Subject: x86, 64-bit: Use user_mode() to determine new stack pointer in copy_thread() Use user_mode() instead of a magic value for sp to determine when returning to kernel mode. Signed-off-by: Brian Gerst LKML-Reference: <1260380084-3707-3-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 92484c2..00ac66f 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -254,7 +254,7 @@ int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) regs.flags = X86_EFLAGS_IF; /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, ~0UL, ®s, 0, NULL, NULL); + return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } EXPORT_SYMBOL(kernel_thread); @@ -312,8 +312,9 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, *childregs = *regs; childregs->ax = 0; - childregs->sp = sp; - if (sp == ~0UL) + if (user_mode(regs)) + childregs->sp = sp; + else childregs->sp = (unsigned long)childregs; p->thread.sp = (unsigned long) childregs; -- cgit v0.10.2 From e840227c141116171c89ab1abb5cc9fee6fdb488 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 9 Dec 2009 12:34:42 -0500 Subject: x86, 32-bit: Use same regs as 64-bit for kernel_thread_helper The arg should be in %eax, but that is clobbered by the return value of clone. The function pointer can be in any register. Also, don't push args onto the stack, since regparm(3) is the normal calling convention now. Signed-off-by: Brian Gerst LKML-Reference: <1260380084-3707-4-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index cb12b9b..44a8e0d 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -1047,12 +1047,8 @@ END(spurious_interrupt_bug) ENTRY(kernel_thread_helper) pushl $0 # fake return address for unwinder CFI_STARTPROC - movl %edx,%eax - push %edx - CFI_ADJUST_CFA_OFFSET 4 - call *%ebx - push %eax - CFI_ADJUST_CFA_OFFSET 4 + movl %edi,%eax + call *%esi call do_exit ud2 # padding for call trace CFI_ENDPROC diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 506d5a7..bd874d2 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -193,8 +193,8 @@ void show_regs(struct pt_regs *regs) } /* - * This gets run with %bx containing the - * function to call, and %dx containing + * This gets run with %si containing the + * function to call, and %di containing * the "args". */ extern void kernel_thread_helper(void); @@ -208,8 +208,8 @@ int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) memset(®s, 0, sizeof(regs)); - regs.bx = (unsigned long) fn; - regs.dx = (unsigned long) arg; + regs.si = (unsigned long) fn; + regs.di = (unsigned long) arg; regs.ds = __USER_DS; regs.es = __USER_DS; -- cgit v0.10.2 From f443ff4201dd25cd4dec183f9919ecba90c8edc2 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 9 Dec 2009 12:34:43 -0500 Subject: x86: Sync 32/64-bit kernel_thread Signed-off-by: Brian Gerst LKML-Reference: <1260380084-3707-5-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index bd874d2..f2e8b05 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -211,14 +211,17 @@ int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) regs.si = (unsigned long) fn; regs.di = (unsigned long) arg; +#ifdef CONFIG_X86_32 regs.ds = __USER_DS; regs.es = __USER_DS; regs.fs = __KERNEL_PERCPU; regs.gs = __KERNEL_STACK_CANARY; +#endif + regs.orig_ax = -1; regs.ip = (unsigned long) kernel_thread_helper; regs.cs = __KERNEL_CS | get_kernel_rpl(); - regs.flags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; + regs.flags = X86_EFLAGS_IF | 0x2; /* Ok, create the new process.. */ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 00ac66f..d49a909 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -248,10 +248,17 @@ int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) regs.si = (unsigned long) fn; regs.di = (unsigned long) arg; +#ifdef CONFIG_X86_32 + regs.ds = __USER_DS; + regs.es = __USER_DS; + regs.fs = __KERNEL_PERCPU; + regs.gs = __KERNEL_STACK_CANARY; +#endif + regs.orig_ax = -1; regs.ip = (unsigned long) kernel_thread_helper; - regs.cs = __KERNEL_CS; - regs.flags = X86_EFLAGS_IF; + regs.cs = __KERNEL_CS | get_kernel_rpl(); + regs.flags = X86_EFLAGS_IF | 0x2; /* Ok, create the new process.. */ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); -- cgit v0.10.2 From df59e7bf439918f523ac29e996ec1eebbed60440 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 9 Dec 2009 12:34:44 -0500 Subject: x86: Merge kernel_thread() Signed-off-by: Brian Gerst LKML-Reference: <1260380084-3707-6-git-send-email-brgerst@gmail.com> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index f3c1a6b..8705cce 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -243,6 +243,41 @@ sys_clone(unsigned long clone_flags, unsigned long newsp, return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); } +/* + * This gets run with %si containing the + * function to call, and %di containing + * the "args". + */ +extern void kernel_thread_helper(void); + +/* + * Create a kernel thread + */ +int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) +{ + struct pt_regs regs; + + memset(®s, 0, sizeof(regs)); + + regs.si = (unsigned long) fn; + regs.di = (unsigned long) arg; + +#ifdef CONFIG_X86_32 + regs.ds = __USER_DS; + regs.es = __USER_DS; + regs.fs = __KERNEL_PERCPU; + regs.gs = __KERNEL_STACK_CANARY; +#endif + + regs.orig_ax = -1; + regs.ip = (unsigned long) kernel_thread_helper; + regs.cs = __KERNEL_CS | get_kernel_rpl(); + regs.flags = X86_EFLAGS_IF | 0x2; + + /* Ok, create the new process.. */ + return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); +} +EXPORT_SYMBOL(kernel_thread); /* * sys_execve() executes a new program. diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index f2e8b05..ccf2342 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -192,42 +192,6 @@ void show_regs(struct pt_regs *regs) show_trace(NULL, regs, ®s->sp, regs->bp); } -/* - * This gets run with %si containing the - * function to call, and %di containing - * the "args". - */ -extern void kernel_thread_helper(void); - -/* - * Create a kernel thread - */ -int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) -{ - struct pt_regs regs; - - memset(®s, 0, sizeof(regs)); - - regs.si = (unsigned long) fn; - regs.di = (unsigned long) arg; - -#ifdef CONFIG_X86_32 - regs.ds = __USER_DS; - regs.es = __USER_DS; - regs.fs = __KERNEL_PERCPU; - regs.gs = __KERNEL_STACK_CANARY; -#endif - - regs.orig_ax = -1; - regs.ip = (unsigned long) kernel_thread_helper; - regs.cs = __KERNEL_CS | get_kernel_rpl(); - regs.flags = X86_EFLAGS_IF | 0x2; - - /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); -} -EXPORT_SYMBOL(kernel_thread); - void release_thread(struct task_struct *dead_task) { BUG_ON(dead_task->mm); diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index d49a909..1a362c5b 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -229,42 +229,6 @@ void show_regs(struct pt_regs *regs) show_trace(NULL, regs, (void *)(regs + 1), regs->bp); } -/* - * This gets run with %si containing the - * function to call, and %di containing - * the "args". - */ -extern void kernel_thread_helper(void); - -/* - * Create a kernel thread - */ -int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) -{ - struct pt_regs regs; - - memset(®s, 0, sizeof(regs)); - - regs.si = (unsigned long) fn; - regs.di = (unsigned long) arg; - -#ifdef CONFIG_X86_32 - regs.ds = __USER_DS; - regs.es = __USER_DS; - regs.fs = __KERNEL_PERCPU; - regs.gs = __KERNEL_STACK_CANARY; -#endif - - regs.orig_ax = -1; - regs.ip = (unsigned long) kernel_thread_helper; - regs.cs = __KERNEL_CS | get_kernel_rpl(); - regs.flags = X86_EFLAGS_IF | 0x2; - - /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); -} -EXPORT_SYMBOL(kernel_thread); - void release_thread(struct task_struct *dead_task) { if (dead_task->mm) { -- cgit v0.10.2 From f25c525c1412675d2b23d5d88660fb5c9f3a5341 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 10 Dec 2009 21:00:53 +0300 Subject: powerpc/83xx/suspend: Clear deep_sleeping after devices resume Currently 83xx PMC driver clears deep_sleeping variable very early, before devices are resumed. This makes fsl_deep_sleep() unusable in drivers' resume() callback. Sure, drivers can store fsl_deep_sleep() value on suspend and use the stored value on resume. But a better solution is to postpone clearing the deep_sleeping variable, i.e. move it into finish() callback. Signed-off-by: Anton Vorontsov Acked-by: Scott Wood Signed-off-by: Kumar Gala diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index d306f07..b0c2619 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -194,7 +194,7 @@ out: return ret; } -static void mpc83xx_suspend_finish(void) +static void mpc83xx_suspend_end(void) { deep_sleeping = 0; } @@ -278,7 +278,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = { .valid = mpc83xx_suspend_valid, .begin = mpc83xx_suspend_begin, .enter = mpc83xx_suspend_enter, - .finish = mpc83xx_suspend_finish, + .end = mpc83xx_suspend_end, }; static int pmc_probe(struct of_device *ofdev, -- cgit v0.10.2 From 87faaabb09d0802d54ff863a16ca821d7c669cb6 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 10 Dec 2009 21:00:56 +0300 Subject: powerpc/83xx/suspend: Save and restore SICRL, SICRH and SCCR We need to save SICRL, SICRH and SCCR registers on suspend, and restore them on resume. Otherwise, we lose IO and clocks setup on MPC8315E-RDB boards when ULPI USB PHY is used (non-POR setup). Signed-off-by: Anton Vorontsov Acked-by: Scott Wood Signed-off-by: Kumar Gala diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index b0c2619..4380534 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -32,6 +32,7 @@ #define PMCCR1_NEXT_STATE 0x0C /* Next state for power management */ #define PMCCR1_NEXT_STATE_SHIFT 2 #define PMCCR1_CURR_STATE 0x03 /* Current state for power management*/ +#define IMMR_SYSCR_OFFSET 0x100 #define IMMR_RCW_OFFSET 0x900 #define RCW_PCI_HOST 0x80000000 @@ -78,6 +79,22 @@ struct mpc83xx_clock { u32 sccr; }; +struct mpc83xx_syscr { + __be32 sgprl; + __be32 sgprh; + __be32 spridr; + __be32 :32; + __be32 spcr; + __be32 sicrl; + __be32 sicrh; +}; + +struct mpc83xx_saved { + u32 sicrl; + u32 sicrh; + u32 sccr; +}; + struct pmc_type { int has_deep_sleep; }; @@ -87,6 +104,8 @@ static int has_deep_sleep, deep_sleeping; static int pmc_irq; static struct mpc83xx_pmc __iomem *pmc_regs; static struct mpc83xx_clock __iomem *clock_regs; +static struct mpc83xx_syscr __iomem *syscr_regs; +static struct mpc83xx_saved saved_regs; static int is_pci_agent, wake_from_pci; static phys_addr_t immrbase; static int pci_pm_state; @@ -137,6 +156,20 @@ static irqreturn_t pmc_irq_handler(int irq, void *dev_id) return ret; } +static void mpc83xx_suspend_restore_regs(void) +{ + out_be32(&syscr_regs->sicrl, saved_regs.sicrl); + out_be32(&syscr_regs->sicrh, saved_regs.sicrh); + out_be32(&clock_regs->sccr, saved_regs.sccr); +} + +static void mpc83xx_suspend_save_regs(void) +{ + saved_regs.sicrl = in_be32(&syscr_regs->sicrl); + saved_regs.sicrh = in_be32(&syscr_regs->sicrh); + saved_regs.sccr = in_be32(&clock_regs->sccr); +} + static int mpc83xx_suspend_enter(suspend_state_t state) { int ret = -EAGAIN; @@ -166,6 +199,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state) */ if (deep_sleeping) { + mpc83xx_suspend_save_regs(); + out_be32(&pmc_regs->mask, PMCER_ALL); out_be32(&pmc_regs->config1, @@ -179,6 +214,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state) in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF); out_be32(&pmc_regs->mask, PMCER_PMCI); + + mpc83xx_suspend_restore_regs(); } else { out_be32(&pmc_regs->mask, PMCER_PMCI); @@ -333,12 +370,23 @@ static int pmc_probe(struct of_device *ofdev, goto out_pmc; } + if (has_deep_sleep) { + syscr_regs = ioremap(immrbase + IMMR_SYSCR_OFFSET, + sizeof(*syscr_regs)); + if (!syscr_regs) { + ret = -ENOMEM; + goto out_syscr; + } + } + if (is_pci_agent) mpc83xx_set_agent(); suspend_set_ops(&mpc83xx_suspend_ops); return 0; +out_syscr: + iounmap(clock_regs); out_pmc: iounmap(pmc_regs); out: -- cgit v0.10.2 From 1cad2c874162d84bf7b2d31344a08b9cb724d138 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 10 Dec 2009 21:01:03 +0300 Subject: powerpc/83xx: Add power management support for MPC8315E-RDB boards - Add nodes for PMC and GTM controllers. GTM4 can be used as a wakeup source; - Add fsl,magic-packet properties to eTSEC nodes, i.e. wake-on-lan support. Unlike MPC8313 processors, MPC8315 can resume from deep sleep upon magic packet reception. Signed-off-by: Anton Vorontsov Acked-by: Scott Wood Signed-off-by: Kumar Gala diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index 32e10f5..8a3a4f3 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts @@ -204,6 +204,7 @@ interrupt-parent = <&ipic>; tbi-handle = <&tbi0>; phy-handle = < &phy0 >; + fsl,magic-packet; mdio@520 { #address-cells = <1>; @@ -246,6 +247,7 @@ interrupt-parent = <&ipic>; tbi-handle = <&tbi1>; phy-handle = < &phy1 >; + fsl,magic-packet; mdio@520 { #address-cells = <1>; @@ -309,6 +311,22 @@ interrupt-parent = <&ipic>; }; + gtm1: timer@500 { + compatible = "fsl,mpc8315-gtm", "fsl,gtm"; + reg = <0x500 0x100>; + interrupts = <90 8 78 8 84 8 72 8>; + interrupt-parent = <&ipic>; + clock-frequency = <133333333>; + }; + + timer@600 { + compatible = "fsl,mpc8315-gtm", "fsl,gtm"; + reg = <0x600 0x100>; + interrupts = <91 8 79 8 85 8 73 8>; + interrupt-parent = <&ipic>; + clock-frequency = <133333333>; + }; + /* IPIC * interrupts cell = * sense values match linux IORESOURCE_IRQ_* defines: @@ -337,6 +355,15 @@ 0x59 0x8>; interrupt-parent = < &ipic >; }; + + pmc: power@b00 { + compatible = "fsl,mpc8315-pmc", "fsl,mpc8313-pmc", + "fsl,mpc8349-pmc"; + reg = <0xb00 0x100 0xa00 0x100>; + interrupts = <80 8>; + interrupt-parent = <&ipic>; + fsl,mpc8313-wakeup-timer = <>m1>; + }; }; pci0: pci@e0008500 { -- cgit v0.10.2 From 135d082171766922c6a9e2c741a326e518268428 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 10 Dec 2009 18:02:19 -0800 Subject: sparc64: Use kprobes_built_in() to avoid ifdefs in fault_64.c Signed-off-by: David S. Miller diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c index 43b0da9..0aa50b2 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c @@ -31,13 +31,12 @@ #include #include -#ifdef CONFIG_KPROBES static inline int notify_page_fault(struct pt_regs *regs) { int ret = 0; /* kprobe_running() needs smp_processor_id() */ - if (!user_mode(regs)) { + if (kprobes_built_in() && !user_mode(regs)) { preempt_disable(); if (kprobe_running() && kprobe_fault_handler(regs, 0)) ret = 1; @@ -45,12 +44,6 @@ static inline int notify_page_fault(struct pt_regs *regs) } return ret; } -#else -static inline int notify_page_fault(struct pt_regs *regs) -{ - return 0; -} -#endif static void __kprobes unhandled_fault(unsigned long address, struct task_struct *tsk, -- cgit v0.10.2 From 78331aded913d76c7ff996a1a0747d54b057460b Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Tue, 1 Dec 2009 21:48:13 +0100 Subject: powerpc/gpio: support gpio_to_irq() gpiolib returns -ENXIO if struct gpio_chip::to_irq isn't set, so it's safe to always call. Signed-off-by: Peter Korsgaard Signed-off-by: Kumar Gala diff --git a/arch/powerpc/include/asm/gpio.h b/arch/powerpc/include/asm/gpio.h index ea04632..38762ed 100644 --- a/arch/powerpc/include/asm/gpio.h +++ b/arch/powerpc/include/asm/gpio.h @@ -38,12 +38,9 @@ static inline int gpio_cansleep(unsigned int gpio) return __gpio_cansleep(gpio); } -/* - * Not implemented, yet. - */ static inline int gpio_to_irq(unsigned int gpio) { - return -ENOSYS; + return __gpio_to_irq(gpio); } static inline int irq_to_gpio(unsigned int irq) -- cgit v0.10.2 From 4ed5d5e4299f42438dd5ac6dcb1f2168ea4fb02a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 10 Dec 2009 18:08:29 -0800 Subject: sparc64: Add some missing __kprobes annotations to kernel fault paths. Signed-off-by: David S. Miller diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c index 0aa50b2..6081936 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c @@ -31,7 +31,7 @@ #include #include -static inline int notify_page_fault(struct pt_regs *regs) +static inline __kprobes int notify_page_fault(struct pt_regs *regs) { int ret = 0; @@ -66,7 +66,7 @@ static void __kprobes unhandled_fault(unsigned long address, die_if_kernel("Oops", regs); } -static void bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr) +static void __kprobes bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr) { printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n", regs->tpc); @@ -163,8 +163,9 @@ static unsigned int get_fault_insn(struct pt_regs *regs, unsigned int insn) return insn; } -static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, - unsigned int insn, unsigned long address) +static void __kprobes do_kernel_fault(struct pt_regs *regs, int si_code, + int fault_code, unsigned int insn, + unsigned long address) { unsigned char asi = ASI_P; @@ -218,7 +219,7 @@ cannot_handle: unhandled_fault (address, current, regs); } -static void noinline bogus_32bit_fault_tpc(struct pt_regs *regs) +static void noinline __kprobes bogus_32bit_fault_tpc(struct pt_regs *regs) { static int times; @@ -230,8 +231,8 @@ static void noinline bogus_32bit_fault_tpc(struct pt_regs *regs) show_regs(regs); } -static void noinline bogus_32bit_fault_address(struct pt_regs *regs, - unsigned long addr) +static void noinline __kprobes bogus_32bit_fault_address(struct pt_regs *regs, + unsigned long addr) { static int times; -- cgit v0.10.2 From c1a676dfa2fa25fb9ec77c92ebe3ff580648b6ac Mon Sep 17 00:00:00 2001 From: Felix Radensky Date: Wed, 12 Aug 2009 08:57:39 +0300 Subject: powerpc/85xx: Workaround MPC8572/MPC8536 GPIO 1 errata. On MPC8572 and MPC8536 the status of GPIO pins configured as output cannot be determined by reading GPDAT register. Workaround by reading the status of input pins from GPDAT and the status of output pins from a shadow register. Signed-off-by: Felix Radensky Signed-off-by: Kumar Gala diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c index 103eace..ee1c0e1 100644 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c @@ -54,6 +54,22 @@ static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm) mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT); } +/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs + * defined as output cannot be determined by reading GPDAT register, + * so we use shadow data register instead. The status of input pins + * is determined by reading GPDAT register. + */ +static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio) +{ + u32 val; + struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); + struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); + + val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR); + + return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio); +} + static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio) { struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); @@ -136,7 +152,10 @@ static void __init mpc8xxx_add_controller(struct device_node *np) gc->ngpio = MPC8XXX_GPIO_PINS; gc->direction_input = mpc8xxx_gpio_dir_in; gc->direction_output = mpc8xxx_gpio_dir_out; - gc->get = mpc8xxx_gpio_get; + if (of_device_is_compatible(np, "fsl,mpc8572-gpio")) + gc->get = mpc8572_gpio_get; + else + gc->get = mpc8xxx_gpio_get; gc->set = mpc8xxx_gpio_set; ret = of_mm_gpiochip_add(np, mm_gc); -- cgit v0.10.2 From 184210154b9aa570099183f6c062ac4eb11190b7 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Dec 2009 22:54:27 -0500 Subject: ring-buffer: Use sync sched protection on ring buffer resizing There was a comment in the ring buffer code that says the calling layers should prevent tracing or reading of the ring buffer while resizing. I have discovered that the tracers do not honor this arrangement. This patch moves the disabling and synchronizing the ring buffer to a higher layer during resizing. This guarantees that no writes are occurring while the resize takes place. Signed-off-by: Steven Rostedt diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index a1ca495..0d64c51 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1193,9 +1193,6 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages) struct list_head *p; unsigned i; - atomic_inc(&cpu_buffer->record_disabled); - synchronize_sched(); - spin_lock_irq(&cpu_buffer->reader_lock); rb_head_page_deactivate(cpu_buffer); @@ -1214,9 +1211,6 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages) spin_unlock_irq(&cpu_buffer->reader_lock); rb_check_pages(cpu_buffer); - - atomic_dec(&cpu_buffer->record_disabled); - } static void @@ -1227,9 +1221,6 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer, struct list_head *p; unsigned i; - atomic_inc(&cpu_buffer->record_disabled); - synchronize_sched(); - spin_lock_irq(&cpu_buffer->reader_lock); rb_head_page_deactivate(cpu_buffer); @@ -1245,8 +1236,6 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer, spin_unlock_irq(&cpu_buffer->reader_lock); rb_check_pages(cpu_buffer); - - atomic_dec(&cpu_buffer->record_disabled); } /** @@ -1254,11 +1243,6 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer, * @buffer: the buffer to resize. * @size: the new size. * - * The tracer is responsible for making sure that the buffer is - * not being used while changing the size. - * Note: We may be able to change the above requirement by using - * RCU synchronizations. - * * Minimum size is 2 * BUF_PAGE_SIZE. * * Returns -1 on failure. @@ -1290,6 +1274,11 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) if (size == buffer_size) return size; + atomic_inc(&buffer->record_disabled); + + /* Make sure all writers are done with this buffer. */ + synchronize_sched(); + mutex_lock(&buffer->mutex); get_online_cpus(); @@ -1352,6 +1341,8 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) put_online_cpus(); mutex_unlock(&buffer->mutex); + atomic_dec(&buffer->record_disabled); + return size; free_pages: @@ -1361,6 +1352,7 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) } put_online_cpus(); mutex_unlock(&buffer->mutex); + atomic_dec(&buffer->record_disabled); return -ENOMEM; /* @@ -1370,6 +1362,7 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) out_fail: put_online_cpus(); mutex_unlock(&buffer->mutex); + atomic_dec(&buffer->record_disabled); return -1; } EXPORT_SYMBOL_GPL(ring_buffer_resize); -- cgit v0.10.2 From 1cb9f9b086f818eb9543ed759382de7b95c67f87 Mon Sep 17 00:00:00 2001 From: Simon Guinot Date: Wed, 9 Dec 2009 01:43:49 +0100 Subject: [ARM] Kirkwood: Add LaCie Network Space v2 support Signed-off-by: Simon Guinot Signed-off-by: Nicolas Pitre diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index 8bf09ae..f6c6196 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig @@ -52,6 +52,12 @@ config MACH_OPENRD_BASE Say 'Y' here if you want your kernel to support the Marvell OpenRD Base Board. +config MACH_NETSPACE_V2 + bool "LaCie Network Space v2 NAS Board" + help + Say 'Y' here if you want your kernel to support the + LaCie Network Space v2 NAS. + endmenu endif diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index 9f2f67b..d4d7f53 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile @@ -8,5 +8,6 @@ obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o obj-$(CONFIG_MACH_OPENRD_BASE) += openrd_base-setup.o +obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o diff --git a/arch/arm/mach-kirkwood/netspace_v2-setup.c b/arch/arm/mach-kirkwood/netspace_v2-setup.c new file mode 100644 index 0000000..9a06406 --- /dev/null +++ b/arch/arm/mach-kirkwood/netspace_v2-setup.c @@ -0,0 +1,325 @@ +/* + * arch/arm/mach-kirkwood/netspace_v2-setup.c + * + * LaCie Network Space v2 board setup + * + * Copyright (C) 2009 Simon Guinot + * Copyright (C) 2009 Benoît Canet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +/***************************************************************************** + * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005) + ****************************************************************************/ + +static struct mtd_partition netspace_v2_flash_parts[] = { + { + .name = "u-boot", + .size = MTDPART_SIZ_FULL, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, +}; + +static const struct flash_platform_data netspace_v2_flash = { + .type = "mx25l4005a", + .name = "spi_flash", + .parts = netspace_v2_flash_parts, + .nr_parts = ARRAY_SIZE(netspace_v2_flash_parts), +}; + +static struct spi_board_info __initdata netspace_v2_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &netspace_v2_flash, + .irq = -1, + .max_speed_hz = 20000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data netspace_v2_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +/***************************************************************************** + * I2C devices + ****************************************************************************/ + +static struct at24_platform_data at24c04 = { + .byte_len = SZ_4K / 8, + .page_size = 16, +}; + +/* + * i2c addr | chip | description + * 0x50 | HT24LC04 | eeprom (512B) + */ + +static struct i2c_board_info __initdata netspace_v2_i2c_info[] = { + { + I2C_BOARD_INFO("24c04", 0x50), + .platform_data = &at24c04, + } +}; + +/***************************************************************************** + * SATA + ****************************************************************************/ + +static struct mv_sata_platform_data netspace_v2_sata_data = { + .n_ports = 2, +}; + +#define NETSPACE_V2_GPIO_SATA0_POWER 16 +#define NETSPACE_V2_GPIO_SATA1_POWER 17 + +static void __init netspace_v2_sata_power_init(void) +{ + int err; + + err = gpio_request(NETSPACE_V2_GPIO_SATA0_POWER, "SATA0 power"); + if (err == 0) { + err = gpio_direction_output(NETSPACE_V2_GPIO_SATA0_POWER, 1); + if (err) + gpio_free(NETSPACE_V2_GPIO_SATA0_POWER); + } + if (err) + pr_err("netspace_v2: failed to setup SATA0 power\n"); +} + +/***************************************************************************** + * GPIO keys + ****************************************************************************/ + +#define NETSPACE_V2_PUSH_BUTTON 32 + +static struct gpio_keys_button netspace_v2_buttons[] = { + [0] = { + .code = KEY_POWER, + .gpio = NETSPACE_V2_PUSH_BUTTON, + .desc = "Power push button", + .active_low = 0, + }, +}; + +static struct gpio_keys_platform_data netspace_v2_button_data = { + .buttons = netspace_v2_buttons, + .nbuttons = ARRAY_SIZE(netspace_v2_buttons), +}; + +static struct platform_device netspace_v2_gpio_buttons = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &netspace_v2_button_data, + }, +}; + +/***************************************************************************** + * GPIO LEDs + ****************************************************************************/ + +/* + * The blue front LED is wired to a CPLD and can blink in relation with the + * SATA activity. + * + * The following array detail the different LED registers and the combination + * of their possible values: + * + * cmd_led | slow_led | /SATA active | LED state + * | | | + * 1 | 0 | x | off + * - | 1 | x | on + * 0 | 0 | 1 | on + * 0 | 0 | 0 | blink (rate 300ms) + */ + +#define NETSPACE_V2_GPIO_RED_LED 12 +#define NETSPACE_V2_GPIO_BLUE_LED_SLOW 29 +#define NETSPACE_V2_GPIO_BLUE_LED_CMD 30 + + +static struct gpio_led netspace_v2_gpio_led_pins[] = { + { + .name = "ns_v2:red:fail", + .gpio = NETSPACE_V2_GPIO_RED_LED, + }, +}; + +static struct gpio_led_platform_data netspace_v2_gpio_leds_data = { + .num_leds = ARRAY_SIZE(netspace_v2_gpio_led_pins), + .leds = netspace_v2_gpio_led_pins, +}; + +static struct platform_device netspace_v2_gpio_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &netspace_v2_gpio_leds_data, + }, +}; + +static void __init netspace_v2_gpio_leds_init(void) +{ + platform_device_register(&netspace_v2_gpio_leds); + + /* + * Configure the front blue LED to blink in relation with the SATA + * activity. + */ + if (gpio_request(NETSPACE_V2_GPIO_BLUE_LED_SLOW, + "SATA blue LED slow") != 0) + return; + if (gpio_direction_output(NETSPACE_V2_GPIO_BLUE_LED_SLOW, 0) != 0) + goto err_free_1; + if (gpio_request(NETSPACE_V2_GPIO_BLUE_LED_CMD, + "SATA blue LED command") != 0) + goto err_free_1; + if (gpio_direction_output(NETSPACE_V2_GPIO_BLUE_LED_CMD, 0) != 0) + goto err_free_2; + + return; + +err_free_2: + gpio_free(NETSPACE_V2_GPIO_BLUE_LED_CMD); +err_free_1: + gpio_free(NETSPACE_V2_GPIO_BLUE_LED_SLOW); + pr_err("netspace_v2: failed to configure SATA blue LED\n"); +} + +/***************************************************************************** + * Timer + ****************************************************************************/ + +static void netspace_v2_timer_init(void) +{ + kirkwood_tclk = 166666667; + orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); +} + +struct sys_timer netspace_v2_timer = { + .init = netspace_v2_timer_init, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +static unsigned int netspace_v2_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP4_NF_IO6, + MPP5_NF_IO7, + MPP6_SYSRST_OUTn, + MPP8_TW_SDA, + MPP9_TW_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP12_GPO, /* Red led */ + MPP14_GPIO, /* USB fuse */ + MPP16_GPIO, /* SATA 0 power */ + MPP18_NF_IO0, + MPP19_NF_IO1, + MPP20_SATA1_ACTn, + MPP21_SATA0_ACTn, + MPP24_GPIO, /* USB mode select */ + MPP25_GPIO, /* Fan rotation fail */ + MPP26_GPIO, /* USB device vbus */ + MPP28_GPIO, /* USB enable host vbus */ + MPP29_GPIO, /* Blue led (slow register) */ + MPP30_GPIO, /* Blue led (command register) */ + MPP31_GPIO, /* Board power off */ + MPP32_GPIO, /* Power button (0 = Released, 1 = Pushed) */ + 0 +}; + +#define NETSPACE_V2_GPIO_POWER_OFF 31 + +static void netspace_v2_power_off(void) +{ + gpio_set_value(NETSPACE_V2_GPIO_POWER_OFF, 1); +} + +static void __init netspace_v2_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(netspace_v2_mpp_config); + + netspace_v2_sata_power_init(); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&netspace_v2_ge00_data); + kirkwood_sata_init(&netspace_v2_sata_data); + kirkwood_uart0_init(); + spi_register_board_info(netspace_v2_spi_slave_info, + ARRAY_SIZE(netspace_v2_spi_slave_info)); + kirkwood_spi_init(); + kirkwood_i2c_init(); + i2c_register_board_info(0, netspace_v2_i2c_info, + ARRAY_SIZE(netspace_v2_i2c_info)); + + netspace_v2_gpio_leds_init(); + platform_device_register(&netspace_v2_gpio_buttons); + + if (gpio_request(NETSPACE_V2_GPIO_POWER_OFF, "power-off") == 0 && + gpio_direction_output(NETSPACE_V2_GPIO_POWER_OFF, 0) == 0) + pm_power_off = netspace_v2_power_off; + else + pr_err("netspace_v2: failed to configure power-off GPIO\n"); +} + +MACHINE_START(NETSPACE_V2, "LaCie Network Space v2") + .phys_io = KIRKWOOD_REGS_PHYS_BASE, + .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = netspace_v2_init, + .map_io = kirkwood_map_io, + .init_irq = kirkwood_init_irq, + .timer = &netspace_v2_timer, +MACHINE_END -- cgit v0.10.2 From dd7f59435782a02ceb6d16b9ce823dd3345d75ec Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 10 Dec 2009 23:20:52 -0500 Subject: ring-buffer: Move resize integrity check under reader lock While using an application that does splice on the ftrace ring buffer at start up, I triggered an integrity check failure. Looking into this, I discovered that resizing the buffer performs an integrity check after the buffer is resized. This check unfortunately is preformed after it releases the reader lock. If a reader is reading the buffer it may cause the integrity check to trigger a false failure. This patch simply moves the integrity checker under the protection of the ring buffer reader lock. Signed-off-by: Steven Rostedt diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 0d64c51..eccb4cf 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1208,9 +1208,9 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages) return; rb_reset_cpu(cpu_buffer); - spin_unlock_irq(&cpu_buffer->reader_lock); - rb_check_pages(cpu_buffer); + + spin_unlock_irq(&cpu_buffer->reader_lock); } static void @@ -1233,9 +1233,9 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer, list_add_tail(&bpage->list, cpu_buffer->pages); } rb_reset_cpu(cpu_buffer); - spin_unlock_irq(&cpu_buffer->reader_lock); - rb_check_pages(cpu_buffer); + + spin_unlock_irq(&cpu_buffer->reader_lock); } /** -- cgit v0.10.2 From c4da6940a7a41c72781ff2d62ebd4b99f3749f14 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 17 Nov 2009 17:05:14 -0700 Subject: PNPACPI: save struct acpi_device, not just acpi_handle Some drivers need to look at things in the acpi_device structure besides the handle. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 83b8b5a..b2348fc 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -80,7 +80,8 @@ static int pnpacpi_get_resources(struct pnp_dev *dev) static int pnpacpi_set_resources(struct pnp_dev *dev) { - acpi_handle handle = dev->data; + struct acpi_device *acpi_dev = dev->data; + acpi_handle handle = acpi_dev->handle; struct acpi_buffer buffer; int ret; @@ -103,7 +104,8 @@ static int pnpacpi_set_resources(struct pnp_dev *dev) static int pnpacpi_disable_resources(struct pnp_dev *dev) { - acpi_handle handle = dev->data; + struct acpi_device *acpi_dev = dev->data; + acpi_handle handle = acpi_dev->handle; int ret; dev_dbg(&dev->dev, "disable resources\n"); @@ -121,6 +123,8 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev) #ifdef CONFIG_ACPI_SLEEP static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) { + struct acpi_device *acpi_dev = dev->data; + acpi_handle handle = acpi_dev->handle; int power_state; power_state = acpi_pm_device_sleep_state(&dev->dev, NULL); @@ -128,12 +132,15 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) power_state = (state.event == PM_EVENT_ON) ? ACPI_STATE_D0 : ACPI_STATE_D3; - return acpi_bus_set_power((acpi_handle) dev->data, power_state); + return acpi_bus_set_power(handle, power_state); } static int pnpacpi_resume(struct pnp_dev *dev) { - return acpi_bus_set_power((acpi_handle) dev->data, ACPI_STATE_D0); + struct acpi_device *acpi_dev = dev->data; + acpi_handle handle = acpi_dev->handle; + + return acpi_bus_set_power(handle, ACPI_STATE_D0); } #endif @@ -168,7 +175,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device) if (!dev) return -ENOMEM; - dev->data = device->handle; + dev->data = device; /* .enabled means the device can decode the resources */ dev->active = device->status.enabled; status = acpi_get_handle(device->handle, "_SRS", &temp); diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index ef3a2cd3a..5702b2c 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -465,7 +465,8 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, int pnpacpi_parse_allocated_resource(struct pnp_dev *dev) { - acpi_handle handle = dev->data; + struct acpi_device *acpi_dev = dev->data; + acpi_handle handle = acpi_dev->handle; acpi_status status; pnp_dbg(&dev->dev, "parse allocated resources\n"); @@ -773,7 +774,8 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev) { - acpi_handle handle = dev->data; + struct acpi_device *acpi_dev = dev->data; + acpi_handle handle = acpi_dev->handle; acpi_status status; struct acpipnp_parse_option_s parse_data; @@ -845,7 +847,8 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data) int pnpacpi_build_resource_template(struct pnp_dev *dev, struct acpi_buffer *buffer) { - acpi_handle handle = dev->data; + struct acpi_device *acpi_dev = dev->data; + acpi_handle handle = acpi_dev->handle; struct acpi_resource *resource; int res_cnt = 0; acpi_status status; -- cgit v0.10.2 From d580cd96c8ee0c2647b810a2a8762cf631a5f97b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 11 Dec 2009 15:25:41 +0900 Subject: sh: ftrace: Fix up syscall tracing build. Syscall tracing metadata was shuffled around, update accordingly. Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c index b6f41c1..a48cded 100644 --- a/arch/sh/kernel/ftrace.c +++ b/arch/sh/kernel/ftrace.c @@ -401,82 +401,10 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ #ifdef CONFIG_FTRACE_SYSCALLS - -extern unsigned long __start_syscalls_metadata[]; -extern unsigned long __stop_syscalls_metadata[]; extern unsigned long *sys_call_table; -static struct syscall_metadata **syscalls_metadata; - -static struct syscall_metadata *find_syscall_meta(unsigned long *syscall) -{ - struct syscall_metadata *start; - struct syscall_metadata *stop; - char str[KSYM_SYMBOL_LEN]; - - - start = (struct syscall_metadata *)__start_syscalls_metadata; - stop = (struct syscall_metadata *)__stop_syscalls_metadata; - kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str); - - for ( ; start < stop; start++) { - if (start->name && !strcmp(start->name, str)) - return start; - } - - return NULL; -} - -struct syscall_metadata *syscall_nr_to_meta(int nr) -{ - if (!syscalls_metadata || nr >= FTRACE_SYSCALL_MAX || nr < 0) - return NULL; - - return syscalls_metadata[nr]; -} - -int syscall_name_to_nr(char *name) -{ - int i; - - if (!syscalls_metadata) - return -1; - for (i = 0; i < NR_syscalls; i++) - if (syscalls_metadata[i]) - if (!strcmp(syscalls_metadata[i]->name, name)) - return i; - return -1; -} - -void set_syscall_enter_id(int num, int id) -{ - syscalls_metadata[num]->enter_id = id; -} - -void set_syscall_exit_id(int num, int id) -{ - syscalls_metadata[num]->exit_id = id; -} - -static int __init arch_init_ftrace_syscalls(void) +unsigned long __init arch_syscall_addr(int nr) { - int i; - struct syscall_metadata *meta; - unsigned long **psys_syscall_table = &sys_call_table; - - syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * - FTRACE_SYSCALL_MAX, GFP_KERNEL); - if (!syscalls_metadata) { - WARN_ON(1); - return -ENOMEM; - } - - for (i = 0; i < FTRACE_SYSCALL_MAX; i++) { - meta = find_syscall_meta(psys_syscall_table[i]); - syscalls_metadata[i] = meta; - } - - return 0; + return (unsigned long)sys_call_table[nr]; } -arch_initcall(arch_init_ftrace_syscalls); #endif /* CONFIG_FTRACE_SYSCALLS */ -- cgit v0.10.2 From ddb4f0f0e05871c7ac540cc778993c06ff53b765 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 4 Dec 2009 19:44:41 +0100 Subject: sh: DMA driver has to specify its alignment requirements The SH DMA driver by default uses 32-byte transfers, in this mode buffers and sizes have to be 32-byte aligned. Specifying this requirement also fixes Oopses with dmatest. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Dan Williams diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index b3b065c..f5fae12 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -677,6 +677,8 @@ static int __init sh_dmae_probe(struct platform_device *pdev) shdev->common.device_is_tx_complete = sh_dmae_is_complete; shdev->common.device_issue_pending = sh_dmae_memcpy_issue_pending; shdev->common.dev = &pdev->dev; + /* Default transfer size of 32 bytes requires 32-byte alignment */ + shdev->common.copy_align = 5; #if defined(CONFIG_CPU_SH4) /* Non Mix IRQ mode SH7722/SH7730 etc... */ -- cgit v0.10.2 From cfe4f2751ef1a5390b56c5d263f90b6ff138ba31 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 4 Dec 2009 19:44:48 +0100 Subject: dmaengine: fix dmatest to verify minimum transfer length and test buffer size Transfers and the test buffer have to be at least align bytes long. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Dan Williams diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index a32a4cf..8b90516 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c @@ -298,10 +298,6 @@ static int dmatest_func(void *data) total_tests++; - len = dmatest_random() % test_buf_size + 1; - src_off = dmatest_random() % (test_buf_size - len + 1); - dst_off = dmatest_random() % (test_buf_size - len + 1); - /* honor alignment restrictions */ if (thread->type == DMA_MEMCPY) align = dev->copy_align; @@ -310,7 +306,19 @@ static int dmatest_func(void *data) else if (thread->type == DMA_PQ) align = dev->pq_align; + if (1 << align > test_buf_size) { + pr_err("%u-byte buffer too small for %d-byte alignment\n", + test_buf_size, 1 << align); + break; + } + + len = dmatest_random() % test_buf_size + 1; len = (len >> align) << align; + if (!len) + len = 1 << align; + src_off = dmatest_random() % (test_buf_size - len + 1); + dst_off = dmatest_random() % (test_buf_size - len + 1); + src_off = (src_off >> align) << align; dst_off = (dst_off >> align) << align; -- cgit v0.10.2 From c89fbd3987d058fad3ea072aab68adfbdd13e498 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 11 Dec 2009 15:29:31 +0900 Subject: sh: Wire up recvmmsg syscall. The stub already existed in the _64 syscall table, but was lacking a __NR_recvmmsg definition, while it was absent entirely for _32 variants. Signed-off-by: Paul Mundt diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h index f3fd1b9..f18c4f9 100644 --- a/arch/sh/include/asm/unistd_32.h +++ b/arch/sh/include/asm/unistd_32.h @@ -345,8 +345,9 @@ #define __NR_pwritev 334 #define __NR_rt_tgsigqueueinfo 335 #define __NR_perf_event_open 336 +#define __NR_recvmmsg 337 -#define NR_syscalls 337 +#define NR_syscalls 338 #ifdef __KERNEL__ diff --git a/arch/sh/include/asm/unistd_64.h b/arch/sh/include/asm/unistd_64.h index 343ce8f..3e7645d 100644 --- a/arch/sh/include/asm/unistd_64.h +++ b/arch/sh/include/asm/unistd_64.h @@ -385,10 +385,11 @@ #define __NR_pwritev 362 #define __NR_rt_tgsigqueueinfo 363 #define __NR_perf_event_open 364 +#define __NR_recvmmsg 365 #ifdef __KERNEL__ -#define NR_syscalls 365 +#define NR_syscalls 366 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index 19fd11d..4bd5a11 100644 --- a/arch/sh/kernel/syscalls_32.S +++ b/arch/sh/kernel/syscalls_32.S @@ -353,3 +353,4 @@ ENTRY(sys_call_table) .long sys_pwritev .long sys_rt_tgsigqueueinfo /* 335 */ .long sys_perf_event_open + .long sys_recvmmsg -- cgit v0.10.2 From 86d61b33e48f1da5a6b310d3de93187db62ab72a Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 10 Dec 2009 18:35:07 +0100 Subject: sh: stylistic improvements for the DMA driver Signed-off-by: Guennadi Liakhovetski Signed-off-by: Dan Williams diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index f5fae12..8d9acd7 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -80,17 +80,17 @@ static int sh_dmae_rst(int id) unsigned short dmaor; sh_dmae_ctl_stop(id); - dmaor = (dmaor_read_reg(id)|DMAOR_INIT); + dmaor = dmaor_read_reg(id) | DMAOR_INIT; dmaor_write_reg(id, dmaor); - if ((dmaor_read_reg(id) & (DMAOR_AE | DMAOR_NMIF))) { + if (dmaor_read_reg(id) & (DMAOR_AE | DMAOR_NMIF)) { pr_warning(KERN_ERR "dma-sh: Can't initialize DMAOR.\n"); return -EINVAL; } return 0; } -static int dmae_is_idle(struct sh_dmae_chan *sh_chan) +static int dmae_is_busy(struct sh_dmae_chan *sh_chan) { u32 chcr = sh_dmae_readl(sh_chan, CHCR); if (chcr & CHCR_DE) { @@ -110,15 +110,14 @@ static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs hw) { sh_dmae_writel(sh_chan, hw.sar, SAR); sh_dmae_writel(sh_chan, hw.dar, DAR); - sh_dmae_writel(sh_chan, - (hw.tcr >> calc_xmit_shift(sh_chan)), TCR); + sh_dmae_writel(sh_chan, hw.tcr >> calc_xmit_shift(sh_chan), TCR); } static void dmae_start(struct sh_dmae_chan *sh_chan) { u32 chcr = sh_dmae_readl(sh_chan, CHCR); - chcr |= (CHCR_DE|CHCR_IE); + chcr |= CHCR_DE | CHCR_IE; sh_dmae_writel(sh_chan, chcr, CHCR); } @@ -132,7 +131,7 @@ static void dmae_halt(struct sh_dmae_chan *sh_chan) static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val) { - int ret = dmae_is_idle(sh_chan); + int ret = dmae_is_busy(sh_chan); /* When DMA was working, can not set data to CHCR */ if (ret) return ret; @@ -149,7 +148,7 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) { u32 addr; int shift = 0; - int ret = dmae_is_idle(sh_chan); + int ret = dmae_is_busy(sh_chan); if (ret) return ret; @@ -307,7 +306,7 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_memcpy( new = sh_dmae_get_desc(sh_chan); if (!new) { dev_err(sh_chan->dev, - "No free memory for link descriptor\n"); + "No free memory for link descriptor\n"); goto err_get_desc; } @@ -388,7 +387,7 @@ static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) struct sh_dmae_regs hw; /* DMA work check */ - if (dmae_is_idle(sh_chan)) + if (dmae_is_busy(sh_chan)) return; /* Find the first un-transfer desciptor */ @@ -497,8 +496,9 @@ static void dmae_do_tasklet(unsigned long data) struct sh_dmae_chan *sh_chan = (struct sh_dmae_chan *)data; struct sh_desc *desc, *_desc, *cur_desc = NULL; u32 sar_buf = sh_dmae_readl(sh_chan, SAR); + list_for_each_entry_safe(desc, _desc, - &sh_chan->ld_queue, node) { + &sh_chan->ld_queue, node) { if ((desc->hw.sar + desc->hw.tcr) == sar_buf) { cur_desc = desc; break; @@ -543,8 +543,8 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id) /* alloc channel */ new_sh_chan = kzalloc(sizeof(struct sh_dmae_chan), GFP_KERNEL); if (!new_sh_chan) { - dev_err(shdev->common.dev, "No free memory for allocating " - "dma channels!\n"); + dev_err(shdev->common.dev, + "No free memory for allocating dma channels!\n"); return -ENOMEM; } @@ -586,8 +586,8 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id) "sh-dmae%d", new_sh_chan->id); /* set up channel irq */ - err = request_irq(irq, &sh_dmae_interrupt, - irqflags, new_sh_chan->dev_id, new_sh_chan); + err = request_irq(irq, &sh_dmae_interrupt, irqflags, + new_sh_chan->dev_id, new_sh_chan); if (err) { dev_err(shdev->common.dev, "DMA channel %d request_irq error " "with return %d\n", id, err); @@ -691,8 +691,8 @@ static int __init sh_dmae_probe(struct platform_device *pdev) } for (ecnt = 0 ; ecnt < ARRAY_SIZE(eirq); ecnt++) { - err = request_irq(eirq[ecnt], sh_dmae_err, - irqflags, "DMAC Address Error", shdev); + err = request_irq(eirq[ecnt], sh_dmae_err, irqflags, + "DMAC Address Error", shdev); if (err) { dev_err(&pdev->dev, "DMA device request_irq" "error (irq %d) with return %d\n", diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h index 2b4bc15..60b81e5 100644 --- a/drivers/dma/shdma.h +++ b/drivers/dma/shdma.h @@ -35,15 +35,15 @@ struct sh_desc { struct sh_dmae_chan { dma_cookie_t completed_cookie; /* The maximum cookie completed */ - spinlock_t desc_lock; /* Descriptor operation lock */ - struct list_head ld_queue; /* Link descriptors queue */ - struct list_head ld_free; /* Link descriptors free */ - struct dma_chan common; /* DMA common channel */ - struct device *dev; /* Channel device */ + spinlock_t desc_lock; /* Descriptor operation lock */ + struct list_head ld_queue; /* Link descriptors queue */ + struct list_head ld_free; /* Link descriptors free */ + struct dma_chan common; /* DMA common channel */ + struct device *dev; /* Channel device */ struct tasklet_struct tasklet; /* Tasklet */ - int descs_allocated; /* desc count */ + int descs_allocated; /* desc count */ int id; /* Raw id of this channel */ - char dev_id[16]; /* unique name per DMAC of channel */ + char dev_id[16]; /* unique name per DMAC of channel */ /* Set chcr */ int (*set_chcr)(struct sh_dmae_chan *sh_chan, u32 regs); -- cgit v0.10.2 From a88f6667078412e5eff37ead68a043ee0ec9f1da Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 10 Dec 2009 18:35:15 +0100 Subject: dmaengine: clarify the meaning of the DMA_CTRL_ACK flag DMA_CTRL_ACK's description applies to its clear state, not to its set state. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Dan Williams diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 2b9f2ac..7878498 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -74,7 +74,7 @@ enum dma_transaction_type { * control completion, and communicate status. * @DMA_PREP_INTERRUPT - trigger an interrupt (callback) upon completion of * this transaction - * @DMA_CTRL_ACK - the descriptor cannot be reused until the client + * @DMA_CTRL_ACK - if clear, the descriptor cannot be reused until the client * acknowledges receipt, i.e. has has a chance to establish any dependency * chains * @DMA_COMPL_SKIP_SRC_UNMAP - set to disable dma-unmapping the source buffer(s) -- cgit v0.10.2 From a1a541d86f50a9957beeedb122a035870d602647 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 2 Dec 2009 13:31:00 +0800 Subject: ACPI: support customizing ACPI control methods at runtime Introduce a new debugfs I/F (/sys/kernel/debug/acpi/custom_method) for ACPI, which can be used to customize the ACPI control methods at runtime. We can use this to debug the AML code level bugs instead of overriding the whole DSDT table, without rebuilding/rebooting kernel any more. Detailed description about how to use this debugfs I/F is stated in Documentation/acpi/method-customizing.txt Signed-off-by: Zhang Rui Signed-off-by: Len Brown diff --git a/Documentation/acpi/method-customizing.txt b/Documentation/acpi/method-customizing.txt new file mode 100644 index 0000000..e628cd2 --- /dev/null +++ b/Documentation/acpi/method-customizing.txt @@ -0,0 +1,66 @@ +Linux ACPI Custom Control Method How To +======================================= + +Written by Zhang Rui + + +Linux supports customizing ACPI control methods at runtime. + +Users can use this to +1. override an existing method which may not work correctly, + or just for debugging purposes. +2. insert a completely new method in order to create a missing + method such as _OFF, _ON, _STA, _INI, etc. +For these cases, it is far simpler to dynamically install a single +control method rather than override the entire DSDT, because kernel +rebuild/reboot is not needed and test result can be got in minutes. + +Note: Only ACPI METHOD can be overridden, any other object types like + "Device", "OperationRegion", are not recognized. +Note: The same ACPI control method can be overridden for many times, + and it's always the latest one that used by Linux/kernel. + +1. override an existing method + a) get the ACPI table via ACPI sysfs I/F. e.g. to get the DSDT, + just run "cat /sys/firmware/acpi/tables/DSDT > /tmp/dsdt.dat" + b) disassemble the table by running "iasl -d dsdt.dat". + c) rewrite the ASL code of the method and save it in a new file, + d) package the new file (psr.asl) to an ACPI table format. + Here is an example of a customized \_SB._AC._PSR method, + + DefinitionBlock ("", "SSDT", 1, "", "", 0x20080715) + { + External (ACON) + + Method (\_SB_.AC._PSR, 0, NotSerialized) + { + Store ("In AC _PSR", Debug) + Return (ACON) + } + } + Note that the full pathname of the method in ACPI namespace + should be used. + And remember to use "External" to declare external objects. + e) assemble the file to generate the AML code of the method. + e.g. "iasl psr.asl" (psr.aml is generated as a result) + f) mount debugfs by "mount -t debugfs none /sys/kernel/debug" + g) override the old method via the debugfs by running + "cat /tmp/psr.aml > /sys/kernel/debug/acpi/custom_method" + +2. insert a new method + This is easier than overriding an existing method. + We just need to create the ASL code of the method we want to + insert and then follow the step c) ~ g) in section 1. + +3. undo your changes + The "undo" operation is not supported for a new inserted method + right now, i.e. we can not remove a method currently. + For an overrided method, in order to undo your changes, please + save a copy of the method original ASL code in step c) section 1, + and redo step c) ~ g) to override the method with the original one. + + +Note: We can use a kernel with multiple custom ACPI method running, + But each individual write to debugfs can implement a SINGLE + method override. i.e. if we want to insert/override multiple + ACPI methods, we need to redo step c) ~ g) for multiple times. diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index 8a690c3..0bedd15 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -196,6 +197,79 @@ module_param_call(trace_state, param_set_trace_state, param_get_trace_state, NULL, 0644); /* -------------------------------------------------------------------------- + DebugFS Interface + -------------------------------------------------------------------------- */ + +static ssize_t cm_write(struct file *file, const char __user *user_buf, + size_t count, loff_t *ppos) +{ + static char *buf; + static int uncopied_bytes; + struct acpi_table_header table; + acpi_status status; + + if (!(*ppos)) { + /* parse the table header to get the table length */ + if (count <= sizeof(struct acpi_table_header)) + return -EINVAL; + if (copy_from_user(&table, user_buf, + sizeof(struct acpi_table_header))) + return -EFAULT; + uncopied_bytes = table.length; + buf = kzalloc(uncopied_bytes, GFP_KERNEL); + if (!buf) + return -ENOMEM; + } + + if (uncopied_bytes < count) { + kfree(buf); + return -EINVAL; + } + + if (copy_from_user(buf + (*ppos), user_buf, count)) { + kfree(buf); + return -EFAULT; + } + + uncopied_bytes -= count; + *ppos += count; + + if (!uncopied_bytes) { + status = acpi_install_method(buf); + kfree(buf); + if (ACPI_FAILURE(status)) + return -EINVAL; + } + + return count; +} + +static const struct file_operations cm_fops = { + .write = cm_write, +}; + +static int acpi_debugfs_init(void) +{ + struct dentry *acpi_dir, *cm_dentry; + + acpi_dir = debugfs_create_dir("acpi", NULL); + if (!acpi_dir) + goto err; + + cm_dentry = debugfs_create_file("custom_method", S_IWUGO, + acpi_dir, NULL, &cm_fops); + if (!cm_dentry) + goto err; + + return 0; + +err: + if (acpi_dir) + debugfs_remove(acpi_dir); + return -EINVAL; +} + +/* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ #ifdef CONFIG_ACPI_PROCFS @@ -286,7 +360,7 @@ static const struct file_operations acpi_system_debug_proc_fops = { }; #endif -int __init acpi_debug_init(void) +int __init acpi_procfs_init(void) { #ifdef CONFIG_ACPI_PROCFS struct proc_dir_entry *entry; @@ -321,3 +395,10 @@ int __init acpi_debug_init(void) return 0; #endif } + +int __init acpi_debug_init(void) +{ + acpi_debugfs_init(); + acpi_procfs_init(); + return 0; +} -- cgit v0.10.2 From fb34035e7b4bb3edc7c2dc0683cfe21f57a9574d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 10 Dec 2009 23:05:23 -0800 Subject: sparc: Use __builtin_object_size() to validate the buffer size for copy_from_user() This mirrors x86 commit 9f0cf4adb6aa0bfccf675c938124e68f7f06349d (x86: Use __builtin_object_size() to validate the buffer size for copy_from_user()) Signed-off-by: David S. Miller diff --git a/arch/sparc/Kconfig.debug b/arch/sparc/Kconfig.debug index 90d5fe2..9d3c889 100644 --- a/arch/sparc/Kconfig.debug +++ b/arch/sparc/Kconfig.debug @@ -33,4 +33,18 @@ config FRAME_POINTER depends on MCOUNT default y +config DEBUG_STRICT_USER_COPY_CHECKS + bool "Strict copy size checks" + depends on DEBUG_KERNEL && !TRACE_BRANCH_PROFILING + ---help--- + Enabling this option turns a certain set of sanity checks for user + copy operations into compile time failures. + + The copy_from_user() etc checks are there to help test if there + are sufficient security checks on the length argument of + the copy operation, by having gcc prove that the argument is + within bounds. + + If unsure, or if you run an older (pre 4.4) gcc, say N. + endmenu diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h index 8303ac4..489d2ba 100644 --- a/arch/sparc/include/asm/uaccess_32.h +++ b/arch/sparc/include/asm/uaccess_32.h @@ -260,8 +260,23 @@ static inline unsigned long __copy_to_user(void __user *to, const void *from, un return __copy_user(to, (__force void __user *) from, n); } +extern void copy_from_user_overflow(void) +#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS + __compiletime_error("copy_from_user() buffer size is not provably correct") +#else + __compiletime_warning("copy_from_user() buffer size is not provably correct") +#endif +; + static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) { + int sz = __compiletime_object_size(to); + + if (unlikely(sz != -1 && sz < n)) { + copy_from_user_overflow(); + return -EFAULT; + } + if (n && __access_ok((unsigned long) from, n)) return __copy_user((__force void __user *) to, from, n); else diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h index 9ea271e..dbc1416 100644 --- a/arch/sparc/include/asm/uaccess_64.h +++ b/arch/sparc/include/asm/uaccess_64.h @@ -6,6 +6,7 @@ */ #ifdef __KERNEL__ +#include #include #include #include @@ -204,6 +205,14 @@ __asm__ __volatile__( \ extern int __get_user_bad(void); +extern void copy_from_user_overflow(void) +#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS + __compiletime_error("copy_from_user() buffer size is not provably correct") +#else + __compiletime_warning("copy_from_user() buffer size is not provably correct") +#endif +; + extern unsigned long __must_check ___copy_from_user(void *to, const void __user *from, unsigned long size); @@ -212,10 +221,16 @@ extern unsigned long copy_from_user_fixup(void *to, const void __user *from, static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long size) { - unsigned long ret = ___copy_from_user(to, from, size); - - if (unlikely(ret)) - ret = copy_from_user_fixup(to, from, size); + unsigned long ret = (unsigned long) -EFAULT; + int sz = __compiletime_object_size(to); + + if (likely(sz == -1 || sz >= size)) { + ret = ___copy_from_user(to, from, size); + if (unlikely(ret)) + ret = copy_from_user_fixup(to, from, size); + } else { + copy_from_user_overflow(); + } return ret; } #define __copy_from_user copy_from_user diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index e75faf0..c4b5e03 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -44,3 +44,4 @@ obj-y += iomap.o obj-$(CONFIG_SPARC32) += atomic32.o obj-y += ksyms.o obj-$(CONFIG_SPARC64) += PeeCeeI.o +obj-y += usercopy.o diff --git a/arch/sparc/lib/usercopy.c b/arch/sparc/lib/usercopy.c new file mode 100644 index 0000000..14b363f --- /dev/null +++ b/arch/sparc/lib/usercopy.c @@ -0,0 +1,8 @@ +#include +#include + +void copy_from_user_overflow(void) +{ + WARN(1, "Buffer overflow detected!\n"); +} +EXPORT_SYMBOL(copy_from_user_overflow); -- cgit v0.10.2 From 4d14a459857bd151ecbd14bcd37b4628da00792b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 10 Dec 2009 23:32:10 -0800 Subject: sparc: Stop trying to be so fancy and use __builtin_{memcpy,memset}() This mirrors commit ff60fab71bb3b4fdbf8caf57ff3739ffd0887396 (x86: Use __builtin_memset and __builtin_memcpy for memset/memcpy) Signed-off-by: David S. Miller diff --git a/arch/sparc/include/asm/string_32.h b/arch/sparc/include/asm/string_32.h index 6c5fddb..edf196e 100644 --- a/arch/sparc/include/asm/string_32.h +++ b/arch/sparc/include/asm/string_32.h @@ -16,8 +16,6 @@ #ifdef __KERNEL__ extern void __memmove(void *,const void *,__kernel_size_t); -extern __kernel_size_t __memcpy(void *,const void *,__kernel_size_t); -extern __kernel_size_t __memset(void *,int,__kernel_size_t); #ifndef EXPORT_SYMTAB_STROPS @@ -32,82 +30,10 @@ extern __kernel_size_t __memset(void *,int,__kernel_size_t); }) #define __HAVE_ARCH_MEMCPY - -static inline void *__constant_memcpy(void *to, const void *from, __kernel_size_t n) -{ - extern void __copy_1page(void *, const void *); - - if(n <= 32) { - __builtin_memcpy(to, from, n); - } else if (((unsigned int) to & 7) != 0) { - /* Destination is not aligned on the double-word boundary */ - __memcpy(to, from, n); - } else { - switch(n) { - case PAGE_SIZE: - __copy_1page(to, from); - break; - default: - __memcpy(to, from, n); - break; - } - } - return to; -} - -static inline void *__nonconstant_memcpy(void *to, const void *from, __kernel_size_t n) -{ - __memcpy(to, from, n); - return to; -} - -#undef memcpy -#define memcpy(t, f, n) \ -(__builtin_constant_p(n) ? \ - __constant_memcpy((t),(f),(n)) : \ - __nonconstant_memcpy((t),(f),(n))) +#define memcpy(t, f, n) __builtin_memcpy(t, f, n) #define __HAVE_ARCH_MEMSET - -static inline void *__constant_c_and_count_memset(void *s, char c, __kernel_size_t count) -{ - extern void bzero_1page(void *); - extern __kernel_size_t __bzero(void *, __kernel_size_t); - - if(!c) { - if(count == PAGE_SIZE) - bzero_1page(s); - else - __bzero(s, count); - } else { - __memset(s, c, count); - } - return s; -} - -static inline void *__constant_c_memset(void *s, char c, __kernel_size_t count) -{ - extern __kernel_size_t __bzero(void *, __kernel_size_t); - - if(!c) - __bzero(s, count); - else - __memset(s, c, count); - return s; -} - -static inline void *__nonconstant_memset(void *s, char c, __kernel_size_t count) -{ - __memset(s, c, count); - return s; -} - -#undef memset -#define memset(s, c, count) \ -(__builtin_constant_p(c) ? (__builtin_constant_p(count) ? \ - __constant_c_and_count_memset((s), (c), (count)) : \ - __constant_c_memset((s), (c), (count))) \ - : __nonconstant_memset((s), (c), (count))) +#define memset(s, c, count) __builtin_memset(s, c, count) #define __HAVE_ARCH_MEMSCAN diff --git a/arch/sparc/include/asm/string_64.h b/arch/sparc/include/asm/string_64.h index 43161f2..9623bc2 100644 --- a/arch/sparc/include/asm/string_64.h +++ b/arch/sparc/include/asm/string_64.h @@ -15,8 +15,6 @@ #include -extern void *__memset(void *,int,__kernel_size_t); - #ifndef EXPORT_SYMTAB_STROPS /* First the mem*() things. */ @@ -24,29 +22,10 @@ extern void *__memset(void *,int,__kernel_size_t); extern void *memmove(void *, const void *, __kernel_size_t); #define __HAVE_ARCH_MEMCPY -extern void *memcpy(void *, const void *, __kernel_size_t); +#define memcpy(t, f, n) __builtin_memcpy(t, f, n) #define __HAVE_ARCH_MEMSET -extern void *__builtin_memset(void *,int,__kernel_size_t); - -static inline void *__constant_memset(void *s, int c, __kernel_size_t count) -{ - extern __kernel_size_t __bzero(void *, __kernel_size_t); - - if (!c) { - __bzero(s, count); - return s; - } else - return __memset(s, c, count); -} - -#undef memset -#define memset(s, c, count) \ -((__builtin_constant_p(count) && (count) <= 32) ? \ - __builtin_memset((s), (c), (count)) : \ - (__builtin_constant_p(c) ? \ - __constant_memset((s), (c), (count)) : \ - __memset((s), (c), (count)))) +#define memset(s, c, count) __builtin_memset(s, c, count) #define __HAVE_ARCH_MEMSCAN diff --git a/arch/sparc/lib/bzero.S b/arch/sparc/lib/bzero.S index b655729..615f401 100644 --- a/arch/sparc/lib/bzero.S +++ b/arch/sparc/lib/bzero.S @@ -6,10 +6,6 @@ .text - .globl __memset - .type __memset, #function -__memset: /* %o0=buf, %o1=pat, %o2=len */ - .globl memset .type memset, #function memset: /* %o0=buf, %o1=pat, %o2=len */ @@ -83,7 +79,6 @@ __bzero_done: retl mov %o3, %o0 .size __bzero, .-__bzero - .size __memset, .-__memset .size memset, .-memset #define EX_ST(x,y) \ diff --git a/arch/sparc/lib/checksum_32.S b/arch/sparc/lib/checksum_32.S index 77f2285..3632cb3 100644 --- a/arch/sparc/lib/checksum_32.S +++ b/arch/sparc/lib/checksum_32.S @@ -560,7 +560,7 @@ __csum_partial_copy_end: mov %i0, %o1 mov %i1, %o0 5: - call __memcpy + call memcpy mov %i2, %o2 tst %o0 bne,a 2f diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c index 704b126..1b30bb3 100644 --- a/arch/sparc/lib/ksyms.c +++ b/arch/sparc/lib/ksyms.c @@ -30,7 +30,6 @@ EXPORT_SYMBOL(__memscan_generic); EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memset); -EXPORT_SYMBOL(__memset); EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(__bzero); @@ -81,7 +80,6 @@ EXPORT_SYMBOL(__csum_partial_copy_sparc_generic); /* Special internal versions of library functions. */ EXPORT_SYMBOL(__copy_1page); -EXPORT_SYMBOL(__memcpy); EXPORT_SYMBOL(__memmove); EXPORT_SYMBOL(bzero_1page); diff --git a/arch/sparc/lib/memcpy.S b/arch/sparc/lib/memcpy.S index ce10bc8..34fe657 100644 --- a/arch/sparc/lib/memcpy.S +++ b/arch/sparc/lib/memcpy.S @@ -543,9 +543,6 @@ FUNC(memmove) b 3f add %o0, 2, %o0 -#ifdef __KERNEL__ -FUNC(__memcpy) -#endif FUNC(memcpy) /* %o0=dst %o1=src %o2=len */ sub %o0, %o1, %o4 diff --git a/arch/sparc/lib/memset.S b/arch/sparc/lib/memset.S index 1c37ea89..99c017b 100644 --- a/arch/sparc/lib/memset.S +++ b/arch/sparc/lib/memset.S @@ -60,11 +60,10 @@ .globl __bzero_begin __bzero_begin: - .globl __bzero, __memset, + .globl __bzero .globl memset .globl __memset_start, __memset_end __memset_start: -__memset: memset: and %o1, 0xff, %g3 sll %g3, 8, %g2 -- cgit v0.10.2 From c658ad1b4e1520511da8323aa5e60d444cc303ed Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 11 Dec 2009 00:44:47 -0800 Subject: sparc64: Add syscall tracepoint support. Signed-off-by: David S. Miller diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 33ac1a9..108197a 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -43,6 +43,7 @@ config SPARC64 select HAVE_SYSCALL_WRAPPERS select HAVE_DYNAMIC_FTRACE select HAVE_FTRACE_MCOUNT_RECORD + select HAVE_SYSCALL_TRACEPOINTS select USE_GENERIC_SMP_HELPERS if SMP select RTC_DRV_CMOS select RTC_DRV_BQ4802 diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h index 1b45a7b..7257ebb 100644 --- a/arch/sparc/include/asm/thread_info_64.h +++ b/arch/sparc/include/asm/thread_info_64.h @@ -227,6 +227,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); /* flag bit 8 is available */ #define TIF_SECCOMP 9 /* secure computing */ #define TIF_SYSCALL_AUDIT 10 /* syscall auditing active */ +#define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */ /* flag bit 11 is available */ /* NOTE: Thread flags >= 12 should be ones we have no interest * in using in assembly, else we can't use the mask as @@ -246,6 +247,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define _TIF_32BIT (1< #include #include +#include #include @@ -91,3 +92,13 @@ int __init ftrace_dyn_arch_init(void *data) } #endif +#ifdef CONFIG_FTRACE_SYSCALLS + +extern unsigned int sys_call_table[]; + +unsigned long __init arch_syscall_addr(int nr) +{ + return (unsigned long)sys_call_table[nr]; +} + +#endif diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index 4ae91dc..2f6524d 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,9 @@ #include #include +#define CREATE_TRACE_POINTS +#include + #include "entry.h" /* #define ALLOW_INIT_TRACING */ @@ -1059,6 +1063,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) if (test_thread_flag(TIF_SYSCALL_TRACE)) ret = tracehook_report_syscall_entry(regs); + if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) + trace_sys_enter(regs, regs->u_regs[UREG_G1]); + if (unlikely(current->audit_context) && !ret) audit_syscall_entry((test_thread_flag(TIF_32BIT) ? AUDIT_ARCH_SPARC : @@ -1084,6 +1091,9 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs) audit_syscall_exit(result, regs->u_regs[UREG_I0]); } + if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) + trace_sys_exit(regs, regs->u_regs[UREG_G1]); + if (test_thread_flag(TIF_SYSCALL_TRACE)) tracehook_report_syscall_exit(regs, 0); } diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index d150c2a..dc4a458 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -62,7 +62,7 @@ sys32_rt_sigreturn: #endif .align 32 1: ldx [%g6 + TI_FLAGS], %l5 - andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 + andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 be,pt %icc, rtrap nop call syscall_trace_leave @@ -187,7 +187,7 @@ linux_syscall_trace: .globl linux_sparc_syscall32 linux_sparc_syscall32: /* Direct access to user regs, much faster. */ - cmp %g1, NR_SYSCALLS ! IEU1 Group + cmp %g1, NR_syscalls ! IEU1 Group bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI srl %i0, 0, %o0 ! IEU0 sll %g1, 2, %l4 ! IEU0 Group @@ -198,7 +198,7 @@ linux_sparc_syscall32: srl %i5, 0, %o5 ! IEU1 srl %i2, 0, %o2 ! IEU0 Group - andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 bne,pn %icc, linux_syscall_trace32 ! CTI mov %i0, %l5 ! IEU1 call %l7 ! CTI Group brk forced @@ -210,7 +210,7 @@ linux_sparc_syscall32: .globl linux_sparc_syscall linux_sparc_syscall: /* Direct access to user regs, much faster. */ - cmp %g1, NR_SYSCALLS ! IEU1 Group + cmp %g1, NR_syscalls ! IEU1 Group bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI mov %i0, %o0 ! IEU0 sll %g1, 2, %l4 ! IEU0 Group @@ -221,7 +221,7 @@ linux_sparc_syscall: mov %i3, %o3 ! IEU1 mov %i4, %o4 ! IEU0 Group - andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 bne,pn %icc, linux_syscall_trace ! CTI Group mov %i0, %l5 ! IEU0 2: call %l7 ! CTI Group brk forced @@ -245,7 +245,7 @@ ret_sys_call: cmp %o0, -ERESTART_RESTARTBLOCK bgeu,pn %xcc, 1f - andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6 80: /* System call success, clear Carry condition code. */ andn %g3, %g2, %g3 @@ -260,7 +260,7 @@ ret_sys_call: /* System call failure, set Carry condition code. * Also, get abs(errno) to return to the process. */ - andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6 sub %g0, %o0, %o0 or %g3, %g2, %g3 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] -- cgit v0.10.2 From 121dd5f2776522e03970916514b46e355480e538 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 11 Dec 2009 01:07:53 -0800 Subject: sparc: Add alignment and emulation fault perf events. This mirrors commit 196f02bf900c5eb6f85d889c4f70e7cc11fda7e8 (powerpc: perf_event: Add alignment-faults and emulation-faults software events) Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/unaligned_32.c b/arch/sparc/kernel/unaligned_32.c index 6b1e6cd..f8514e2 100644 --- a/arch/sparc/kernel/unaligned_32.c +++ b/arch/sparc/kernel/unaligned_32.c @@ -17,8 +17,7 @@ #include #include #include - -/* #define DEBUG_MNA */ +#include enum direction { load, /* ld, ldd, ldh, ldsh */ @@ -29,12 +28,6 @@ enum direction { invalid, }; -#ifdef DEBUG_MNA -static char *dirstrings[] = { - "load", "store", "both", "fpload", "fpstore", "invalid" -}; -#endif - static inline enum direction decode_direction(unsigned int insn) { unsigned long tmp = (insn >> 21) & 1; @@ -255,10 +248,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) unsigned long addr = compute_effective_address(regs, insn); int err; -#ifdef DEBUG_MNA - printk("KMNA: pc=%08lx [dir=%s addr=%08lx size=%d] retpc[%08lx]\n", - regs->pc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]); -#endif + perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr); switch (dir) { case load: err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f), @@ -350,6 +340,7 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn) } addr = compute_effective_address(regs, insn); + perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr); switch(dir) { case load: err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f), diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index 3792099..378ca82 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c @@ -20,10 +20,9 @@ #include #include #include +#include #include -/* #define DEBUG_MNA */ - enum direction { load, /* ld, ldd, ldh, ldsh */ store, /* st, std, sth, stsh */ @@ -33,12 +32,6 @@ enum direction { invalid, }; -#ifdef DEBUG_MNA -static char *dirstrings[] = { - "load", "store", "both", "fpload", "fpstore", "invalid" -}; -#endif - static inline enum direction decode_direction(unsigned int insn) { unsigned long tmp = (insn >> 21) & 1; @@ -327,12 +320,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) addr = compute_effective_address(regs, insn, ((insn >> 25) & 0x1f)); -#ifdef DEBUG_MNA - printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] " - "retpc[%016lx]\n", - regs->tpc, dirstrings[dir], addr, size, - regs->u_regs[UREG_RETPC]); -#endif + perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, addr); switch (asi) { case ASI_NL: case ASI_AIUPL: @@ -399,6 +387,7 @@ int handle_popc(u32 insn, struct pt_regs *regs) int ret, i, rd = ((insn >> 25) & 0x1f); int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; + perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); if (insn & 0x2000) { maybe_flush_windows(0, 0, rd, from_kernel); value = sign_extend_imm13(insn); @@ -445,6 +434,8 @@ int handle_ldf_stq(u32 insn, struct pt_regs *regs) int asi = decode_asi(insn, regs); int flag = (freg < 32) ? FPRS_DL : FPRS_DU; + perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); + save_and_clear_fpu(); current_thread_info()->xfsr[0] &= ~0x1c000; if (freg & 3) { @@ -566,6 +557,8 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; unsigned long *reg; + perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); + maybe_flush_windows(0, 0, rd, from_kernel); reg = fetch_reg_addr(rd, regs); if (from_kernel || rd < 16) { @@ -596,6 +589,7 @@ void handle_lddfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr if (tstate & TSTATE_PRIV) die_if_kernel("lddfmna from kernel", regs); + perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, sfar); if (test_thread_flag(TIF_32BIT)) pc = (u32)pc; if (get_user(insn, (u32 __user *) pc) != -EFAULT) { @@ -657,6 +651,7 @@ void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr if (tstate & TSTATE_PRIV) die_if_kernel("stdfmna from kernel", regs); + perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, sfar); if (test_thread_flag(TIF_32BIT)) pc = (u32)pc; if (get_user(insn, (u32 __user *) pc) != -EFAULT) { diff --git a/arch/sparc/kernel/visemul.c b/arch/sparc/kernel/visemul.c index d231cbd..9dfd2eb 100644 --- a/arch/sparc/kernel/visemul.c +++ b/arch/sparc/kernel/visemul.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -801,6 +802,8 @@ int vis_emul(struct pt_regs *regs, unsigned int insn) BUG_ON(regs->tstate & TSTATE_PRIV); + perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); + if (test_thread_flag(TIF_32BIT)) pc = (u32)pc; diff --git a/arch/sparc/math-emu/math_32.c b/arch/sparc/math-emu/math_32.c index e13f65d..a3fccde 100644 --- a/arch/sparc/math-emu/math_32.c +++ b/arch/sparc/math-emu/math_32.c @@ -67,6 +67,7 @@ #include #include #include +#include #include #include "sfp-util_32.h" @@ -163,6 +164,8 @@ int do_mathemu(struct pt_regs *regs, struct task_struct *fpt) int retcode = 0; /* assume all succeed */ unsigned long insn; + perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); + #ifdef DEBUG_MATHEMU printk("In do_mathemu()... pc is %08lx\n", regs->pc); printk("fpqdepth is %ld\n", fpt->thread.fpqdepth); diff --git a/arch/sparc/math-emu/math_64.c b/arch/sparc/math-emu/math_64.c index 6863c9b..56d2c44 100644 --- a/arch/sparc/math-emu/math_64.c +++ b/arch/sparc/math-emu/math_64.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -183,6 +184,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f) if (tstate & TSTATE_PRIV) die_if_kernel("unfinished/unimplemented FPop from kernel", regs); + perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, 0); if (test_thread_flag(TIF_32BIT)) pc = (u32)pc; if (get_user(insn, (u32 __user *) pc) != -EFAULT) { -- cgit v0.10.2 From adfe67ddffbea51322b118896178bd71aaa4b4d8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 11 Dec 2009 01:16:46 -0800 Subject: sparc64: Use free_bootmem_late() in mdesc_lmb_free(). Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index 938da19..cdc91d9 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -108,25 +109,15 @@ static struct mdesc_handle * __init mdesc_lmb_alloc(unsigned int mdesc_size) static void mdesc_lmb_free(struct mdesc_handle *hp) { - unsigned int alloc_size, handle_size = hp->handle_size; - unsigned long start, end; + unsigned int alloc_size; + unsigned long start; BUG_ON(atomic_read(&hp->refcnt) != 0); BUG_ON(!list_empty(&hp->list)); - alloc_size = PAGE_ALIGN(handle_size); - - start = (unsigned long) hp; - end = start + alloc_size; - - while (start < end) { - struct page *p; - - p = virt_to_page(start); - ClearPageReserved(p); - __free_page(p); - start += PAGE_SIZE; - } + alloc_size = PAGE_ALIGN(hp->handle_size); + start = __pa(hp); + free_bootmem_late(start, alloc_size); } static struct mdesc_mem_ops lmb_mdesc_ops = { -- cgit v0.10.2 From 6865b7f9dddbb79277dabaa538ec9a97bccc17c0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 11 Dec 2009 01:27:29 -0800 Subject: sparc64: Use clock{source,events}_calc_mult_shift(). Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 63f73ae..c310875 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -774,26 +774,9 @@ void __devinit setup_sparc64_timer(void) static struct clocksource clocksource_tick = { .rating = 100, .mask = CLOCKSOURCE_MASK(64), - .shift = 16, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void __init setup_clockevent_multiplier(unsigned long hz) -{ - unsigned long mult, shift = 32; - - while (1) { - mult = div_sc(hz, NSEC_PER_SEC, shift); - if (mult && (mult >> 32UL) == 0UL) - break; - - shift--; - } - - sparc64_clockevent.shift = shift; - sparc64_clockevent.mult = mult; -} - static unsigned long tb_ticks_per_usec __read_mostly; void __delay(unsigned long loops) @@ -828,9 +811,7 @@ void __init time_init(void) clocksource_hz2mult(freq, SPARC64_NSEC_PER_CYC_SHIFT); clocksource_tick.name = tick_ops->name; - clocksource_tick.mult = - clocksource_hz2mult(freq, - clocksource_tick.shift); + clocksource_calc_mult_shift(&clocksource_tick, freq, 4); clocksource_tick.read = clocksource_tick_read; printk("clocksource: mult[%x] shift[%d]\n", @@ -839,8 +820,7 @@ void __init time_init(void) clocksource_register(&clocksource_tick); sparc64_clockevent.name = tick_ops->name; - - setup_clockevent_multiplier(freq); + clockevents_calc_mult_shift(&sparc64_clockevent, freq, 4); sparc64_clockevent.max_delta_ns = clockevent_delta2ns(0x7fffffffffffffffUL, &sparc64_clockevent); -- cgit v0.10.2 From bb6eddf7676e1c1f3e637aa93c5224488d99036f Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 10 Dec 2009 15:35:10 +0100 Subject: clockevents: Prevent clockevent_devices list corruption on cpu hotplug Xiaotian Feng triggered a list corruption in the clock events list on CPU hotplug and debugged the root cause. If a CPU registers more than one per cpu clock event device, then only the active clock event device is removed on CPU_DEAD. The unused devices are kept in the clock events device list. On CPU up the clock event devices are registered again, which means that we list_add an already enqueued list_head. That results in list corruption. Resolve this by removing all devices which are associated to the dead CPU on CPU_DEAD. Reported-by: Xiaotian Feng Signed-off-by: Thomas Gleixner Tested-by: Xiaotian Feng Cc: stable@kernel.org diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 20a8920..91db2e3 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -238,8 +238,9 @@ void clockevents_exchange_device(struct clock_event_device *old, */ void clockevents_notify(unsigned long reason, void *arg) { - struct list_head *node, *tmp; + struct clock_event_device *dev, *tmp; unsigned long flags; + int cpu; spin_lock_irqsave(&clockevents_lock, flags); clockevents_do_notify(reason, arg); @@ -250,8 +251,19 @@ void clockevents_notify(unsigned long reason, void *arg) * Unregister the clock event devices which were * released from the users in the notify chain. */ - list_for_each_safe(node, tmp, &clockevents_released) - list_del(node); + list_for_each_entry_safe(dev, tmp, &clockevents_released, list) + list_del(&dev->list); + /* + * Now check whether the CPU has left unused per cpu devices + */ + cpu = *((int *)arg); + list_for_each_entry_safe(dev, tmp, &clockevent_devices, list) { + if (cpumask_test_cpu(cpu, dev->cpumask) && + cpumask_weight(dev->cpumask) == 1) { + BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED); + list_del(&dev->list); + } + } break; default: break; -- cgit v0.10.2 From 3975bc56305256af7689bcce62284fc62e09fc8f Mon Sep 17 00:00:00 2001 From: Robert Schedel Date: Fri, 11 Dec 2009 00:37:11 +0100 Subject: HID: Support 171 byte variant of Samsung USB IR receiver Extends the existing Samsung USB IrDA (0419:0001) quirk with newly reported 171 byte variant. It needs the same quirk as the other devices already supported by hid-samsung (wrong logical range) Refactors duplicate trace call into local helper function. The original bug report for the new variant is available at the second half of this ticket page: https://bugs.launchpad.net/bugs/326986 Signed-off-by: Robert Schedel Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c index 5b222ee..510dd13 100644 --- a/drivers/hid/hid-samsung.c +++ b/drivers/hid/hid-samsung.c @@ -39,7 +39,17 @@ * * 3. 135 byte report descriptor * Report #4 has an array field with logical range 0..17 instead of 1..14. + * + * 4. 171 byte report descriptor + * Report #3 has an array field with logical range 0..1 instead of 1..3. */ +static inline void samsung_dev_trace(struct hid_device *hdev, + unsigned int rsize) +{ + dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report " + "descriptor\n", rsize); +} + static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int rsize) { @@ -47,8 +57,7 @@ static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, rdesc[177] == 0x75 && rdesc[178] == 0x30 && rdesc[179] == 0x95 && rdesc[180] == 0x01 && rdesc[182] == 0x40) { - dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report " - "descriptor\n", 184); + samsung_dev_trace(hdev, 184); rdesc[176] = 0xff; rdesc[178] = 0x08; rdesc[180] = 0x06; @@ -56,17 +65,21 @@ static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, } else if (rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 && rdesc[194] == 0x25 && rdesc[195] == 0x12) { - dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report " - "descriptor\n", 203); + samsung_dev_trace(hdev, 203); rdesc[193] = 0x1; rdesc[195] = 0xf; } else if (rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 && rdesc[126] == 0x25 && rdesc[127] == 0x11) { - dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report " - "descriptor\n", 135); + samsung_dev_trace(hdev, 135); rdesc[125] = 0x1; rdesc[127] = 0xe; + } else + if (rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 && + rdesc[162] == 0x25 && rdesc[163] == 0x01) { + samsung_dev_trace(hdev, 171); + rdesc[161] = 0x1; + rdesc[163] = 0x3; } } -- cgit v0.10.2 From 7466bd3caab6bd1d0095de957affbacd02ca58a7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 11 Dec 2009 02:05:05 -0800 Subject: sparc64: Fix clock event multiplier printf format. The type got changed to u32, so %lx generated warnings (and thus build failure on sparc64) Stephen Rothwell fixed it like so: - printk("clockevent: mult[%lx] shift[%d]\n", + printk("clockevent: mult[%ux] shift[%d]\n", But that's not a valid transformation, we now get: clockevent: mult[51539607x] shift[32] in the logs. Fix it to use the correct plain "%x" instead. Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index c310875..67e1651 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -827,7 +827,7 @@ void __init time_init(void) sparc64_clockevent.min_delta_ns = clockevent_delta2ns(0xF, &sparc64_clockevent); - printk("clockevent: mult[%ux] shift[%d]\n", + printk("clockevent: mult[%x] shift[%d]\n", sparc64_clockevent.mult, sparc64_clockevent.shift); setup_sparc64_timer(); -- cgit v0.10.2 From 070bae1fb03bbf6a19a18722464a984eb3ddf55e Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Fri, 11 Dec 2009 03:39:53 +0000 Subject: powerpc/44x: Extend Katmai dts for ADMA and RAID56 support Add nodes for PPC440SPe DMA, I2O, XOR engines and Memory Queue module which are used in the updated PPC440SPe ADMA driver. Also extend plb ranges property to specify address ranges for DMA0/1 and I2O engines. Signed-off-by: Yuri Tikhonov Signed-off-by: Anatolij Gustschin Signed-off-by: Josh Boyer diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts index 51eb6ed..8f345de9 100644 --- a/arch/powerpc/boot/dts/katmai.dts +++ b/arch/powerpc/boot/dts/katmai.dts @@ -108,12 +108,19 @@ dcr-reg = <0x00c 0x002>; }; + MQ0: mq { + compatible = "ibm,mq-440spe"; + dcr-reg = <0x040 0x020>; + }; + plb { compatible = "ibm,plb-440spe", "ibm,plb-440gp", "ibm,plb4"; #address-cells = <2>; #size-cells = <1>; /* addr-child addr-parent size */ - ranges = <0x4 0xe0000000 0x4 0xe0000000 0x20000000 + ranges = <0x4 0x00100000 0x4 0x00100000 0x00001000 + 0x4 0x00200000 0x4 0x00200000 0x00000400 + 0x4 0xe0000000 0x4 0xe0000000 0x20000000 0xc 0x00000000 0xc 0x00000000 0x20000000 0xd 0x00000000 0xd 0x00000000 0x80000000 0xd 0x80000000 0xd 0x80000000 0x80000000 @@ -400,6 +407,49 @@ 0x0 0x0 0x0 0x3 &UIC3 0xa 0x4 /* swizzled int C */ 0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>; }; + + I2O: i2o@400100000 { + compatible = "ibm,i2o-440spe"; + reg = <0x00000004 0x00100000 0x100>; + dcr-reg = <0x060 0x020>; + }; + + DMA0: dma0@400100100 { + compatible = "ibm,dma-440spe"; + cell-index = <0>; + reg = <0x00000004 0x00100100 0x100>; + dcr-reg = <0x060 0x020>; + interrupt-parent = <&DMA0>; + interrupts = <0 1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = < + 0 &UIC0 0x14 4 + 1 &UIC1 0x16 4>; + }; + + DMA1: dma1@400100200 { + compatible = "ibm,dma-440spe"; + cell-index = <1>; + reg = <0x00000004 0x00100200 0x100>; + dcr-reg = <0x060 0x020>; + interrupt-parent = <&DMA1>; + interrupts = <0 1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = < + 0 &UIC0 0x16 4 + 1 &UIC1 0x16 4>; + }; + + xor-accel@400200000 { + compatible = "amcc,xor-accelerator"; + reg = <0x00000004 0x00200000 0x400>; + interrupt-parent = <&UIC1>; + interrupts = <0x1f 4>; + }; }; chosen { -- cgit v0.10.2 From a18cb387e5c29be5c95cded5b5a55110bb930f5c Mon Sep 17 00:00:00 2001 From: Sean MacLennan Date: Tue, 8 Dec 2009 19:04:37 +0000 Subject: powerpc/44x: Increase warp SD buffer Newer revs of the FPGA have a larger SD buffer. Signed-off-by: Sean MacLennan Signed-off-by: Josh Boyer diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts index 31605ee..e576ee8 100644 --- a/arch/powerpc/boot/dts/warp.dts +++ b/arch/powerpc/boot/dts/warp.dts @@ -146,7 +146,7 @@ fpga@2,4000 { compatible = "pika,fpga-sd"; - reg = <0x00000002 0x00004000 0x00000A00>; + reg = <0x00000002 0x00004000 0x00004000>; }; nor@0,0 { -- cgit v0.10.2 From 03889384cee7a198a79447c1ea6aca2c8e54d155 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 11 Dec 2009 09:48:22 -0500 Subject: tracing: Add trace_dump_stack() I've been asked a few times about how to find out what is calling some location in the kernel. One way is to use dynamic function tracing and implement the func_stack_trace. But this only finds out who is calling a particular function. It does not tell you who is calling that function and entering a specific if conditional. I have myself implemented a quick version of trace_dump_stack() for this purpose a few times, and just needed it now. This is when I realized that this would be a good tool to have in the kernel like trace_printk(). Using trace_dump_stack() is similar to dump_stack() except that it writes to the trace buffer instead and can be used in critical locations. For example: @@ -5485,8 +5485,12 @@ need_resched_nonpreemptible: if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) { if (unlikely(signal_pending_state(prev->state, prev))) prev->state = TASK_RUNNING; - else + else { deactivate_task(rq, prev, 1); + trace_printk("Deactivating task %s:%d\n", + prev->comm, prev->pid); + trace_dump_stack(); + } switch_count = &prev->nvcsw; } Produces: <...>-3249 [001] 296.105269: schedule: Deactivating task ntpd:3249 <...>-3249 [001] 296.105270: => schedule => schedule_hrtimeout_range => poll_schedule_timeout => do_select => core_sys_select => sys_select => system_call_fastpath Signed-off-by: Steven Rostedt diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 3fa4c59..5ad4199 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -492,6 +492,8 @@ extern int __trace_printk(unsigned long ip, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); +extern void trace_dump_stack(void); + /* * The double __builtin_constant_p is because gcc will give us an error * if we try to allocate the static variable to fmt if it is not a diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 88bd9ae..f531301 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1151,6 +1151,22 @@ void __trace_stack(struct trace_array *tr, unsigned long flags, int skip, __ftrace_trace_stack(tr->buffer, flags, skip, pc); } +/** + * trace_dump_stack - record a stack back trace in the trace buffer + */ +void trace_dump_stack(void) +{ + unsigned long flags; + + if (tracing_disabled || tracing_selftest_running) + return 0; + + local_save_flags(flags); + + /* skipping 3 traces, seems to get us at the caller of this function */ + __ftrace_trace_stack(global_trace.buffer, flags, 3, preempt_count()); +} + void ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc) { -- cgit v0.10.2 From cc51a0fca66658ea710db566ba17e80e3f7d4957 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 11 Dec 2009 11:54:51 -0500 Subject: tracing: Add stack trace to irqsoff tracer The irqsoff and friends tracers help in finding causes of latency in the kernel. The also work with the function tracer to show what was happening when interrupts or preemption are disabled. But the function tracer has a bit of an overhead and can cause exagerated readings. Currently, when tracing with /proc/sys/kernel/ftrace_enabled = 0, where the function tracer is disabled, the information that is provided can end up being useless. For example, a 2 and a half millisecond latency only showed: # tracer: preemptirqsoff # # preemptirqsoff latency trace v1.1.5 on 2.6.32 # -------------------------------------------------------------------- # latency: 2463 us, #4/4, CPU#2 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4) # ----------------- # | task: -4242 (uid:0 nice:0 policy:0 rt_prio:0) # ----------------- # => started at: _spin_lock_irqsave # => ended at: remove_wait_queue # # # _------=> CPU# # / _-----=> irqs-off # | / _----=> need-resched # || / _---=> hardirq/softirq # ||| / _--=> preempt-depth # |||| /_--=> lock-depth # |||||/ delay # cmd pid |||||| time | caller # \ / |||||| \ | / hackbenc-4242 2d.... 0us!: trace_hardirqs_off <-_spin_lock_irqsave hackbenc-4242 2...1. 2463us+: _spin_unlock_irqrestore <-remove_wait_queue hackbenc-4242 2...1. 2466us : trace_preempt_on <-remove_wait_queue The above lets us know that hackbench with pid 2463 grabbed a spin lock somewhere and enabled preemption at remove_wait_queue. This helps a little but where this actually happened is not informative. This patch adds the stack dump to the end of the irqsoff tracer. This provides the following output: hackbenc-4242 2d.... 0us!: trace_hardirqs_off <-_spin_lock_irqsave hackbenc-4242 2...1. 2463us+: _spin_unlock_irqrestore <-remove_wait_queue hackbenc-4242 2...1. 2466us : trace_preempt_on <-remove_wait_queue hackbenc-4242 2...1. 2467us : => sub_preempt_count => _spin_unlock_irqrestore => remove_wait_queue => free_poll_entry => poll_freewait => do_sys_poll => sys_poll => system_call_fastpath Now we see that the culprit of this latency was the free_poll_entry code. Signed-off-by: Steven Rostedt diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 3aa7eaa..2974bc7 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -151,6 +151,8 @@ check_critical_timing(struct trace_array *tr, goto out_unlock; trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc); + /* Skip 5 functions to get to the irq/preempt enable function */ + __trace_stack(tr, flags, 5, pc); if (data->critical_sequence != max_sequence) goto out_unlock; -- cgit v0.10.2 From 23e707dd9b0b26215d801c59e87feed1c218a0f9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 11 Dec 2009 15:38:46 -0800 Subject: Staging: batman: fix debug Kconfig option The debug batman option needs to depend on the correct config option. Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/batman-adv/Kconfig b/drivers/staging/batman-adv/Kconfig index b9742e7..7632f57 100644 --- a/drivers/staging/batman-adv/Kconfig +++ b/drivers/staging/batman-adv/Kconfig @@ -15,7 +15,7 @@ config BATMAN_ADV config BATMAN_DEBUG bool "B.A.T.M.A.N. debugging" - depends on BATMAN != n + depends on BATMAN_ADV != n help This is an option for use by developers; most people should -- cgit v0.10.2 From 2e032b62c4c8560d6416ad3cc925cfc2a5eafb07 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 11 Dec 2009 21:24:33 -0700 Subject: iop-adma.c: use resource_size() The size of the requested and ioremaped memory is off by 1. Use resource_size() to get the correct value. Signed-off-by: H Hartley Sweeten Signed-off-by: Dan Williams diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index 645ca8d..ca6e6a0 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c @@ -1470,7 +1470,7 @@ static int __devinit iop_adma_probe(struct platform_device *pdev) return -ENODEV; if (!devm_request_mem_region(&pdev->dev, res->start, - res->end - res->start, pdev->name)) + resource_size(res), pdev->name)) return -EBUSY; adev = kzalloc(sizeof(*adev), GFP_KERNEL); @@ -1542,7 +1542,7 @@ static int __devinit iop_adma_probe(struct platform_device *pdev) iop_chan->device = adev; iop_chan->mmr_base = devm_ioremap(&pdev->dev, res->start, - res->end - res->start); + resource_size(res)); if (!iop_chan->mmr_base) { ret = -ENOMEM; goto err_free_iop_chan; -- cgit v0.10.2 From 12458ea06efd7b44281e68fe59c950ec7d59c649 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Fri, 11 Dec 2009 21:24:44 -0700 Subject: ppc440spe-adma: adds updated ppc440spe adma driver This patch adds new version of the PPC440SPe ADMA driver. Signed-off-by: Yuri Tikhonov Signed-off-by: Anatolij Gustschin Signed-off-by: Dan Williams diff --git a/Documentation/powerpc/dts-bindings/4xx/ppc440spe-adma.txt b/Documentation/powerpc/dts-bindings/4xx/ppc440spe-adma.txt new file mode 100644 index 0000000..515ebcf --- /dev/null +++ b/Documentation/powerpc/dts-bindings/4xx/ppc440spe-adma.txt @@ -0,0 +1,93 @@ +PPC440SPe DMA/XOR (DMA Controller and XOR Accelerator) + +Device nodes needed for operation of the ppc440spe-adma driver +are specified hereby. These are I2O/DMA, DMA and XOR nodes +for DMA engines and Memory Queue Module node. The latter is used +by ADMA driver for configuration of RAID-6 H/W capabilities of +the PPC440SPe. In addition to the nodes and properties described +below, the ranges property of PLB node must specify ranges for +DMA devices. + + i) The I2O node + + Required properties: + + - compatible : "ibm,i2o-440spe"; + - reg : + - dcr-reg : + + Example: + + I2O: i2o@400100000 { + compatible = "ibm,i2o-440spe"; + reg = <0x00000004 0x00100000 0x100>; + dcr-reg = <0x060 0x020>; + }; + + + ii) The DMA node + + Required properties: + + - compatible : "ibm,dma-440spe"; + - cell-index : 1 cell, hardware index of the DMA engine + (typically 0x0 and 0x1 for DMA0 and DMA1) + - reg : + - dcr-reg : + - interrupts : . + - interrupt-parent : needed for interrupt mapping + + Example: + + DMA0: dma0@400100100 { + compatible = "ibm,dma-440spe"; + cell-index = <0>; + reg = <0x00000004 0x00100100 0x100>; + dcr-reg = <0x060 0x020>; + interrupt-parent = <&DMA0>; + interrupts = <0 1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = < + 0 &UIC0 0x14 4 + 1 &UIC1 0x16 4>; + }; + + + iii) XOR Accelerator node + + Required properties: + + - compatible : "amcc,xor-accelerator"; + - reg : + - interrupts : + - interrupt-parent : for interrupt mapping + + Example: + + xor-accel@400200000 { + compatible = "amcc,xor-accelerator"; + reg = <0x00000004 0x00200000 0x400>; + interrupt-parent = <&UIC1>; + interrupts = <0x1f 4>; + }; + + + iv) Memory Queue Module node + + Required properties: + + - compatible : "ibm,mq-440spe"; + - dcr-reg : + + Example: + + MQ0: mq { + compatible = "ibm,mq-440spe"; + dcr-reg = <0x040 0x020>; + }; + diff --git a/arch/powerpc/include/asm/async_tx.h b/arch/powerpc/include/asm/async_tx.h new file mode 100644 index 0000000..8b2dc55 --- /dev/null +++ b/arch/powerpc/include/asm/async_tx.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008-2009 DENX Software Engineering. + * + * Author: Yuri Tikhonov + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution in the + * file called COPYING. + */ +#ifndef _ASM_POWERPC_ASYNC_TX_H_ +#define _ASM_POWERPC_ASYNC_TX_H_ + +#if defined(CONFIG_440SPe) || defined(CONFIG_440SP) +extern struct dma_chan * +ppc440spe_async_tx_find_best_channel(enum dma_transaction_type cap, + struct page **dst_lst, int dst_cnt, struct page **src_lst, + int src_cnt, size_t src_sz); + +#define async_tx_find_channel(dep, cap, dst_lst, dst_cnt, src_lst, \ + src_cnt, src_sz) \ + ppc440spe_async_tx_find_best_channel(cap, dst_lst, dst_cnt, src_lst, \ + src_cnt, src_sz) +#else + +#define async_tx_find_channel(dep, type, dst, dst_count, src, src_count, len) \ + __async_tx_find_channel(dep, type) + +struct dma_chan * +__async_tx_find_channel(struct async_submit_ctl *submit, + enum dma_transaction_type tx_type); + +#endif + +#endif diff --git a/arch/powerpc/include/asm/dcr-regs.h b/arch/powerpc/include/asm/dcr-regs.h index 828e3aa..380274d 100644 --- a/arch/powerpc/include/asm/dcr-regs.h +++ b/arch/powerpc/include/asm/dcr-regs.h @@ -157,4 +157,27 @@ #define L2C_SNP_SSR_32G 0x0000f000 #define L2C_SNP_ESR 0x00000800 +/* + * DCR register offsets for 440SP/440SPe I2O/DMA controller. + * The base address is configured in the device tree. + */ +#define DCRN_I2O0_IBAL 0x006 +#define DCRN_I2O0_IBAH 0x007 +#define I2O_REG_ENABLE 0x00000001 /* Enable I2O/DMA access */ + +/* 440SP/440SPe Software Reset DCR */ +#define DCRN_SDR0_SRST 0x0200 +#define DCRN_SDR0_SRST_I2ODMA (0x80000000 >> 15) /* Reset I2O/DMA */ + +/* 440SP/440SPe Memory Queue DCR offsets */ +#define DCRN_MQ0_XORBA 0x04 +#define DCRN_MQ0_CF2H 0x06 +#define DCRN_MQ0_CFBHL 0x0f +#define DCRN_MQ0_BAUH 0x10 + +/* HB/LL Paths Configuration Register */ +#define MQ0_CFBHL_TPLM 28 +#define MQ0_CFBHL_HBCL 23 +#define MQ0_CFBHL_POLY 15 + #endif /* __DCR_REGS_H__ */ diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 24cdd20..fe93d70 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -116,6 +116,17 @@ config COH901318 help Enable support for ST-Ericsson COH 901 318 DMA. +config AMCC_PPC440SPE_ADMA + tristate "AMCC PPC440SPe ADMA support" + depends on 440SPe || 440SP + select DMA_ENGINE + select ARCH_HAS_ASYNC_TX_FIND_CHANNEL + help + Enable support for the AMCC PPC440SPe RAID engines. + +config ARCH_HAS_ASYNC_TX_FIND_CHANNEL + bool + config DMA_ENGINE bool diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 4db768e..807053d 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_MX3_IPU) += ipu/ obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o obj-$(CONFIG_SH_DMAE) += shdma.o obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o +obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/ diff --git a/drivers/dma/ppc4xx/Makefile b/drivers/dma/ppc4xx/Makefile new file mode 100644 index 0000000..b3d259b --- /dev/null +++ b/drivers/dma/ppc4xx/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += adma.o diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c new file mode 100644 index 0000000..0a3478e --- /dev/null +++ b/drivers/dma/ppc4xx/adma.c @@ -0,0 +1,5027 @@ +/* + * Copyright (C) 2006-2009 DENX Software Engineering. + * + * Author: Yuri Tikhonov + * + * Further porting to arch/powerpc by + * Anatolij Gustschin + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution in the + * file called COPYING. + */ + +/* + * This driver supports the asynchrounous DMA copy and RAID engines available + * on the AMCC PPC440SPe Processors. + * Based on the Intel Xscale(R) family of I/O Processors (IOP 32x, 33x, 134x) + * ADMA driver written by D.Williams. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "adma.h" + +enum ppc_adma_init_code { + PPC_ADMA_INIT_OK = 0, + PPC_ADMA_INIT_MEMRES, + PPC_ADMA_INIT_MEMREG, + PPC_ADMA_INIT_ALLOC, + PPC_ADMA_INIT_COHERENT, + PPC_ADMA_INIT_CHANNEL, + PPC_ADMA_INIT_IRQ1, + PPC_ADMA_INIT_IRQ2, + PPC_ADMA_INIT_REGISTER +}; + +static char *ppc_adma_errors[] = { + [PPC_ADMA_INIT_OK] = "ok", + [PPC_ADMA_INIT_MEMRES] = "failed to get memory resource", + [PPC_ADMA_INIT_MEMREG] = "failed to request memory region", + [PPC_ADMA_INIT_ALLOC] = "failed to allocate memory for adev " + "structure", + [PPC_ADMA_INIT_COHERENT] = "failed to allocate coherent memory for " + "hardware descriptors", + [PPC_ADMA_INIT_CHANNEL] = "failed to allocate memory for channel", + [PPC_ADMA_INIT_IRQ1] = "failed to request first irq", + [PPC_ADMA_INIT_IRQ2] = "failed to request second irq", + [PPC_ADMA_INIT_REGISTER] = "failed to register dma async device", +}; + +static enum ppc_adma_init_code +ppc440spe_adma_devices[PPC440SPE_ADMA_ENGINES_NUM]; + +struct ppc_dma_chan_ref { + struct dma_chan *chan; + struct list_head node; +}; + +/* The list of channels exported by ppc440spe ADMA */ +struct list_head +ppc440spe_adma_chan_list = LIST_HEAD_INIT(ppc440spe_adma_chan_list); + +/* This flag is set when want to refetch the xor chain in the interrupt + * handler + */ +static u32 do_xor_refetch; + +/* Pointer to DMA0, DMA1 CP/CS FIFO */ +static void *ppc440spe_dma_fifo_buf; + +/* Pointers to last submitted to DMA0, DMA1 CDBs */ +static struct ppc440spe_adma_desc_slot *chan_last_sub[3]; +static struct ppc440spe_adma_desc_slot *chan_first_cdb[3]; + +/* Pointer to last linked and submitted xor CB */ +static struct ppc440spe_adma_desc_slot *xor_last_linked; +static struct ppc440spe_adma_desc_slot *xor_last_submit; + +/* This array is used in data-check operations for storing a pattern */ +static char ppc440spe_qword[16]; + +static atomic_t ppc440spe_adma_err_irq_ref; +static dcr_host_t ppc440spe_mq_dcr_host; +static unsigned int ppc440spe_mq_dcr_len; + +/* Since RXOR operations use the common register (MQ0_CF2H) for setting-up + * the block size in transactions, then we do not allow to activate more than + * only one RXOR transactions simultaneously. So use this var to store + * the information about is RXOR currently active (PPC440SPE_RXOR_RUN bit is + * set) or not (PPC440SPE_RXOR_RUN is clear). + */ +static unsigned long ppc440spe_rxor_state; + +/* These are used in enable & check routines + */ +static u32 ppc440spe_r6_enabled; +static struct ppc440spe_adma_chan *ppc440spe_r6_tchan; +static struct completion ppc440spe_r6_test_comp; + +static int ppc440spe_adma_dma2rxor_prep_src( + struct ppc440spe_adma_desc_slot *desc, + struct ppc440spe_rxor *cursor, int index, + int src_cnt, u32 addr); +static void ppc440spe_adma_dma2rxor_set_src( + struct ppc440spe_adma_desc_slot *desc, + int index, dma_addr_t addr); +static void ppc440spe_adma_dma2rxor_set_mult( + struct ppc440spe_adma_desc_slot *desc, + int index, u8 mult); + +#ifdef ADMA_LL_DEBUG +#define ADMA_LL_DBG(x) ({ if (1) x; 0; }) +#else +#define ADMA_LL_DBG(x) ({ if (0) x; 0; }) +#endif + +static void print_cb(struct ppc440spe_adma_chan *chan, void *block) +{ + struct dma_cdb *cdb; + struct xor_cb *cb; + int i; + + switch (chan->device->id) { + case 0: + case 1: + cdb = block; + + pr_debug("CDB at %p [%d]:\n" + "\t attr 0x%02x opc 0x%02x cnt 0x%08x\n" + "\t sg1u 0x%08x sg1l 0x%08x\n" + "\t sg2u 0x%08x sg2l 0x%08x\n" + "\t sg3u 0x%08x sg3l 0x%08x\n", + cdb, chan->device->id, + cdb->attr, cdb->opc, le32_to_cpu(cdb->cnt), + le32_to_cpu(cdb->sg1u), le32_to_cpu(cdb->sg1l), + le32_to_cpu(cdb->sg2u), le32_to_cpu(cdb->sg2l), + le32_to_cpu(cdb->sg3u), le32_to_cpu(cdb->sg3l) + ); + break; + case 2: + cb = block; + + pr_debug("CB at %p [%d]:\n" + "\t cbc 0x%08x cbbc 0x%08x cbs 0x%08x\n" + "\t cbtah 0x%08x cbtal 0x%08x\n" + "\t cblah 0x%08x cblal 0x%08x\n", + cb, chan->device->id, + cb->cbc, cb->cbbc, cb->cbs, + cb->cbtah, cb->cbtal, + cb->cblah, cb->cblal); + for (i = 0; i < 16; i++) { + if (i && !cb->ops[i].h && !cb->ops[i].l) + continue; + pr_debug("\t ops[%2d]: h 0x%08x l 0x%08x\n", + i, cb->ops[i].h, cb->ops[i].l); + } + break; + } +} + +static void print_cb_list(struct ppc440spe_adma_chan *chan, + struct ppc440spe_adma_desc_slot *iter) +{ + for (; iter; iter = iter->hw_next) + print_cb(chan, iter->hw_desc); +} + +static void prep_dma_xor_dbg(int id, dma_addr_t dst, dma_addr_t *src, + unsigned int src_cnt) +{ + int i; + + pr_debug("\n%s(%d):\nsrc: ", __func__, id); + for (i = 0; i < src_cnt; i++) + pr_debug("\t0x%016llx ", src[i]); + pr_debug("dst:\n\t0x%016llx\n", dst); +} + +static void prep_dma_pq_dbg(int id, dma_addr_t *dst, dma_addr_t *src, + unsigned int src_cnt) +{ + int i; + + pr_debug("\n%s(%d):\nsrc: ", __func__, id); + for (i = 0; i < src_cnt; i++) + pr_debug("\t0x%016llx ", src[i]); + pr_debug("dst: "); + for (i = 0; i < 2; i++) + pr_debug("\t0x%016llx ", dst[i]); +} + +static void prep_dma_pqzero_sum_dbg(int id, dma_addr_t *src, + unsigned int src_cnt, + const unsigned char *scf) +{ + int i; + + pr_debug("\n%s(%d):\nsrc(coef): ", __func__, id); + if (scf) { + for (i = 0; i < src_cnt; i++) + pr_debug("\t0x%016llx(0x%02x) ", src[i], scf[i]); + } else { + for (i = 0; i < src_cnt; i++) + pr_debug("\t0x%016llx(no) ", src[i]); + } + + pr_debug("dst: "); + for (i = 0; i < 2; i++) + pr_debug("\t0x%016llx ", src[src_cnt + i]); +} + +/****************************************************************************** + * Command (Descriptor) Blocks low-level routines + ******************************************************************************/ +/** + * ppc440spe_desc_init_interrupt - initialize the descriptor for INTERRUPT + * pseudo operation + */ +static void ppc440spe_desc_init_interrupt(struct ppc440spe_adma_desc_slot *desc, + struct ppc440spe_adma_chan *chan) +{ + struct xor_cb *p; + + switch (chan->device->id) { + case PPC440SPE_XOR_ID: + p = desc->hw_desc; + memset(desc->hw_desc, 0, sizeof(struct xor_cb)); + /* NOP with Command Block Complete Enable */ + p->cbc = XOR_CBCR_CBCE_BIT; + break; + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + memset(desc->hw_desc, 0, sizeof(struct dma_cdb)); + /* NOP with interrupt */ + set_bit(PPC440SPE_DESC_INT, &desc->flags); + break; + default: + printk(KERN_ERR "Unsupported id %d in %s\n", chan->device->id, + __func__); + break; + } +} + +/** + * ppc440spe_desc_init_null_xor - initialize the descriptor for NULL XOR + * pseudo operation + */ +static void ppc440spe_desc_init_null_xor(struct ppc440spe_adma_desc_slot *desc) +{ + memset(desc->hw_desc, 0, sizeof(struct xor_cb)); + desc->hw_next = NULL; + desc->src_cnt = 0; + desc->dst_cnt = 1; +} + +/** + * ppc440spe_desc_init_xor - initialize the descriptor for XOR operation + */ +static void ppc440spe_desc_init_xor(struct ppc440spe_adma_desc_slot *desc, + int src_cnt, unsigned long flags) +{ + struct xor_cb *hw_desc = desc->hw_desc; + + memset(desc->hw_desc, 0, sizeof(struct xor_cb)); + desc->hw_next = NULL; + desc->src_cnt = src_cnt; + desc->dst_cnt = 1; + + hw_desc->cbc = XOR_CBCR_TGT_BIT | src_cnt; + if (flags & DMA_PREP_INTERRUPT) + /* Enable interrupt on completion */ + hw_desc->cbc |= XOR_CBCR_CBCE_BIT; +} + +/** + * ppc440spe_desc_init_dma2pq - initialize the descriptor for PQ + * operation in DMA2 controller + */ +static void ppc440spe_desc_init_dma2pq(struct ppc440spe_adma_desc_slot *desc, + int dst_cnt, int src_cnt, unsigned long flags) +{ + struct xor_cb *hw_desc = desc->hw_desc; + + memset(desc->hw_desc, 0, sizeof(struct xor_cb)); + desc->hw_next = NULL; + desc->src_cnt = src_cnt; + desc->dst_cnt = dst_cnt; + memset(desc->reverse_flags, 0, sizeof(desc->reverse_flags)); + desc->descs_per_op = 0; + + hw_desc->cbc = XOR_CBCR_TGT_BIT; + if (flags & DMA_PREP_INTERRUPT) + /* Enable interrupt on completion */ + hw_desc->cbc |= XOR_CBCR_CBCE_BIT; +} + +#define DMA_CTRL_FLAGS_LAST DMA_PREP_FENCE +#define DMA_PREP_ZERO_P (DMA_CTRL_FLAGS_LAST << 1) +#define DMA_PREP_ZERO_Q (DMA_PREP_ZERO_P << 1) + +/** + * ppc440spe_desc_init_dma01pq - initialize the descriptors for PQ operation + * with DMA0/1 + */ +static void ppc440spe_desc_init_dma01pq(struct ppc440spe_adma_desc_slot *desc, + int dst_cnt, int src_cnt, unsigned long flags, + unsigned long op) +{ + struct dma_cdb *hw_desc; + struct ppc440spe_adma_desc_slot *iter; + u8 dopc; + + /* Common initialization of a PQ descriptors chain */ + set_bits(op, &desc->flags); + desc->src_cnt = src_cnt; + desc->dst_cnt = dst_cnt; + + /* WXOR MULTICAST if both P and Q are being computed + * MV_SG1_SG2 if Q only + */ + dopc = (desc->dst_cnt == DMA_DEST_MAX_NUM) ? + DMA_CDB_OPC_MULTICAST : DMA_CDB_OPC_MV_SG1_SG2; + + list_for_each_entry(iter, &desc->group_list, chain_node) { + hw_desc = iter->hw_desc; + memset(iter->hw_desc, 0, sizeof(struct dma_cdb)); + + if (likely(!list_is_last(&iter->chain_node, + &desc->group_list))) { + /* set 'next' pointer */ + iter->hw_next = list_entry(iter->chain_node.next, + struct ppc440spe_adma_desc_slot, chain_node); + clear_bit(PPC440SPE_DESC_INT, &iter->flags); + } else { + /* this is the last descriptor. + * this slot will be pasted from ADMA level + * each time it wants to configure parameters + * of the transaction (src, dst, ...) + */ + iter->hw_next = NULL; + if (flags & DMA_PREP_INTERRUPT) + set_bit(PPC440SPE_DESC_INT, &iter->flags); + else + clear_bit(PPC440SPE_DESC_INT, &iter->flags); + } + } + + /* Set OPS depending on WXOR/RXOR type of operation */ + if (!test_bit(PPC440SPE_DESC_RXOR, &desc->flags)) { + /* This is a WXOR only chain: + * - first descriptors are for zeroing destinations + * if PPC440SPE_ZERO_P/Q set; + * - descriptors remained are for GF-XOR operations. + */ + iter = list_first_entry(&desc->group_list, + struct ppc440spe_adma_desc_slot, + chain_node); + + if (test_bit(PPC440SPE_ZERO_P, &desc->flags)) { + hw_desc = iter->hw_desc; + hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2; + iter = list_first_entry(&iter->chain_node, + struct ppc440spe_adma_desc_slot, + chain_node); + } + + if (test_bit(PPC440SPE_ZERO_Q, &desc->flags)) { + hw_desc = iter->hw_desc; + hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2; + iter = list_first_entry(&iter->chain_node, + struct ppc440spe_adma_desc_slot, + chain_node); + } + + list_for_each_entry_from(iter, &desc->group_list, chain_node) { + hw_desc = iter->hw_desc; + hw_desc->opc = dopc; + } + } else { + /* This is either RXOR-only or mixed RXOR/WXOR */ + + /* The first 1 or 2 slots in chain are always RXOR, + * if need to calculate P & Q, then there are two + * RXOR slots; if only P or only Q, then there is one + */ + iter = list_first_entry(&desc->group_list, + struct ppc440spe_adma_desc_slot, + chain_node); + hw_desc = iter->hw_desc; + hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2; + + if (desc->dst_cnt == DMA_DEST_MAX_NUM) { + iter = list_first_entry(&iter->chain_node, + struct ppc440spe_adma_desc_slot, + chain_node); + hw_desc = iter->hw_desc; + hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2; + } + + /* The remaining descs (if any) are WXORs */ + if (test_bit(PPC440SPE_DESC_WXOR, &desc->flags)) { + iter = list_first_entry(&iter->chain_node, + struct ppc440spe_adma_desc_slot, + chain_node); + list_for_each_entry_from(iter, &desc->group_list, + chain_node) { + hw_desc = iter->hw_desc; + hw_desc->opc = dopc; + } + } + } +} + +/** + * ppc440spe_desc_init_dma01pqzero_sum - initialize the descriptor + * for PQ_ZERO_SUM operation + */ +static void ppc440spe_desc_init_dma01pqzero_sum( + struct ppc440spe_adma_desc_slot *desc, + int dst_cnt, int src_cnt) +{ + struct dma_cdb *hw_desc; + struct ppc440spe_adma_desc_slot *iter; + int i = 0; + u8 dopc = (dst_cnt == 2) ? DMA_CDB_OPC_MULTICAST : + DMA_CDB_OPC_MV_SG1_SG2; + /* + * Initialize starting from 2nd or 3rd descriptor dependent + * on dst_cnt. First one or two slots are for cloning P + * and/or Q to chan->pdest and/or chan->qdest as we have + * to preserve original P/Q. + */ + iter = list_first_entry(&desc->group_list, + struct ppc440spe_adma_desc_slot, chain_node); + iter = list_entry(iter->chain_node.next, + struct ppc440spe_adma_desc_slot, chain_node); + + if (dst_cnt > 1) { + iter = list_entry(iter->chain_node.next, + struct ppc440spe_adma_desc_slot, chain_node); + } + /* initialize each source descriptor in chain */ + list_for_each_entry_from(iter, &desc->group_list, chain_node) { + hw_desc = iter->hw_desc; + memset(iter->hw_desc, 0, sizeof(struct dma_cdb)); + iter->src_cnt = 0; + iter->dst_cnt = 0; + + /* This is a ZERO_SUM operation: + * - descriptors starting from 2nd or 3rd + * descriptor are for GF-XOR operations; + * - remaining descriptors are for checking the result + */ + if (i++ < src_cnt) + /* MV_SG1_SG2 if only Q is being verified + * MULTICAST if both P and Q are being verified + */ + hw_desc->opc = dopc; + else + /* DMA_CDB_OPC_DCHECK128 operation */ + hw_desc->opc = DMA_CDB_OPC_DCHECK128; + + if (likely(!list_is_last(&iter->chain_node, + &desc->group_list))) { + /* set 'next' pointer */ + iter->hw_next = list_entry(iter->chain_node.next, + struct ppc440spe_adma_desc_slot, + chain_node); + } else { + /* this is the last descriptor. + * this slot will be pasted from ADMA level + * each time it wants to configure parameters + * of the transaction (src, dst, ...) + */ + iter->hw_next = NULL; + /* always enable interrupt generation since we get + * the status of pqzero from the handler + */ + set_bit(PPC440SPE_DESC_INT, &iter->flags); + } + } + desc->src_cnt = src_cnt; + desc->dst_cnt = dst_cnt; +} + +/** + * ppc440spe_desc_init_memcpy - initialize the descriptor for MEMCPY operation + */ +static void ppc440spe_desc_init_memcpy(struct ppc440spe_adma_desc_slot *desc, + unsigned long flags) +{ + struct dma_cdb *hw_desc = desc->hw_desc; + + memset(desc->hw_desc, 0, sizeof(struct dma_cdb)); + desc->hw_next = NULL; + desc->src_cnt = 1; + desc->dst_cnt = 1; + + if (flags & DMA_PREP_INTERRUPT) + set_bit(PPC440SPE_DESC_INT, &desc->flags); + else + clear_bit(PPC440SPE_DESC_INT, &desc->flags); + + hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2; +} + +/** + * ppc440spe_desc_init_memset - initialize the descriptor for MEMSET operation + */ +static void ppc440spe_desc_init_memset(struct ppc440spe_adma_desc_slot *desc, + int value, unsigned long flags) +{ + struct dma_cdb *hw_desc = desc->hw_desc; + + memset(desc->hw_desc, 0, sizeof(struct dma_cdb)); + desc->hw_next = NULL; + desc->src_cnt = 1; + desc->dst_cnt = 1; + + if (flags & DMA_PREP_INTERRUPT) + set_bit(PPC440SPE_DESC_INT, &desc->flags); + else + clear_bit(PPC440SPE_DESC_INT, &desc->flags); + + hw_desc->sg1u = hw_desc->sg1l = cpu_to_le32((u32)value); + hw_desc->sg3u = hw_desc->sg3l = cpu_to_le32((u32)value); + hw_desc->opc = DMA_CDB_OPC_DFILL128; +} + +/** + * ppc440spe_desc_set_src_addr - set source address into the descriptor + */ +static void ppc440spe_desc_set_src_addr(struct ppc440spe_adma_desc_slot *desc, + struct ppc440spe_adma_chan *chan, + int src_idx, dma_addr_t addrh, + dma_addr_t addrl) +{ + struct dma_cdb *dma_hw_desc; + struct xor_cb *xor_hw_desc; + phys_addr_t addr64, tmplow, tmphi; + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + if (!addrh) { + addr64 = addrl; + tmphi = (addr64 >> 32); + tmplow = (addr64 & 0xFFFFFFFF); + } else { + tmphi = addrh; + tmplow = addrl; + } + dma_hw_desc = desc->hw_desc; + dma_hw_desc->sg1l = cpu_to_le32((u32)tmplow); + dma_hw_desc->sg1u |= cpu_to_le32((u32)tmphi); + break; + case PPC440SPE_XOR_ID: + xor_hw_desc = desc->hw_desc; + xor_hw_desc->ops[src_idx].l = addrl; + xor_hw_desc->ops[src_idx].h |= addrh; + break; + } +} + +/** + * ppc440spe_desc_set_src_mult - set source address mult into the descriptor + */ +static void ppc440spe_desc_set_src_mult(struct ppc440spe_adma_desc_slot *desc, + struct ppc440spe_adma_chan *chan, u32 mult_index, + int sg_index, unsigned char mult_value) +{ + struct dma_cdb *dma_hw_desc; + struct xor_cb *xor_hw_desc; + u32 *psgu; + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + dma_hw_desc = desc->hw_desc; + + switch (sg_index) { + /* for RXOR operations set multiplier + * into source cued address + */ + case DMA_CDB_SG_SRC: + psgu = &dma_hw_desc->sg1u; + break; + /* for WXOR operations set multiplier + * into destination cued address(es) + */ + case DMA_CDB_SG_DST1: + psgu = &dma_hw_desc->sg2u; + break; + case DMA_CDB_SG_DST2: + psgu = &dma_hw_desc->sg3u; + break; + default: + BUG(); + } + + *psgu |= cpu_to_le32(mult_value << mult_index); + break; + case PPC440SPE_XOR_ID: + xor_hw_desc = desc->hw_desc; + break; + default: + BUG(); + } +} + +/** + * ppc440spe_desc_set_dest_addr - set destination address into the descriptor + */ +static void ppc440spe_desc_set_dest_addr(struct ppc440spe_adma_desc_slot *desc, + struct ppc440spe_adma_chan *chan, + dma_addr_t addrh, dma_addr_t addrl, + u32 dst_idx) +{ + struct dma_cdb *dma_hw_desc; + struct xor_cb *xor_hw_desc; + phys_addr_t addr64, tmphi, tmplow; + u32 *psgu, *psgl; + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + if (!addrh) { + addr64 = addrl; + tmphi = (addr64 >> 32); + tmplow = (addr64 & 0xFFFFFFFF); + } else { + tmphi = addrh; + tmplow = addrl; + } + dma_hw_desc = desc->hw_desc; + + psgu = dst_idx ? &dma_hw_desc->sg3u : &dma_hw_desc->sg2u; + psgl = dst_idx ? &dma_hw_desc->sg3l : &dma_hw_desc->sg2l; + + *psgl = cpu_to_le32((u32)tmplow); + *psgu |= cpu_to_le32((u32)tmphi); + break; + case PPC440SPE_XOR_ID: + xor_hw_desc = desc->hw_desc; + xor_hw_desc->cbtal = addrl; + xor_hw_desc->cbtah |= addrh; + break; + } +} + +/** + * ppc440spe_desc_set_byte_count - set number of data bytes involved + * into the operation + */ +static void ppc440spe_desc_set_byte_count(struct ppc440spe_adma_desc_slot *desc, + struct ppc440spe_adma_chan *chan, + u32 byte_count) +{ + struct dma_cdb *dma_hw_desc; + struct xor_cb *xor_hw_desc; + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + dma_hw_desc = desc->hw_desc; + dma_hw_desc->cnt = cpu_to_le32(byte_count); + break; + case PPC440SPE_XOR_ID: + xor_hw_desc = desc->hw_desc; + xor_hw_desc->cbbc = byte_count; + break; + } +} + +/** + * ppc440spe_desc_set_rxor_block_size - set RXOR block size + */ +static inline void ppc440spe_desc_set_rxor_block_size(u32 byte_count) +{ + /* assume that byte_count is aligned on the 512-boundary; + * thus write it directly to the register (bits 23:31 are + * reserved there). + */ + dcr_write(ppc440spe_mq_dcr_host, DCRN_MQ0_CF2H, byte_count); +} + +/** + * ppc440spe_desc_set_dcheck - set CHECK pattern + */ +static void ppc440spe_desc_set_dcheck(struct ppc440spe_adma_desc_slot *desc, + struct ppc440spe_adma_chan *chan, u8 *qword) +{ + struct dma_cdb *dma_hw_desc; + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + dma_hw_desc = desc->hw_desc; + iowrite32(qword[0], &dma_hw_desc->sg3l); + iowrite32(qword[4], &dma_hw_desc->sg3u); + iowrite32(qword[8], &dma_hw_desc->sg2l); + iowrite32(qword[12], &dma_hw_desc->sg2u); + break; + default: + BUG(); + } +} + +/** + * ppc440spe_xor_set_link - set link address in xor CB + */ +static void ppc440spe_xor_set_link(struct ppc440spe_adma_desc_slot *prev_desc, + struct ppc440spe_adma_desc_slot *next_desc) +{ + struct xor_cb *xor_hw_desc = prev_desc->hw_desc; + + if (unlikely(!next_desc || !(next_desc->phys))) { + printk(KERN_ERR "%s: next_desc=0x%p; next_desc->phys=0x%llx\n", + __func__, next_desc, + next_desc ? next_desc->phys : 0); + BUG(); + } + + xor_hw_desc->cbs = 0; + xor_hw_desc->cblal = next_desc->phys; + xor_hw_desc->cblah = 0; + xor_hw_desc->cbc |= XOR_CBCR_LNK_BIT; +} + +/** + * ppc440spe_desc_set_link - set the address of descriptor following this + * descriptor in chain + */ +static void ppc440spe_desc_set_link(struct ppc440spe_adma_chan *chan, + struct ppc440spe_adma_desc_slot *prev_desc, + struct ppc440spe_adma_desc_slot *next_desc) +{ + unsigned long flags; + struct ppc440spe_adma_desc_slot *tail = next_desc; + + if (unlikely(!prev_desc || !next_desc || + (prev_desc->hw_next && prev_desc->hw_next != next_desc))) { + /* If previous next is overwritten something is wrong. + * though we may refetch from append to initiate list + * processing; in this case - it's ok. + */ + printk(KERN_ERR "%s: prev_desc=0x%p; next_desc=0x%p; " + "prev->hw_next=0x%p\n", __func__, prev_desc, + next_desc, prev_desc ? prev_desc->hw_next : 0); + BUG(); + } + + local_irq_save(flags); + + /* do s/w chaining both for DMA and XOR descriptors */ + prev_desc->hw_next = next_desc; + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + break; + case PPC440SPE_XOR_ID: + /* bind descriptor to the chain */ + while (tail->hw_next) + tail = tail->hw_next; + xor_last_linked = tail; + + if (prev_desc == xor_last_submit) + /* do not link to the last submitted CB */ + break; + ppc440spe_xor_set_link(prev_desc, next_desc); + break; + } + + local_irq_restore(flags); +} + +/** + * ppc440spe_desc_get_src_addr - extract the source address from the descriptor + */ +static u32 ppc440spe_desc_get_src_addr(struct ppc440spe_adma_desc_slot *desc, + struct ppc440spe_adma_chan *chan, int src_idx) +{ + struct dma_cdb *dma_hw_desc; + struct xor_cb *xor_hw_desc; + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + dma_hw_desc = desc->hw_desc; + /* May have 0, 1, 2, or 3 sources */ + switch (dma_hw_desc->opc) { + case DMA_CDB_OPC_NO_OP: + case DMA_CDB_OPC_DFILL128: + return 0; + case DMA_CDB_OPC_DCHECK128: + if (unlikely(src_idx)) { + printk(KERN_ERR "%s: try to get %d source for" + " DCHECK128\n", __func__, src_idx); + BUG(); + } + return le32_to_cpu(dma_hw_desc->sg1l); + case DMA_CDB_OPC_MULTICAST: + case DMA_CDB_OPC_MV_SG1_SG2: + if (unlikely(src_idx > 2)) { + printk(KERN_ERR "%s: try to get %d source from" + " DMA descr\n", __func__, src_idx); + BUG(); + } + if (src_idx) { + if (le32_to_cpu(dma_hw_desc->sg1u) & + DMA_CUED_XOR_WIN_MSK) { + u8 region; + + if (src_idx == 1) + return le32_to_cpu( + dma_hw_desc->sg1l) + + desc->unmap_len; + + region = (le32_to_cpu( + dma_hw_desc->sg1u)) >> + DMA_CUED_REGION_OFF; + + region &= DMA_CUED_REGION_MSK; + switch (region) { + case DMA_RXOR123: + return le32_to_cpu( + dma_hw_desc->sg1l) + + (desc->unmap_len << 1); + case DMA_RXOR124: + return le32_to_cpu( + dma_hw_desc->sg1l) + + (desc->unmap_len * 3); + case DMA_RXOR125: + return le32_to_cpu( + dma_hw_desc->sg1l) + + (desc->unmap_len << 2); + default: + printk(KERN_ERR + "%s: try to" + " get src3 for region %02x" + "PPC440SPE_DESC_RXOR12?\n", + __func__, region); + BUG(); + } + } else { + printk(KERN_ERR + "%s: try to get %d" + " source for non-cued descr\n", + __func__, src_idx); + BUG(); + } + } + return le32_to_cpu(dma_hw_desc->sg1l); + default: + printk(KERN_ERR "%s: unknown OPC 0x%02x\n", + __func__, dma_hw_desc->opc); + BUG(); + } + return le32_to_cpu(dma_hw_desc->sg1l); + case PPC440SPE_XOR_ID: + /* May have up to 16 sources */ + xor_hw_desc = desc->hw_desc; + return xor_hw_desc->ops[src_idx].l; + } + return 0; +} + +/** + * ppc440spe_desc_get_dest_addr - extract the destination address from the + * descriptor + */ +static u32 ppc440spe_desc_get_dest_addr(struct ppc440spe_adma_desc_slot *desc, + struct ppc440spe_adma_chan *chan, int idx) +{ + struct dma_cdb *dma_hw_desc; + struct xor_cb *xor_hw_desc; + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + dma_hw_desc = desc->hw_desc; + + if (likely(!idx)) + return le32_to_cpu(dma_hw_desc->sg2l); + return le32_to_cpu(dma_hw_desc->sg3l); + case PPC440SPE_XOR_ID: + xor_hw_desc = desc->hw_desc; + return xor_hw_desc->cbtal; + } + return 0; +} + +/** + * ppc440spe_desc_get_src_num - extract the number of source addresses from + * the descriptor + */ +static u32 ppc440spe_desc_get_src_num(struct ppc440spe_adma_desc_slot *desc, + struct ppc440spe_adma_chan *chan) +{ + struct dma_cdb *dma_hw_desc; + struct xor_cb *xor_hw_desc; + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + dma_hw_desc = desc->hw_desc; + + switch (dma_hw_desc->opc) { + case DMA_CDB_OPC_NO_OP: + case DMA_CDB_OPC_DFILL128: + return 0; + case DMA_CDB_OPC_DCHECK128: + return 1; + case DMA_CDB_OPC_MV_SG1_SG2: + case DMA_CDB_OPC_MULTICAST: + /* + * Only for RXOR operations we have more than + * one source + */ + if (le32_to_cpu(dma_hw_desc->sg1u) & + DMA_CUED_XOR_WIN_MSK) { + /* RXOR op, there are 2 or 3 sources */ + if (((le32_to_cpu(dma_hw_desc->sg1u) >> + DMA_CUED_REGION_OFF) & + DMA_CUED_REGION_MSK) == DMA_RXOR12) { + /* RXOR 1-2 */ + return 2; + } else { + /* RXOR 1-2-3/1-2-4/1-2-5 */ + return 3; + } + } + return 1; + default: + printk(KERN_ERR "%s: unknown OPC 0x%02x\n", + __func__, dma_hw_desc->opc); + BUG(); + } + case PPC440SPE_XOR_ID: + /* up to 16 sources */ + xor_hw_desc = desc->hw_desc; + return xor_hw_desc->cbc & XOR_CDCR_OAC_MSK; + default: + BUG(); + } + return 0; +} + +/** + * ppc440spe_desc_get_dst_num - get the number of destination addresses in + * this descriptor + */ +static u32 ppc440spe_desc_get_dst_num(struct ppc440spe_adma_desc_slot *desc, + struct ppc440spe_adma_chan *chan) +{ + struct dma_cdb *dma_hw_desc; + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + /* May be 1 or 2 destinations */ + dma_hw_desc = desc->hw_desc; + switch (dma_hw_desc->opc) { + case DMA_CDB_OPC_NO_OP: + case DMA_CDB_OPC_DCHECK128: + return 0; + case DMA_CDB_OPC_MV_SG1_SG2: + case DMA_CDB_OPC_DFILL128: + return 1; + case DMA_CDB_OPC_MULTICAST: + if (desc->dst_cnt == 2) + return 2; + else + return 1; + default: + printk(KERN_ERR "%s: unknown OPC 0x%02x\n", + __func__, dma_hw_desc->opc); + BUG(); + } + case PPC440SPE_XOR_ID: + /* Always only 1 destination */ + return 1; + default: + BUG(); + } + return 0; +} + +/** + * ppc440spe_desc_get_link - get the address of the descriptor that + * follows this one + */ +static inline u32 ppc440spe_desc_get_link(struct ppc440spe_adma_desc_slot *desc, + struct ppc440spe_adma_chan *chan) +{ + if (!desc->hw_next) + return 0; + + return desc->hw_next->phys; +} + +/** + * ppc440spe_desc_is_aligned - check alignment + */ +static inline int ppc440spe_desc_is_aligned( + struct ppc440spe_adma_desc_slot *desc, int num_slots) +{ + return (desc->idx & (num_slots - 1)) ? 0 : 1; +} + +/** + * ppc440spe_chan_xor_slot_count - get the number of slots necessary for + * XOR operation + */ +static int ppc440spe_chan_xor_slot_count(size_t len, int src_cnt, + int *slots_per_op) +{ + int slot_cnt; + + /* each XOR descriptor provides up to 16 source operands */ + slot_cnt = *slots_per_op = (src_cnt + XOR_MAX_OPS - 1)/XOR_MAX_OPS; + + if (likely(len <= PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT)) + return slot_cnt; + + printk(KERN_ERR "%s: len %d > max %d !!\n", + __func__, len, PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT); + BUG(); + return slot_cnt; +} + +/** + * ppc440spe_dma2_pq_slot_count - get the number of slots necessary for + * DMA2 PQ operation + */ +static int ppc440spe_dma2_pq_slot_count(dma_addr_t *srcs, + int src_cnt, size_t len) +{ + signed long long order = 0; + int state = 0; + int addr_count = 0; + int i; + for (i = 1; i < src_cnt; i++) { + dma_addr_t cur_addr = srcs[i]; + dma_addr_t old_addr = srcs[i-1]; + switch (state) { + case 0: + if (cur_addr == old_addr + len) { + /* direct RXOR */ + order = 1; + state = 1; + if (i == src_cnt-1) + addr_count++; + } else if (old_addr == cur_addr + len) { + /* reverse RXOR */ + order = -1; + state = 1; + if (i == src_cnt-1) + addr_count++; + } else { + state = 3; + } + break; + case 1: + if (i == src_cnt-2 || (order == -1 + && cur_addr != old_addr - len)) { + order = 0; + state = 0; + addr_count++; + } else if (cur_addr == old_addr + len*order) { + state = 2; + if (i == src_cnt-1) + addr_count++; + } else if (cur_addr == old_addr + 2*len) { + state = 2; + if (i == src_cnt-1) + addr_count++; + } else if (cur_addr == old_addr + 3*len) { + state = 2; + if (i == src_cnt-1) + addr_count++; + } else { + order = 0; + state = 0; + addr_count++; + } + break; + case 2: + order = 0; + state = 0; + addr_count++; + break; + } + if (state == 3) + break; + } + if (src_cnt <= 1 || (state != 1 && state != 2)) { + pr_err("%s: src_cnt=%d, state=%d, addr_count=%d, order=%lld\n", + __func__, src_cnt, state, addr_count, order); + for (i = 0; i < src_cnt; i++) + pr_err("\t[%d] 0x%llx \n", i, srcs[i]); + BUG(); + } + + return (addr_count + XOR_MAX_OPS - 1) / XOR_MAX_OPS; +} + + +/****************************************************************************** + * ADMA channel low-level routines + ******************************************************************************/ + +static u32 +ppc440spe_chan_get_current_descriptor(struct ppc440spe_adma_chan *chan); +static void ppc440spe_chan_append(struct ppc440spe_adma_chan *chan); + +/** + * ppc440spe_adma_device_clear_eot_status - interrupt ack to XOR or DMA engine + */ +static void ppc440spe_adma_device_clear_eot_status( + struct ppc440spe_adma_chan *chan) +{ + struct dma_regs *dma_reg; + struct xor_regs *xor_reg; + u8 *p = chan->device->dma_desc_pool_virt; + struct dma_cdb *cdb; + u32 rv, i; + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + /* read FIFO to ack */ + dma_reg = chan->device->dma_reg; + while ((rv = ioread32(&dma_reg->csfpl))) { + i = rv & DMA_CDB_ADDR_MSK; + cdb = (struct dma_cdb *)&p[i - + (u32)chan->device->dma_desc_pool]; + + /* Clear opcode to ack. This is necessary for + * ZeroSum operations only + */ + cdb->opc = 0; + + if (test_bit(PPC440SPE_RXOR_RUN, + &ppc440spe_rxor_state)) { + /* probably this is a completed RXOR op, + * get pointer to CDB using the fact that + * physical and virtual addresses of CDB + * in pools have the same offsets + */ + if (le32_to_cpu(cdb->sg1u) & + DMA_CUED_XOR_BASE) { + /* this is a RXOR */ + clear_bit(PPC440SPE_RXOR_RUN, + &ppc440spe_rxor_state); + } + } + + if (rv & DMA_CDB_STATUS_MSK) { + /* ZeroSum check failed + */ + struct ppc440spe_adma_desc_slot *iter; + dma_addr_t phys = rv & ~DMA_CDB_MSK; + + /* + * Update the status of corresponding + * descriptor. + */ + list_for_each_entry(iter, &chan->chain, + chain_node) { + if (iter->phys == phys) + break; + } + /* + * if cannot find the corresponding + * slot it's a bug + */ + BUG_ON(&iter->chain_node == &chan->chain); + + if (iter->xor_check_result) { + if (test_bit(PPC440SPE_DESC_PCHECK, + &iter->flags)) { + *iter->xor_check_result |= + SUM_CHECK_P_RESULT; + } else + if (test_bit(PPC440SPE_DESC_QCHECK, + &iter->flags)) { + *iter->xor_check_result |= + SUM_CHECK_Q_RESULT; + } else + BUG(); + } + } + } + + rv = ioread32(&dma_reg->dsts); + if (rv) { + pr_err("DMA%d err status: 0x%x\n", + chan->device->id, rv); + /* write back to clear */ + iowrite32(rv, &dma_reg->dsts); + } + break; + case PPC440SPE_XOR_ID: + /* reset status bits to ack */ + xor_reg = chan->device->xor_reg; + rv = ioread32be(&xor_reg->sr); + iowrite32be(rv, &xor_reg->sr); + + if (rv & (XOR_IE_ICBIE_BIT|XOR_IE_ICIE_BIT|XOR_IE_RPTIE_BIT)) { + if (rv & XOR_IE_RPTIE_BIT) { + /* Read PLB Timeout Error. + * Try to resubmit the CB + */ + u32 val = ioread32be(&xor_reg->ccbalr); + + iowrite32be(val, &xor_reg->cblalr); + + val = ioread32be(&xor_reg->crsr); + iowrite32be(val | XOR_CRSR_XAE_BIT, + &xor_reg->crsr); + } else + pr_err("XOR ERR 0x%x status\n", rv); + break; + } + + /* if the XORcore is idle, but there are unprocessed CBs + * then refetch the s/w chain here + */ + if (!(ioread32be(&xor_reg->sr) & XOR_SR_XCP_BIT) && + do_xor_refetch) + ppc440spe_chan_append(chan); + break; + } +} + +/** + * ppc440spe_chan_is_busy - get the channel status + */ +static int ppc440spe_chan_is_busy(struct ppc440spe_adma_chan *chan) +{ + struct dma_regs *dma_reg; + struct xor_regs *xor_reg; + int busy = 0; + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + dma_reg = chan->device->dma_reg; + /* if command FIFO's head and tail pointers are equal and + * status tail is the same as command, then channel is free + */ + if (ioread16(&dma_reg->cpfhp) != ioread16(&dma_reg->cpftp) || + ioread16(&dma_reg->cpftp) != ioread16(&dma_reg->csftp)) + busy = 1; + break; + case PPC440SPE_XOR_ID: + /* use the special status bit for the XORcore + */ + xor_reg = chan->device->xor_reg; + busy = (ioread32be(&xor_reg->sr) & XOR_SR_XCP_BIT) ? 1 : 0; + break; + } + + return busy; +} + +/** + * ppc440spe_chan_set_first_xor_descriptor - init XORcore chain + */ +static void ppc440spe_chan_set_first_xor_descriptor( + struct ppc440spe_adma_chan *chan, + struct ppc440spe_adma_desc_slot *next_desc) +{ + struct xor_regs *xor_reg = chan->device->xor_reg; + + if (ioread32be(&xor_reg->sr) & XOR_SR_XCP_BIT) + printk(KERN_INFO "%s: Warn: XORcore is running " + "when try to set the first CDB!\n", + __func__); + + xor_last_submit = xor_last_linked = next_desc; + + iowrite32be(XOR_CRSR_64BA_BIT, &xor_reg->crsr); + + iowrite32be(next_desc->phys, &xor_reg->cblalr); + iowrite32be(0, &xor_reg->cblahr); + iowrite32be(ioread32be(&xor_reg->cbcr) | XOR_CBCR_LNK_BIT, + &xor_reg->cbcr); + + chan->hw_chain_inited = 1; +} + +/** + * ppc440spe_dma_put_desc - put DMA0,1 descriptor to FIFO. + * called with irqs disabled + */ +static void ppc440spe_dma_put_desc(struct ppc440spe_adma_chan *chan, + struct ppc440spe_adma_desc_slot *desc) +{ + u32 pcdb; + struct dma_regs *dma_reg = chan->device->dma_reg; + + pcdb = desc->phys; + if (!test_bit(PPC440SPE_DESC_INT, &desc->flags)) + pcdb |= DMA_CDB_NO_INT; + + chan_last_sub[chan->device->id] = desc; + + ADMA_LL_DBG(print_cb(chan, desc->hw_desc)); + + iowrite32(pcdb, &dma_reg->cpfpl); +} + +/** + * ppc440spe_chan_append - update the h/w chain in the channel + */ +static void ppc440spe_chan_append(struct ppc440spe_adma_chan *chan) +{ + struct xor_regs *xor_reg; + struct ppc440spe_adma_desc_slot *iter; + struct xor_cb *xcb; + u32 cur_desc; + unsigned long flags; + + local_irq_save(flags); + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + cur_desc = ppc440spe_chan_get_current_descriptor(chan); + + if (likely(cur_desc)) { + iter = chan_last_sub[chan->device->id]; + BUG_ON(!iter); + } else { + /* first peer */ + iter = chan_first_cdb[chan->device->id]; + BUG_ON(!iter); + ppc440spe_dma_put_desc(chan, iter); + chan->hw_chain_inited = 1; + } + + /* is there something new to append */ + if (!iter->hw_next) + break; + + /* flush descriptors from the s/w queue to fifo */ + list_for_each_entry_continue(iter, &chan->chain, chain_node) { + ppc440spe_dma_put_desc(chan, iter); + if (!iter->hw_next) + break; + } + break; + case PPC440SPE_XOR_ID: + /* update h/w links and refetch */ + if (!xor_last_submit->hw_next) + break; + + xor_reg = chan->device->xor_reg; + /* the last linked CDB has to generate an interrupt + * that we'd be able to append the next lists to h/w + * regardless of the XOR engine state at the moment of + * appending of these next lists + */ + xcb = xor_last_linked->hw_desc; + xcb->cbc |= XOR_CBCR_CBCE_BIT; + + if (!(ioread32be(&xor_reg->sr) & XOR_SR_XCP_BIT)) { + /* XORcore is idle. Refetch now */ + do_xor_refetch = 0; + ppc440spe_xor_set_link(xor_last_submit, + xor_last_submit->hw_next); + + ADMA_LL_DBG(print_cb_list(chan, + xor_last_submit->hw_next)); + + xor_last_submit = xor_last_linked; + iowrite32be(ioread32be(&xor_reg->crsr) | + XOR_CRSR_RCBE_BIT | XOR_CRSR_64BA_BIT, + &xor_reg->crsr); + } else { + /* XORcore is running. Refetch later in the handler */ + do_xor_refetch = 1; + } + + break; + } + + local_irq_restore(flags); +} + +/** + * ppc440spe_chan_get_current_descriptor - get the currently executed descriptor + */ +static u32 +ppc440spe_chan_get_current_descriptor(struct ppc440spe_adma_chan *chan) +{ + struct dma_regs *dma_reg; + struct xor_regs *xor_reg; + + if (unlikely(!chan->hw_chain_inited)) + /* h/w descriptor chain is not initialized yet */ + return 0; + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + dma_reg = chan->device->dma_reg; + return ioread32(&dma_reg->acpl) & (~DMA_CDB_MSK); + case PPC440SPE_XOR_ID: + xor_reg = chan->device->xor_reg; + return ioread32be(&xor_reg->ccbalr); + } + return 0; +} + +/** + * ppc440spe_chan_run - enable the channel + */ +static void ppc440spe_chan_run(struct ppc440spe_adma_chan *chan) +{ + struct xor_regs *xor_reg; + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + /* DMAs are always enabled, do nothing */ + break; + case PPC440SPE_XOR_ID: + /* drain write buffer */ + xor_reg = chan->device->xor_reg; + + /* fetch descriptor pointed to in */ + iowrite32be(XOR_CRSR_64BA_BIT | XOR_CRSR_XAE_BIT, + &xor_reg->crsr); + break; + } +} + +/****************************************************************************** + * ADMA device level + ******************************************************************************/ + +static void ppc440spe_chan_start_null_xor(struct ppc440spe_adma_chan *chan); +static int ppc440spe_adma_alloc_chan_resources(struct dma_chan *chan); + +static dma_cookie_t +ppc440spe_adma_tx_submit(struct dma_async_tx_descriptor *tx); + +static void ppc440spe_adma_set_dest(struct ppc440spe_adma_desc_slot *tx, + dma_addr_t addr, int index); +static void +ppc440spe_adma_memcpy_xor_set_src(struct ppc440spe_adma_desc_slot *tx, + dma_addr_t addr, int index); + +static void +ppc440spe_adma_pq_set_dest(struct ppc440spe_adma_desc_slot *tx, + dma_addr_t *paddr, unsigned long flags); +static void +ppc440spe_adma_pq_set_src(struct ppc440spe_adma_desc_slot *tx, + dma_addr_t addr, int index); +static void +ppc440spe_adma_pq_set_src_mult(struct ppc440spe_adma_desc_slot *tx, + unsigned char mult, int index, int dst_pos); +static void +ppc440spe_adma_pqzero_sum_set_dest(struct ppc440spe_adma_desc_slot *tx, + dma_addr_t paddr, dma_addr_t qaddr); + +static struct page *ppc440spe_rxor_srcs[32]; + +/** + * ppc440spe_can_rxor - check if the operands may be processed with RXOR + */ +static int ppc440spe_can_rxor(struct page **srcs, int src_cnt, size_t len) +{ + int i, order = 0, state = 0; + int idx = 0; + + if (unlikely(!(src_cnt > 1))) + return 0; + + BUG_ON(src_cnt > ARRAY_SIZE(ppc440spe_rxor_srcs)); + + /* Skip holes in the source list before checking */ + for (i = 0; i < src_cnt; i++) { + if (!srcs[i]) + continue; + ppc440spe_rxor_srcs[idx++] = srcs[i]; + } + src_cnt = idx; + + for (i = 1; i < src_cnt; i++) { + char *cur_addr = page_address(ppc440spe_rxor_srcs[i]); + char *old_addr = page_address(ppc440spe_rxor_srcs[i - 1]); + + switch (state) { + case 0: + if (cur_addr == old_addr + len) { + /* direct RXOR */ + order = 1; + state = 1; + } else if (old_addr == cur_addr + len) { + /* reverse RXOR */ + order = -1; + state = 1; + } else + goto out; + break; + case 1: + if ((i == src_cnt - 2) || + (order == -1 && cur_addr != old_addr - len)) { + order = 0; + state = 0; + } else if ((cur_addr == old_addr + len * order) || + (cur_addr == old_addr + 2 * len) || + (cur_addr == old_addr + 3 * len)) { + state = 2; + } else { + order = 0; + state = 0; + } + break; + case 2: + order = 0; + state = 0; + break; + } + } + +out: + if (state == 1 || state == 2) + return 1; + + return 0; +} + +/** + * ppc440spe_adma_device_estimate - estimate the efficiency of processing + * the operation given on this channel. It's assumed that 'chan' is + * capable to process 'cap' type of operation. + * @chan: channel to use + * @cap: type of transaction + * @dst_lst: array of destination pointers + * @dst_cnt: number of destination operands + * @src_lst: array of source pointers + * @src_cnt: number of source operands + * @src_sz: size of each source operand + */ +static int ppc440spe_adma_estimate(struct dma_chan *chan, + enum dma_transaction_type cap, struct page **dst_lst, int dst_cnt, + struct page **src_lst, int src_cnt, size_t src_sz) +{ + int ef = 1; + + if (cap == DMA_PQ || cap == DMA_PQ_VAL) { + /* If RAID-6 capabilities were not activated don't try + * to use them + */ + if (unlikely(!ppc440spe_r6_enabled)) + return -1; + } + /* In the current implementation of ppc440spe ADMA driver it + * makes sense to pick out only pq case, because it may be + * processed: + * (1) either using Biskup method on DMA2; + * (2) or on DMA0/1. + * Thus we give a favour to (1) if the sources are suitable; + * else let it be processed on one of the DMA0/1 engines. + * In the sum_product case where destination is also the + * source process it on DMA0/1 only. + */ + if (cap == DMA_PQ && chan->chan_id == PPC440SPE_XOR_ID) { + + if (dst_cnt == 1 && src_cnt == 2 && dst_lst[0] == src_lst[1]) + ef = 0; /* sum_product case, process on DMA0/1 */ + else if (ppc440spe_can_rxor(src_lst, src_cnt, src_sz)) + ef = 3; /* override (DMA0/1 + idle) */ + else + ef = 0; /* can't process on DMA2 if !rxor */ + } + + /* channel idleness increases the priority */ + if (likely(ef) && + !ppc440spe_chan_is_busy(to_ppc440spe_adma_chan(chan))) + ef++; + + return ef; +} + +struct dma_chan * +ppc440spe_async_tx_find_best_channel(enum dma_transaction_type cap, + struct page **dst_lst, int dst_cnt, struct page **src_lst, + int src_cnt, size_t src_sz) +{ + struct dma_chan *best_chan = NULL; + struct ppc_dma_chan_ref *ref; + int best_rank = -1; + + if (unlikely(!src_sz)) + return NULL; + if (src_sz > PAGE_SIZE) { + /* + * should a user of the api ever pass > PAGE_SIZE requests + * we sort out cases where temporary page-sized buffers + * are used. + */ + switch (cap) { + case DMA_PQ: + if (src_cnt == 1 && dst_lst[1] == src_lst[0]) + return NULL; + if (src_cnt == 2 && dst_lst[1] == src_lst[1]) + return NULL; + break; + case DMA_PQ_VAL: + case DMA_XOR_VAL: + return NULL; + default: + break; + } + } + + list_for_each_entry(ref, &ppc440spe_adma_chan_list, node) { + if (dma_has_cap(cap, ref->chan->device->cap_mask)) { + int rank; + + rank = ppc440spe_adma_estimate(ref->chan, cap, dst_lst, + dst_cnt, src_lst, src_cnt, src_sz); + if (rank > best_rank) { + best_rank = rank; + best_chan = ref->chan; + } + } + } + + return best_chan; +} +EXPORT_SYMBOL_GPL(ppc440spe_async_tx_find_best_channel); + +/** + * ppc440spe_get_group_entry - get group entry with index idx + * @tdesc: is the last allocated slot in the group. + */ +static struct ppc440spe_adma_desc_slot * +ppc440spe_get_group_entry(struct ppc440spe_adma_desc_slot *tdesc, u32 entry_idx) +{ + struct ppc440spe_adma_desc_slot *iter = tdesc->group_head; + int i = 0; + + if (entry_idx < 0 || entry_idx >= (tdesc->src_cnt + tdesc->dst_cnt)) { + printk("%s: entry_idx %d, src_cnt %d, dst_cnt %d\n", + __func__, entry_idx, tdesc->src_cnt, tdesc->dst_cnt); + BUG(); + } + + list_for_each_entry(iter, &tdesc->group_list, chain_node) { + if (i++ == entry_idx) + break; + } + return iter; +} + +/** + * ppc440spe_adma_free_slots - flags descriptor slots for reuse + * @slot: Slot to free + * Caller must hold &ppc440spe_chan->lock while calling this function + */ +static void ppc440spe_adma_free_slots(struct ppc440spe_adma_desc_slot *slot, + struct ppc440spe_adma_chan *chan) +{ + int stride = slot->slots_per_op; + + while (stride--) { + slot->slots_per_op = 0; + slot = list_entry(slot->slot_node.next, + struct ppc440spe_adma_desc_slot, + slot_node); + } +} + +static void ppc440spe_adma_unmap(struct ppc440spe_adma_chan *chan, + struct ppc440spe_adma_desc_slot *desc) +{ + u32 src_cnt, dst_cnt; + dma_addr_t addr; + + /* + * get the number of sources & destination + * included in this descriptor and unmap + * them all + */ + src_cnt = ppc440spe_desc_get_src_num(desc, chan); + dst_cnt = ppc440spe_desc_get_dst_num(desc, chan); + + /* unmap destinations */ + if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) { + while (dst_cnt--) { + addr = ppc440spe_desc_get_dest_addr( + desc, chan, dst_cnt); + dma_unmap_page(chan->device->dev, + addr, desc->unmap_len, + DMA_FROM_DEVICE); + } + } + + /* unmap sources */ + if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) { + while (src_cnt--) { + addr = ppc440spe_desc_get_src_addr( + desc, chan, src_cnt); + dma_unmap_page(chan->device->dev, + addr, desc->unmap_len, + DMA_TO_DEVICE); + } + } +} + +/** + * ppc440spe_adma_run_tx_complete_actions - call functions to be called + * upon completion + */ +static dma_cookie_t ppc440spe_adma_run_tx_complete_actions( + struct ppc440spe_adma_desc_slot *desc, + struct ppc440spe_adma_chan *chan, + dma_cookie_t cookie) +{ + int i; + + BUG_ON(desc->async_tx.cookie < 0); + if (desc->async_tx.cookie > 0) { + cookie = desc->async_tx.cookie; + desc->async_tx.cookie = 0; + + /* call the callback (must not sleep or submit new + * operations to this channel) + */ + if (desc->async_tx.callback) + desc->async_tx.callback( + desc->async_tx.callback_param); + + /* unmap dma addresses + * (unmap_single vs unmap_page?) + * + * actually, ppc's dma_unmap_page() functions are empty, so + * the following code is just for the sake of completeness + */ + if (chan && chan->needs_unmap && desc->group_head && + desc->unmap_len) { + struct ppc440spe_adma_desc_slot *unmap = + desc->group_head; + /* assume 1 slot per op always */ + u32 slot_count = unmap->slot_cnt; + + /* Run through the group list and unmap addresses */ + for (i = 0; i < slot_count; i++) { + BUG_ON(!unmap); + ppc440spe_adma_unmap(chan, unmap); + unmap = unmap->hw_next; + } + } + } + + /* run dependent operations */ + dma_run_dependencies(&desc->async_tx); + + return cookie; +} + +/** + * ppc440spe_adma_clean_slot - clean up CDB slot (if ack is set) + */ +static int ppc440spe_adma_clean_slot(struct ppc440spe_adma_desc_slot *desc, + struct ppc440spe_adma_chan *chan) +{ + /* the client is allowed to attach dependent operations + * until 'ack' is set + */ + if (!async_tx_test_ack(&desc->async_tx)) + return 0; + + /* leave the last descriptor in the chain + * so we can append to it + */ + if (list_is_last(&desc->chain_node, &chan->chain) || + desc->phys == ppc440spe_chan_get_current_descriptor(chan)) + return 1; + + if (chan->device->id != PPC440SPE_XOR_ID) { + /* our DMA interrupt handler clears opc field of + * each processed descriptor. For all types of + * operations except for ZeroSum we do not actually + * need ack from the interrupt handler. ZeroSum is a + * special case since the result of this operation + * is available from the handler only, so if we see + * such type of descriptor (which is unprocessed yet) + * then leave it in chain. + */ + struct dma_cdb *cdb = desc->hw_desc; + if (cdb->opc == DMA_CDB_OPC_DCHECK128) + return 1; + } + + dev_dbg(chan->device->common.dev, "\tfree slot %llx: %d stride: %d\n", + desc->phys, desc->idx, desc->slots_per_op); + + list_del(&desc->chain_node); + ppc440spe_adma_free_slots(desc, chan); + return 0; +} + +/** + * __ppc440spe_adma_slot_cleanup - this is the common clean-up routine + * which runs through the channel CDBs list until reach the descriptor + * currently processed. When routine determines that all CDBs of group + * are completed then corresponding callbacks (if any) are called and slots + * are freed. + */ +static void __ppc440spe_adma_slot_cleanup(struct ppc440spe_adma_chan *chan) +{ + struct ppc440spe_adma_desc_slot *iter, *_iter, *group_start = NULL; + dma_cookie_t cookie = 0; + u32 current_desc = ppc440spe_chan_get_current_descriptor(chan); + int busy = ppc440spe_chan_is_busy(chan); + int seen_current = 0, slot_cnt = 0, slots_per_op = 0; + + dev_dbg(chan->device->common.dev, "ppc440spe adma%d: %s\n", + chan->device->id, __func__); + + if (!current_desc) { + /* There were no transactions yet, so + * nothing to clean + */ + return; + } + + /* free completed slots from the chain starting with + * the oldest descriptor + */ + list_for_each_entry_safe(iter, _iter, &chan->chain, + chain_node) { + dev_dbg(chan->device->common.dev, "\tcookie: %d slot: %d " + "busy: %d this_desc: %#llx next_desc: %#x " + "cur: %#x ack: %d\n", + iter->async_tx.cookie, iter->idx, busy, iter->phys, + ppc440spe_desc_get_link(iter, chan), current_desc, + async_tx_test_ack(&iter->async_tx)); + prefetch(_iter); + prefetch(&_iter->async_tx); + + /* do not advance past the current descriptor loaded into the + * hardware channel,subsequent descriptors are either in process + * or have not been submitted + */ + if (seen_current) + break; + + /* stop the search if we reach the current descriptor and the + * channel is busy, or if it appears that the current descriptor + * needs to be re-read (i.e. has been appended to) + */ + if (iter->phys == current_desc) { + BUG_ON(seen_current++); + if (busy || ppc440spe_desc_get_link(iter, chan)) { + /* not all descriptors of the group have + * been completed; exit. + */ + break; + } + } + + /* detect the start of a group transaction */ + if (!slot_cnt && !slots_per_op) { + slot_cnt = iter->slot_cnt; + slots_per_op = iter->slots_per_op; + if (slot_cnt <= slots_per_op) { + slot_cnt = 0; + slots_per_op = 0; + } + } + + if (slot_cnt) { + if (!group_start) + group_start = iter; + slot_cnt -= slots_per_op; + } + + /* all the members of a group are complete */ + if (slots_per_op != 0 && slot_cnt == 0) { + struct ppc440spe_adma_desc_slot *grp_iter, *_grp_iter; + int end_of_chain = 0; + + /* clean up the group */ + slot_cnt = group_start->slot_cnt; + grp_iter = group_start; + list_for_each_entry_safe_from(grp_iter, _grp_iter, + &chan->chain, chain_node) { + + cookie = ppc440spe_adma_run_tx_complete_actions( + grp_iter, chan, cookie); + + slot_cnt -= slots_per_op; + end_of_chain = ppc440spe_adma_clean_slot( + grp_iter, chan); + if (end_of_chain && slot_cnt) { + /* Should wait for ZeroSum completion */ + if (cookie > 0) + chan->completed_cookie = cookie; + return; + } + + if (slot_cnt == 0 || end_of_chain) + break; + } + + /* the group should be complete at this point */ + BUG_ON(slot_cnt); + + slots_per_op = 0; + group_start = NULL; + if (end_of_chain) + break; + else + continue; + } else if (slots_per_op) /* wait for group completion */ + continue; + + cookie = ppc440spe_adma_run_tx_complete_actions(iter, chan, + cookie); + + if (ppc440spe_adma_clean_slot(iter, chan)) + break; + } + + BUG_ON(!seen_current); + + if (cookie > 0) { + chan->completed_cookie = cookie; + pr_debug("\tcompleted cookie %d\n", cookie); + } + +} + +/** + * ppc440spe_adma_tasklet - clean up watch-dog initiator + */ +static void ppc440spe_adma_tasklet(unsigned long data) +{ + struct ppc440spe_adma_chan *chan = (struct ppc440spe_adma_chan *) data; + + spin_lock_nested(&chan->lock, SINGLE_DEPTH_NESTING); + __ppc440spe_adma_slot_cleanup(chan); + spin_unlock(&chan->lock); +} + +/** + * ppc440spe_adma_slot_cleanup - clean up scheduled initiator + */ +static void ppc440spe_adma_slot_cleanup(struct ppc440spe_adma_chan *chan) +{ + spin_lock_bh(&chan->lock); + __ppc440spe_adma_slot_cleanup(chan); + spin_unlock_bh(&chan->lock); +} + +/** + * ppc440spe_adma_alloc_slots - allocate free slots (if any) + */ +static struct ppc440spe_adma_desc_slot *ppc440spe_adma_alloc_slots( + struct ppc440spe_adma_chan *chan, int num_slots, + int slots_per_op) +{ + struct ppc440spe_adma_desc_slot *iter = NULL, *_iter; + struct ppc440spe_adma_desc_slot *alloc_start = NULL; + struct list_head chain = LIST_HEAD_INIT(chain); + int slots_found, retry = 0; + + + BUG_ON(!num_slots || !slots_per_op); + /* start search from the last allocated descrtiptor + * if a contiguous allocation can not be found start searching + * from the beginning of the list + */ +retry: + slots_found = 0; + if (retry == 0) + iter = chan->last_used; + else + iter = list_entry(&chan->all_slots, + struct ppc440spe_adma_desc_slot, + slot_node); + list_for_each_entry_safe_continue(iter, _iter, &chan->all_slots, + slot_node) { + prefetch(_iter); + prefetch(&_iter->async_tx); + if (iter->slots_per_op) { + slots_found = 0; + continue; + } + + /* start the allocation if the slot is correctly aligned */ + if (!slots_found++) + alloc_start = iter; + + if (slots_found == num_slots) { + struct ppc440spe_adma_desc_slot *alloc_tail = NULL; + struct ppc440spe_adma_desc_slot *last_used = NULL; + + iter = alloc_start; + while (num_slots) { + int i; + /* pre-ack all but the last descriptor */ + if (num_slots != slots_per_op) + async_tx_ack(&iter->async_tx); + + list_add_tail(&iter->chain_node, &chain); + alloc_tail = iter; + iter->async_tx.cookie = 0; + iter->hw_next = NULL; + iter->flags = 0; + iter->slot_cnt = num_slots; + iter->xor_check_result = NULL; + for (i = 0; i < slots_per_op; i++) { + iter->slots_per_op = slots_per_op - i; + last_used = iter; + iter = list_entry(iter->slot_node.next, + struct ppc440spe_adma_desc_slot, + slot_node); + } + num_slots -= slots_per_op; + } + alloc_tail->group_head = alloc_start; + alloc_tail->async_tx.cookie = -EBUSY; + list_splice(&chain, &alloc_tail->group_list); + chan->last_used = last_used; + return alloc_tail; + } + } + if (!retry++) + goto retry; + + /* try to free some slots if the allocation fails */ + tasklet_schedule(&chan->irq_tasklet); + return NULL; +} + +/** + * ppc440spe_adma_alloc_chan_resources - allocate pools for CDB slots + */ +static int ppc440spe_adma_alloc_chan_resources(struct dma_chan *chan) +{ + struct ppc440spe_adma_chan *ppc440spe_chan; + struct ppc440spe_adma_desc_slot *slot = NULL; + char *hw_desc; + int i, db_sz; + int init; + + ppc440spe_chan = to_ppc440spe_adma_chan(chan); + init = ppc440spe_chan->slots_allocated ? 0 : 1; + chan->chan_id = ppc440spe_chan->device->id; + + /* Allocate descriptor slots */ + i = ppc440spe_chan->slots_allocated; + if (ppc440spe_chan->device->id != PPC440SPE_XOR_ID) + db_sz = sizeof(struct dma_cdb); + else + db_sz = sizeof(struct xor_cb); + + for (; i < (ppc440spe_chan->device->pool_size / db_sz); i++) { + slot = kzalloc(sizeof(struct ppc440spe_adma_desc_slot), + GFP_KERNEL); + if (!slot) { + printk(KERN_INFO "SPE ADMA Channel only initialized" + " %d descriptor slots", i--); + break; + } + + hw_desc = (char *) ppc440spe_chan->device->dma_desc_pool_virt; + slot->hw_desc = (void *) &hw_desc[i * db_sz]; + dma_async_tx_descriptor_init(&slot->async_tx, chan); + slot->async_tx.tx_submit = ppc440spe_adma_tx_submit; + INIT_LIST_HEAD(&slot->chain_node); + INIT_LIST_HEAD(&slot->slot_node); + INIT_LIST_HEAD(&slot->group_list); + slot->phys = ppc440spe_chan->device->dma_desc_pool + i * db_sz; + slot->idx = i; + + spin_lock_bh(&ppc440spe_chan->lock); + ppc440spe_chan->slots_allocated++; + list_add_tail(&slot->slot_node, &ppc440spe_chan->all_slots); + spin_unlock_bh(&ppc440spe_chan->lock); + } + + if (i && !ppc440spe_chan->last_used) { + ppc440spe_chan->last_used = + list_entry(ppc440spe_chan->all_slots.next, + struct ppc440spe_adma_desc_slot, + slot_node); + } + + dev_dbg(ppc440spe_chan->device->common.dev, + "ppc440spe adma%d: allocated %d descriptor slots\n", + ppc440spe_chan->device->id, i); + + /* initialize the channel and the chain with a null operation */ + if (init) { + switch (ppc440spe_chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + ppc440spe_chan->hw_chain_inited = 0; + /* Use WXOR for self-testing */ + if (!ppc440spe_r6_tchan) + ppc440spe_r6_tchan = ppc440spe_chan; + break; + case PPC440SPE_XOR_ID: + ppc440spe_chan_start_null_xor(ppc440spe_chan); + break; + default: + BUG(); + } + ppc440spe_chan->needs_unmap = 1; + } + + return (i > 0) ? i : -ENOMEM; +} + +/** + * ppc440spe_desc_assign_cookie - assign a cookie + */ +static dma_cookie_t ppc440spe_desc_assign_cookie( + struct ppc440spe_adma_chan *chan, + struct ppc440spe_adma_desc_slot *desc) +{ + dma_cookie_t cookie = chan->common.cookie; + + cookie++; + if (cookie < 0) + cookie = 1; + chan->common.cookie = desc->async_tx.cookie = cookie; + return cookie; +} + +/** + * ppc440spe_rxor_set_region_data - + */ +static void ppc440spe_rxor_set_region(struct ppc440spe_adma_desc_slot *desc, + u8 xor_arg_no, u32 mask) +{ + struct xor_cb *xcb = desc->hw_desc; + + xcb->ops[xor_arg_no].h |= mask; +} + +/** + * ppc440spe_rxor_set_src - + */ +static void ppc440spe_rxor_set_src(struct ppc440spe_adma_desc_slot *desc, + u8 xor_arg_no, dma_addr_t addr) +{ + struct xor_cb *xcb = desc->hw_desc; + + xcb->ops[xor_arg_no].h |= DMA_CUED_XOR_BASE; + xcb->ops[xor_arg_no].l = addr; +} + +/** + * ppc440spe_rxor_set_mult - + */ +static void ppc440spe_rxor_set_mult(struct ppc440spe_adma_desc_slot *desc, + u8 xor_arg_no, u8 idx, u8 mult) +{ + struct xor_cb *xcb = desc->hw_desc; + + xcb->ops[xor_arg_no].h |= mult << (DMA_CUED_MULT1_OFF + idx * 8); +} + +/** + * ppc440spe_adma_check_threshold - append CDBs to h/w chain if threshold + * has been achieved + */ +static void ppc440spe_adma_check_threshold(struct ppc440spe_adma_chan *chan) +{ + dev_dbg(chan->device->common.dev, "ppc440spe adma%d: pending: %d\n", + chan->device->id, chan->pending); + + if (chan->pending >= PPC440SPE_ADMA_THRESHOLD) { + chan->pending = 0; + ppc440spe_chan_append(chan); + } +} + +/** + * ppc440spe_adma_tx_submit - submit new descriptor group to the channel + * (it's not necessary that descriptors will be submitted to the h/w + * chains too right now) + */ +static dma_cookie_t ppc440spe_adma_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct ppc440spe_adma_desc_slot *sw_desc; + struct ppc440spe_adma_chan *chan = to_ppc440spe_adma_chan(tx->chan); + struct ppc440spe_adma_desc_slot *group_start, *old_chain_tail; + int slot_cnt; + int slots_per_op; + dma_cookie_t cookie; + + sw_desc = tx_to_ppc440spe_adma_slot(tx); + + group_start = sw_desc->group_head; + slot_cnt = group_start->slot_cnt; + slots_per_op = group_start->slots_per_op; + + spin_lock_bh(&chan->lock); + + cookie = ppc440spe_desc_assign_cookie(chan, sw_desc); + + if (unlikely(list_empty(&chan->chain))) { + /* first peer */ + list_splice_init(&sw_desc->group_list, &chan->chain); + chan_first_cdb[chan->device->id] = group_start; + } else { + /* isn't first peer, bind CDBs to chain */ + old_chain_tail = list_entry(chan->chain.prev, + struct ppc440spe_adma_desc_slot, + chain_node); + list_splice_init(&sw_desc->group_list, + &old_chain_tail->chain_node); + /* fix up the hardware chain */ + ppc440spe_desc_set_link(chan, old_chain_tail, group_start); + } + + /* increment the pending count by the number of operations */ + chan->pending += slot_cnt / slots_per_op; + ppc440spe_adma_check_threshold(chan); + spin_unlock_bh(&chan->lock); + + dev_dbg(chan->device->common.dev, + "ppc440spe adma%d: %s cookie: %d slot: %d tx %p\n", + chan->device->id, __func__, + sw_desc->async_tx.cookie, sw_desc->idx, sw_desc); + + return cookie; +} + +/** + * ppc440spe_adma_prep_dma_interrupt - prepare CDB for a pseudo DMA operation + */ +static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_interrupt( + struct dma_chan *chan, unsigned long flags) +{ + struct ppc440spe_adma_chan *ppc440spe_chan; + struct ppc440spe_adma_desc_slot *sw_desc, *group_start; + int slot_cnt, slots_per_op; + + ppc440spe_chan = to_ppc440spe_adma_chan(chan); + + dev_dbg(ppc440spe_chan->device->common.dev, + "ppc440spe adma%d: %s\n", ppc440spe_chan->device->id, + __func__); + + spin_lock_bh(&ppc440spe_chan->lock); + slot_cnt = slots_per_op = 1; + sw_desc = ppc440spe_adma_alloc_slots(ppc440spe_chan, slot_cnt, + slots_per_op); + if (sw_desc) { + group_start = sw_desc->group_head; + ppc440spe_desc_init_interrupt(group_start, ppc440spe_chan); + group_start->unmap_len = 0; + sw_desc->async_tx.flags = flags; + } + spin_unlock_bh(&ppc440spe_chan->lock); + + return sw_desc ? &sw_desc->async_tx : NULL; +} + +/** + * ppc440spe_adma_prep_dma_memcpy - prepare CDB for a MEMCPY operation + */ +static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_memcpy( + struct dma_chan *chan, dma_addr_t dma_dest, + dma_addr_t dma_src, size_t len, unsigned long flags) +{ + struct ppc440spe_adma_chan *ppc440spe_chan; + struct ppc440spe_adma_desc_slot *sw_desc, *group_start; + int slot_cnt, slots_per_op; + + ppc440spe_chan = to_ppc440spe_adma_chan(chan); + + if (unlikely(!len)) + return NULL; + + BUG_ON(unlikely(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT)); + + spin_lock_bh(&ppc440spe_chan->lock); + + dev_dbg(ppc440spe_chan->device->common.dev, + "ppc440spe adma%d: %s len: %u int_en %d\n", + ppc440spe_chan->device->id, __func__, len, + flags & DMA_PREP_INTERRUPT ? 1 : 0); + slot_cnt = slots_per_op = 1; + sw_desc = ppc440spe_adma_alloc_slots(ppc440spe_chan, slot_cnt, + slots_per_op); + if (sw_desc) { + group_start = sw_desc->group_head; + ppc440spe_desc_init_memcpy(group_start, flags); + ppc440spe_adma_set_dest(group_start, dma_dest, 0); + ppc440spe_adma_memcpy_xor_set_src(group_start, dma_src, 0); + ppc440spe_desc_set_byte_count(group_start, ppc440spe_chan, len); + sw_desc->unmap_len = len; + sw_desc->async_tx.flags = flags; + } + spin_unlock_bh(&ppc440spe_chan->lock); + + return sw_desc ? &sw_desc->async_tx : NULL; +} + +/** + * ppc440spe_adma_prep_dma_memset - prepare CDB for a MEMSET operation + */ +static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_memset( + struct dma_chan *chan, dma_addr_t dma_dest, int value, + size_t len, unsigned long flags) +{ + struct ppc440spe_adma_chan *ppc440spe_chan; + struct ppc440spe_adma_desc_slot *sw_desc, *group_start; + int slot_cnt, slots_per_op; + + ppc440spe_chan = to_ppc440spe_adma_chan(chan); + + if (unlikely(!len)) + return NULL; + + BUG_ON(unlikely(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT)); + + spin_lock_bh(&ppc440spe_chan->lock); + + dev_dbg(ppc440spe_chan->device->common.dev, + "ppc440spe adma%d: %s cal: %u len: %u int_en %d\n", + ppc440spe_chan->device->id, __func__, value, len, + flags & DMA_PREP_INTERRUPT ? 1 : 0); + + slot_cnt = slots_per_op = 1; + sw_desc = ppc440spe_adma_alloc_slots(ppc440spe_chan, slot_cnt, + slots_per_op); + if (sw_desc) { + group_start = sw_desc->group_head; + ppc440spe_desc_init_memset(group_start, value, flags); + ppc440spe_adma_set_dest(group_start, dma_dest, 0); + ppc440spe_desc_set_byte_count(group_start, ppc440spe_chan, len); + sw_desc->unmap_len = len; + sw_desc->async_tx.flags = flags; + } + spin_unlock_bh(&ppc440spe_chan->lock); + + return sw_desc ? &sw_desc->async_tx : NULL; +} + +/** + * ppc440spe_adma_prep_dma_xor - prepare CDB for a XOR operation + */ +static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_xor( + struct dma_chan *chan, dma_addr_t dma_dest, + dma_addr_t *dma_src, u32 src_cnt, size_t len, + unsigned long flags) +{ + struct ppc440spe_adma_chan *ppc440spe_chan; + struct ppc440spe_adma_desc_slot *sw_desc, *group_start; + int slot_cnt, slots_per_op; + + ppc440spe_chan = to_ppc440spe_adma_chan(chan); + + ADMA_LL_DBG(prep_dma_xor_dbg(ppc440spe_chan->device->id, + dma_dest, dma_src, src_cnt)); + if (unlikely(!len)) + return NULL; + BUG_ON(unlikely(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT)); + + dev_dbg(ppc440spe_chan->device->common.dev, + "ppc440spe adma%d: %s src_cnt: %d len: %u int_en: %d\n", + ppc440spe_chan->device->id, __func__, src_cnt, len, + flags & DMA_PREP_INTERRUPT ? 1 : 0); + + spin_lock_bh(&ppc440spe_chan->lock); + slot_cnt = ppc440spe_chan_xor_slot_count(len, src_cnt, &slots_per_op); + sw_desc = ppc440spe_adma_alloc_slots(ppc440spe_chan, slot_cnt, + slots_per_op); + if (sw_desc) { + group_start = sw_desc->group_head; + ppc440spe_desc_init_xor(group_start, src_cnt, flags); + ppc440spe_adma_set_dest(group_start, dma_dest, 0); + while (src_cnt--) + ppc440spe_adma_memcpy_xor_set_src(group_start, + dma_src[src_cnt], src_cnt); + ppc440spe_desc_set_byte_count(group_start, ppc440spe_chan, len); + sw_desc->unmap_len = len; + sw_desc->async_tx.flags = flags; + } + spin_unlock_bh(&ppc440spe_chan->lock); + + return sw_desc ? &sw_desc->async_tx : NULL; +} + +static inline void +ppc440spe_desc_set_xor_src_cnt(struct ppc440spe_adma_desc_slot *desc, + int src_cnt); +static void ppc440spe_init_rxor_cursor(struct ppc440spe_rxor *cursor); + +/** + * ppc440spe_adma_init_dma2rxor_slot - + */ +static void ppc440spe_adma_init_dma2rxor_slot( + struct ppc440spe_adma_desc_slot *desc, + dma_addr_t *src, int src_cnt) +{ + int i; + + /* initialize CDB */ + for (i = 0; i < src_cnt; i++) { + ppc440spe_adma_dma2rxor_prep_src(desc, &desc->rxor_cursor, i, + desc->src_cnt, (u32)src[i]); + } +} + +/** + * ppc440spe_dma01_prep_mult - + * for Q operation where destination is also the source + */ +static struct ppc440spe_adma_desc_slot *ppc440spe_dma01_prep_mult( + struct ppc440spe_adma_chan *ppc440spe_chan, + dma_addr_t *dst, int dst_cnt, dma_addr_t *src, int src_cnt, + const unsigned char *scf, size_t len, unsigned long flags) +{ + struct ppc440spe_adma_desc_slot *sw_desc = NULL; + unsigned long op = 0; + int slot_cnt; + + set_bit(PPC440SPE_DESC_WXOR, &op); + slot_cnt = 2; + + spin_lock_bh(&ppc440spe_chan->lock); + + /* use WXOR, each descriptor occupies one slot */ + sw_desc = ppc440spe_adma_alloc_slots(ppc440spe_chan, slot_cnt, 1); + if (sw_desc) { + struct ppc440spe_adma_chan *chan; + struct ppc440spe_adma_desc_slot *iter; + struct dma_cdb *hw_desc; + + chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan); + set_bits(op, &sw_desc->flags); + sw_desc->src_cnt = src_cnt; + sw_desc->dst_cnt = dst_cnt; + /* First descriptor, zero data in the destination and copy it + * to q page using MULTICAST transfer. + */ + iter = list_first_entry(&sw_desc->group_list, + struct ppc440spe_adma_desc_slot, + chain_node); + memset(iter->hw_desc, 0, sizeof(struct dma_cdb)); + /* set 'next' pointer */ + iter->hw_next = list_entry(iter->chain_node.next, + struct ppc440spe_adma_desc_slot, + chain_node); + clear_bit(PPC440SPE_DESC_INT, &iter->flags); + hw_desc = iter->hw_desc; + hw_desc->opc = DMA_CDB_OPC_MULTICAST; + + ppc440spe_desc_set_dest_addr(iter, chan, + DMA_CUED_XOR_BASE, dst[0], 0); + ppc440spe_desc_set_dest_addr(iter, chan, 0, dst[1], 1); + ppc440spe_desc_set_src_addr(iter, chan, 0, DMA_CUED_XOR_HB, + src[0]); + ppc440spe_desc_set_byte_count(iter, ppc440spe_chan, len); + iter->unmap_len = len; + + /* + * Second descriptor, multiply data from the q page + * and store the result in real destination. + */ + iter = list_first_entry(&iter->chain_node, + struct ppc440spe_adma_desc_slot, + chain_node); + memset(iter->hw_desc, 0, sizeof(struct dma_cdb)); + iter->hw_next = NULL; + if (flags & DMA_PREP_INTERRUPT) + set_bit(PPC440SPE_DESC_INT, &iter->flags); + else + clear_bit(PPC440SPE_DESC_INT, &iter->flags); + + hw_desc = iter->hw_desc; + hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2; + ppc440spe_desc_set_src_addr(iter, chan, 0, + DMA_CUED_XOR_HB, dst[1]); + ppc440spe_desc_set_dest_addr(iter, chan, + DMA_CUED_XOR_BASE, dst[0], 0); + + ppc440spe_desc_set_src_mult(iter, chan, DMA_CUED_MULT1_OFF, + DMA_CDB_SG_DST1, scf[0]); + ppc440spe_desc_set_byte_count(iter, ppc440spe_chan, len); + iter->unmap_len = len; + sw_desc->async_tx.flags = flags; + } + + spin_unlock_bh(&ppc440spe_chan->lock); + + return sw_desc; +} + +/** + * ppc440spe_dma01_prep_sum_product - + * Dx = A*(P+Pxy) + B*(Q+Qxy) operation where destination is also + * the source. + */ +static struct ppc440spe_adma_desc_slot *ppc440spe_dma01_prep_sum_product( + struct ppc440spe_adma_chan *ppc440spe_chan, + dma_addr_t *dst, dma_addr_t *src, int src_cnt, + const unsigned char *scf, size_t len, unsigned long flags) +{ + struct ppc440spe_adma_desc_slot *sw_desc = NULL; + unsigned long op = 0; + int slot_cnt; + + set_bit(PPC440SPE_DESC_WXOR, &op); + slot_cnt = 3; + + spin_lock_bh(&ppc440spe_chan->lock); + + /* WXOR, each descriptor occupies one slot */ + sw_desc = ppc440spe_adma_alloc_slots(ppc440spe_chan, slot_cnt, 1); + if (sw_desc) { + struct ppc440spe_adma_chan *chan; + struct ppc440spe_adma_desc_slot *iter; + struct dma_cdb *hw_desc; + + chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan); + set_bits(op, &sw_desc->flags); + sw_desc->src_cnt = src_cnt; + sw_desc->dst_cnt = 1; + /* 1st descriptor, src[1] data to q page and zero destination */ + iter = list_first_entry(&sw_desc->group_list, + struct ppc440spe_adma_desc_slot, + chain_node); + memset(iter->hw_desc, 0, sizeof(struct dma_cdb)); + iter->hw_next = list_entry(iter->chain_node.next, + struct ppc440spe_adma_desc_slot, + chain_node); + clear_bit(PPC440SPE_DESC_INT, &iter->flags); + hw_desc = iter->hw_desc; + hw_desc->opc = DMA_CDB_OPC_MULTICAST; + + ppc440spe_desc_set_dest_addr(iter, chan, DMA_CUED_XOR_BASE, + *dst, 0); + ppc440spe_desc_set_dest_addr(iter, chan, 0, + ppc440spe_chan->qdest, 1); + ppc440spe_desc_set_src_addr(iter, chan, 0, DMA_CUED_XOR_HB, + src[1]); + ppc440spe_desc_set_byte_count(iter, ppc440spe_chan, len); + iter->unmap_len = len; + + /* 2nd descriptor, multiply src[1] data and store the + * result in destination */ + iter = list_first_entry(&iter->chain_node, + struct ppc440spe_adma_desc_slot, + chain_node); + memset(iter->hw_desc, 0, sizeof(struct dma_cdb)); + /* set 'next' pointer */ + iter->hw_next = list_entry(iter->chain_node.next, + struct ppc440spe_adma_desc_slot, + chain_node); + if (flags & DMA_PREP_INTERRUPT) + set_bit(PPC440SPE_DESC_INT, &iter->flags); + else + clear_bit(PPC440SPE_DESC_INT, &iter->flags); + + hw_desc = iter->hw_desc; + hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2; + ppc440spe_desc_set_src_addr(iter, chan, 0, DMA_CUED_XOR_HB, + ppc440spe_chan->qdest); + ppc440spe_desc_set_dest_addr(iter, chan, DMA_CUED_XOR_BASE, + *dst, 0); + ppc440spe_desc_set_src_mult(iter, chan, DMA_CUED_MULT1_OFF, + DMA_CDB_SG_DST1, scf[1]); + ppc440spe_desc_set_byte_count(iter, ppc440spe_chan, len); + iter->unmap_len = len; + + /* + * 3rd descriptor, multiply src[0] data and xor it + * with destination + */ + iter = list_first_entry(&iter->chain_node, + struct ppc440spe_adma_desc_slot, + chain_node); + memset(iter->hw_desc, 0, sizeof(struct dma_cdb)); + iter->hw_next = NULL; + if (flags & DMA_PREP_INTERRUPT) + set_bit(PPC440SPE_DESC_INT, &iter->flags); + else + clear_bit(PPC440SPE_DESC_INT, &iter->flags); + + hw_desc = iter->hw_desc; + hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2; + ppc440spe_desc_set_src_addr(iter, chan, 0, DMA_CUED_XOR_HB, + src[0]); + ppc440spe_desc_set_dest_addr(iter, chan, DMA_CUED_XOR_BASE, + *dst, 0); + ppc440spe_desc_set_src_mult(iter, chan, DMA_CUED_MULT1_OFF, + DMA_CDB_SG_DST1, scf[0]); + ppc440spe_desc_set_byte_count(iter, ppc440spe_chan, len); + iter->unmap_len = len; + sw_desc->async_tx.flags = flags; + } + + spin_unlock_bh(&ppc440spe_chan->lock); + + return sw_desc; +} + +static struct ppc440spe_adma_desc_slot *ppc440spe_dma01_prep_pq( + struct ppc440spe_adma_chan *ppc440spe_chan, + dma_addr_t *dst, int dst_cnt, dma_addr_t *src, int src_cnt, + const unsigned char *scf, size_t len, unsigned long flags) +{ + int slot_cnt; + struct ppc440spe_adma_desc_slot *sw_desc = NULL, *iter; + unsigned long op = 0; + unsigned char mult = 1; + + pr_debug("%s: dst_cnt %d, src_cnt %d, len %d\n", + __func__, dst_cnt, src_cnt, len); + /* select operations WXOR/RXOR depending on the + * source addresses of operators and the number + * of destinations (RXOR support only Q-parity calculations) + */ + set_bit(PPC440SPE_DESC_WXOR, &op); + if (!test_and_set_bit(PPC440SPE_RXOR_RUN, &ppc440spe_rxor_state)) { + /* no active RXOR; + * do RXOR if: + * - there are more than 1 source, + * - len is aligned on 512-byte boundary, + * - source addresses fit to one of 4 possible regions. + */ + if (src_cnt > 1 && + !(len & MQ0_CF2H_RXOR_BS_MASK) && + (src[0] + len) == src[1]) { + /* may do RXOR R1 R2 */ + set_bit(PPC440SPE_DESC_RXOR, &op); + if (src_cnt != 2) { + /* may try to enhance region of RXOR */ + if ((src[1] + len) == src[2]) { + /* do RXOR R1 R2 R3 */ + set_bit(PPC440SPE_DESC_RXOR123, + &op); + } else if ((src[1] + len * 2) == src[2]) { + /* do RXOR R1 R2 R4 */ + set_bit(PPC440SPE_DESC_RXOR124, &op); + } else if ((src[1] + len * 3) == src[2]) { + /* do RXOR R1 R2 R5 */ + set_bit(PPC440SPE_DESC_RXOR125, + &op); + } else { + /* do RXOR R1 R2 */ + set_bit(PPC440SPE_DESC_RXOR12, + &op); + } + } else { + /* do RXOR R1 R2 */ + set_bit(PPC440SPE_DESC_RXOR12, &op); + } + } + + if (!test_bit(PPC440SPE_DESC_RXOR, &op)) { + /* can not do this operation with RXOR */ + clear_bit(PPC440SPE_RXOR_RUN, + &ppc440spe_rxor_state); + } else { + /* can do; set block size right now */ + ppc440spe_desc_set_rxor_block_size(len); + } + } + + /* Number of necessary slots depends on operation type selected */ + if (!test_bit(PPC440SPE_DESC_RXOR, &op)) { + /* This is a WXOR only chain. Need descriptors for each + * source to GF-XOR them with WXOR, and need descriptors + * for each destination to zero them with WXOR + */ + slot_cnt = src_cnt; + + if (flags & DMA_PREP_ZERO_P) { + slot_cnt++; + set_bit(PPC440SPE_ZERO_P, &op); + } + if (flags & DMA_PREP_ZERO_Q) { + slot_cnt++; + set_bit(PPC440SPE_ZERO_Q, &op); + } + } else { + /* Need 1/2 descriptor for RXOR operation, and + * need (src_cnt - (2 or 3)) for WXOR of sources + * remained (if any) + */ + slot_cnt = dst_cnt; + + if (flags & DMA_PREP_ZERO_P) + set_bit(PPC440SPE_ZERO_P, &op); + if (flags & DMA_PREP_ZERO_Q) + set_bit(PPC440SPE_ZERO_Q, &op); + + if (test_bit(PPC440SPE_DESC_RXOR12, &op)) + slot_cnt += src_cnt - 2; + else + slot_cnt += src_cnt - 3; + + /* Thus we have either RXOR only chain or + * mixed RXOR/WXOR + */ + if (slot_cnt == dst_cnt) + /* RXOR only chain */ + clear_bit(PPC440SPE_DESC_WXOR, &op); + } + + spin_lock_bh(&ppc440spe_chan->lock); + /* for both RXOR/WXOR each descriptor occupies one slot */ + sw_desc = ppc440spe_adma_alloc_slots(ppc440spe_chan, slot_cnt, 1); + if (sw_desc) { + ppc440spe_desc_init_dma01pq(sw_desc, dst_cnt, src_cnt, + flags, op); + + /* setup dst/src/mult */ + pr_debug("%s: set dst descriptor 0, 1: 0x%016llx, 0x%016llx\n", + __func__, dst[0], dst[1]); + ppc440spe_adma_pq_set_dest(sw_desc, dst, flags); + while (src_cnt--) { + ppc440spe_adma_pq_set_src(sw_desc, src[src_cnt], + src_cnt); + + /* NOTE: "Multi = 0 is equivalent to = 1" as it + * stated in 440SPSPe_RAID6_Addendum_UM_1_17.pdf + * doesn't work for RXOR with DMA0/1! Instead, multi=0 + * leads to zeroing source data after RXOR. + * So, for P case set-up mult=1 explicitly. + */ + if (!(flags & DMA_PREP_PQ_DISABLE_Q)) + mult = scf[src_cnt]; + ppc440spe_adma_pq_set_src_mult(sw_desc, + mult, src_cnt, dst_cnt - 1); + } + + /* Setup byte count foreach slot just allocated */ + sw_desc->async_tx.flags = flags; + list_for_each_entry(iter, &sw_desc->group_list, + chain_node) { + ppc440spe_desc_set_byte_count(iter, + ppc440spe_chan, len); + iter->unmap_len = len; + } + } + spin_unlock_bh(&ppc440spe_chan->lock); + + return sw_desc; +} + +static struct ppc440spe_adma_desc_slot *ppc440spe_dma2_prep_pq( + struct ppc440spe_adma_chan *ppc440spe_chan, + dma_addr_t *dst, int dst_cnt, dma_addr_t *src, int src_cnt, + const unsigned char *scf, size_t len, unsigned long flags) +{ + int slot_cnt, descs_per_op; + struct ppc440spe_adma_desc_slot *sw_desc = NULL, *iter; + unsigned long op = 0; + unsigned char mult = 1; + + BUG_ON(!dst_cnt); + /*pr_debug("%s: dst_cnt %d, src_cnt %d, len %d\n", + __func__, dst_cnt, src_cnt, len);*/ + + spin_lock_bh(&ppc440spe_chan->lock); + descs_per_op = ppc440spe_dma2_pq_slot_count(src, src_cnt, len); + if (descs_per_op < 0) { + spin_unlock_bh(&ppc440spe_chan->lock); + return NULL; + } + + /* depending on number of sources we have 1 or 2 RXOR chains */ + slot_cnt = descs_per_op * dst_cnt; + + sw_desc = ppc440spe_adma_alloc_slots(ppc440spe_chan, slot_cnt, 1); + if (sw_desc) { + op = slot_cnt; + sw_desc->async_tx.flags = flags; + list_for_each_entry(iter, &sw_desc->group_list, chain_node) { + ppc440spe_desc_init_dma2pq(iter, dst_cnt, src_cnt, + --op ? 0 : flags); + ppc440spe_desc_set_byte_count(iter, ppc440spe_chan, + len); + iter->unmap_len = len; + + ppc440spe_init_rxor_cursor(&(iter->rxor_cursor)); + iter->rxor_cursor.len = len; + iter->descs_per_op = descs_per_op; + } + op = 0; + list_for_each_entry(iter, &sw_desc->group_list, chain_node) { + op++; + if (op % descs_per_op == 0) + ppc440spe_adma_init_dma2rxor_slot(iter, src, + src_cnt); + if (likely(!list_is_last(&iter->chain_node, + &sw_desc->group_list))) { + /* set 'next' pointer */ + iter->hw_next = + list_entry(iter->chain_node.next, + struct ppc440spe_adma_desc_slot, + chain_node); + ppc440spe_xor_set_link(iter, iter->hw_next); + } else { + /* this is the last descriptor. */ + iter->hw_next = NULL; + } + } + + /* fixup head descriptor */ + sw_desc->dst_cnt = dst_cnt; + if (flags & DMA_PREP_ZERO_P) + set_bit(PPC440SPE_ZERO_P, &sw_desc->flags); + if (flags & DMA_PREP_ZERO_Q) + set_bit(PPC440SPE_ZERO_Q, &sw_desc->flags); + + /* setup dst/src/mult */ + ppc440spe_adma_pq_set_dest(sw_desc, dst, flags); + + while (src_cnt--) { + /* handle descriptors (if dst_cnt == 2) inside + * the ppc440spe_adma_pq_set_srcxxx() functions + */ + ppc440spe_adma_pq_set_src(sw_desc, src[src_cnt], + src_cnt); + if (!(flags & DMA_PREP_PQ_DISABLE_Q)) + mult = scf[src_cnt]; + ppc440spe_adma_pq_set_src_mult(sw_desc, + mult, src_cnt, dst_cnt - 1); + } + } + spin_unlock_bh(&ppc440spe_chan->lock); + ppc440spe_desc_set_rxor_block_size(len); + return sw_desc; +} + +/** + * ppc440spe_adma_prep_dma_pq - prepare CDB (group) for a GF-XOR operation + */ +static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_pq( + struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src, + unsigned int src_cnt, const unsigned char *scf, + size_t len, unsigned long flags) +{ + struct ppc440spe_adma_chan *ppc440spe_chan; + struct ppc440spe_adma_desc_slot *sw_desc = NULL; + int dst_cnt = 0; + + ppc440spe_chan = to_ppc440spe_adma_chan(chan); + + ADMA_LL_DBG(prep_dma_pq_dbg(ppc440spe_chan->device->id, + dst, src, src_cnt)); + BUG_ON(!len); + BUG_ON(unlikely(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT)); + BUG_ON(!src_cnt); + + if (src_cnt == 1 && dst[1] == src[0]) { + dma_addr_t dest[2]; + + /* dst[1] is real destination (Q) */ + dest[0] = dst[1]; + /* this is the page to multicast source data to */ + dest[1] = ppc440spe_chan->qdest; + sw_desc = ppc440spe_dma01_prep_mult(ppc440spe_chan, + dest, 2, src, src_cnt, scf, len, flags); + return sw_desc ? &sw_desc->async_tx : NULL; + } + + if (src_cnt == 2 && dst[1] == src[1]) { + sw_desc = ppc440spe_dma01_prep_sum_product(ppc440spe_chan, + &dst[1], src, 2, scf, len, flags); + return sw_desc ? &sw_desc->async_tx : NULL; + } + + if (!(flags & DMA_PREP_PQ_DISABLE_P)) { + BUG_ON(!dst[0]); + dst_cnt++; + flags |= DMA_PREP_ZERO_P; + } + + if (!(flags & DMA_PREP_PQ_DISABLE_Q)) { + BUG_ON(!dst[1]); + dst_cnt++; + flags |= DMA_PREP_ZERO_Q; + } + + BUG_ON(!dst_cnt); + + dev_dbg(ppc440spe_chan->device->common.dev, + "ppc440spe adma%d: %s src_cnt: %d len: %u int_en: %d\n", + ppc440spe_chan->device->id, __func__, src_cnt, len, + flags & DMA_PREP_INTERRUPT ? 1 : 0); + + switch (ppc440spe_chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + sw_desc = ppc440spe_dma01_prep_pq(ppc440spe_chan, + dst, dst_cnt, src, src_cnt, scf, + len, flags); + break; + + case PPC440SPE_XOR_ID: + sw_desc = ppc440spe_dma2_prep_pq(ppc440spe_chan, + dst, dst_cnt, src, src_cnt, scf, + len, flags); + break; + } + + return sw_desc ? &sw_desc->async_tx : NULL; +} + +/** + * ppc440spe_adma_prep_dma_pqzero_sum - prepare CDB group for + * a PQ_ZERO_SUM operation + */ +static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_pqzero_sum( + struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src, + unsigned int src_cnt, const unsigned char *scf, size_t len, + enum sum_check_flags *pqres, unsigned long flags) +{ + struct ppc440spe_adma_chan *ppc440spe_chan; + struct ppc440spe_adma_desc_slot *sw_desc, *iter; + dma_addr_t pdest, qdest; + int slot_cnt, slots_per_op, idst, dst_cnt; + + ppc440spe_chan = to_ppc440spe_adma_chan(chan); + + if (flags & DMA_PREP_PQ_DISABLE_P) + pdest = 0; + else + pdest = pq[0]; + + if (flags & DMA_PREP_PQ_DISABLE_Q) + qdest = 0; + else + qdest = pq[1]; + + ADMA_LL_DBG(prep_dma_pqzero_sum_dbg(ppc440spe_chan->device->id, + src, src_cnt, scf)); + + /* Always use WXOR for P/Q calculations (two destinations). + * Need 1 or 2 extra slots to verify results are zero. + */ + idst = dst_cnt = (pdest && qdest) ? 2 : 1; + + /* One additional slot per destination to clone P/Q + * before calculation (we have to preserve destinations). + */ + slot_cnt = src_cnt + dst_cnt * 2; + slots_per_op = 1; + + spin_lock_bh(&ppc440spe_chan->lock); + sw_desc = ppc440spe_adma_alloc_slots(ppc440spe_chan, slot_cnt, + slots_per_op); + if (sw_desc) { + ppc440spe_desc_init_dma01pqzero_sum(sw_desc, dst_cnt, src_cnt); + + /* Setup byte count for each slot just allocated */ + sw_desc->async_tx.flags = flags; + list_for_each_entry(iter, &sw_desc->group_list, chain_node) { + ppc440spe_desc_set_byte_count(iter, ppc440spe_chan, + len); + iter->unmap_len = len; + } + + if (pdest) { + struct dma_cdb *hw_desc; + struct ppc440spe_adma_chan *chan; + + iter = sw_desc->group_head; + chan = to_ppc440spe_adma_chan(iter->async_tx.chan); + memset(iter->hw_desc, 0, sizeof(struct dma_cdb)); + iter->hw_next = list_entry(iter->chain_node.next, + struct ppc440spe_adma_desc_slot, + chain_node); + hw_desc = iter->hw_desc; + hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2; + iter->src_cnt = 0; + iter->dst_cnt = 0; + ppc440spe_desc_set_dest_addr(iter, chan, 0, + ppc440spe_chan->pdest, 0); + ppc440spe_desc_set_src_addr(iter, chan, 0, 0, pdest); + ppc440spe_desc_set_byte_count(iter, ppc440spe_chan, + len); + iter->unmap_len = 0; + /* override pdest to preserve original P */ + pdest = ppc440spe_chan->pdest; + } + if (qdest) { + struct dma_cdb *hw_desc; + struct ppc440spe_adma_chan *chan; + + iter = list_first_entry(&sw_desc->group_list, + struct ppc440spe_adma_desc_slot, + chain_node); + chan = to_ppc440spe_adma_chan(iter->async_tx.chan); + + if (pdest) { + iter = list_entry(iter->chain_node.next, + struct ppc440spe_adma_desc_slot, + chain_node); + } + + memset(iter->hw_desc, 0, sizeof(struct dma_cdb)); + iter->hw_next = list_entry(iter->chain_node.next, + struct ppc440spe_adma_desc_slot, + chain_node); + hw_desc = iter->hw_desc; + hw_desc->opc = DMA_CDB_OPC_MV_SG1_SG2; + iter->src_cnt = 0; + iter->dst_cnt = 0; + ppc440spe_desc_set_dest_addr(iter, chan, 0, + ppc440spe_chan->qdest, 0); + ppc440spe_desc_set_src_addr(iter, chan, 0, 0, qdest); + ppc440spe_desc_set_byte_count(iter, ppc440spe_chan, + len); + iter->unmap_len = 0; + /* override qdest to preserve original Q */ + qdest = ppc440spe_chan->qdest; + } + + /* Setup destinations for P/Q ops */ + ppc440spe_adma_pqzero_sum_set_dest(sw_desc, pdest, qdest); + + /* Setup zero QWORDs into DCHECK CDBs */ + idst = dst_cnt; + list_for_each_entry_reverse(iter, &sw_desc->group_list, + chain_node) { + /* + * The last CDB corresponds to Q-parity check, + * the one before last CDB corresponds + * P-parity check + */ + if (idst == DMA_DEST_MAX_NUM) { + if (idst == dst_cnt) { + set_bit(PPC440SPE_DESC_QCHECK, + &iter->flags); + } else { + set_bit(PPC440SPE_DESC_PCHECK, + &iter->flags); + } + } else { + if (qdest) { + set_bit(PPC440SPE_DESC_QCHECK, + &iter->flags); + } else { + set_bit(PPC440SPE_DESC_PCHECK, + &iter->flags); + } + } + iter->xor_check_result = pqres; + + /* + * set it to zero, if check fail then result will + * be updated + */ + *iter->xor_check_result = 0; + ppc440spe_desc_set_dcheck(iter, ppc440spe_chan, + ppc440spe_qword); + + if (!(--dst_cnt)) + break; + } + + /* Setup sources and mults for P/Q ops */ + list_for_each_entry_continue_reverse(iter, &sw_desc->group_list, + chain_node) { + struct ppc440spe_adma_chan *chan; + u32 mult_dst; + + chan = to_ppc440spe_adma_chan(iter->async_tx.chan); + ppc440spe_desc_set_src_addr(iter, chan, 0, + DMA_CUED_XOR_HB, + src[src_cnt - 1]); + if (qdest) { + mult_dst = (dst_cnt - 1) ? DMA_CDB_SG_DST2 : + DMA_CDB_SG_DST1; + ppc440spe_desc_set_src_mult(iter, chan, + DMA_CUED_MULT1_OFF, + mult_dst, + scf[src_cnt - 1]); + } + if (!(--src_cnt)) + break; + } + } + spin_unlock_bh(&ppc440spe_chan->lock); + return sw_desc ? &sw_desc->async_tx : NULL; +} + +/** + * ppc440spe_adma_prep_dma_xor_zero_sum - prepare CDB group for + * XOR ZERO_SUM operation + */ +static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_xor_zero_sum( + struct dma_chan *chan, dma_addr_t *src, unsigned int src_cnt, + size_t len, enum sum_check_flags *result, unsigned long flags) +{ + struct dma_async_tx_descriptor *tx; + dma_addr_t pq[2]; + + /* validate P, disable Q */ + pq[0] = src[0]; + pq[1] = 0; + flags |= DMA_PREP_PQ_DISABLE_Q; + + tx = ppc440spe_adma_prep_dma_pqzero_sum(chan, pq, &src[1], + src_cnt - 1, 0, len, + result, flags); + return tx; +} + +/** + * ppc440spe_adma_set_dest - set destination address into descriptor + */ +static void ppc440spe_adma_set_dest(struct ppc440spe_adma_desc_slot *sw_desc, + dma_addr_t addr, int index) +{ + struct ppc440spe_adma_chan *chan; + + BUG_ON(index >= sw_desc->dst_cnt); + + chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan); + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + /* to do: support transfers lengths > + * PPC440SPE_ADMA_DMA/XOR_MAX_BYTE_COUNT + */ + ppc440spe_desc_set_dest_addr(sw_desc->group_head, + chan, 0, addr, index); + break; + case PPC440SPE_XOR_ID: + sw_desc = ppc440spe_get_group_entry(sw_desc, index); + ppc440spe_desc_set_dest_addr(sw_desc, + chan, 0, addr, index); + break; + } +} + +static void ppc440spe_adma_pq_zero_op(struct ppc440spe_adma_desc_slot *iter, + struct ppc440spe_adma_chan *chan, dma_addr_t addr) +{ + /* To clear destinations update the descriptor + * (P or Q depending on index) as follows: + * addr is destination (0 corresponds to SG2): + */ + ppc440spe_desc_set_dest_addr(iter, chan, DMA_CUED_XOR_BASE, addr, 0); + + /* ... and the addr is source: */ + ppc440spe_desc_set_src_addr(iter, chan, 0, DMA_CUED_XOR_HB, addr); + + /* addr is always SG2 then the mult is always DST1 */ + ppc440spe_desc_set_src_mult(iter, chan, DMA_CUED_MULT1_OFF, + DMA_CDB_SG_DST1, 1); +} + +/** + * ppc440spe_adma_pq_set_dest - set destination address into descriptor + * for the PQXOR operation + */ +static void ppc440spe_adma_pq_set_dest(struct ppc440spe_adma_desc_slot *sw_desc, + dma_addr_t *addrs, unsigned long flags) +{ + struct ppc440spe_adma_desc_slot *iter; + struct ppc440spe_adma_chan *chan; + dma_addr_t paddr, qaddr; + dma_addr_t addr = 0, ppath, qpath; + int index = 0, i; + + chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan); + + if (flags & DMA_PREP_PQ_DISABLE_P) + paddr = 0; + else + paddr = addrs[0]; + + if (flags & DMA_PREP_PQ_DISABLE_Q) + qaddr = 0; + else + qaddr = addrs[1]; + + if (!paddr || !qaddr) + addr = paddr ? paddr : qaddr; + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + /* walk through the WXOR source list and set P/Q-destinations + * for each slot: + */ + if (!test_bit(PPC440SPE_DESC_RXOR, &sw_desc->flags)) { + /* This is WXOR-only chain; may have 1/2 zero descs */ + if (test_bit(PPC440SPE_ZERO_P, &sw_desc->flags)) + index++; + if (test_bit(PPC440SPE_ZERO_Q, &sw_desc->flags)) + index++; + + iter = ppc440spe_get_group_entry(sw_desc, index); + if (addr) { + /* one destination */ + list_for_each_entry_from(iter, + &sw_desc->group_list, chain_node) + ppc440spe_desc_set_dest_addr(iter, chan, + DMA_CUED_XOR_BASE, addr, 0); + } else { + /* two destinations */ + list_for_each_entry_from(iter, + &sw_desc->group_list, chain_node) { + ppc440spe_desc_set_dest_addr(iter, chan, + DMA_CUED_XOR_BASE, paddr, 0); + ppc440spe_desc_set_dest_addr(iter, chan, + DMA_CUED_XOR_BASE, qaddr, 1); + } + } + + if (index) { + /* To clear destinations update the descriptor + * (1st,2nd, or both depending on flags) + */ + index = 0; + if (test_bit(PPC440SPE_ZERO_P, + &sw_desc->flags)) { + iter = ppc440spe_get_group_entry( + sw_desc, index++); + ppc440spe_adma_pq_zero_op(iter, chan, + paddr); + } + + if (test_bit(PPC440SPE_ZERO_Q, + &sw_desc->flags)) { + iter = ppc440spe_get_group_entry( + sw_desc, index++); + ppc440spe_adma_pq_zero_op(iter, chan, + qaddr); + } + + return; + } + } else { + /* This is RXOR-only or RXOR/WXOR mixed chain */ + + /* If we want to include destination into calculations, + * then make dest addresses cued with mult=1 (XOR). + */ + ppath = test_bit(PPC440SPE_ZERO_P, &sw_desc->flags) ? + DMA_CUED_XOR_HB : + DMA_CUED_XOR_BASE | + (1 << DMA_CUED_MULT1_OFF); + qpath = test_bit(PPC440SPE_ZERO_Q, &sw_desc->flags) ? + DMA_CUED_XOR_HB : + DMA_CUED_XOR_BASE | + (1 << DMA_CUED_MULT1_OFF); + + /* Setup destination(s) in RXOR slot(s) */ + iter = ppc440spe_get_group_entry(sw_desc, index++); + ppc440spe_desc_set_dest_addr(iter, chan, + paddr ? ppath : qpath, + paddr ? paddr : qaddr, 0); + if (!addr) { + /* two destinations */ + iter = ppc440spe_get_group_entry(sw_desc, + index++); + ppc440spe_desc_set_dest_addr(iter, chan, + qpath, qaddr, 0); + } + + if (test_bit(PPC440SPE_DESC_WXOR, &sw_desc->flags)) { + /* Setup destination(s) in remaining WXOR + * slots + */ + iter = ppc440spe_get_group_entry(sw_desc, + index); + if (addr) { + /* one destination */ + list_for_each_entry_from(iter, + &sw_desc->group_list, + chain_node) + ppc440spe_desc_set_dest_addr( + iter, chan, + DMA_CUED_XOR_BASE, + addr, 0); + + } else { + /* two destinations */ + list_for_each_entry_from(iter, + &sw_desc->group_list, + chain_node) { + ppc440spe_desc_set_dest_addr( + iter, chan, + DMA_CUED_XOR_BASE, + paddr, 0); + ppc440spe_desc_set_dest_addr( + iter, chan, + DMA_CUED_XOR_BASE, + qaddr, 1); + } + } + } + + } + break; + + case PPC440SPE_XOR_ID: + /* DMA2 descriptors have only 1 destination, so there are + * two chains - one for each dest. + * If we want to include destination into calculations, + * then make dest addresses cued with mult=1 (XOR). + */ + ppath = test_bit(PPC440SPE_ZERO_P, &sw_desc->flags) ? + DMA_CUED_XOR_HB : + DMA_CUED_XOR_BASE | + (1 << DMA_CUED_MULT1_OFF); + + qpath = test_bit(PPC440SPE_ZERO_Q, &sw_desc->flags) ? + DMA_CUED_XOR_HB : + DMA_CUED_XOR_BASE | + (1 << DMA_CUED_MULT1_OFF); + + iter = ppc440spe_get_group_entry(sw_desc, 0); + for (i = 0; i < sw_desc->descs_per_op; i++) { + ppc440spe_desc_set_dest_addr(iter, chan, + paddr ? ppath : qpath, + paddr ? paddr : qaddr, 0); + iter = list_entry(iter->chain_node.next, + struct ppc440spe_adma_desc_slot, + chain_node); + } + + if (!addr) { + /* Two destinations; setup Q here */ + iter = ppc440spe_get_group_entry(sw_desc, + sw_desc->descs_per_op); + for (i = 0; i < sw_desc->descs_per_op; i++) { + ppc440spe_desc_set_dest_addr(iter, + chan, qpath, qaddr, 0); + iter = list_entry(iter->chain_node.next, + struct ppc440spe_adma_desc_slot, + chain_node); + } + } + + break; + } +} + +/** + * ppc440spe_adma_pq_zero_sum_set_dest - set destination address into descriptor + * for the PQ_ZERO_SUM operation + */ +static void ppc440spe_adma_pqzero_sum_set_dest( + struct ppc440spe_adma_desc_slot *sw_desc, + dma_addr_t paddr, dma_addr_t qaddr) +{ + struct ppc440spe_adma_desc_slot *iter, *end; + struct ppc440spe_adma_chan *chan; + dma_addr_t addr = 0; + int idx; + + chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan); + + /* walk through the WXOR source list and set P/Q-destinations + * for each slot + */ + idx = (paddr && qaddr) ? 2 : 1; + /* set end */ + list_for_each_entry_reverse(end, &sw_desc->group_list, + chain_node) { + if (!(--idx)) + break; + } + /* set start */ + idx = (paddr && qaddr) ? 2 : 1; + iter = ppc440spe_get_group_entry(sw_desc, idx); + + if (paddr && qaddr) { + /* two destinations */ + list_for_each_entry_from(iter, &sw_desc->group_list, + chain_node) { + if (unlikely(iter == end)) + break; + ppc440spe_desc_set_dest_addr(iter, chan, + DMA_CUED_XOR_BASE, paddr, 0); + ppc440spe_desc_set_dest_addr(iter, chan, + DMA_CUED_XOR_BASE, qaddr, 1); + } + } else { + /* one destination */ + addr = paddr ? paddr : qaddr; + list_for_each_entry_from(iter, &sw_desc->group_list, + chain_node) { + if (unlikely(iter == end)) + break; + ppc440spe_desc_set_dest_addr(iter, chan, + DMA_CUED_XOR_BASE, addr, 0); + } + } + + /* The remaining descriptors are DATACHECK. These have no need in + * destination. Actually, these destinations are used there + * as sources for check operation. So, set addr as source. + */ + ppc440spe_desc_set_src_addr(end, chan, 0, 0, addr ? addr : paddr); + + if (!addr) { + end = list_entry(end->chain_node.next, + struct ppc440spe_adma_desc_slot, chain_node); + ppc440spe_desc_set_src_addr(end, chan, 0, 0, qaddr); + } +} + +/** + * ppc440spe_desc_set_xor_src_cnt - set source count into descriptor + */ +static inline void ppc440spe_desc_set_xor_src_cnt( + struct ppc440spe_adma_desc_slot *desc, + int src_cnt) +{ + struct xor_cb *hw_desc = desc->hw_desc; + + hw_desc->cbc &= ~XOR_CDCR_OAC_MSK; + hw_desc->cbc |= src_cnt; +} + +/** + * ppc440spe_adma_pq_set_src - set source address into descriptor + */ +static void ppc440spe_adma_pq_set_src(struct ppc440spe_adma_desc_slot *sw_desc, + dma_addr_t addr, int index) +{ + struct ppc440spe_adma_chan *chan; + dma_addr_t haddr = 0; + struct ppc440spe_adma_desc_slot *iter = NULL; + + chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan); + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + /* DMA0,1 may do: WXOR, RXOR, RXOR+WXORs chain + */ + if (test_bit(PPC440SPE_DESC_RXOR, &sw_desc->flags)) { + /* RXOR-only or RXOR/WXOR operation */ + int iskip = test_bit(PPC440SPE_DESC_RXOR12, + &sw_desc->flags) ? 2 : 3; + + if (index == 0) { + /* 1st slot (RXOR) */ + /* setup sources region (R1-2-3, R1-2-4, + * or R1-2-5) + */ + if (test_bit(PPC440SPE_DESC_RXOR12, + &sw_desc->flags)) + haddr = DMA_RXOR12 << + DMA_CUED_REGION_OFF; + else if (test_bit(PPC440SPE_DESC_RXOR123, + &sw_desc->flags)) + haddr = DMA_RXOR123 << + DMA_CUED_REGION_OFF; + else if (test_bit(PPC440SPE_DESC_RXOR124, + &sw_desc->flags)) + haddr = DMA_RXOR124 << + DMA_CUED_REGION_OFF; + else if (test_bit(PPC440SPE_DESC_RXOR125, + &sw_desc->flags)) + haddr = DMA_RXOR125 << + DMA_CUED_REGION_OFF; + else + BUG(); + haddr |= DMA_CUED_XOR_BASE; + iter = ppc440spe_get_group_entry(sw_desc, 0); + } else if (index < iskip) { + /* 1st slot (RXOR) + * shall actually set source address only once + * instead of first + */ + iter = NULL; + } else { + /* 2nd/3d and next slots (WXOR); + * skip first slot with RXOR + */ + haddr = DMA_CUED_XOR_HB; + iter = ppc440spe_get_group_entry(sw_desc, + index - iskip + sw_desc->dst_cnt); + } + } else { + int znum = 0; + + /* WXOR-only operation; skip first slots with + * zeroing destinations + */ + if (test_bit(PPC440SPE_ZERO_P, &sw_desc->flags)) + znum++; + if (test_bit(PPC440SPE_ZERO_Q, &sw_desc->flags)) + znum++; + + haddr = DMA_CUED_XOR_HB; + iter = ppc440spe_get_group_entry(sw_desc, + index + znum); + } + + if (likely(iter)) { + ppc440spe_desc_set_src_addr(iter, chan, 0, haddr, addr); + + if (!index && + test_bit(PPC440SPE_DESC_RXOR, &sw_desc->flags) && + sw_desc->dst_cnt == 2) { + /* if we have two destinations for RXOR, then + * setup source in the second descr too + */ + iter = ppc440spe_get_group_entry(sw_desc, 1); + ppc440spe_desc_set_src_addr(iter, chan, 0, + haddr, addr); + } + } + break; + + case PPC440SPE_XOR_ID: + /* DMA2 may do Biskup */ + iter = sw_desc->group_head; + if (iter->dst_cnt == 2) { + /* both P & Q calculations required; set P src here */ + ppc440spe_adma_dma2rxor_set_src(iter, index, addr); + + /* this is for Q */ + iter = ppc440spe_get_group_entry(sw_desc, + sw_desc->descs_per_op); + } + ppc440spe_adma_dma2rxor_set_src(iter, index, addr); + break; + } +} + +/** + * ppc440spe_adma_memcpy_xor_set_src - set source address into descriptor + */ +static void ppc440spe_adma_memcpy_xor_set_src( + struct ppc440spe_adma_desc_slot *sw_desc, + dma_addr_t addr, int index) +{ + struct ppc440spe_adma_chan *chan; + + chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan); + sw_desc = sw_desc->group_head; + + if (likely(sw_desc)) + ppc440spe_desc_set_src_addr(sw_desc, chan, index, 0, addr); +} + +/** + * ppc440spe_adma_dma2rxor_inc_addr - + */ +static void ppc440spe_adma_dma2rxor_inc_addr( + struct ppc440spe_adma_desc_slot *desc, + struct ppc440spe_rxor *cursor, int index, int src_cnt) +{ + cursor->addr_count++; + if (index == src_cnt - 1) { + ppc440spe_desc_set_xor_src_cnt(desc, cursor->addr_count); + } else if (cursor->addr_count == XOR_MAX_OPS) { + ppc440spe_desc_set_xor_src_cnt(desc, cursor->addr_count); + cursor->addr_count = 0; + cursor->desc_count++; + } +} + +/** + * ppc440spe_adma_dma2rxor_prep_src - setup RXOR types in DMA2 CDB + */ +static int ppc440spe_adma_dma2rxor_prep_src( + struct ppc440spe_adma_desc_slot *hdesc, + struct ppc440spe_rxor *cursor, int index, + int src_cnt, u32 addr) +{ + int rval = 0; + u32 sign; + struct ppc440spe_adma_desc_slot *desc = hdesc; + int i; + + for (i = 0; i < cursor->desc_count; i++) { + desc = list_entry(hdesc->chain_node.next, + struct ppc440spe_adma_desc_slot, + chain_node); + } + + switch (cursor->state) { + case 0: + if (addr == cursor->addrl + cursor->len) { + /* direct RXOR */ + cursor->state = 1; + cursor->xor_count++; + if (index == src_cnt-1) { + ppc440spe_rxor_set_region(desc, + cursor->addr_count, + DMA_RXOR12 << DMA_CUED_REGION_OFF); + ppc440spe_adma_dma2rxor_inc_addr( + desc, cursor, index, src_cnt); + } + } else if (cursor->addrl == addr + cursor->len) { + /* reverse RXOR */ + cursor->state = 1; + cursor->xor_count++; + set_bit(cursor->addr_count, &desc->reverse_flags[0]); + if (index == src_cnt-1) { + ppc440spe_rxor_set_region(desc, + cursor->addr_count, + DMA_RXOR12 << DMA_CUED_REGION_OFF); + ppc440spe_adma_dma2rxor_inc_addr( + desc, cursor, index, src_cnt); + } + } else { + printk(KERN_ERR "Cannot build " + "DMA2 RXOR command block.\n"); + BUG(); + } + break; + case 1: + sign = test_bit(cursor->addr_count, + desc->reverse_flags) + ? -1 : 1; + if (index == src_cnt-2 || (sign == -1 + && addr != cursor->addrl - 2*cursor->len)) { + cursor->state = 0; + cursor->xor_count = 1; + cursor->addrl = addr; + ppc440spe_rxor_set_region(desc, + cursor->addr_count, + DMA_RXOR12 << DMA_CUED_REGION_OFF); + ppc440spe_adma_dma2rxor_inc_addr( + desc, cursor, index, src_cnt); + } else if (addr == cursor->addrl + 2*sign*cursor->len) { + cursor->state = 2; + cursor->xor_count = 0; + ppc440spe_rxor_set_region(desc, + cursor->addr_count, + DMA_RXOR123 << DMA_CUED_REGION_OFF); + if (index == src_cnt-1) { + ppc440spe_adma_dma2rxor_inc_addr( + desc, cursor, index, src_cnt); + } + } else if (addr == cursor->addrl + 3*cursor->len) { + cursor->state = 2; + cursor->xor_count = 0; + ppc440spe_rxor_set_region(desc, + cursor->addr_count, + DMA_RXOR124 << DMA_CUED_REGION_OFF); + if (index == src_cnt-1) { + ppc440spe_adma_dma2rxor_inc_addr( + desc, cursor, index, src_cnt); + } + } else if (addr == cursor->addrl + 4*cursor->len) { + cursor->state = 2; + cursor->xor_count = 0; + ppc440spe_rxor_set_region(desc, + cursor->addr_count, + DMA_RXOR125 << DMA_CUED_REGION_OFF); + if (index == src_cnt-1) { + ppc440spe_adma_dma2rxor_inc_addr( + desc, cursor, index, src_cnt); + } + } else { + cursor->state = 0; + cursor->xor_count = 1; + cursor->addrl = addr; + ppc440spe_rxor_set_region(desc, + cursor->addr_count, + DMA_RXOR12 << DMA_CUED_REGION_OFF); + ppc440spe_adma_dma2rxor_inc_addr( + desc, cursor, index, src_cnt); + } + break; + case 2: + cursor->state = 0; + cursor->addrl = addr; + cursor->xor_count++; + if (index) { + ppc440spe_adma_dma2rxor_inc_addr( + desc, cursor, index, src_cnt); + } + break; + } + + return rval; +} + +/** + * ppc440spe_adma_dma2rxor_set_src - set RXOR source address; it's assumed that + * ppc440spe_adma_dma2rxor_prep_src() has already done prior this call + */ +static void ppc440spe_adma_dma2rxor_set_src( + struct ppc440spe_adma_desc_slot *desc, + int index, dma_addr_t addr) +{ + struct xor_cb *xcb = desc->hw_desc; + int k = 0, op = 0, lop = 0; + + /* get the RXOR operand which corresponds to index addr */ + while (op <= index) { + lop = op; + if (k == XOR_MAX_OPS) { + k = 0; + desc = list_entry(desc->chain_node.next, + struct ppc440spe_adma_desc_slot, chain_node); + xcb = desc->hw_desc; + + } + if ((xcb->ops[k++].h & (DMA_RXOR12 << DMA_CUED_REGION_OFF)) == + (DMA_RXOR12 << DMA_CUED_REGION_OFF)) + op += 2; + else + op += 3; + } + + BUG_ON(k < 1); + + if (test_bit(k-1, desc->reverse_flags)) { + /* reverse operand order; put last op in RXOR group */ + if (index == op - 1) + ppc440spe_rxor_set_src(desc, k - 1, addr); + } else { + /* direct operand order; put first op in RXOR group */ + if (index == lop) + ppc440spe_rxor_set_src(desc, k - 1, addr); + } +} + +/** + * ppc440spe_adma_dma2rxor_set_mult - set RXOR multipliers; it's assumed that + * ppc440spe_adma_dma2rxor_prep_src() has already done prior this call + */ +static void ppc440spe_adma_dma2rxor_set_mult( + struct ppc440spe_adma_desc_slot *desc, + int index, u8 mult) +{ + struct xor_cb *xcb = desc->hw_desc; + int k = 0, op = 0, lop = 0; + + /* get the RXOR operand which corresponds to index mult */ + while (op <= index) { + lop = op; + if (k == XOR_MAX_OPS) { + k = 0; + desc = list_entry(desc->chain_node.next, + struct ppc440spe_adma_desc_slot, + chain_node); + xcb = desc->hw_desc; + + } + if ((xcb->ops[k++].h & (DMA_RXOR12 << DMA_CUED_REGION_OFF)) == + (DMA_RXOR12 << DMA_CUED_REGION_OFF)) + op += 2; + else + op += 3; + } + + BUG_ON(k < 1); + if (test_bit(k-1, desc->reverse_flags)) { + /* reverse order */ + ppc440spe_rxor_set_mult(desc, k - 1, op - index - 1, mult); + } else { + /* direct order */ + ppc440spe_rxor_set_mult(desc, k - 1, index - lop, mult); + } +} + +/** + * ppc440spe_init_rxor_cursor - + */ +static void ppc440spe_init_rxor_cursor(struct ppc440spe_rxor *cursor) +{ + memset(cursor, 0, sizeof(struct ppc440spe_rxor)); + cursor->state = 2; +} + +/** + * ppc440spe_adma_pq_set_src_mult - set multiplication coefficient into + * descriptor for the PQXOR operation + */ +static void ppc440spe_adma_pq_set_src_mult( + struct ppc440spe_adma_desc_slot *sw_desc, + unsigned char mult, int index, int dst_pos) +{ + struct ppc440spe_adma_chan *chan; + u32 mult_idx, mult_dst; + struct ppc440spe_adma_desc_slot *iter = NULL, *iter1 = NULL; + + chan = to_ppc440spe_adma_chan(sw_desc->async_tx.chan); + + switch (chan->device->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + if (test_bit(PPC440SPE_DESC_RXOR, &sw_desc->flags)) { + int region = test_bit(PPC440SPE_DESC_RXOR12, + &sw_desc->flags) ? 2 : 3; + + if (index < region) { + /* RXOR multipliers */ + iter = ppc440spe_get_group_entry(sw_desc, + sw_desc->dst_cnt - 1); + if (sw_desc->dst_cnt == 2) + iter1 = ppc440spe_get_group_entry( + sw_desc, 0); + + mult_idx = DMA_CUED_MULT1_OFF + (index << 3); + mult_dst = DMA_CDB_SG_SRC; + } else { + /* WXOR multiplier */ + iter = ppc440spe_get_group_entry(sw_desc, + index - region + + sw_desc->dst_cnt); + mult_idx = DMA_CUED_MULT1_OFF; + mult_dst = dst_pos ? DMA_CDB_SG_DST2 : + DMA_CDB_SG_DST1; + } + } else { + int znum = 0; + + /* WXOR-only; + * skip first slots with destinations (if ZERO_DST has + * place) + */ + if (test_bit(PPC440SPE_ZERO_P, &sw_desc->flags)) + znum++; + if (test_bit(PPC440SPE_ZERO_Q, &sw_desc->flags)) + znum++; + + iter = ppc440spe_get_group_entry(sw_desc, index + znum); + mult_idx = DMA_CUED_MULT1_OFF; + mult_dst = dst_pos ? DMA_CDB_SG_DST2 : DMA_CDB_SG_DST1; + } + + if (likely(iter)) { + ppc440spe_desc_set_src_mult(iter, chan, + mult_idx, mult_dst, mult); + + if (unlikely(iter1)) { + /* if we have two destinations for RXOR, then + * we've just set Q mult. Set-up P now. + */ + ppc440spe_desc_set_src_mult(iter1, chan, + mult_idx, mult_dst, 1); + } + + } + break; + + case PPC440SPE_XOR_ID: + iter = sw_desc->group_head; + if (sw_desc->dst_cnt == 2) { + /* both P & Q calculations required; set P mult here */ + ppc440spe_adma_dma2rxor_set_mult(iter, index, 1); + + /* and then set Q mult */ + iter = ppc440spe_get_group_entry(sw_desc, + sw_desc->descs_per_op); + } + ppc440spe_adma_dma2rxor_set_mult(iter, index, mult); + break; + } +} + +/** + * ppc440spe_adma_free_chan_resources - free the resources allocated + */ +static void ppc440spe_adma_free_chan_resources(struct dma_chan *chan) +{ + struct ppc440spe_adma_chan *ppc440spe_chan; + struct ppc440spe_adma_desc_slot *iter, *_iter; + int in_use_descs = 0; + + ppc440spe_chan = to_ppc440spe_adma_chan(chan); + ppc440spe_adma_slot_cleanup(ppc440spe_chan); + + spin_lock_bh(&ppc440spe_chan->lock); + list_for_each_entry_safe(iter, _iter, &ppc440spe_chan->chain, + chain_node) { + in_use_descs++; + list_del(&iter->chain_node); + } + list_for_each_entry_safe_reverse(iter, _iter, + &ppc440spe_chan->all_slots, slot_node) { + list_del(&iter->slot_node); + kfree(iter); + ppc440spe_chan->slots_allocated--; + } + ppc440spe_chan->last_used = NULL; + + dev_dbg(ppc440spe_chan->device->common.dev, + "ppc440spe adma%d %s slots_allocated %d\n", + ppc440spe_chan->device->id, + __func__, ppc440spe_chan->slots_allocated); + spin_unlock_bh(&ppc440spe_chan->lock); + + /* one is ok since we left it on there on purpose */ + if (in_use_descs > 1) + printk(KERN_ERR "SPE: Freeing %d in use descriptors!\n", + in_use_descs - 1); +} + +/** + * ppc440spe_adma_is_complete - poll the status of an ADMA transaction + * @chan: ADMA channel handle + * @cookie: ADMA transaction identifier + */ +static enum dma_status ppc440spe_adma_is_complete(struct dma_chan *chan, + dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) +{ + struct ppc440spe_adma_chan *ppc440spe_chan; + dma_cookie_t last_used; + dma_cookie_t last_complete; + enum dma_status ret; + + ppc440spe_chan = to_ppc440spe_adma_chan(chan); + last_used = chan->cookie; + last_complete = ppc440spe_chan->completed_cookie; + + if (done) + *done = last_complete; + if (used) + *used = last_used; + + ret = dma_async_is_complete(cookie, last_complete, last_used); + if (ret == DMA_SUCCESS) + return ret; + + ppc440spe_adma_slot_cleanup(ppc440spe_chan); + + last_used = chan->cookie; + last_complete = ppc440spe_chan->completed_cookie; + + if (done) + *done = last_complete; + if (used) + *used = last_used; + + return dma_async_is_complete(cookie, last_complete, last_used); +} + +/** + * ppc440spe_adma_eot_handler - end of transfer interrupt handler + */ +static irqreturn_t ppc440spe_adma_eot_handler(int irq, void *data) +{ + struct ppc440spe_adma_chan *chan = data; + + dev_dbg(chan->device->common.dev, + "ppc440spe adma%d: %s\n", chan->device->id, __func__); + + tasklet_schedule(&chan->irq_tasklet); + ppc440spe_adma_device_clear_eot_status(chan); + + return IRQ_HANDLED; +} + +/** + * ppc440spe_adma_err_handler - DMA error interrupt handler; + * do the same things as a eot handler + */ +static irqreturn_t ppc440spe_adma_err_handler(int irq, void *data) +{ + struct ppc440spe_adma_chan *chan = data; + + dev_dbg(chan->device->common.dev, + "ppc440spe adma%d: %s\n", chan->device->id, __func__); + + tasklet_schedule(&chan->irq_tasklet); + ppc440spe_adma_device_clear_eot_status(chan); + + return IRQ_HANDLED; +} + +/** + * ppc440spe_test_callback - called when test operation has been done + */ +static void ppc440spe_test_callback(void *unused) +{ + complete(&ppc440spe_r6_test_comp); +} + +/** + * ppc440spe_adma_issue_pending - flush all pending descriptors to h/w + */ +static void ppc440spe_adma_issue_pending(struct dma_chan *chan) +{ + struct ppc440spe_adma_chan *ppc440spe_chan; + + ppc440spe_chan = to_ppc440spe_adma_chan(chan); + dev_dbg(ppc440spe_chan->device->common.dev, + "ppc440spe adma%d: %s %d \n", ppc440spe_chan->device->id, + __func__, ppc440spe_chan->pending); + + if (ppc440spe_chan->pending) { + ppc440spe_chan->pending = 0; + ppc440spe_chan_append(ppc440spe_chan); + } +} + +/** + * ppc440spe_chan_start_null_xor - initiate the first XOR operation (DMA engines + * use FIFOs (as opposite to chains used in XOR) so this is a XOR + * specific operation) + */ +static void ppc440spe_chan_start_null_xor(struct ppc440spe_adma_chan *chan) +{ + struct ppc440spe_adma_desc_slot *sw_desc, *group_start; + dma_cookie_t cookie; + int slot_cnt, slots_per_op; + + dev_dbg(chan->device->common.dev, + "ppc440spe adma%d: %s\n", chan->device->id, __func__); + + spin_lock_bh(&chan->lock); + slot_cnt = ppc440spe_chan_xor_slot_count(0, 2, &slots_per_op); + sw_desc = ppc440spe_adma_alloc_slots(chan, slot_cnt, slots_per_op); + if (sw_desc) { + group_start = sw_desc->group_head; + list_splice_init(&sw_desc->group_list, &chan->chain); + async_tx_ack(&sw_desc->async_tx); + ppc440spe_desc_init_null_xor(group_start); + + cookie = chan->common.cookie; + cookie++; + if (cookie <= 1) + cookie = 2; + + /* initialize the completed cookie to be less than + * the most recently used cookie + */ + chan->completed_cookie = cookie - 1; + chan->common.cookie = sw_desc->async_tx.cookie = cookie; + + /* channel should not be busy */ + BUG_ON(ppc440spe_chan_is_busy(chan)); + + /* set the descriptor address */ + ppc440spe_chan_set_first_xor_descriptor(chan, sw_desc); + + /* run the descriptor */ + ppc440spe_chan_run(chan); + } else + printk(KERN_ERR "ppc440spe adma%d" + " failed to allocate null descriptor\n", + chan->device->id); + spin_unlock_bh(&chan->lock); +} + +/** + * ppc440spe_test_raid6 - test are RAID-6 capabilities enabled successfully. + * For this we just perform one WXOR operation with the same source + * and destination addresses, the GF-multiplier is 1; so if RAID-6 + * capabilities are enabled then we'll get src/dst filled with zero. + */ +static int ppc440spe_test_raid6(struct ppc440spe_adma_chan *chan) +{ + struct ppc440spe_adma_desc_slot *sw_desc, *iter; + struct page *pg; + char *a; + dma_addr_t dma_addr, addrs[2]; + unsigned long op = 0; + int rval = 0; + + set_bit(PPC440SPE_DESC_WXOR, &op); + + pg = alloc_page(GFP_KERNEL); + if (!pg) + return -ENOMEM; + + spin_lock_bh(&chan->lock); + sw_desc = ppc440spe_adma_alloc_slots(chan, 1, 1); + if (sw_desc) { + /* 1 src, 1 dsr, int_ena, WXOR */ + ppc440spe_desc_init_dma01pq(sw_desc, 1, 1, 1, op); + list_for_each_entry(iter, &sw_desc->group_list, chain_node) { + ppc440spe_desc_set_byte_count(iter, chan, PAGE_SIZE); + iter->unmap_len = PAGE_SIZE; + } + } else { + rval = -EFAULT; + spin_unlock_bh(&chan->lock); + goto exit; + } + spin_unlock_bh(&chan->lock); + + /* Fill the test page with ones */ + memset(page_address(pg), 0xFF, PAGE_SIZE); + dma_addr = dma_map_page(chan->device->dev, pg, 0, + PAGE_SIZE, DMA_BIDIRECTIONAL); + + /* Setup addresses */ + ppc440spe_adma_pq_set_src(sw_desc, dma_addr, 0); + ppc440spe_adma_pq_set_src_mult(sw_desc, 1, 0, 0); + addrs[0] = dma_addr; + addrs[1] = 0; + ppc440spe_adma_pq_set_dest(sw_desc, addrs, DMA_PREP_PQ_DISABLE_Q); + + async_tx_ack(&sw_desc->async_tx); + sw_desc->async_tx.callback = ppc440spe_test_callback; + sw_desc->async_tx.callback_param = NULL; + + init_completion(&ppc440spe_r6_test_comp); + + ppc440spe_adma_tx_submit(&sw_desc->async_tx); + ppc440spe_adma_issue_pending(&chan->common); + + wait_for_completion(&ppc440spe_r6_test_comp); + + /* Now check if the test page is zeroed */ + a = page_address(pg); + if ((*(u32 *)a) == 0 && memcmp(a, a+4, PAGE_SIZE-4) == 0) { + /* page is zero - RAID-6 enabled */ + rval = 0; + } else { + /* RAID-6 was not enabled */ + rval = -EINVAL; + } +exit: + __free_page(pg); + return rval; +} + +static void ppc440spe_adma_init_capabilities(struct ppc440spe_adma_device *adev) +{ + switch (adev->id) { + case PPC440SPE_DMA0_ID: + case PPC440SPE_DMA1_ID: + dma_cap_set(DMA_MEMCPY, adev->common.cap_mask); + dma_cap_set(DMA_INTERRUPT, adev->common.cap_mask); + dma_cap_set(DMA_MEMSET, adev->common.cap_mask); + dma_cap_set(DMA_PQ, adev->common.cap_mask); + dma_cap_set(DMA_PQ_VAL, adev->common.cap_mask); + dma_cap_set(DMA_XOR_VAL, adev->common.cap_mask); + break; + case PPC440SPE_XOR_ID: + dma_cap_set(DMA_XOR, adev->common.cap_mask); + dma_cap_set(DMA_PQ, adev->common.cap_mask); + dma_cap_set(DMA_INTERRUPT, adev->common.cap_mask); + adev->common.cap_mask = adev->common.cap_mask; + break; + } + + /* Set base routines */ + adev->common.device_alloc_chan_resources = + ppc440spe_adma_alloc_chan_resources; + adev->common.device_free_chan_resources = + ppc440spe_adma_free_chan_resources; + adev->common.device_is_tx_complete = ppc440spe_adma_is_complete; + adev->common.device_issue_pending = ppc440spe_adma_issue_pending; + + /* Set prep routines based on capability */ + if (dma_has_cap(DMA_MEMCPY, adev->common.cap_mask)) { + adev->common.device_prep_dma_memcpy = + ppc440spe_adma_prep_dma_memcpy; + } + if (dma_has_cap(DMA_MEMSET, adev->common.cap_mask)) { + adev->common.device_prep_dma_memset = + ppc440spe_adma_prep_dma_memset; + } + if (dma_has_cap(DMA_XOR, adev->common.cap_mask)) { + adev->common.max_xor = XOR_MAX_OPS; + adev->common.device_prep_dma_xor = + ppc440spe_adma_prep_dma_xor; + } + if (dma_has_cap(DMA_PQ, adev->common.cap_mask)) { + switch (adev->id) { + case PPC440SPE_DMA0_ID: + dma_set_maxpq(&adev->common, + DMA0_FIFO_SIZE / sizeof(struct dma_cdb), 0); + break; + case PPC440SPE_DMA1_ID: + dma_set_maxpq(&adev->common, + DMA1_FIFO_SIZE / sizeof(struct dma_cdb), 0); + break; + case PPC440SPE_XOR_ID: + adev->common.max_pq = XOR_MAX_OPS * 3; + break; + } + adev->common.device_prep_dma_pq = + ppc440spe_adma_prep_dma_pq; + } + if (dma_has_cap(DMA_PQ_VAL, adev->common.cap_mask)) { + switch (adev->id) { + case PPC440SPE_DMA0_ID: + adev->common.max_pq = DMA0_FIFO_SIZE / + sizeof(struct dma_cdb); + break; + case PPC440SPE_DMA1_ID: + adev->common.max_pq = DMA1_FIFO_SIZE / + sizeof(struct dma_cdb); + break; + } + adev->common.device_prep_dma_pq_val = + ppc440spe_adma_prep_dma_pqzero_sum; + } + if (dma_has_cap(DMA_XOR_VAL, adev->common.cap_mask)) { + switch (adev->id) { + case PPC440SPE_DMA0_ID: + adev->common.max_xor = DMA0_FIFO_SIZE / + sizeof(struct dma_cdb); + break; + case PPC440SPE_DMA1_ID: + adev->common.max_xor = DMA1_FIFO_SIZE / + sizeof(struct dma_cdb); + break; + } + adev->common.device_prep_dma_xor_val = + ppc440spe_adma_prep_dma_xor_zero_sum; + } + if (dma_has_cap(DMA_INTERRUPT, adev->common.cap_mask)) { + adev->common.device_prep_dma_interrupt = + ppc440spe_adma_prep_dma_interrupt; + } + pr_info("%s: AMCC(R) PPC440SP(E) ADMA Engine: " + "( %s%s%s%s%s%s%s)\n", + dev_name(adev->dev), + dma_has_cap(DMA_PQ, adev->common.cap_mask) ? "pq " : "", + dma_has_cap(DMA_PQ_VAL, adev->common.cap_mask) ? "pq_val " : "", + dma_has_cap(DMA_XOR, adev->common.cap_mask) ? "xor " : "", + dma_has_cap(DMA_XOR_VAL, adev->common.cap_mask) ? "xor_val " : "", + dma_has_cap(DMA_MEMCPY, adev->common.cap_mask) ? "memcpy " : "", + dma_has_cap(DMA_MEMSET, adev->common.cap_mask) ? "memset " : "", + dma_has_cap(DMA_INTERRUPT, adev->common.cap_mask) ? "intr " : ""); +} + +static int ppc440spe_adma_setup_irqs(struct ppc440spe_adma_device *adev, + struct ppc440spe_adma_chan *chan, + int *initcode) +{ + struct device_node *np; + int ret; + + np = container_of(adev->dev, struct of_device, dev)->node; + if (adev->id != PPC440SPE_XOR_ID) { + adev->err_irq = irq_of_parse_and_map(np, 1); + if (adev->err_irq == NO_IRQ) { + dev_warn(adev->dev, "no err irq resource?\n"); + *initcode = PPC_ADMA_INIT_IRQ2; + adev->err_irq = -ENXIO; + } else + atomic_inc(&ppc440spe_adma_err_irq_ref); + } else { + adev->err_irq = -ENXIO; + } + + adev->irq = irq_of_parse_and_map(np, 0); + if (adev->irq == NO_IRQ) { + dev_err(adev->dev, "no irq resource\n"); + *initcode = PPC_ADMA_INIT_IRQ1; + ret = -ENXIO; + goto err_irq_map; + } + dev_dbg(adev->dev, "irq %d, err irq %d\n", + adev->irq, adev->err_irq); + + ret = request_irq(adev->irq, ppc440spe_adma_eot_handler, + 0, dev_driver_string(adev->dev), chan); + if (ret) { + dev_err(adev->dev, "can't request irq %d\n", + adev->irq); + *initcode = PPC_ADMA_INIT_IRQ1; + ret = -EIO; + goto err_req1; + } + + /* only DMA engines have a separate error IRQ + * so it's Ok if err_irq < 0 in XOR engine case. + */ + if (adev->err_irq > 0) { + /* both DMA engines share common error IRQ */ + ret = request_irq(adev->err_irq, + ppc440spe_adma_err_handler, + IRQF_SHARED, + dev_driver_string(adev->dev), + chan); + if (ret) { + dev_err(adev->dev, "can't request irq %d\n", + adev->err_irq); + *initcode = PPC_ADMA_INIT_IRQ2; + ret = -EIO; + goto err_req2; + } + } + + if (adev->id == PPC440SPE_XOR_ID) { + /* enable XOR engine interrupts */ + iowrite32be(XOR_IE_CBCIE_BIT | XOR_IE_ICBIE_BIT | + XOR_IE_ICIE_BIT | XOR_IE_RPTIE_BIT, + &adev->xor_reg->ier); + } else { + u32 mask, enable; + + np = of_find_compatible_node(NULL, NULL, "ibm,i2o-440spe"); + if (!np) { + pr_err("%s: can't find I2O device tree node\n", + __func__); + ret = -ENODEV; + goto err_req2; + } + adev->i2o_reg = of_iomap(np, 0); + if (!adev->i2o_reg) { + pr_err("%s: failed to map I2O registers\n", __func__); + of_node_put(np); + ret = -EINVAL; + goto err_req2; + } + of_node_put(np); + /* Unmask 'CS FIFO Attention' interrupts and + * enable generating interrupts on errors + */ + enable = (adev->id == PPC440SPE_DMA0_ID) ? + ~(I2O_IOPIM_P0SNE | I2O_IOPIM_P0EM) : + ~(I2O_IOPIM_P1SNE | I2O_IOPIM_P1EM); + mask = ioread32(&adev->i2o_reg->iopim) & enable; + iowrite32(mask, &adev->i2o_reg->iopim); + } + return 0; + +err_req2: + free_irq(adev->irq, chan); +err_req1: + irq_dispose_mapping(adev->irq); +err_irq_map: + if (adev->err_irq > 0) { + if (atomic_dec_and_test(&ppc440spe_adma_err_irq_ref)) + irq_dispose_mapping(adev->err_irq); + } + return ret; +} + +static void ppc440spe_adma_release_irqs(struct ppc440spe_adma_device *adev, + struct ppc440spe_adma_chan *chan) +{ + u32 mask, disable; + + if (adev->id == PPC440SPE_XOR_ID) { + /* disable XOR engine interrupts */ + mask = ioread32be(&adev->xor_reg->ier); + mask &= ~(XOR_IE_CBCIE_BIT | XOR_IE_ICBIE_BIT | + XOR_IE_ICIE_BIT | XOR_IE_RPTIE_BIT); + iowrite32be(mask, &adev->xor_reg->ier); + } else { + /* disable DMAx engine interrupts */ + disable = (adev->id == PPC440SPE_DMA0_ID) ? + (I2O_IOPIM_P0SNE | I2O_IOPIM_P0EM) : + (I2O_IOPIM_P1SNE | I2O_IOPIM_P1EM); + mask = ioread32(&adev->i2o_reg->iopim) | disable; + iowrite32(mask, &adev->i2o_reg->iopim); + } + free_irq(adev->irq, chan); + irq_dispose_mapping(adev->irq); + if (adev->err_irq > 0) { + free_irq(adev->err_irq, chan); + if (atomic_dec_and_test(&ppc440spe_adma_err_irq_ref)) { + irq_dispose_mapping(adev->err_irq); + iounmap(adev->i2o_reg); + } + } +} + +/** + * ppc440spe_adma_probe - probe the asynch device + */ +static int __devinit ppc440spe_adma_probe(struct of_device *ofdev, + const struct of_device_id *match) +{ + struct device_node *np = ofdev->node; + struct resource res; + struct ppc440spe_adma_device *adev; + struct ppc440spe_adma_chan *chan; + struct ppc_dma_chan_ref *ref, *_ref; + int ret = 0, initcode = PPC_ADMA_INIT_OK; + const u32 *idx; + int len; + void *regs; + u32 id, pool_size; + + if (of_device_is_compatible(np, "amcc,xor-accelerator")) { + id = PPC440SPE_XOR_ID; + /* As far as the XOR engine is concerned, it does not + * use FIFOs but uses linked list. So there is no dependency + * between pool size to allocate and the engine configuration. + */ + pool_size = PAGE_SIZE << 1; + } else { + /* it is DMA0 or DMA1 */ + idx = of_get_property(np, "cell-index", &len); + if (!idx || (len != sizeof(u32))) { + dev_err(&ofdev->dev, "Device node %s has missing " + "or invalid cell-index property\n", + np->full_name); + return -EINVAL; + } + id = *idx; + /* DMA0,1 engines use FIFO to maintain CDBs, so we + * should allocate the pool accordingly to size of this + * FIFO. Thus, the pool size depends on the FIFO depth: + * how much CDBs pointers the FIFO may contain then so + * much CDBs we should provide in the pool. + * That is + * CDB size = 32B; + * CDBs number = (DMA0_FIFO_SIZE >> 3); + * Pool size = CDBs number * CDB size = + * = (DMA0_FIFO_SIZE >> 3) << 5 = DMA0_FIFO_SIZE << 2. + */ + pool_size = (id == PPC440SPE_DMA0_ID) ? + DMA0_FIFO_SIZE : DMA1_FIFO_SIZE; + pool_size <<= 2; + } + + if (of_address_to_resource(np, 0, &res)) { + dev_err(&ofdev->dev, "failed to get memory resource\n"); + initcode = PPC_ADMA_INIT_MEMRES; + ret = -ENODEV; + goto out; + } + + if (!request_mem_region(res.start, resource_size(&res), + dev_driver_string(&ofdev->dev))) { + dev_err(&ofdev->dev, "failed to request memory region " + "(0x%016llx-0x%016llx)\n", + (u64)res.start, (u64)res.end); + initcode = PPC_ADMA_INIT_MEMREG; + ret = -EBUSY; + goto out; + } + + /* create a device */ + adev = kzalloc(sizeof(*adev), GFP_KERNEL); + if (!adev) { + dev_err(&ofdev->dev, "failed to allocate device\n"); + initcode = PPC_ADMA_INIT_ALLOC; + ret = -ENOMEM; + goto err_adev_alloc; + } + + adev->id = id; + adev->pool_size = pool_size; + /* allocate coherent memory for hardware descriptors */ + adev->dma_desc_pool_virt = dma_alloc_coherent(&ofdev->dev, + adev->pool_size, &adev->dma_desc_pool, + GFP_KERNEL); + if (adev->dma_desc_pool_virt == NULL) { + dev_err(&ofdev->dev, "failed to allocate %d bytes of coherent " + "memory for hardware descriptors\n", + adev->pool_size); + initcode = PPC_ADMA_INIT_COHERENT; + ret = -ENOMEM; + goto err_dma_alloc; + } + dev_dbg(&ofdev->dev, "allocted descriptor pool virt 0x%p phys 0x%llx\n", + adev->dma_desc_pool_virt, (u64)adev->dma_desc_pool); + + regs = ioremap(res.start, resource_size(&res)); + if (!regs) { + dev_err(&ofdev->dev, "failed to ioremap regs!\n"); + goto err_regs_alloc; + } + + if (adev->id == PPC440SPE_XOR_ID) { + adev->xor_reg = regs; + /* Reset XOR */ + iowrite32be(XOR_CRSR_XASR_BIT, &adev->xor_reg->crsr); + iowrite32be(XOR_CRSR_64BA_BIT, &adev->xor_reg->crrr); + } else { + size_t fifo_size = (adev->id == PPC440SPE_DMA0_ID) ? + DMA0_FIFO_SIZE : DMA1_FIFO_SIZE; + adev->dma_reg = regs; + /* DMAx_FIFO_SIZE is defined in bytes, + * - is defined in number of CDB pointers (8byte). + * DMA FIFO Length = CSlength + CPlength, where + * CSlength = CPlength = (fsiz + 1) * 8. + */ + iowrite32(DMA_FIFO_ENABLE | ((fifo_size >> 3) - 2), + &adev->dma_reg->fsiz); + /* Configure DMA engine */ + iowrite32(DMA_CFG_DXEPR_HP | DMA_CFG_DFMPP_HP | DMA_CFG_FALGN, + &adev->dma_reg->cfg); + /* Clear Status */ + iowrite32(~0, &adev->dma_reg->dsts); + } + + adev->dev = &ofdev->dev; + adev->common.dev = &ofdev->dev; + INIT_LIST_HEAD(&adev->common.channels); + dev_set_drvdata(&ofdev->dev, adev); + + /* create a channel */ + chan = kzalloc(sizeof(*chan), GFP_KERNEL); + if (!chan) { + dev_err(&ofdev->dev, "can't allocate channel structure\n"); + initcode = PPC_ADMA_INIT_CHANNEL; + ret = -ENOMEM; + goto err_chan_alloc; + } + + spin_lock_init(&chan->lock); + INIT_LIST_HEAD(&chan->chain); + INIT_LIST_HEAD(&chan->all_slots); + chan->device = adev; + chan->common.device = &adev->common; + list_add_tail(&chan->common.device_node, &adev->common.channels); + tasklet_init(&chan->irq_tasklet, ppc440spe_adma_tasklet, + (unsigned long)chan); + + /* allocate and map helper pages for async validation or + * async_mult/async_sum_product operations on DMA0/1. + */ + if (adev->id != PPC440SPE_XOR_ID) { + chan->pdest_page = alloc_page(GFP_KERNEL); + chan->qdest_page = alloc_page(GFP_KERNEL); + if (!chan->pdest_page || + !chan->qdest_page) { + if (chan->pdest_page) + __free_page(chan->pdest_page); + if (chan->qdest_page) + __free_page(chan->qdest_page); + ret = -ENOMEM; + goto err_page_alloc; + } + chan->pdest = dma_map_page(&ofdev->dev, chan->pdest_page, 0, + PAGE_SIZE, DMA_BIDIRECTIONAL); + chan->qdest = dma_map_page(&ofdev->dev, chan->qdest_page, 0, + PAGE_SIZE, DMA_BIDIRECTIONAL); + } + + ref = kmalloc(sizeof(*ref), GFP_KERNEL); + if (ref) { + ref->chan = &chan->common; + INIT_LIST_HEAD(&ref->node); + list_add_tail(&ref->node, &ppc440spe_adma_chan_list); + } else { + dev_err(&ofdev->dev, "failed to allocate channel reference!\n"); + ret = -ENOMEM; + goto err_ref_alloc; + } + + ret = ppc440spe_adma_setup_irqs(adev, chan, &initcode); + if (ret) + goto err_irq; + + ppc440spe_adma_init_capabilities(adev); + + ret = dma_async_device_register(&adev->common); + if (ret) { + initcode = PPC_ADMA_INIT_REGISTER; + dev_err(&ofdev->dev, "failed to register dma device\n"); + goto err_dev_reg; + } + + goto out; + +err_dev_reg: + ppc440spe_adma_release_irqs(adev, chan); +err_irq: + list_for_each_entry_safe(ref, _ref, &ppc440spe_adma_chan_list, node) { + if (chan == to_ppc440spe_adma_chan(ref->chan)) { + list_del(&ref->node); + kfree(ref); + } + } +err_ref_alloc: + if (adev->id != PPC440SPE_XOR_ID) { + dma_unmap_page(&ofdev->dev, chan->pdest, + PAGE_SIZE, DMA_BIDIRECTIONAL); + dma_unmap_page(&ofdev->dev, chan->qdest, + PAGE_SIZE, DMA_BIDIRECTIONAL); + __free_page(chan->pdest_page); + __free_page(chan->qdest_page); + } +err_page_alloc: + kfree(chan); +err_chan_alloc: + if (adev->id == PPC440SPE_XOR_ID) + iounmap(adev->xor_reg); + else + iounmap(adev->dma_reg); +err_regs_alloc: + dma_free_coherent(adev->dev, adev->pool_size, + adev->dma_desc_pool_virt, + adev->dma_desc_pool); +err_dma_alloc: + kfree(adev); +err_adev_alloc: + release_mem_region(res.start, resource_size(&res)); +out: + if (id < PPC440SPE_ADMA_ENGINES_NUM) + ppc440spe_adma_devices[id] = initcode; + + return ret; +} + +/** + * ppc440spe_adma_remove - remove the asynch device + */ +static int __devexit ppc440spe_adma_remove(struct of_device *ofdev) +{ + struct ppc440spe_adma_device *adev = dev_get_drvdata(&ofdev->dev); + struct device_node *np = ofdev->node; + struct resource res; + struct dma_chan *chan, *_chan; + struct ppc_dma_chan_ref *ref, *_ref; + struct ppc440spe_adma_chan *ppc440spe_chan; + + dev_set_drvdata(&ofdev->dev, NULL); + if (adev->id < PPC440SPE_ADMA_ENGINES_NUM) + ppc440spe_adma_devices[adev->id] = -1; + + dma_async_device_unregister(&adev->common); + + list_for_each_entry_safe(chan, _chan, &adev->common.channels, + device_node) { + ppc440spe_chan = to_ppc440spe_adma_chan(chan); + ppc440spe_adma_release_irqs(adev, ppc440spe_chan); + tasklet_kill(&ppc440spe_chan->irq_tasklet); + if (adev->id != PPC440SPE_XOR_ID) { + dma_unmap_page(&ofdev->dev, ppc440spe_chan->pdest, + PAGE_SIZE, DMA_BIDIRECTIONAL); + dma_unmap_page(&ofdev->dev, ppc440spe_chan->qdest, + PAGE_SIZE, DMA_BIDIRECTIONAL); + __free_page(ppc440spe_chan->pdest_page); + __free_page(ppc440spe_chan->qdest_page); + } + list_for_each_entry_safe(ref, _ref, &ppc440spe_adma_chan_list, + node) { + if (ppc440spe_chan == + to_ppc440spe_adma_chan(ref->chan)) { + list_del(&ref->node); + kfree(ref); + } + } + list_del(&chan->device_node); + kfree(ppc440spe_chan); + } + + dma_free_coherent(adev->dev, adev->pool_size, + adev->dma_desc_pool_virt, adev->dma_desc_pool); + if (adev->id == PPC440SPE_XOR_ID) + iounmap(adev->xor_reg); + else + iounmap(adev->dma_reg); + of_address_to_resource(np, 0, &res); + release_mem_region(res.start, resource_size(&res)); + kfree(adev); + return 0; +} + +/* + * /sys driver interface to enable h/w RAID-6 capabilities + * Files created in e.g. /sys/devices/plb.0/400100100.dma0/driver/ + * directory are "devices", "enable" and "poly". + * "devices" shows available engines. + * "enable" is used to enable RAID-6 capabilities or to check + * whether these has been activated. + * "poly" allows setting/checking used polynomial (for PPC440SPe only). + */ + +static ssize_t show_ppc440spe_devices(struct device_driver *dev, char *buf) +{ + ssize_t size = 0; + int i; + + for (i = 0; i < PPC440SPE_ADMA_ENGINES_NUM; i++) { + if (ppc440spe_adma_devices[i] == -1) + continue; + size += snprintf(buf + size, PAGE_SIZE - size, + "PPC440SP(E)-ADMA.%d: %s\n", i, + ppc_adma_errors[ppc440spe_adma_devices[i]]); + } + return size; +} + +static ssize_t show_ppc440spe_r6enable(struct device_driver *dev, char *buf) +{ + return snprintf(buf, PAGE_SIZE, + "PPC440SP(e) RAID-6 capabilities are %sABLED.\n", + ppc440spe_r6_enabled ? "EN" : "DIS"); +} + +static ssize_t store_ppc440spe_r6enable(struct device_driver *dev, + const char *buf, size_t count) +{ + unsigned long val; + + if (!count || count > 11) + return -EINVAL; + + if (!ppc440spe_r6_tchan) + return -EFAULT; + + /* Write a key */ + sscanf(buf, "%lx", &val); + dcr_write(ppc440spe_mq_dcr_host, DCRN_MQ0_XORBA, val); + isync(); + + /* Verify whether it really works now */ + if (ppc440spe_test_raid6(ppc440spe_r6_tchan) == 0) { + pr_info("PPC440SP(e) RAID-6 has been activated " + "successfully\n"); + ppc440spe_r6_enabled = 1; + } else { + pr_info("PPC440SP(e) RAID-6 hasn't been activated!" + " Error key ?\n"); + ppc440spe_r6_enabled = 0; + } + return count; +} + +static ssize_t show_ppc440spe_r6poly(struct device_driver *dev, char *buf) +{ + ssize_t size = 0; + u32 reg; + +#ifdef CONFIG_440SP + /* 440SP has fixed polynomial */ + reg = 0x4d; +#else + reg = dcr_read(ppc440spe_mq_dcr_host, DCRN_MQ0_CFBHL); + reg >>= MQ0_CFBHL_POLY; + reg &= 0xFF; +#endif + + size = snprintf(buf, PAGE_SIZE, "PPC440SP(e) RAID-6 driver " + "uses 0x1%02x polynomial.\n", reg); + return size; +} + +static ssize_t store_ppc440spe_r6poly(struct device_driver *dev, + const char *buf, size_t count) +{ + unsigned long reg, val; + +#ifdef CONFIG_440SP + /* 440SP uses default 0x14D polynomial only */ + return -EINVAL; +#endif + + if (!count || count > 6) + return -EINVAL; + + /* e.g., 0x14D or 0x11D */ + sscanf(buf, "%lx", &val); + + if (val & ~0x1FF) + return -EINVAL; + + val &= 0xFF; + reg = dcr_read(ppc440spe_mq_dcr_host, DCRN_MQ0_CFBHL); + reg &= ~(0xFF << MQ0_CFBHL_POLY); + reg |= val << MQ0_CFBHL_POLY; + dcr_write(ppc440spe_mq_dcr_host, DCRN_MQ0_CFBHL, reg); + + return count; +} + +static DRIVER_ATTR(devices, S_IRUGO, show_ppc440spe_devices, NULL); +static DRIVER_ATTR(enable, S_IRUGO | S_IWUSR, show_ppc440spe_r6enable, + store_ppc440spe_r6enable); +static DRIVER_ATTR(poly, S_IRUGO | S_IWUSR, show_ppc440spe_r6poly, + store_ppc440spe_r6poly); + +/* + * Common initialisation for RAID engines; allocate memory for + * DMAx FIFOs, perform configuration common for all DMA engines. + * Further DMA engine specific configuration is done at probe time. + */ +static int ppc440spe_configure_raid_devices(void) +{ + struct device_node *np; + struct resource i2o_res; + struct i2o_regs __iomem *i2o_reg; + dcr_host_t i2o_dcr_host; + unsigned int dcr_base, dcr_len; + int i, ret; + + np = of_find_compatible_node(NULL, NULL, "ibm,i2o-440spe"); + if (!np) { + pr_err("%s: can't find I2O device tree node\n", + __func__); + return -ENODEV; + } + + if (of_address_to_resource(np, 0, &i2o_res)) { + of_node_put(np); + return -EINVAL; + } + + i2o_reg = of_iomap(np, 0); + if (!i2o_reg) { + pr_err("%s: failed to map I2O registers\n", __func__); + of_node_put(np); + return -EINVAL; + } + + /* Get I2O DCRs base */ + dcr_base = dcr_resource_start(np, 0); + dcr_len = dcr_resource_len(np, 0); + if (!dcr_base && !dcr_len) { + pr_err("%s: can't get DCR registers base/len!\n", + np->full_name); + of_node_put(np); + iounmap(i2o_reg); + return -ENODEV; + } + + i2o_dcr_host = dcr_map(np, dcr_base, dcr_len); + if (!DCR_MAP_OK(i2o_dcr_host)) { + pr_err("%s: failed to map DCRs!\n", np->full_name); + of_node_put(np); + iounmap(i2o_reg); + return -ENODEV; + } + of_node_put(np); + + /* Provide memory regions for DMA's FIFOs: I2O, DMA0 and DMA1 share + * the base address of FIFO memory space. + * Actually we need twice more physical memory than programmed in the + * register (because there are two FIFOs for each DMA: CP and CS) + */ + ppc440spe_dma_fifo_buf = kmalloc((DMA0_FIFO_SIZE + DMA1_FIFO_SIZE) << 1, + GFP_KERNEL); + if (!ppc440spe_dma_fifo_buf) { + pr_err("%s: DMA FIFO buffer allocation failed.\n", __func__); + iounmap(i2o_reg); + dcr_unmap(i2o_dcr_host, dcr_len); + return -ENOMEM; + } + + /* + * Configure h/w + */ + /* Reset I2O/DMA */ + mtdcri(SDR0, DCRN_SDR0_SRST, DCRN_SDR0_SRST_I2ODMA); + mtdcri(SDR0, DCRN_SDR0_SRST, 0); + + /* Setup the base address of mmaped registers */ + dcr_write(i2o_dcr_host, DCRN_I2O0_IBAH, (u32)(i2o_res.start >> 32)); + dcr_write(i2o_dcr_host, DCRN_I2O0_IBAL, (u32)(i2o_res.start) | + I2O_REG_ENABLE); + dcr_unmap(i2o_dcr_host, dcr_len); + + /* Setup FIFO memory space base address */ + iowrite32(0, &i2o_reg->ifbah); + iowrite32(((u32)__pa(ppc440spe_dma_fifo_buf)), &i2o_reg->ifbal); + + /* set zero FIFO size for I2O, so the whole + * ppc440spe_dma_fifo_buf is used by DMAs. + * DMAx_FIFOs will be configured while probe. + */ + iowrite32(0, &i2o_reg->ifsiz); + iounmap(i2o_reg); + + /* To prepare WXOR/RXOR functionality we need access to + * Memory Queue Module DCRs (finally it will be enabled + * via /sys interface of the ppc440spe ADMA driver). + */ + np = of_find_compatible_node(NULL, NULL, "ibm,mq-440spe"); + if (!np) { + pr_err("%s: can't find MQ device tree node\n", + __func__); + ret = -ENODEV; + goto out_free; + } + + /* Get MQ DCRs base */ + dcr_base = dcr_resource_start(np, 0); + dcr_len = dcr_resource_len(np, 0); + if (!dcr_base && !dcr_len) { + pr_err("%s: can't get DCR registers base/len!\n", + np->full_name); + ret = -ENODEV; + goto out_mq; + } + + ppc440spe_mq_dcr_host = dcr_map(np, dcr_base, dcr_len); + if (!DCR_MAP_OK(ppc440spe_mq_dcr_host)) { + pr_err("%s: failed to map DCRs!\n", np->full_name); + ret = -ENODEV; + goto out_mq; + } + of_node_put(np); + ppc440spe_mq_dcr_len = dcr_len; + + /* Set HB alias */ + dcr_write(ppc440spe_mq_dcr_host, DCRN_MQ0_BAUH, DMA_CUED_XOR_HB); + + /* Set: + * - LL transaction passing limit to 1; + * - Memory controller cycle limit to 1; + * - Galois Polynomial to 0x14d (default) + */ + dcr_write(ppc440spe_mq_dcr_host, DCRN_MQ0_CFBHL, + (1 << MQ0_CFBHL_TPLM) | (1 << MQ0_CFBHL_HBCL) | + (PPC440SPE_DEFAULT_POLY << MQ0_CFBHL_POLY)); + + atomic_set(&ppc440spe_adma_err_irq_ref, 0); + for (i = 0; i < PPC440SPE_ADMA_ENGINES_NUM; i++) + ppc440spe_adma_devices[i] = -1; + + return 0; + +out_mq: + of_node_put(np); +out_free: + kfree(ppc440spe_dma_fifo_buf); + return ret; +} + +static struct of_device_id __devinitdata ppc440spe_adma_of_match[] = { + { .compatible = "ibm,dma-440spe", }, + { .compatible = "amcc,xor-accelerator", }, + {}, +}; +MODULE_DEVICE_TABLE(of, ppc440spe_adma_of_match); + +static struct of_platform_driver ppc440spe_adma_driver = { + .match_table = ppc440spe_adma_of_match, + .probe = ppc440spe_adma_probe, + .remove = __devexit_p(ppc440spe_adma_remove), + .driver = { + .name = "PPC440SP(E)-ADMA", + .owner = THIS_MODULE, + }, +}; + +static __init int ppc440spe_adma_init(void) +{ + int ret; + + ret = ppc440spe_configure_raid_devices(); + if (ret) + return ret; + + ret = of_register_platform_driver(&ppc440spe_adma_driver); + if (ret) { + pr_err("%s: failed to register platform driver\n", + __func__); + goto out_reg; + } + + /* Initialization status */ + ret = driver_create_file(&ppc440spe_adma_driver.driver, + &driver_attr_devices); + if (ret) + goto out_dev; + + /* RAID-6 h/w enable entry */ + ret = driver_create_file(&ppc440spe_adma_driver.driver, + &driver_attr_enable); + if (ret) + goto out_en; + + /* GF polynomial to use */ + ret = driver_create_file(&ppc440spe_adma_driver.driver, + &driver_attr_poly); + if (!ret) + return ret; + + driver_remove_file(&ppc440spe_adma_driver.driver, + &driver_attr_enable); +out_en: + driver_remove_file(&ppc440spe_adma_driver.driver, + &driver_attr_devices); +out_dev: + /* User will not be able to enable h/w RAID-6 */ + pr_err("%s: failed to create RAID-6 driver interface\n", + __func__); + of_unregister_platform_driver(&ppc440spe_adma_driver); +out_reg: + dcr_unmap(ppc440spe_mq_dcr_host, ppc440spe_mq_dcr_len); + kfree(ppc440spe_dma_fifo_buf); + return ret; +} + +static void __exit ppc440spe_adma_exit(void) +{ + driver_remove_file(&ppc440spe_adma_driver.driver, + &driver_attr_poly); + driver_remove_file(&ppc440spe_adma_driver.driver, + &driver_attr_enable); + driver_remove_file(&ppc440spe_adma_driver.driver, + &driver_attr_devices); + of_unregister_platform_driver(&ppc440spe_adma_driver); + dcr_unmap(ppc440spe_mq_dcr_host, ppc440spe_mq_dcr_len); + kfree(ppc440spe_dma_fifo_buf); +} + +arch_initcall(ppc440spe_adma_init); +module_exit(ppc440spe_adma_exit); + +MODULE_AUTHOR("Yuri Tikhonov "); +MODULE_DESCRIPTION("PPC440SPE ADMA Engine Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/dma/ppc4xx/adma.h b/drivers/dma/ppc4xx/adma.h new file mode 100644 index 0000000..8ada5a81 --- /dev/null +++ b/drivers/dma/ppc4xx/adma.h @@ -0,0 +1,195 @@ +/* + * 2006-2009 (C) DENX Software Engineering. + * + * Author: Yuri Tikhonov + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of + * any kind, whether express or implied. + */ + +#ifndef _PPC440SPE_ADMA_H +#define _PPC440SPE_ADMA_H + +#include +#include "dma.h" +#include "xor.h" + +#define to_ppc440spe_adma_chan(chan) \ + container_of(chan, struct ppc440spe_adma_chan, common) +#define to_ppc440spe_adma_device(dev) \ + container_of(dev, struct ppc440spe_adma_device, common) +#define tx_to_ppc440spe_adma_slot(tx) \ + container_of(tx, struct ppc440spe_adma_desc_slot, async_tx) + +/* Default polynomial (for 440SP is only available) */ +#define PPC440SPE_DEFAULT_POLY 0x4d + +#define PPC440SPE_ADMA_ENGINES_NUM (XOR_ENGINES_NUM + DMA_ENGINES_NUM) + +#define PPC440SPE_ADMA_WATCHDOG_MSEC 3 +#define PPC440SPE_ADMA_THRESHOLD 1 + +#define PPC440SPE_DMA0_ID 0 +#define PPC440SPE_DMA1_ID 1 +#define PPC440SPE_XOR_ID 2 + +#define PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT 0xFFFFFFUL +/* this is the XOR_CBBCR width */ +#define PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT (1 << 31) +#define PPC440SPE_ADMA_ZERO_SUM_MAX_BYTE_COUNT PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT + +#define PPC440SPE_RXOR_RUN 0 + +#define MQ0_CF2H_RXOR_BS_MASK 0x1FF + +#undef ADMA_LL_DEBUG + +/** + * struct ppc440spe_adma_device - internal representation of an ADMA device + * @dev: device + * @dma_reg: base for DMAx register access + * @xor_reg: base for XOR register access + * @i2o_reg: base for I2O register access + * @id: HW ADMA Device selector + * @dma_desc_pool_virt: base of DMA descriptor region (CPU address) + * @dma_desc_pool: base of DMA descriptor region (DMA address) + * @pool_size: size of the pool + * @irq: DMAx or XOR irq number + * @err_irq: DMAx error irq number + * @common: embedded struct dma_device + */ +struct ppc440spe_adma_device { + struct device *dev; + struct dma_regs __iomem *dma_reg; + struct xor_regs __iomem *xor_reg; + struct i2o_regs __iomem *i2o_reg; + int id; + void *dma_desc_pool_virt; + dma_addr_t dma_desc_pool; + size_t pool_size; + int irq; + int err_irq; + struct dma_device common; +}; + +/** + * struct ppc440spe_adma_chan - internal representation of an ADMA channel + * @lock: serializes enqueue/dequeue operations to the slot pool + * @device: parent device + * @chain: device chain view of the descriptors + * @common: common dmaengine channel object members + * @all_slots: complete domain of slots usable by the channel + * @pending: allows batching of hardware operations + * @completed_cookie: identifier for the most recently completed operation + * @slots_allocated: records the actual size of the descriptor slot pool + * @hw_chain_inited: h/w descriptor chain initialization flag + * @irq_tasklet: bottom half where ppc440spe_adma_slot_cleanup runs + * @needs_unmap: if buffers should not be unmapped upon final processing + * @pdest_page: P destination page for async validate operation + * @qdest_page: Q destination page for async validate operation + * @pdest: P dma addr for async validate operation + * @qdest: Q dma addr for async validate operation + */ +struct ppc440spe_adma_chan { + spinlock_t lock; + struct ppc440spe_adma_device *device; + struct list_head chain; + struct dma_chan common; + struct list_head all_slots; + struct ppc440spe_adma_desc_slot *last_used; + int pending; + dma_cookie_t completed_cookie; + int slots_allocated; + int hw_chain_inited; + struct tasklet_struct irq_tasklet; + u8 needs_unmap; + struct page *pdest_page; + struct page *qdest_page; + dma_addr_t pdest; + dma_addr_t qdest; +}; + +struct ppc440spe_rxor { + u32 addrl; + u32 addrh; + int len; + int xor_count; + int addr_count; + int desc_count; + int state; +}; + +/** + * struct ppc440spe_adma_desc_slot - PPC440SPE-ADMA software descriptor + * @phys: hardware address of the hardware descriptor chain + * @group_head: first operation in a transaction + * @hw_next: pointer to the next descriptor in chain + * @async_tx: support for the async_tx api + * @slot_node: node on the iop_adma_chan.all_slots list + * @chain_node: node on the op_adma_chan.chain list + * @group_list: list of slots that make up a multi-descriptor transaction + * for example transfer lengths larger than the supported hw max + * @unmap_len: transaction bytecount + * @hw_desc: virtual address of the hardware descriptor chain + * @stride: currently chained or not + * @idx: pool index + * @slot_cnt: total slots used in an transaction (group of operations) + * @src_cnt: number of sources set in this descriptor + * @dst_cnt: number of destinations set in the descriptor + * @slots_per_op: number of slots per operation + * @descs_per_op: number of slot per P/Q operation see comment + * for ppc440spe_prep_dma_pqxor function + * @flags: desc state/type + * @reverse_flags: 1 if a corresponding rxor address uses reversed address order + * @xor_check_result: result of zero sum + * @crc32_result: result crc calculation + */ +struct ppc440spe_adma_desc_slot { + dma_addr_t phys; + struct ppc440spe_adma_desc_slot *group_head; + struct ppc440spe_adma_desc_slot *hw_next; + struct dma_async_tx_descriptor async_tx; + struct list_head slot_node; + struct list_head chain_node; /* node in channel ops list */ + struct list_head group_list; /* list */ + unsigned int unmap_len; + void *hw_desc; + u16 stride; + u16 idx; + u16 slot_cnt; + u8 src_cnt; + u8 dst_cnt; + u8 slots_per_op; + u8 descs_per_op; + unsigned long flags; + unsigned long reverse_flags[8]; + +#define PPC440SPE_DESC_INT 0 /* generate interrupt on complete */ +#define PPC440SPE_ZERO_P 1 /* clear P destionaion */ +#define PPC440SPE_ZERO_Q 2 /* clear Q destination */ +#define PPC440SPE_COHERENT 3 /* src/dst are coherent */ + +#define PPC440SPE_DESC_WXOR 4 /* WXORs are in chain */ +#define PPC440SPE_DESC_RXOR 5 /* RXOR is in chain */ + +#define PPC440SPE_DESC_RXOR123 8 /* CDB for RXOR123 operation */ +#define PPC440SPE_DESC_RXOR124 9 /* CDB for RXOR124 operation */ +#define PPC440SPE_DESC_RXOR125 10 /* CDB for RXOR125 operation */ +#define PPC440SPE_DESC_RXOR12 11 /* CDB for RXOR12 operation */ +#define PPC440SPE_DESC_RXOR_REV 12 /* CDB has srcs in reversed order */ + +#define PPC440SPE_DESC_PCHECK 13 +#define PPC440SPE_DESC_QCHECK 14 + +#define PPC440SPE_DESC_RXOR_MSK 0x3 + + struct ppc440spe_rxor rxor_cursor; + + union { + u32 *xor_check_result; + u32 *crc32_result; + }; +}; + +#endif /* _PPC440SPE_ADMA_H */ diff --git a/drivers/dma/ppc4xx/dma.h b/drivers/dma/ppc4xx/dma.h new file mode 100644 index 0000000..bcde2df --- /dev/null +++ b/drivers/dma/ppc4xx/dma.h @@ -0,0 +1,223 @@ +/* + * 440SPe's DMA engines support header file + * + * 2006-2009 (C) DENX Software Engineering. + * + * Author: Yuri Tikhonov + * + * This file is licensed under the term of the GNU General Public License + * version 2. The program licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#ifndef _PPC440SPE_DMA_H +#define _PPC440SPE_DMA_H + +#include + +/* Number of elements in the array with statical CDBs */ +#define MAX_STAT_DMA_CDBS 16 +/* Number of DMA engines available on the contoller */ +#define DMA_ENGINES_NUM 2 + +/* Maximum h/w supported number of destinations */ +#define DMA_DEST_MAX_NUM 2 + +/* FIFO's params */ +#define DMA0_FIFO_SIZE 0x1000 +#define DMA1_FIFO_SIZE 0x1000 +#define DMA_FIFO_ENABLE (1<<12) + +/* DMA Configuration Register. Data Transfer Engine PLB Priority: */ +#define DMA_CFG_DXEPR_LP (0<<26) +#define DMA_CFG_DXEPR_HP (3<<26) +#define DMA_CFG_DXEPR_HHP (2<<26) +#define DMA_CFG_DXEPR_HHHP (1<<26) + +/* DMA Configuration Register. DMA FIFO Manager PLB Priority: */ +#define DMA_CFG_DFMPP_LP (0<<23) +#define DMA_CFG_DFMPP_HP (3<<23) +#define DMA_CFG_DFMPP_HHP (2<<23) +#define DMA_CFG_DFMPP_HHHP (1<<23) + +/* DMA Configuration Register. Force 64-byte Alignment */ +#define DMA_CFG_FALGN (1 << 19) + +/*UIC0:*/ +#define D0CPF_INT (1<<12) +#define D0CSF_INT (1<<11) +#define D1CPF_INT (1<<10) +#define D1CSF_INT (1<<9) +/*UIC1:*/ +#define DMAE_INT (1<<9) + +/* I2O IOP Interrupt Mask Register */ +#define I2O_IOPIM_P0SNE (1<<3) +#define I2O_IOPIM_P0EM (1<<5) +#define I2O_IOPIM_P1SNE (1<<6) +#define I2O_IOPIM_P1EM (1<<8) + +/* DMA CDB fields */ +#define DMA_CDB_MSK (0xF) +#define DMA_CDB_64B_ADDR (1<<2) +#define DMA_CDB_NO_INT (1<<3) +#define DMA_CDB_STATUS_MSK (0x3) +#define DMA_CDB_ADDR_MSK (0xFFFFFFF0) + +/* DMA CDB OpCodes */ +#define DMA_CDB_OPC_NO_OP (0x00) +#define DMA_CDB_OPC_MV_SG1_SG2 (0x01) +#define DMA_CDB_OPC_MULTICAST (0x05) +#define DMA_CDB_OPC_DFILL128 (0x24) +#define DMA_CDB_OPC_DCHECK128 (0x23) + +#define DMA_CUED_XOR_BASE (0x10000000) +#define DMA_CUED_XOR_HB (0x00000008) + +#ifdef CONFIG_440SP +#define DMA_CUED_MULT1_OFF 0 +#define DMA_CUED_MULT2_OFF 8 +#define DMA_CUED_MULT3_OFF 16 +#define DMA_CUED_REGION_OFF 24 +#define DMA_CUED_XOR_WIN_MSK (0xFC000000) +#else +#define DMA_CUED_MULT1_OFF 2 +#define DMA_CUED_MULT2_OFF 10 +#define DMA_CUED_MULT3_OFF 18 +#define DMA_CUED_REGION_OFF 26 +#define DMA_CUED_XOR_WIN_MSK (0xF0000000) +#endif + +#define DMA_CUED_REGION_MSK 0x3 +#define DMA_RXOR123 0x0 +#define DMA_RXOR124 0x1 +#define DMA_RXOR125 0x2 +#define DMA_RXOR12 0x3 + +/* S/G addresses */ +#define DMA_CDB_SG_SRC 1 +#define DMA_CDB_SG_DST1 2 +#define DMA_CDB_SG_DST2 3 + +/* + * DMAx engines Command Descriptor Block Type + */ +struct dma_cdb { + /* + * Basic CDB structure (Table 20-17, p.499, 440spe_um_1_22.pdf) + */ + u8 pad0[2]; /* reserved */ + u8 attr; /* attributes */ + u8 opc; /* opcode */ + u32 sg1u; /* upper SG1 address */ + u32 sg1l; /* lower SG1 address */ + u32 cnt; /* SG count, 3B used */ + u32 sg2u; /* upper SG2 address */ + u32 sg2l; /* lower SG2 address */ + u32 sg3u; /* upper SG3 address */ + u32 sg3l; /* lower SG3 address */ +}; + +/* + * DMAx hardware registers (p.515 in 440SPe UM 1.22) + */ +struct dma_regs { + u32 cpfpl; + u32 cpfph; + u32 csfpl; + u32 csfph; + u32 dsts; + u32 cfg; + u8 pad0[0x8]; + u16 cpfhp; + u16 cpftp; + u16 csfhp; + u16 csftp; + u8 pad1[0x8]; + u32 acpl; + u32 acph; + u32 s1bpl; + u32 s1bph; + u32 s2bpl; + u32 s2bph; + u32 s3bpl; + u32 s3bph; + u8 pad2[0x10]; + u32 earl; + u32 earh; + u8 pad3[0x8]; + u32 seat; + u32 sead; + u32 op; + u32 fsiz; +}; + +/* + * I2O hardware registers (p.528 in 440SPe UM 1.22) + */ +struct i2o_regs { + u32 ists; + u32 iseat; + u32 isead; + u8 pad0[0x14]; + u32 idbel; + u8 pad1[0xc]; + u32 ihis; + u32 ihim; + u8 pad2[0x8]; + u32 ihiq; + u32 ihoq; + u8 pad3[0x8]; + u32 iopis; + u32 iopim; + u32 iopiq; + u8 iopoq; + u8 pad4[3]; + u16 iiflh; + u16 iiflt; + u16 iiplh; + u16 iiplt; + u16 ioflh; + u16 ioflt; + u16 ioplh; + u16 ioplt; + u32 iidc; + u32 ictl; + u32 ifcpp; + u8 pad5[0x4]; + u16 mfac0; + u16 mfac1; + u16 mfac2; + u16 mfac3; + u16 mfac4; + u16 mfac5; + u16 mfac6; + u16 mfac7; + u16 ifcfh; + u16 ifcht; + u8 pad6[0x4]; + u32 iifmc; + u32 iodb; + u32 iodbc; + u32 ifbal; + u32 ifbah; + u32 ifsiz; + u32 ispd0; + u32 ispd1; + u32 ispd2; + u32 ispd3; + u32 ihipl; + u32 ihiph; + u32 ihopl; + u32 ihoph; + u32 iiipl; + u32 iiiph; + u32 iiopl; + u32 iioph; + u32 ifcpl; + u32 ifcph; + u8 pad7[0x8]; + u32 iopt; +}; + +#endif /* _PPC440SPE_DMA_H */ diff --git a/drivers/dma/ppc4xx/xor.h b/drivers/dma/ppc4xx/xor.h new file mode 100644 index 0000000..daed738 --- /dev/null +++ b/drivers/dma/ppc4xx/xor.h @@ -0,0 +1,110 @@ +/* + * 440SPe's XOR engines support header file + * + * 2006-2009 (C) DENX Software Engineering. + * + * Author: Yuri Tikhonov + * + * This file is licensed under the term of the GNU General Public License + * version 2. The program licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#ifndef _PPC440SPE_XOR_H +#define _PPC440SPE_XOR_H + +#include + +/* Number of XOR engines available on the contoller */ +#define XOR_ENGINES_NUM 1 + +/* Number of operands supported in the h/w */ +#define XOR_MAX_OPS 16 + +/* + * XOR Command Block Control Register bits + */ +#define XOR_CBCR_LNK_BIT (1<<31) /* link present */ +#define XOR_CBCR_TGT_BIT (1<<30) /* target present */ +#define XOR_CBCR_CBCE_BIT (1<<29) /* command block compete enable */ +#define XOR_CBCR_RNZE_BIT (1<<28) /* result not zero enable */ +#define XOR_CBCR_XNOR_BIT (1<<15) /* XOR/XNOR */ +#define XOR_CDCR_OAC_MSK (0x7F) /* operand address count */ + +/* + * XORCore Status Register bits + */ +#define XOR_SR_XCP_BIT (1<<31) /* core processing */ +#define XOR_SR_ICB_BIT (1<<17) /* invalid CB */ +#define XOR_SR_IC_BIT (1<<16) /* invalid command */ +#define XOR_SR_IPE_BIT (1<<15) /* internal parity error */ +#define XOR_SR_RNZ_BIT (1<<2) /* result not Zero */ +#define XOR_SR_CBC_BIT (1<<1) /* CB complete */ +#define XOR_SR_CBLC_BIT (1<<0) /* CB list complete */ + +/* + * XORCore Control Set and Reset Register bits + */ +#define XOR_CRSR_XASR_BIT (1<<31) /* soft reset */ +#define XOR_CRSR_XAE_BIT (1<<30) /* enable */ +#define XOR_CRSR_RCBE_BIT (1<<29) /* refetch CB enable */ +#define XOR_CRSR_PAUS_BIT (1<<28) /* pause */ +#define XOR_CRSR_64BA_BIT (1<<27) /* 64/32 CB format */ +#define XOR_CRSR_CLP_BIT (1<<25) /* continue list processing */ + +/* + * XORCore Interrupt Enable Register + */ +#define XOR_IE_ICBIE_BIT (1<<17) /* Invalid Command Block IRQ Enable */ +#define XOR_IE_ICIE_BIT (1<<16) /* Invalid Command IRQ Enable */ +#define XOR_IE_RPTIE_BIT (1<<14) /* Read PLB Timeout Error IRQ Enable */ +#define XOR_IE_CBCIE_BIT (1<<1) /* CB complete interrupt enable */ +#define XOR_IE_CBLCI_BIT (1<<0) /* CB list complete interrupt enable */ + +/* + * XOR Accelerator engine Command Block Type + */ +struct xor_cb { + /* + * Basic 64-bit format XOR CB (Table 19-1, p.463, 440spe_um_1_22.pdf) + */ + u32 cbc; /* control */ + u32 cbbc; /* byte count */ + u32 cbs; /* status */ + u8 pad0[4]; /* reserved */ + u32 cbtah; /* target address high */ + u32 cbtal; /* target address low */ + u32 cblah; /* link address high */ + u32 cblal; /* link address low */ + struct { + u32 h; + u32 l; + } __attribute__ ((packed)) ops[16]; +} __attribute__ ((packed)); + +/* + * XOR hardware registers Table 19-3, UM 1.22 + */ +struct xor_regs { + u32 op_ar[16][2]; /* operand address[0]-high,[1]-low registers */ + u8 pad0[352]; /* reserved */ + u32 cbcr; /* CB control register */ + u32 cbbcr; /* CB byte count register */ + u32 cbsr; /* CB status register */ + u8 pad1[4]; /* reserved */ + u32 cbtahr; /* operand target address high register */ + u32 cbtalr; /* operand target address low register */ + u32 cblahr; /* CB link address high register */ + u32 cblalr; /* CB link address low register */ + u32 crsr; /* control set register */ + u32 crrr; /* control reset register */ + u32 ccbahr; /* current CB address high register */ + u32 ccbalr; /* current CB address low register */ + u32 plbr; /* PLB configuration register */ + u32 ier; /* interrupt enable register */ + u32 pecr; /* parity error count register */ + u32 sr; /* status register */ + u32 revidr; /* revision ID register */ +}; + +#endif /* _PPC440SPE_XOR_H */ -- cgit v0.10.2 From 4a2ff67c88211026afcbdbc190c13f705dae1b59 Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Tue, 13 Oct 2009 22:22:46 +0200 Subject: kbuild: fix bzImage build for x86 As has been discussed previously (and Sam has been CC'ed), the fix is still incorrect. It replaces "echo -ne" with "/bin/echo -ne", but neither of the two are guaranteed to support the necessary arguments and necessary (hexadecimal) escape sequences. What should be used here is printf(1). The trivial patch below (on top of these kbuild changes) fixes this issue. Signed-Off-By: Michael Tokarev Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index ffdafb2..d9f0cb8 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -208,7 +208,7 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -f -9 > $@) || \ # Bzip2 and LZMA do not include size in file... so we have to fake that; # append the size as a 32-bit littleendian number as gzip does. -size_append = /bin/echo -ne $(shell \ +size_append = printf $(shell \ dec_size=0; \ for F in $1; do \ fsize=$$(stat -c "%s" $$F); \ -- cgit v0.10.2 From 24a675e8b86bef077e549a5ea2c6936989be4815 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 17 Oct 2009 21:14:18 +0200 Subject: kbuild: search arch/$ARCH/include before include/ The namespace used in arch/$ARCH/include is different from what is used in include/ except for the include/asm directory. This patch gives the arch/$ARCH/include/asm directory priority over include/asm. When we add asm-offsets.h to arch/$ARCH/include/asm/ this patch makes sure we pick up the arch specific version and not the one we have in include/asm. The situation with an asm-offsets.h file located in both include/asm _and_ arch/$ARCH/include/asm will happen when we move more files over to include/generated. This happens because in some cases it is not practical to rename all users so we simply add a file in arch/$ARCH/include/asm that includes the generated version. This is the solution we use for asm-offsets.h as an example. Signed-off-by: Sam Ravnborg Cc: Stephen Rothwell Signed-off-by: Michal Marek diff --git a/Makefile b/Makefile index 33d4732..0771178 100644 --- a/Makefile +++ b/Makefile @@ -334,9 +334,8 @@ CFLAGS_GCOV = -fprofile-arcs -ftest-coverage # Use LINUXINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option -LINUXINCLUDE := -Iinclude \ +LINUXINCLUDE := -I$(srctree)/arch/$(hdr-arch)/include -Iinclude \ $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \ - -I$(srctree)/arch/$(hdr-arch)/include \ -include include/linux/autoconf.h KBUILD_CPPFLAGS := -D__KERNEL__ -- cgit v0.10.2 From 9367858dd08caf4e6ebd511abd2fca0a2d87b648 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 17 Oct 2009 21:33:34 +0200 Subject: dontdiff: add generated We move more and more stuff to include/generated - so lets ignore the content for users of plain diff. Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/Documentation/dontdiff b/Documentation/dontdiff index e151b2a..3ad6ace 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff @@ -103,6 +103,7 @@ gconf gen-devlist gen_crc32table gen_init_cpio +generated genheaders genksyms *_gray256.c -- cgit v0.10.2 From 01fc0ac198eabcbf460e1ed058860a935b6c2c9a Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 19 Apr 2009 21:57:19 +0200 Subject: kbuild: move bounds.h to include/generated Signed-off-by: Sam Ravnborg Cc: Al Viro Signed-off-by: Michal Marek diff --git a/.gitignore b/.gitignore index 946c7ec..36d9cd6 100644 --- a/.gitignore +++ b/.gitignore @@ -52,7 +52,6 @@ include/linux/autoconf.h include/linux/compile.h include/linux/version.h include/linux/utsrelease.h -include/linux/bounds.h include/generated # stgit generated dirs diff --git a/Kbuild b/Kbuild index f056b4f..1165d7a 100644 --- a/Kbuild +++ b/Kbuild @@ -8,7 +8,7 @@ ##### # 1) Generate bounds.h -bounds-file := include/linux/bounds.h +bounds-file := include/generated/bounds.h always := $(bounds-file) targets := $(bounds-file) kernel/bounds.s diff --git a/Makefile b/Makefile index 0771178..b58e931 100644 --- a/Makefile +++ b/Makefile @@ -1197,7 +1197,7 @@ MRPROPER_DIRS += include/config include2 usr/include include/generated MRPROPER_FILES += .config .config.old include/asm .version .old_version \ include/linux/autoconf.h include/linux/version.h \ include/linux/utsrelease.h \ - include/linux/bounds.h include/asm*/asm-offsets.h \ + include/asm*/asm-offsets.h \ Module.symvers Module.markers tags TAGS cscope* # clean - Delete most, but leave enough to build external modules diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 6f75617..30fe668 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 6b202b1..ef36725 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -8,7 +8,7 @@ #include #ifndef __GENERATING_BOUNDS_H #include -#include +#include #endif /* !__GENERATING_BOUNDS_H */ /* diff --git a/kernel/bounds.c b/kernel/bounds.c index 3c53013..98a51f2 100644 --- a/kernel/bounds.c +++ b/kernel/bounds.c @@ -12,7 +12,7 @@ void foo(void) { - /* The enum constants to put into include/linux/bounds.h */ + /* The enum constants to put into include/generated/bounds.h */ DEFINE(NR_PAGEFLAGS, __NR_PAGEFLAGS); DEFINE(MAX_NR_ZONES, __MAX_NR_ZONES); /* End of constants */ -- cgit v0.10.2 From 559df2e0210352f83926d178c40c51142292a18c Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 19 Apr 2009 22:35:10 +0200 Subject: kbuild: move asm-offsets.h to include/generated The simplest method was to add an extra asm-offsets.h file in arch/$ARCH/include/asm that references the generated file. We can now migrate the architectures one-by-one to reference the generated file direct - and when done we can delete the temporary arch/$ARCH/include/asm/asm-offsets.h file. Signed-off-by: Sam Ravnborg Cc: Al Viro Signed-off-by: Michal Marek diff --git a/.gitignore b/.gitignore index 36d9cd6..3582f422 100644 --- a/.gitignore +++ b/.gitignore @@ -46,7 +46,6 @@ Module.symvers # Generated include files # include/asm -include/asm-*/asm-offsets.h include/config include/linux/autoconf.h include/linux/compile.h diff --git a/Kbuild b/Kbuild index 1165d7a..e3737ad 100644 --- a/Kbuild +++ b/Kbuild @@ -43,7 +43,7 @@ $(obj)/$(bounds-file): kernel/bounds.s Kbuild # 2) Generate asm-offsets.h # -offsets-file := include/asm/asm-offsets.h +offsets-file := include/generated/asm-offsets.h always += $(offsets-file) targets += $(offsets-file) diff --git a/Makefile b/Makefile index b58e931..eb43b9f 100644 --- a/Makefile +++ b/Makefile @@ -1197,7 +1197,6 @@ MRPROPER_DIRS += include/config include2 usr/include include/generated MRPROPER_FILES += .config .config.old include/asm .version .old_version \ include/linux/autoconf.h include/linux/version.h \ include/linux/utsrelease.h \ - include/asm*/asm-offsets.h \ Module.symvers Module.markers tags TAGS cscope* # clean - Delete most, but leave enough to build external modules diff --git a/arch/alpha/include/asm/asm-offsets.h b/arch/alpha/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/alpha/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/include/asm/asm-offsets.h b/arch/arm/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/arm/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/avr32/include/asm/asm-offsets.h b/arch/avr32/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/avr32/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/blackfin/include/asm/asm-offsets.h b/arch/blackfin/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/blackfin/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/cris/include/asm/asm-offsets.h b/arch/cris/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/cris/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/frv/include/asm/asm-offsets.h b/arch/frv/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/frv/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/h8300/include/asm/asm-offsets.h b/arch/h8300/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/h8300/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/ia64/include/asm/asm-offsets.h b/arch/ia64/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/ia64/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/m68k/include/asm/asm-offsets.h b/arch/m68k/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/m68k/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/microblaze/include/asm/asm-offsets.h b/arch/microblaze/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/microblaze/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/mips/include/asm/asm-offsets.h b/arch/mips/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/mips/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/mn10300/include/asm/asm-offsets.h b/arch/mn10300/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/mn10300/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/parisc/include/asm/asm-offsets.h b/arch/parisc/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/parisc/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/powerpc/include/asm/asm-offsets.h b/arch/powerpc/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/powerpc/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/s390/include/asm/asm-offsets.h b/arch/s390/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/s390/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/sh/include/asm/asm-offsets.h b/arch/sh/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/sh/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/sparc/include/asm/asm-offsets.h b/arch/sparc/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/sparc/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/um/Makefile b/arch/um/Makefile index fc633db..fab8121 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -149,6 +149,6 @@ $(SHARED_HEADERS)/user_constants.h: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s $(SHARED_HEADERS)/kern_constants.h: $(Q)mkdir -p $(dir $@) - $(Q)echo '#include "../../../../include/asm/asm-offsets.h"' >$@ + $(Q)echo '#include "../../../../include/generated/asm-offsets.h"' >$@ export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS HEADER_ARCH DEV_NULL_PATH diff --git a/arch/um/include/asm/asm-offsets.h b/arch/um/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/um/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/x86/include/asm/asm-offsets.h b/arch/x86/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/x86/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/xtensa/include/asm/asm-offsets.h b/arch/xtensa/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/xtensa/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include -- cgit v0.10.2 From 4929d29c0dffd5fdc2df987254366c2e25c392d4 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Mon, 20 Apr 2009 19:35:54 +0200 Subject: ia64: move nr-irqs.h to include/generated Avoid generating files in the now deprecated asm-ia64 dir Simplified the logic in the Makefile when editing stuff in the area Signed-off-by: Sam Ravnborg Cc: Al Viro Cc: Tony Luck Cc: Fenghua Yu Signed-off-by: Michal Marek diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index e7cbaa0..475e272 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -103,4 +103,4 @@ archprepare: make_nr_irqs_h FORCE PHONY += make_nr_irqs_h FORCE make_nr_irqs_h: FORCE - $(Q)$(MAKE) $(build)=arch/ia64/kernel include/asm-ia64/nr-irqs.h + $(Q)$(MAKE) $(build)=arch/ia64/kernel include/generated/nr-irqs.h diff --git a/arch/ia64/include/asm/irq.h b/arch/ia64/include/asm/irq.h index 5282546..91b920fd 100644 --- a/arch/ia64/include/asm/irq.h +++ b/arch/ia64/include/asm/irq.h @@ -13,7 +13,7 @@ #include #include -#include +#include static __inline__ int irq_canonicalize (int irq) diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 6b7edca..2a75e93 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -81,17 +81,14 @@ define cmd_nr_irqs endef # We use internal kbuild rules to avoid the "is up to date" message from make -arch/$(SRCARCH)/kernel/nr-irqs.s: $(srctree)/arch/$(SRCARCH)/kernel/nr-irqs.c \ - $(wildcard $(srctree)/include/asm-ia64/*/irq.h) +arch/$(SRCARCH)/kernel/nr-irqs.s: arch/$(SRCARCH)/kernel/nr-irqs.c $(Q)mkdir -p $(dir $@) $(call if_changed_dep,cc_s_c) -include/asm-ia64/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s +include/generated/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s $(Q)mkdir -p $(dir $@) $(call cmd,nr_irqs) -clean-files += $(objtree)/include/asm-ia64/nr-irqs.h - # # native ivt.S, entry.S and fsys.S # -- cgit v0.10.2 From 66206536fe56e889a8bd86ab5742fc76c78c5b4a Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Mon, 20 Apr 2009 19:59:58 +0200 Subject: arm: move mach-types to include/generated Simplified arch/arm/Makefile by dropping the maketools target It was undocumented and not needed Signed-off-by: Sam Ravnborg Cc: Al Viro Cc: Russell King Signed-off-by: Michal Marek diff --git a/arch/arm/Makefile b/arch/arm/Makefile index fa0cdab..e9da084 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -242,15 +242,8 @@ all: $(KBUILD_IMAGE) boot := arch/arm/boot -# Update machine arch and proc symlinks if something which affects -# them changed. We use .arch to indicate when they were updated -# last, otherwise make uses the target directory mtime. - -archprepare: maketools - -PHONY += maketools FORCE -maketools: include/linux/version.h FORCE - $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h +archprepare: + $(Q)$(MAKE) $(build)=arch/arm/tools include/generated/mach-types.h # Convert bzImage to zImage bzImage: zImage @@ -261,9 +254,6 @@ zImage Image xipImage bootpImage uImage: vmlinux zinstall install: vmlinux $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ -CLEAN_FILES += include/asm-arm/mach-types.h \ - include/asm-arm/arch include/asm-arm/.arch - # We use MRPROPER_FILES and CLEAN_FILES now archclean: $(Q)$(MAKE) $(clean)=$(boot) diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h new file mode 100644 index 0000000..948178c --- /dev/null +++ b/arch/arm/include/asm/mach-types.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile index 1dbaa29..635cb18 100644 --- a/arch/arm/tools/Makefile +++ b/arch/arm/tools/Makefile @@ -4,7 +4,7 @@ # Copyright (C) 2001 Russell King # -include/asm-arm/mach-types.h: $(src)/gen-mach-types $(src)/mach-types +include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types @echo ' Generating $@' @mkdir -p $(dir $@) $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } diff --git a/arch/arm/tools/gen-mach-types b/arch/arm/tools/gen-mach-types index ce319ef..04fef71 100644 --- a/arch/arm/tools/gen-mach-types +++ b/arch/arm/tools/gen-mach-types @@ -1,6 +1,6 @@ #!/bin/awk # -# Awk script to generate include/asm-arm/mach-types.h +# Awk script to generate include/generated/mach-types.h # BEGIN { nr = 0 } /^#/ { next } -- cgit v0.10.2 From 3252b11fc4790d046b93f300c898df2f7cd7c176 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 17 Oct 2009 22:20:22 +0200 Subject: sh: move machtypes.h to include/generated Signed-off-by: Sam Ravnborg Cc: Paul Mundt Cc: Al Viro Signed-off-by: Michal Marek diff --git a/arch/sh/Makefile b/arch/sh/Makefile index ac17c5a..db91925 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -205,10 +205,7 @@ libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec uImage.bin \ zImage vmlinux.srec romImage -PHONY += maketools $(BOOT_TARGETS) FORCE - -maketools: include/linux/version.h FORCE - $(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h +PHONY += $(BOOT_TARGETS) all: $(KBUILD_IMAGE) @@ -217,7 +214,8 @@ $(BOOT_TARGETS): vmlinux compressed: zImage -archprepare: maketools +archprepare: + $(Q)$(MAKE) $(build)=arch/sh/tools include/generated/machtypes.h archclean: $(Q)$(MAKE) $(clean)=$(boot) @@ -234,5 +232,3 @@ define archhelp @echo ' uImage.bz2 - Kernel-only image for U-Boot (bzip2)' @echo ' uImage.lzma - Kernel-only image for U-Boot (lzma)' endef - -CLEAN_FILES += include/asm-sh/machtypes.h diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c index 052b354..7898f14 100644 --- a/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c @@ -15,7 +15,7 @@ #include #include #include "pci-sh4.h" -#include +#include #define PCIMCR_MRSET_OFF 0xBFFFFFFF #define PCIMCR_RFSH_OFF 0xFFFFFFFB diff --git a/arch/sh/include/asm/.gitignore b/arch/sh/include/asm/.gitignore deleted file mode 100644 index 378db77..0000000 --- a/arch/sh/include/asm/.gitignore +++ /dev/null @@ -1 +0,0 @@ -machtypes.h diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h index 84dd377..9c30955 100644 --- a/arch/sh/include/asm/machvec.h +++ b/arch/sh/include/asm/machvec.h @@ -12,7 +12,7 @@ #include #include -#include +#include struct sh_machine_vector { void (*mv_setup)(char **cmdline_p); diff --git a/arch/sh/tools/Makefile b/arch/sh/tools/Makefile index 567516b..558a56b 100644 --- a/arch/sh/tools/Makefile +++ b/arch/sh/tools/Makefile @@ -10,7 +10,7 @@ # Shamelessly cloned from ARM. # -include/asm-sh/machtypes.h: $(src)/gen-mach-types $(src)/mach-types +include/generated/machtypes.h: $(src)/gen-mach-types $(src)/mach-types @echo ' Generating $@' - $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi + $(Q)mkdir -p $(dir $@) $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } diff --git a/arch/sh/tools/gen-mach-types b/arch/sh/tools/gen-mach-types index 65161e3..f5ff7c5 100644 --- a/arch/sh/tools/gen-mach-types +++ b/arch/sh/tools/gen-mach-types @@ -1,6 +1,6 @@ #!/bin/awk # -# Awk script to generate include/asm-sh/machtypes.h +# Awk script to generate include/generated/machtypes.h # Heavily based on arch/arm/tools/gen-mach-types # BEGIN { nr = 0 } -- cgit v0.10.2 From 96f13045b6cb0c562bf3ffd3844871811e677e63 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 17 Oct 2009 22:33:27 +0200 Subject: kbuild: drop include2/ used for O=... builds There is no longer any use of the include2/ directory. The generated files has moved to include/generated. Drop all references to said directory. Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/Makefile b/Makefile index eb43b9f..b9d747e 100644 --- a/Makefile +++ b/Makefile @@ -335,7 +335,7 @@ CFLAGS_GCOV = -fprofile-arcs -ftest-coverage # Use LINUXINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option LINUXINCLUDE := -I$(srctree)/arch/$(hdr-arch)/include -Iinclude \ - $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \ + $(if $(KBUILD_SRC), -I$(srctree)/include) \ -include include/linux/autoconf.h KBUILD_CPPFLAGS := -D__KERNEL__ @@ -954,7 +954,6 @@ PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3 # prepare3 is used to check if we are building in a separate output directory, # and if so do: # 1) Check that make has not been executed in the kernel src $(srctree) -# 2) Create the include2 directory, used for the second asm symlink prepare3: include/config/kernel.release ifneq ($(KBUILD_SRC),) @$(kecho) ' Using $(srctree) as source for kernel' @@ -963,10 +962,6 @@ ifneq ($(KBUILD_SRC),) echo " in the '$(srctree)' directory.";\ /bin/false; \ fi; - $(Q)if [ ! -d include2 ]; then \ - mkdir -p include2; \ - ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \ - fi endif # prepare2 creates a makefile if using a separate output directory @@ -1193,7 +1188,7 @@ CLEAN_FILES += vmlinux System.map \ .tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map # Directories & files removed with 'make mrproper' -MRPROPER_DIRS += include/config include2 usr/include include/generated +MRPROPER_DIRS += include/config usr/include include/generated MRPROPER_FILES += .config .config.old include/asm .version .old_version \ include/linux/autoconf.h include/linux/version.h \ include/linux/utsrelease.h \ diff --git a/arch/powerpc/platforms/cell/spufs/Makefile b/arch/powerpc/platforms/cell/spufs/Makefile index b93f877..b9d5d67 100644 --- a/arch/powerpc/platforms/cell/spufs/Makefile +++ b/arch/powerpc/platforms/cell/spufs/Makefile @@ -13,10 +13,8 @@ SPU_CC := $(SPU_CROSS)gcc SPU_AS := $(SPU_CROSS)gcc SPU_LD := $(SPU_CROSS)ld SPU_OBJCOPY := $(SPU_CROSS)objcopy -SPU_CFLAGS := -O2 -Wall -I$(srctree)/include \ - -I$(objtree)/include2 -D__KERNEL__ -SPU_AFLAGS := -c -D__ASSEMBLY__ -I$(srctree)/include \ - -I$(objtree)/include2 -D__KERNEL__ +SPU_CFLAGS := -O2 -Wall -I$(srctree)/include -D__KERNEL__ +SPU_AFLAGS := -c -D__ASSEMBLY__ -I$(srctree)/include -D__KERNEL__ SPU_LDFLAGS := -N -Ttext=0x0 $(obj)/switch.o: $(obj)/spu_save_dump.h $(obj)/spu_restore_dump.h -- cgit v0.10.2 From c95fa08a3e17c3f2983c4cbf409f5c9ae47b7dec Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 17 Oct 2009 22:47:31 +0200 Subject: kbuild: do not check for include/asm-$ARCH No architectures uses include/asm-$ARCH now. So drop check for location of include files Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/Makefile b/Makefile index b9d747e..924c62e 100644 --- a/Makefile +++ b/Makefile @@ -1070,11 +1070,6 @@ firmware_install: FORCE export INSTALL_HDR_PATH = $(objtree)/usr hdr-inst := -rR -f $(srctree)/scripts/Makefile.headersinst obj -# Find out where the Kbuild file is located to support -# arch/$(ARCH)/include/asm -hdr-dir = $(strip \ - $(if $(wildcard $(srctree)/arch/$(hdr-arch)/include/asm/Kbuild), \ - arch/$(hdr-arch)/include/asm, include/asm-$(hdr-arch))) # If we do an all arch process set dst to asm-$(hdr-arch) hdr-dst = $(if $(KBUILD_HEADERS), dst=include/asm-$(hdr-arch), dst=include/asm) @@ -1089,10 +1084,10 @@ headers_install_all: PHONY += headers_install headers_install: __headers - $(if $(wildcard $(srctree)/$(hdr-dir)/Kbuild),, \ + $(if $(wildcard $(srctree)/arch/$(hdr-arch)/include/asm/Kbuild),, \ $(error Headers not exportable for the $(SRCARCH) architecture)) $(Q)$(MAKE) $(hdr-inst)=include - $(Q)$(MAKE) $(hdr-inst)=$(hdr-dir) $(hdr-dst) + $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/asm $(hdr-dst) PHONY += headers_check_all headers_check_all: headers_install_all @@ -1101,7 +1096,7 @@ headers_check_all: headers_install_all PHONY += headers_check headers_check: headers_install $(Q)$(MAKE) $(hdr-inst)=include HDRCHECK=1 - $(Q)$(MAKE) $(hdr-inst)=$(hdr-dir) $(hdr-dst) HDRCHECK=1 + $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/asm $(hdr-dst) HDRCHECK=1 # --------------------------------------------------------------------------- # Modules diff --git a/scripts/headers.sh b/scripts/headers.sh index 0308ecc..1ddcdd3 100755 --- a/scripts/headers.sh +++ b/scripts/headers.sh @@ -8,8 +8,6 @@ do_command() { if [ -f ${srctree}/arch/$2/include/asm/Kbuild ]; then make ARCH=$2 KBUILD_HEADERS=$1 headers_$1 - elif [ -f ${srctree}/include/asm-$2/Kbuild ]; then - make ARCH=$2 KBUILD_HEADERS=$1 headers_$1 else printf "Ignoring arch: %s\n" ${arch} fi -- cgit v0.10.2 From f7f16b7799ed68654850ab340ef812895aebcf4c Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 18 Oct 2009 00:00:43 +0200 Subject: kbuild: drop include/asm We no longer use this directory for generated files and all architectures has moved their header files so no symlink tricks are needed either. Drop the symlink and drop the ARCH check. If we really need to check that the SRCARCH has not changed when we build a kernel we can add this check back - but then we will find a more convenient way to store the info. Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/.gitignore b/.gitignore index 3582f422..e074c1c 100644 --- a/.gitignore +++ b/.gitignore @@ -45,7 +45,6 @@ Module.symvers # # Generated include files # -include/asm include/config include/linux/autoconf.h include/linux/compile.h diff --git a/Makefile b/Makefile index 924c62e..86b66cf 100644 --- a/Makefile +++ b/Makefile @@ -968,7 +968,7 @@ endif prepare2: prepare3 outputmakefile prepare1: prepare2 include/linux/version.h include/linux/utsrelease.h \ - include/asm include/config/auto.conf + include/config/auto.conf $(cmd_crmodverdir) archprepare: prepare1 scripts_basic @@ -980,42 +980,6 @@ prepare0: archprepare FORCE # All the preparing.. prepare: prepare0 -# The asm symlink changes when $(ARCH) changes. -# Detect this and ask user to run make mrproper -# If asm is a stale symlink (point to dir that does not exist) remove it -define check-symlink - set -e; \ - if [ -L include/asm ]; then \ - asmlink=`readlink include/asm | cut -d '-' -f 2`; \ - if [ "$$asmlink" != "$(SRCARCH)" ]; then \ - echo "ERROR: the symlink $@ points to asm-$$asmlink but asm-$(SRCARCH) was expected"; \ - echo " set ARCH or save .config and run 'make mrproper' to fix it"; \ - exit 1; \ - fi; \ - test -e $$asmlink || rm include/asm; \ - elif [ -d include/asm ]; then \ - echo "ERROR: $@ is a directory but a symlink was expected";\ - exit 1; \ - fi -endef - -# We create the target directory of the symlink if it does -# not exist so the test in check-symlink works and we have a -# directory for generated filesas used by some architectures. -define create-symlink - if [ ! -L include/asm ]; then \ - $(kecho) ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \ - if [ ! -d include/asm-$(SRCARCH) ]; then \ - mkdir -p include/asm-$(SRCARCH); \ - fi; \ - ln -fsn asm-$(SRCARCH) $@; \ - fi -endef - -include/asm: FORCE - $(Q)$(check-symlink) - $(Q)$(create-symlink) - # Generate some files # --------------------------------------------------------------------------- @@ -1184,7 +1148,7 @@ CLEAN_FILES += vmlinux System.map \ # Directories & files removed with 'make mrproper' MRPROPER_DIRS += include/config usr/include include/generated -MRPROPER_FILES += .config .config.old include/asm .version .old_version \ +MRPROPER_FILES += .config .config.old .version .old_version \ include/linux/autoconf.h include/linux/version.h \ include/linux/utsrelease.h \ Module.symvers Module.markers tags TAGS cscope* -- cgit v0.10.2 From 92045954058671fdd0ccf031ca06611ce1d929d1 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 18 Oct 2009 00:36:47 +0200 Subject: kbuild: move compile.h to include/generated Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/.gitignore b/.gitignore index e074c1c..c06b4c9 100644 --- a/.gitignore +++ b/.gitignore @@ -47,7 +47,6 @@ Module.symvers # include/config include/linux/autoconf.h -include/linux/compile.h include/linux/version.h include/linux/utsrelease.h include/generated diff --git a/arch/x86/boot/version.c b/arch/x86/boot/version.c index 2723d9b..4d88763 100644 --- a/arch/x86/boot/version.c +++ b/arch/x86/boot/version.c @@ -14,7 +14,7 @@ #include "boot.h" #include -#include +#include const char kernel_version[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") " diff --git a/init/Makefile b/init/Makefile index 4a243df..0bf677a 100644 --- a/init/Makefile +++ b/init/Makefile @@ -15,12 +15,8 @@ mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o -# files to be removed upon make clean -clean-files := ../include/linux/compile.h - # dependencies on generated files need to be listed explicitly - -$(obj)/version.o: include/linux/compile.h +$(obj)/version.o: include/generated/compile.h # compile.h changes depending on hostname, generation number, etc, # so we regenerate it always. @@ -30,7 +26,7 @@ $(obj)/version.o: include/linux/compile.h chk_compile.h = : quiet_chk_compile.h = echo ' CHK $@' silent_chk_compile.h = : -include/linux/compile.h: FORCE +include/generated/compile.h: FORCE @$($(quiet)chk_compile.h) $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(KBUILD_CFLAGS)" diff --git a/init/version.c b/init/version.c index 52a8b98..82328aa 100644 --- a/init/version.c +++ b/init/version.c @@ -6,7 +6,7 @@ * May be freely distributed as part of Linux. */ -#include +#include #include #include #include -- cgit v0.10.2 From 98b8788ae91694499d1995035625bea16a4db0c4 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 18 Oct 2009 00:39:40 +0200 Subject: drop explicit include of autoconf.h kbuild.h forces include of autoconf.h on the commandline using -include - so we do not need to include the file explicit. Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/arch/cris/arch-v32/kernel/head.S b/arch/cris/arch-v32/kernel/head.S index 3db478e..76266f8 100644 --- a/arch/cris/arch-v32/kernel/head.S +++ b/arch/cris/arch-v32/kernel/head.S @@ -10,7 +10,6 @@ * The macros found in mmu_defs_asm.h uses the ## concatenation operator, so * -traditional must not be used when assembling this file. */ -#include #include #include #include diff --git a/arch/cris/kernel/asm-offsets.c b/arch/cris/kernel/asm-offsets.c index ddd6fbb..dd7b8e9 100644 --- a/arch/cris/kernel/asm-offsets.c +++ b/arch/cris/kernel/asm-offsets.c @@ -1,6 +1,5 @@ #include #include -#include /* * Generate definitions needed by assembly language modules. diff --git a/arch/cris/kernel/vmlinux.lds.S b/arch/cris/kernel/vmlinux.lds.S index bbfda67..d49d17d2 100644 --- a/arch/cris/kernel/vmlinux.lds.S +++ b/arch/cris/kernel/vmlinux.lds.S @@ -8,7 +8,6 @@ * the kernel has booted. */ -#include #include #include diff --git a/arch/ia64/kvm/asm-offsets.c b/arch/ia64/kvm/asm-offsets.c index 0c3564a..9324c87 100644 --- a/arch/ia64/kvm/asm-offsets.c +++ b/arch/ia64/kvm/asm-offsets.c @@ -22,7 +22,6 @@ * */ -#include #include #include diff --git a/drivers/accessibility/braille/braille_console.c b/drivers/accessibility/braille/braille_console.c index d672cfe..cb423f5 100644 --- a/drivers/accessibility/braille/braille_console.c +++ b/drivers/accessibility/braille/braille_console.c @@ -21,7 +21,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include #include diff --git a/drivers/hid/hid-lg.h b/drivers/hid/hid-lg.h index 27ae750..bf31592 100644 --- a/drivers/hid/hid-lg.h +++ b/drivers/hid/hid-lg.h @@ -1,8 +1,6 @@ #ifndef __HID_LG_H #define __HID_LG_H -#include - #ifdef CONFIG_LOGITECH_FF int lgff_init(struct hid_device *hdev); #else diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index 11003bb..1a387e7 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c @@ -51,7 +51,6 @@ #include #include #include -#include #define COMPAL_DRIVER_VERSION "0.2.6" diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h index f0b86f0..fd677f0 100644 --- a/drivers/staging/iio/ring_sw.h +++ b/drivers/staging/iio/ring_sw.h @@ -29,7 +29,6 @@ * driver requests - some may support multiple options */ -#include #include "iio.h" #include "ring_generic.h" diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h index 8a55098..ee24ef8 100644 --- a/include/linux/mmdebug.h +++ b/include/linux/mmdebug.h @@ -1,8 +1,6 @@ #ifndef LINUX_MM_DEBUG_H #define LINUX_MM_DEBUG_H 1 -#include - #ifdef CONFIG_DEBUG_VM #define VM_BUG_ON(cond) BUG_ON(cond) #else -- cgit v0.10.2 From 264a26838056fc2d759f58bec2e720e01fcb1bdb Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 18 Oct 2009 00:49:24 +0200 Subject: kbuild: move autoconf.h to include/generated Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/.gitignore b/.gitignore index c06b4c9..c6c19ea 100644 --- a/.gitignore +++ b/.gitignore @@ -46,7 +46,6 @@ Module.symvers # Generated include files # include/config -include/linux/autoconf.h include/linux/version.h include/linux/utsrelease.h include/generated diff --git a/Documentation/kbuild/kconfig.txt b/Documentation/kbuild/kconfig.txt index 849b5e5..ab8dc35 100644 --- a/Documentation/kbuild/kconfig.txt +++ b/Documentation/kbuild/kconfig.txt @@ -106,7 +106,8 @@ This environment variable can be set to specify the path & name of the KCONFIG_AUTOHEADER -------------------------------------------------- This environment variable can be set to specify the path & name of the -"autoconf.h" (header) file. Its default value is "include/linux/autoconf.h". +"autoconf.h" (header) file. +Its default value is "include/generated/autoconf.h". ====================================================================== diff --git a/Makefile b/Makefile index 86b66cf..3bdd932 100644 --- a/Makefile +++ b/Makefile @@ -336,7 +336,7 @@ CFLAGS_GCOV = -fprofile-arcs -ftest-coverage # Needed to be compatible with the O= option LINUXINCLUDE := -I$(srctree)/arch/$(hdr-arch)/include -Iinclude \ $(if $(KBUILD_SRC), -I$(srctree)/include) \ - -include include/linux/autoconf.h + -include include/generated/autoconf.h KBUILD_CPPFLAGS := -D__KERNEL__ @@ -492,17 +492,18 @@ $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; # if auto.conf.cmd is missing then we are probably in a cleaned tree so # we execute the config step to be sure to catch updated Kconfig files include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd + $(Q)mkdir -p include/generated $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig else -# external modules needs include/linux/autoconf.h and include/config/auto.conf +# external modules needs include/generated/autoconf.h and include/config/auto.conf # but do not care if they are up-to-date. Use auto.conf to trigger the test PHONY += include/config/auto.conf include/config/auto.conf: - $(Q)test -e include/linux/autoconf.h -a -e $@ || ( \ + $(Q)test -e include/generated/autoconf.h -a -e $@ || ( \ echo; \ echo " ERROR: Kernel configuration is invalid."; \ - echo " include/linux/autoconf.h or $@ are missing."; \ + echo " include/generated/autoconf.h or $@ are missing.";\ echo " Run 'make oldconfig && make prepare' on kernel src to fix it."; \ echo; \ /bin/false) @@ -1149,7 +1150,7 @@ CLEAN_FILES += vmlinux System.map \ # Directories & files removed with 'make mrproper' MRPROPER_DIRS += include/config usr/include include/generated MRPROPER_FILES += .config .config.old .version .old_version \ - include/linux/autoconf.h include/linux/version.h \ + include/linux/version.h \ include/linux/utsrelease.h \ Module.symvers Module.markers tags TAGS cscope* diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S index 86edb5f..ef54128 100644 --- a/arch/m68k/kernel/head.S +++ b/arch/m68k/kernel/head.S @@ -196,7 +196,7 @@ * for them and trying to understand what they mean. * * CONFIG_xxx: These are the obvious machine configuration defines created - * during configuration. These are defined in include/linux/autoconf.h. + * during configuration. These are defined in autoconf.h. * * CONSOLE: There is support for head.S console in this file. This * console can talk to a Mac frame buffer, but could easily be extrapolated diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 6bf21f8..ea26b23 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -16,15 +16,15 @@ * tells make when to remake a file. * * To use this list as-is however has the drawback that virtually - * every file in the kernel includes . + * every file in the kernel includes autoconf.h. * - * If the user re-runs make *config, linux/autoconf.h will be + * If the user re-runs make *config, autoconf.h will be * regenerated. make notices that and will rebuild every file which * includes autoconf.h, i.e. basically all files. This is extremely * annoying if the user just changed CONFIG_HIS_DRIVER from n to m. * * So we play the same trick that "mkdep" played before. We replace - * the dependency on linux/autoconf.h by a dependency on every config + * the dependency on autoconf.h by a dependency on every config * option which is mentioned in any of the listed prequisites. * * kconfig populates a tree in include/config/ with an empty file @@ -73,7 +73,7 @@ * cmd_ = * * and then basically copies the ..d file to stdout, in the - * process filtering out the dependency on linux/autoconf.h and adding + * process filtering out the dependency on autoconf.h and adding * dependencies on include/config/my/option.h for every * CONFIG_MY_OPTION encountered in any of the prequisites. * @@ -324,7 +324,7 @@ static void parse_dep_file(void *map, size_t len) p++; } memcpy(s, m, p-m); s[p-m] = 0; - if (strrcmp(s, "include/linux/autoconf.h") && + if (strrcmp(s, "include/generated/autoconf.h") && strrcmp(s, "arch/um/include/uml-config.h") && strrcmp(s, ".ver")) { printf(" %s \\\n", s); diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index b55e72f..797a741 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -776,7 +776,7 @@ int conf_write_autoconf(void) name = getenv("KCONFIG_AUTOHEADER"); if (!name) - name = "include/linux/autoconf.h"; + name = "include/generated/autoconf.h"; if (rename(".tmpconfig.h", name)) return 1; name = conf_get_autoconfig_name(); diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index bce3d0f..23dbad8 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -14,7 +14,7 @@ vecho() { [ "${quiet}" = "silent_" ] || echo "$@" ; } # So "sudo make install" won't change the "compiled by " # do "compiled by root" -if [ -r $TARGET -a ! -O include/linux/autoconf.h ]; then +if [ -r $TARGET -a ! -O include/generated/autoconf.h ]; then vecho " SKIPPED $TARGET" exit 0 fi -- cgit v0.10.2 From 273b281fa22c293963ee3e6eec418f5dda2dbc83 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 18 Oct 2009 00:52:28 +0200 Subject: kbuild: move utsrelease.h to include/generated Fix up all users of utsrelease.h Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/.gitignore b/.gitignore index c6c19ea..002d530 100644 --- a/.gitignore +++ b/.gitignore @@ -47,7 +47,6 @@ Module.symvers # include/config include/linux/version.h -include/linux/utsrelease.h include/generated # stgit generated dirs diff --git a/Makefile b/Makefile index 3bdd932..860224d 100644 --- a/Makefile +++ b/Makefile @@ -968,7 +968,7 @@ endif # prepare2 creates a makefile if using a separate output directory prepare2: prepare3 outputmakefile -prepare1: prepare2 include/linux/version.h include/linux/utsrelease.h \ +prepare1: prepare2 include/linux/version.h include/generated/utsrelease.h \ include/config/auto.conf $(cmd_crmodverdir) @@ -1005,7 +1005,7 @@ endef include/linux/version.h: $(srctree)/Makefile FORCE $(call filechk,version.h) -include/linux/utsrelease.h: include/config/kernel.release FORCE +include/generated/utsrelease.h: include/config/kernel.release FORCE $(call filechk,utsrelease.h) PHONY += headerdep @@ -1151,7 +1151,6 @@ CLEAN_FILES += vmlinux System.map \ MRPROPER_DIRS += include/config usr/include include/generated MRPROPER_FILES += .config .config.old .version .old_version \ include/linux/version.h \ - include/linux/utsrelease.h \ Module.symvers Module.markers tags TAGS cscope* # clean - Delete most, but leave enough to build external modules diff --git a/arch/alpha/boot/bootp.c b/arch/alpha/boot/bootp.c index 3af21c7..3c8d1b2 100644 --- a/arch/alpha/boot/bootp.c +++ b/arch/alpha/boot/bootp.c @@ -9,7 +9,7 @@ */ #include #include -#include +#include #include #include diff --git a/arch/alpha/boot/bootpz.c b/arch/alpha/boot/bootpz.c index 1036b51..ade3f12 100644 --- a/arch/alpha/boot/bootpz.c +++ b/arch/alpha/boot/bootpz.c @@ -11,7 +11,7 @@ */ #include #include -#include +#include #include #include diff --git a/arch/alpha/boot/main.c b/arch/alpha/boot/main.c index 89f3be0..644b7db5 100644 --- a/arch/alpha/boot/main.c +++ b/arch/alpha/boot/main.c @@ -7,7 +7,7 @@ */ #include #include -#include +#include #include #include diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c index 55e4fab..75cf7f4 100644 --- a/arch/frv/kernel/setup.c +++ b/arch/frv/kernel/setup.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. */ -#include +#include #include #include #include diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c index bcc69e1..45c0cb9 100644 --- a/arch/powerpc/platforms/52xx/efika.c +++ b/arch/powerpc/platforms/52xx/efika.c @@ -10,7 +10,7 @@ */ #include -#include +#include #include #include #include diff --git a/arch/powerpc/platforms/amigaone/setup.c b/arch/powerpc/platforms/amigaone/setup.c index 9290a7a..fb4eb0d 100644 --- a/arch/powerpc/platforms/amigaone/setup.c +++ b/arch/powerpc/platforms/amigaone/setup.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index cd4ad9a..0a6f5ab 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c index cf66091..9dd789a 100644 --- a/arch/powerpc/platforms/powermac/bootx_init.c +++ b/arch/powerpc/platforms/powermac/bootx_init.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index b31cc54..93e689f4 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -16,7 +16,7 @@ */ #include -#include +#include #include #include #include diff --git a/arch/x86/boot/version.c b/arch/x86/boot/version.c index 4d88763..2b15aa4 100644 --- a/arch/x86/boot/version.c +++ b/arch/x86/boot/version.c @@ -13,7 +13,7 @@ */ #include "boot.h" -#include +#include #include const char kernel_version[] = diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index 4ce399b..f98a524 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include #include diff --git a/include/linux/vermagic.h b/include/linux/vermagic.h index 79b9837..cf97b5b 100644 --- a/include/linux/vermagic.h +++ b/include/linux/vermagic.h @@ -1,4 +1,4 @@ -#include +#include #include /* Simply sanity version stamp for modules. */ diff --git a/init/version.c b/init/version.c index 82328aa..adff586 100644 --- a/init/version.c +++ b/init/version.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #ifndef CONFIG_KALLSYMS diff --git a/kernel/kexec.c b/kernel/kexec.c index f336e21..83f54e2 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 88bd9ae..bfb1b64 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -12,7 +12,7 @@ * Copyright (C) 2004 William Lee Irwin III */ #include -#include +#include #include #include #include -- cgit v0.10.2 From 7a77080dbec28ab2bceb422398601dcc53c142ad Mon Sep 17 00:00:00 2001 From: Jie Zhang Date: Thu, 12 Nov 2009 17:59:56 +0800 Subject: net: add net_tstamp.h to headers_install include/linux/net_tstamp.h is userspace API for hardware time stamping of network packets. It should be exported to userspace. Signed-off-by: Jie Zhang Signed-off-by: Barry Song Signed-off-by: Patrick Ohly Signed-off-by: Michal Marek diff --git a/include/linux/Kbuild b/include/linux/Kbuild index f72914d..756f831 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -118,6 +118,7 @@ header-y += mtio.h header-y += ncp_no.h header-y += neighbour.h header-y += net_dropmon.h +header-y += net_tstamp.h header-y += netfilter_arp.h header-y += netrom.h header-y += nfs2.h -- cgit v0.10.2 From 8723eaeff59a5146326288392f08be4c894fdad7 Mon Sep 17 00:00:00 2001 From: Wenji Huang Date: Thu, 19 Nov 2009 08:44:32 +0800 Subject: Kbuild: clean up marker Drop Module.markers from cleaning list since marker is removed. Signed-off-by: Wenji Huang Signed-off-by: Michal Marek diff --git a/Makefile b/Makefile index 860224d..96b32e5 100644 --- a/Makefile +++ b/Makefile @@ -1151,7 +1151,7 @@ CLEAN_FILES += vmlinux System.map \ MRPROPER_DIRS += include/config usr/include include/generated MRPROPER_FILES += .config .config.old .version .old_version \ include/linux/version.h \ - Module.symvers Module.markers tags TAGS cscope* + Module.symvers tags TAGS cscope* # clean - Delete most, but leave enough to build external modules # @@ -1170,7 +1170,7 @@ clean: archclean $(clean-dirs) \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '*.symtypes' -o -name 'modules.order' \ - -o -name 'Module.markers' -o -name '.tmp_*.o.*' \ + -o -name '.tmp_*.o.*' \ -o -name '*.gcno' \) -type f -print | xargs rm -f # mrproper - Delete all generated files, including .config @@ -1368,7 +1368,6 @@ $(clean-dirs): clean: rm-dirs := $(MODVERDIR) clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers \ - $(KBUILD_EXTMOD)/Module.markers \ $(KBUILD_EXTMOD)/modules.order clean: $(clean-dirs) $(call cmd,rmdirs) -- cgit v0.10.2 From 91d161857ce9672bd2a8cd99ff712a67186e2e76 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 24 Nov 2009 09:11:37 -0600 Subject: scripts/package: tar-pkg: use tar --owner=root Use the --owner= and --group= options to make sure the entries in the built tar file are owned by root. Without this change, a careless sysadmin using the tar-pkg target can easily end up installing a kernel that is writable by the unprivileged user account used to build the kernel. Test that these options are understood before using them so that non-GNU versions of tar can still be used if the operator is appropriately cautious. Signed-off-by: Jonathan Nieder Signed-off-by: Michal Marek diff --git a/scripts/package/buildtar b/scripts/package/buildtar index b1fd48d..51b2aa0 100644 --- a/scripts/package/buildtar +++ b/scripts/package/buildtar @@ -101,7 +101,11 @@ esac # ( cd "${tmpdir}" - tar cf - . | ${compress} > "${tarball}${file_ext}" + opts= + if tar --owner=root --group=root --help >/dev/null 2>&1; then + opts="--owner=root --group=root" + fi + tar cf - . $opts | ${compress} > "${tarball}${file_ext}" ) echo "Tarball successfully created in ${tarball}${file_ext}" -- cgit v0.10.2 From 05ba4488a51edde95df3f89987fdcdbca7c3cebb Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Tue, 24 Nov 2009 09:14:41 -0600 Subject: scripts/package: add KBUILD_PKG_ROOTCMD variable Let the deb-pkg target acquire (fake) root privileges before running commands that need them. Without such privileges, deb-pkg errors out because chown fails. The new KBUILD_PKG_ROOTCMD variable, if defined, is used as a command to run other commands with possibly fake elevated privileges. Since this is not needed for the tar-pkg and rpm-pkg targets, it is only used by deb-pkg. If it is not defined, the behavior is as before, and the user will have to rerun make as root. In other words, as a shortcut, instead of running 'make oldconfig && make && fakeroot -u make deb-pkg', one can use the single command 'make oldconfig deb-pkg KBUILD_PKG_ROOTCMD="fakeroot -u"'. Suggested-by: Ryan Anderson Signed-off-by: Jonathan Nieder Signed-off-by: Michal Marek diff --git a/scripts/package/Makefile b/scripts/package/Makefile index f67cc88..5c0b43a 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -79,7 +79,8 @@ clean-files += $(objtree)/binkernel.spec # --------------------------------------------------------------------------- deb-pkg: FORCE $(MAKE) KBUILD_SRC= - $(CONFIG_SHELL) $(srctree)/scripts/package/builddeb + $(KBUILD_PKG_ROOTCMD) $(CONFIG_SHELL) \ + $(srctree)/scripts/package/builddeb clean-dirs += $(objtree)/debian/ -- cgit v0.10.2 From db1d18657c96cc675596077cb60ef50fbe1947f8 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Tue, 24 Nov 2009 09:21:56 -0600 Subject: scripts/package: deb-pkg: use fakeroot if available Running "make deb-pkg" requires setting KBUILD_PKG_ROOTCMD or becoming root oneself or it errors out. Unless already running as root or KBUILD_PKG_ROOTCMD is already set, use fakeroot as a good default. With this patch applied, you can run "make oldconfig deb-pkg" as an ordinary user to build a binary package for an updated kernel tree and it should just work. fakeroot is too zealous by default in treating files as owned by root. Its wrapped stat() sets st_uid and st_gid to 0 for all files, which causes Git to go on a wild goose chase if CONFIG_LOCALVERSION_AUTO is set, checking if any file's content has changed along with its stat information. Avoid this by telling fakeroot to use the actual owner and group for preexisting files, by passing it the -u option. Signed-off-by: Jonathan Nieder Signed-off-by: Michal Marek diff --git a/scripts/package/Makefile b/scripts/package/Makefile index 5c0b43a..62fcc3a 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -77,10 +77,27 @@ clean-files += $(objtree)/binkernel.spec # Deb target # --------------------------------------------------------------------------- +quiet_cmd_builddeb = BUILDDEB + cmd_builddeb = set -e; \ + test `id -u` = 0 || \ + test -n "$(KBUILD_PKG_ROOTCMD)" || { \ + which fakeroot >/dev/null 2>&1 && \ + KBUILD_PKG_ROOTCMD="fakeroot -u"; \ + } || { \ + echo; \ + echo "builddeb must be run as root (or using fakeroot)."; \ + echo "KBUILD_PKG_ROOTCMD is unset and fakeroot not found."; \ + echo "Try setting KBUILD_PKG_ROOTCMD to a command to acquire"; \ + echo "root privileges (e.g., 'fakeroot -u' or 'sudo')."; \ + false; \ + } && \ + \ + $$KBUILD_PKG_ROOTCMD $(CONFIG_SHELL) \ + $(srctree)/scripts/package/builddeb + deb-pkg: FORCE $(MAKE) KBUILD_SRC= - $(KBUILD_PKG_ROOTCMD) $(CONFIG_SHELL) \ - $(srctree)/scripts/package/builddeb + $(call cmd,builddeb) clean-dirs += $(objtree)/debian/ -- cgit v0.10.2 From 32197c7ffb06b1319850f8fdfa1a49d32a63b79b Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Wed, 25 Nov 2009 15:14:49 +0100 Subject: kbuild: create include/generated in silentoldconfig The toplevel Makefile creates the directory if it runs silentoldconfig automatically, but if run manually, it fails: $ make mrproper $ make defconfig && make silentoldconfig *** Default configuration is based on 'x86_64_defconfig' # # configuration written to .config # scripts/kconfig/conf -s arch/x86/Kconfig *** Error during update of the kernel configuration. ... Move the mkdir command to the silentoldconfig target to make it work. Signed-off-by: Michal Marek diff --git a/Makefile b/Makefile index 96b32e5..aa608c2 100644 --- a/Makefile +++ b/Makefile @@ -492,7 +492,6 @@ $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; # if auto.conf.cmd is missing then we are probably in a cleaned tree so # we execute the config step to be sure to catch updated Kconfig files include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd - $(Q)mkdir -p include/generated $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig else # external modules needs include/generated/autoconf.h and include/config/auto.conf diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 80599e3..999e8a7 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -27,6 +27,7 @@ oldconfig: $(obj)/conf $< -o $(Kconfig) silentoldconfig: $(obj)/conf + $(Q)mkdir -p include/generated $< -s $(Kconfig) localmodconfig: $(obj)/streamline_config.pl $(obj)/conf -- cgit v0.10.2 From eb8f844c0a41c4529a7d06b7801296eca9ae67aa Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 26 Nov 2009 13:34:12 +0100 Subject: kbuild: specify absolute paths for cscope Cscope doesn't hadle relative paths when cscope.out is not in $PWD. Use absolute paths when generating cscope.files, which seems to be the recommended way to generate cscope.out, anyway (at least according to cscope.sf.net). The speed and size differences are minimal, the only drawback is that the database needs to be regenerated if the source directory is moved. [mmarek: fixed for O= builds, modified changelog] Signed-off-by: Daniel Vetter Signed-off-by: Michal Marek diff --git a/scripts/tags.sh b/scripts/tags.sh index d52f7a0..1a0c44d 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -89,7 +89,13 @@ all_defconfigs() docscope() { - (echo \-k; echo \-q; all_sources) > cscope.files + # always use absolute paths for cscope, as recommended by cscope + # upstream + case "$tree" in + /*) ;; + *) tree=$PWD/$tree ;; + esac + (cd /; echo \-k; echo \-q; all_sources) > cscope.files cscope -b -f cscope.out } -- cgit v0.10.2 From d8379ab1dde371f13d7fdddf05346840a82c2b61 Mon Sep 17 00:00:00 2001 From: Tony Finch Date: Fri, 27 Nov 2009 15:50:30 +0000 Subject: unifdef: update to upstream revision 1.190 Fix handling of input files (e.g. with no newline at EOF) that could make unifdef get into an unexpected state and call abort(). The new -B option compresses blank lines around a deleted section so that blank lines around "paragraphs" of code don't get doubled. The evaluator can now handle macros with arguments, and unbracketed arguments to the "defined" operator. Add myself to MAINTAINERS for unifdef. Signed-off-by: Tony Finch Acked-by: Sam Ravnborg Signed-off-by: Michal Marek diff --git a/MAINTAINERS b/MAINTAINERS index d58fa70..94381ed 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5407,6 +5407,12 @@ F: drivers/uwb/* F: include/linux/uwb.h F: include/linux/uwb/ +UNIFDEF +M: Tony Finch +W: http://dotat.at/prog/unifdef +S: Maintained +F: scripts/unifdef.c + UNIFORM CDROM DRIVER M: Jens Axboe W: http://www.kernel.dk diff --git a/scripts/unifdef.c b/scripts/unifdef.c index 30d459f..44d3978 100644 --- a/scripts/unifdef.c +++ b/scripts/unifdef.c @@ -1,13 +1,5 @@ /* - * Copyright (c) 2002 - 2005 Tony Finch . All rights reserved. - * - * This code is derived from software contributed to Berkeley by Dave Yost. - * It was rewritten to support ANSI C by Tony Finch. The original version of - * unifdef carried the following copyright notice. None of its code remains - * in this version (though some of the names remain). - * - * Copyright (c) 1985, 1993 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 2002 - 2009 Tony Finch * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,23 +23,20 @@ * SUCH DAMAGE. */ -#include +/* + * This code was derived from software contributed to Berkeley by Dave Yost. + * It was rewritten to support ANSI C by Tony Finch. The original version + * of unifdef carried the 4-clause BSD copyright licence. None of its code + * remains in this version (though some of the names remain) so it now + * carries a more liberal licence. + * + * The latest version is available from http://dotat.at/prog/unifdef + */ -#ifndef lint -#if 0 -static const char copyright[] = -"@(#) Copyright (c) 1985, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif -#ifdef __IDSTRING -__IDSTRING(Berkeley, "@(#)unifdef.c 8.1 (Berkeley) 6/6/93"); -__IDSTRING(NetBSD, "$NetBSD: unifdef.c,v 1.8 2000/07/03 02:51:36 matt Exp $"); -__IDSTRING(dotat, "$dotat: things/unifdef.c,v 1.171 2005/03/08 12:38:48 fanf2 Exp $"); -#endif -#endif /* not lint */ -#ifdef __FBSDID -__FBSDID("$FreeBSD: /repoman/r/ncvs/src/usr.bin/unifdef/unifdef.c,v 1.20 2005/05/21 09:55:09 ru Exp $"); -#endif +static const char * const copyright[] = { + "@(#) Copyright (c) 2002 - 2009 Tony Finch \n", + "$dotat: unifdef/unifdef.c,v 1.190 2009/11/27 17:21:26 fanf2 Exp $", +}; /* * unifdef - remove ifdef'ed lines @@ -72,8 +61,6 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/usr.bin/unifdef/unifdef.c,v 1.20 2005/05 #include #include -size_t strlcpy(char *dst, const char *src, size_t siz); - /* types of input lines: */ typedef enum { LT_TRUEI, /* a true #if with ignore flag */ @@ -90,6 +77,7 @@ typedef enum { LT_DODGY_LAST = LT_DODGY + LT_ENDIF, LT_PLAIN, /* ordinary line */ LT_EOF, /* end of file */ + LT_ERROR, /* unevaluable #if */ LT_COUNT } Linetype; @@ -100,7 +88,7 @@ static char const * const linetype_name[] = { "DODGY IF", "DODGY TRUE", "DODGY FALSE", "DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE", "DODGY ELSE", "DODGY ENDIF", - "PLAIN", "EOF" + "PLAIN", "EOF", "ERROR" }; /* state of #if processing */ @@ -168,11 +156,13 @@ static char const * const linestate_name[] = { * Globals. */ +static bool compblank; /* -B: compress blank lines */ +static bool lnblank; /* -b: blank deleted lines */ static bool complement; /* -c: do the complement */ static bool debugging; /* -d: debugging reports */ static bool iocccok; /* -e: fewer IOCCC errors */ +static bool strictlogic; /* -K: keep ambiguous #ifs */ static bool killconsts; /* -k: eval constant #ifs */ -static bool lnblank; /* -l: blank deleted lines */ static bool lnnum; /* -n: add #line directives */ static bool symlist; /* -s: output symbol list */ static bool text; /* -t: this is a text file */ @@ -196,7 +186,9 @@ static bool ignoring[MAXDEPTH]; /* ignore comments state */ static int stifline[MAXDEPTH]; /* start of current #if */ static int depth; /* current #if nesting */ static int delcount; /* count of deleted lines */ -static bool keepthis; /* don't delete constant #if */ +static unsigned blankcount; /* count of blank lines */ +static unsigned blankmax; /* maximum recent blankcount */ +static bool constexpr; /* constant #if expression */ static int exitstat; /* program exit status */ @@ -206,13 +198,14 @@ static void done(void); static void error(const char *); static int findsym(const char *); static void flushline(bool); -static Linetype get_line(void); +static Linetype parseline(void); static Linetype ifeval(const char **); static void ignoreoff(void); static void ignoreon(void); static void keywordedit(const char *); static void nest(void); static void process(void); +static const char *skipargs(const char *); static const char *skipcomment(const char *); static const char *skipsym(const char *); static void state(Ifstate); @@ -220,7 +213,7 @@ static int strlcmp(const char *, const char *, size_t); static void unnest(void); static void usage(void); -#define endsym(c) (!isalpha((unsigned char)c) && !isdigit((unsigned char)c) && c != '_') +#define endsym(c) (!isalnum((unsigned char)c) && c != '_') /* * The main program. @@ -230,7 +223,7 @@ main(int argc, char *argv[]) { int opt; - while ((opt = getopt(argc, argv, "i:D:U:I:cdeklnst")) != -1) + while ((opt = getopt(argc, argv, "i:D:U:I:BbcdeKklnst")) != -1) switch (opt) { case 'i': /* treat stuff controlled by these symbols as text */ /* @@ -255,6 +248,13 @@ main(int argc, char *argv[]) case 'I': /* no-op for compatibility with cpp */ break; + case 'B': /* compress blank lines around removed section */ + compblank = true; + break; + case 'b': /* blank deleted lines instead of omitting them */ + case 'l': /* backwards compatibility */ + lnblank = true; + break; case 'c': /* treat -D as -U and vice versa */ complement = true; break; @@ -264,12 +264,12 @@ main(int argc, char *argv[]) case 'e': /* fewer errors from dodgy lines */ iocccok = true; break; + case 'K': /* keep ambiguous #ifs */ + strictlogic = true; + break; case 'k': /* process constant #ifs */ killconsts = true; break; - case 'l': /* blank deleted lines instead of omitting them */ - lnblank = true; - break; case 'n': /* add #line directive after deleted lines */ lnnum = true; break; @@ -284,6 +284,8 @@ main(int argc, char *argv[]) } argc -= optind; argv += optind; + if (compblank && lnblank) + errx(2, "-B and -b are mutually exclusive"); if (argc > 1) { errx(2, "can only do one file"); } else if (argc == 1 && strcmp(*argv, "-") != 0) { @@ -302,7 +304,7 @@ main(int argc, char *argv[]) static void usage(void) { - fprintf(stderr, "usage: unifdef [-cdeklnst] [-Ipath]" + fprintf(stderr, "usage: unifdef [-BbcdeKknst] [-Ipath]" " [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n"); exit(2); } @@ -383,46 +385,46 @@ static state_fn * const trans_table[IS_COUNT][LT_COUNT] = { /* IS_OUTSIDE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Eendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eendif, - print, done }, + print, done, abort }, /* IS_FALSE_PREFIX */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Strue, Sfalse,Selse, Dendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Eioccc,Eioccc,Eioccc,Eioccc, - drop, Eeof }, + drop, Eeof, abort }, /* IS_TRUE_PREFIX */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Dfalse,Dfalse,Dfalse,Delse, Dendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc, - print, Eeof }, + print, Eeof, abort }, /* IS_PASS_MIDDLE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Pelif, Mtrue, Delif, Pelse, Pendif, Oiffy, Oiffy, Fpass, Oif, Oif, Pelif, Oelif, Oelif, Pelse, Pendif, - print, Eeof }, + print, Eeof, abort }, /* IS_FALSE_MIDDLE */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Pelif, Mtrue, Delif, Pelse, Pendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc, - drop, Eeof }, + drop, Eeof, abort }, /* IS_TRUE_MIDDLE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Melif, Melif, Melif, Melse, Pendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Pendif, - print, Eeof }, + print, Eeof, abort }, /* IS_PASS_ELSE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Pendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Pendif, - print, Eeof }, + print, Eeof, abort }, /* IS_FALSE_ELSE */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Dendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Eioccc, - drop, Eeof }, + drop, Eeof, abort }, /* IS_TRUE_ELSE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Dendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eioccc, - print, Eeof }, + print, Eeof, abort }, /* IS_FALSE_TRAILER */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Dendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Eioccc, - drop, Eeof } + drop, Eeof, abort } /*TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF (DODGY) - PLAIN EOF */ + PLAIN EOF ERROR */ }; /* @@ -463,9 +465,11 @@ keywordedit(const char *replacement) static void nest(void) { - depth += 1; - if (depth >= MAXDEPTH) + if (depth > MAXDEPTH-1) + abort(); /* bug */ + if (depth == MAXDEPTH-1) error("Too many levels of nesting"); + depth += 1; stifline[depth] = linenum; } static void @@ -490,15 +494,23 @@ flushline(bool keep) if (symlist) return; if (keep ^ complement) { - if (lnnum && delcount > 0) - printf("#line %d\n", linenum); - fputs(tline, stdout); - delcount = 0; + bool blankline = tline[strspn(tline, " \t\n")] == '\0'; + if (blankline && compblank && blankcount != blankmax) { + delcount += 1; + blankcount += 1; + } else { + if (lnnum && delcount > 0) + printf("#line %d\n", linenum); + fputs(tline, stdout); + delcount = 0; + blankmax = blankcount = blankline ? blankcount + 1 : 0; + } } else { if (lnblank) putc('\n', stdout); exitstat = 1; delcount += 1; + blankcount = 0; } } @@ -510,9 +522,12 @@ process(void) { Linetype lineval; + /* When compressing blank lines, act as if the file + is preceded by a large number of blank lines. */ + blankmax = blankcount = 1000; for (;;) { linenum++; - lineval = get_line(); + lineval = parseline(); trans_table[ifstate[depth]][lineval](); debug("process %s -> %s depth %d", linetype_name[lineval], @@ -526,7 +541,7 @@ process(void) * help from skipcomment(). */ static Linetype -get_line(void) +parseline(void) { const char *cp; int cursym; @@ -595,9 +610,21 @@ get_line(void) if (incomment) linestate = LS_DIRTY; } - /* skipcomment should have changed the state */ - if (linestate == LS_HASH) - abort(); /* bug */ + /* skipcomment normally changes the state, except + if the last line of the file lacks a newline, or + if there is too much whitespace in a directive */ + if (linestate == LS_HASH) { + size_t len = cp - tline; + if (fgets(tline + len, MAXLINE - len, input) == NULL) { + /* append the missing newline */ + tline[len+0] = '\n'; + tline[len+1] = '\0'; + cp++; + linestate = LS_START; + } else { + linestate = LS_DIRTY; + } + } } if (linestate == LS_DIRTY) { while (*cp != '\0') @@ -610,17 +637,40 @@ get_line(void) /* * These are the binary operators that are supported by the expression - * evaluator. Note that if support for division is added then we also - * need short-circuiting booleans because of divide-by-zero. + * evaluator. */ -static int op_lt(int a, int b) { return (a < b); } -static int op_gt(int a, int b) { return (a > b); } -static int op_le(int a, int b) { return (a <= b); } -static int op_ge(int a, int b) { return (a >= b); } -static int op_eq(int a, int b) { return (a == b); } -static int op_ne(int a, int b) { return (a != b); } -static int op_or(int a, int b) { return (a || b); } -static int op_and(int a, int b) { return (a && b); } +static Linetype op_strict(int *p, int v, Linetype at, Linetype bt) { + if(at == LT_IF || bt == LT_IF) return (LT_IF); + return (*p = v, v ? LT_TRUE : LT_FALSE); +} +static Linetype op_lt(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a < b, at, bt); +} +static Linetype op_gt(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a > b, at, bt); +} +static Linetype op_le(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a <= b, at, bt); +} +static Linetype op_ge(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a >= b, at, bt); +} +static Linetype op_eq(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a == b, at, bt); +} +static Linetype op_ne(int *p, Linetype at, int a, Linetype bt, int b) { + return op_strict(p, a != b, at, bt); +} +static Linetype op_or(int *p, Linetype at, int a, Linetype bt, int b) { + if (!strictlogic && (at == LT_TRUE || bt == LT_TRUE)) + return (*p = 1, LT_TRUE); + return op_strict(p, a || b, at, bt); +} +static Linetype op_and(int *p, Linetype at, int a, Linetype bt, int b) { + if (!strictlogic && (at == LT_FALSE || bt == LT_FALSE)) + return (*p = 0, LT_FALSE); + return op_strict(p, a && b, at, bt); +} /* * An evaluation function takes three arguments, as follows: (1) a pointer to @@ -629,8 +679,8 @@ static int op_and(int a, int b) { return (a && b); } * value of the expression; and (3) a pointer to a char* that points to the * expression to be evaluated and that is updated to the end of the expression * when evaluation is complete. The function returns LT_FALSE if the value of - * the expression is zero, LT_TRUE if it is non-zero, or LT_IF if the - * expression could not be evaluated. + * the expression is zero, LT_TRUE if it is non-zero, LT_IF if the expression + * depends on an unknown symbol, or LT_ERROR if there is a parse failure. */ struct ops; @@ -649,7 +699,7 @@ static const struct ops { eval_fn *inner; struct op { const char *str; - int (*fn)(int, int); + Linetype (*fn)(int *, Linetype, int, Linetype, int); } op[5]; } eval_ops[] = { { eval_table, { { "||", op_or } } }, @@ -664,8 +714,8 @@ static const struct ops { /* * Function for evaluating the innermost parts of expressions, - * viz. !expr (expr) defined(symbol) symbol number - * We reset the keepthis flag when we find a non-constant subexpression. + * viz. !expr (expr) number defined(symbol) symbol + * We reset the constexpr flag in the last two cases. */ static Linetype eval_unary(const struct ops *ops, int *valp, const char **cpp) @@ -673,68 +723,83 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp) const char *cp; char *ep; int sym; + bool defparen; + Linetype lt; cp = skipcomment(*cpp); if (*cp == '!') { debug("eval%d !", ops - eval_ops); cp++; - if (eval_unary(ops, valp, &cp) == LT_IF) { - *cpp = cp; - return (LT_IF); + lt = eval_unary(ops, valp, &cp); + if (lt == LT_ERROR) + return (LT_ERROR); + if (lt != LT_IF) { + *valp = !*valp; + lt = *valp ? LT_TRUE : LT_FALSE; } - *valp = !*valp; } else if (*cp == '(') { cp++; debug("eval%d (", ops - eval_ops); - if (eval_table(eval_ops, valp, &cp) == LT_IF) - return (LT_IF); + lt = eval_table(eval_ops, valp, &cp); + if (lt == LT_ERROR) + return (LT_ERROR); cp = skipcomment(cp); if (*cp++ != ')') - return (LT_IF); + return (LT_ERROR); } else if (isdigit((unsigned char)*cp)) { debug("eval%d number", ops - eval_ops); *valp = strtol(cp, &ep, 0); + if (ep == cp) + return (LT_ERROR); + lt = *valp ? LT_TRUE : LT_FALSE; cp = skipsym(cp); } else if (strncmp(cp, "defined", 7) == 0 && endsym(cp[7])) { cp = skipcomment(cp+7); debug("eval%d defined", ops - eval_ops); - if (*cp++ != '(') - return (LT_IF); - cp = skipcomment(cp); + if (*cp == '(') { + cp = skipcomment(cp+1); + defparen = true; + } else { + defparen = false; + } sym = findsym(cp); - cp = skipsym(cp); - cp = skipcomment(cp); - if (*cp++ != ')') - return (LT_IF); - if (sym >= 0) + if (sym < 0) { + lt = LT_IF; + } else { *valp = (value[sym] != NULL); - else { - *cpp = cp; - return (LT_IF); + lt = *valp ? LT_TRUE : LT_FALSE; } - keepthis = false; + cp = skipsym(cp); + cp = skipcomment(cp); + if (defparen && *cp++ != ')') + return (LT_ERROR); + constexpr = false; } else if (!endsym(*cp)) { debug("eval%d symbol", ops - eval_ops); sym = findsym(cp); - if (sym < 0) - return (LT_IF); - if (value[sym] == NULL) + cp = skipsym(cp); + if (sym < 0) { + lt = LT_IF; + cp = skipargs(cp); + } else if (value[sym] == NULL) { *valp = 0; - else { + lt = LT_FALSE; + } else { *valp = strtol(value[sym], &ep, 0); if (*ep != '\0' || ep == value[sym]) - return (LT_IF); + return (LT_ERROR); + lt = *valp ? LT_TRUE : LT_FALSE; + cp = skipargs(cp); } - cp = skipsym(cp); - keepthis = false; + constexpr = false; } else { debug("eval%d bad expr", ops - eval_ops); - return (LT_IF); + return (LT_ERROR); } *cpp = cp; debug("eval%d = %d", ops - eval_ops, *valp); - return (*valp ? LT_TRUE : LT_FALSE); + return (lt); } /* @@ -746,11 +811,13 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) const struct op *op; const char *cp; int val; - Linetype lhs, rhs; + Linetype lt, rt; debug("eval%d", ops - eval_ops); cp = *cpp; - lhs = ops->inner(ops+1, valp, &cp); + lt = ops->inner(ops+1, valp, &cp); + if (lt == LT_ERROR) + return (LT_ERROR); for (;;) { cp = skipcomment(cp); for (op = ops->op; op->str != NULL; op++) @@ -760,32 +827,16 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) break; cp += strlen(op->str); debug("eval%d %s", ops - eval_ops, op->str); - rhs = ops->inner(ops+1, &val, &cp); - if (op->fn == op_and && (lhs == LT_FALSE || rhs == LT_FALSE)) { - debug("eval%d: and always false", ops - eval_ops); - if (lhs == LT_IF) - *valp = val; - lhs = LT_FALSE; - continue; - } - if (op->fn == op_or && (lhs == LT_TRUE || rhs == LT_TRUE)) { - debug("eval%d: or always true", ops - eval_ops); - if (lhs == LT_IF) - *valp = val; - lhs = LT_TRUE; - continue; - } - if (rhs == LT_IF) - lhs = LT_IF; - if (lhs != LT_IF) - *valp = op->fn(*valp, val); + rt = ops->inner(ops+1, &val, &cp); + if (rt == LT_ERROR) + return (LT_ERROR); + lt = op->fn(valp, lt, *valp, rt, val); } *cpp = cp; debug("eval%d = %d", ops - eval_ops, *valp); - if (lhs != LT_IF) - lhs = (*valp ? LT_TRUE : LT_FALSE); - return lhs; + debug("eval%d lt = %s", ops - eval_ops, linetype_name[lt]); + return (lt); } /* @@ -796,17 +847,14 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) static Linetype ifeval(const char **cpp) { - const char *cp = *cpp; int ret; - int val; + int val = 0; debug("eval %s", *cpp); - keepthis = killconsts ? false : true; - ret = eval_table(eval_ops, &val, &cp); - if (ret != LT_IF) - *cpp = cp; + constexpr = killconsts ? false : true; + ret = eval_table(eval_ops, &val, cpp); debug("eval = %d", val); - return (keepthis ? LT_IF : ret); + return (constexpr ? LT_IF : ret == LT_ERROR ? LT_IF : ret); } /* @@ -918,6 +966,31 @@ skipcomment(const char *cp) } /* + * Skip macro arguments. + */ +static const char * +skipargs(const char *cp) +{ + const char *ocp = cp; + int level = 0; + cp = skipcomment(cp); + if (*cp != '(') + return (cp); + do { + if (*cp == '(') + level++; + if (*cp == ')') + level--; + cp = skipcomment(cp+1); + } while (level != 0 && *cp != '\0'); + if (level == 0) + return (cp); + else + /* Rewind and re-detect the syntax error later. */ + return (ocp); +} + +/* * Skip over an identifier. */ static const char * @@ -929,7 +1002,7 @@ skipsym(const char *cp) } /* - * Look for the symbol in the symbol table. If is is found, we return + * Look for the symbol in the symbol table. If it is found, we return * the symbol table index, else we return -1. */ static int -- cgit v0.10.2 From 75f0d92b6a11736429940bdd58f9c141abee8865 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Fri, 4 Dec 2009 20:46:17 +0000 Subject: score: add asm/asm-offsets.h wrapper A recent kbuild patch moved asm-offsets.h to include/generated. Provide a wrapper header as for other architectures. Signed-off-by: Michal Marek diff --git a/arch/score/include/asm/asm-offsets.h b/arch/score/include/asm/asm-offsets.h new file mode 100644 index 0000000..d370ee3 --- /dev/null +++ b/arch/score/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include -- cgit v0.10.2 From 6299fee7b84ac7b4429b4e2787b99470a89cd5f5 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Sat, 5 Dec 2009 20:20:50 +0000 Subject: genksyms: properly consider EXPORT_UNUSED_SYMBOL{,_GPL}() Despite being unused these should also get a CRC calculated. Primarily I view this as a consistency thing. But I also think this is one of the reasons why __crc_* need to be weak (which I think should be avoided, and hence we should have the goal to eliminate this so that failure to calculate a proper CRC for a symbol causes the build to fail). Signed-off-by: Jan Beulich Cc: Anibal Monsalve Salazar Cc: Steven Rostedt Cc: Sam Ravnborg Signed-off-by: Andrew Morton Signed-off-by: Michal Marek diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped index 287467a..8060e06 100644 --- a/scripts/genksyms/keywords.c_shipped +++ b/scripts/genksyms/keywords.c_shipped @@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.0.3 */ +/* ANSI-C code produced by gperf version 3.0.4 */ /* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -34,7 +34,7 @@ struct resword; static const struct resword *is_reserved_word(register const char *str, register unsigned int len); #line 5 "scripts/genksyms/keywords.gperf" struct resword { const char *name; int token; }; -/* maximum key range = 62, duplicates = 0 */ +/* maximum key range = 64, duplicates = 0 */ #ifdef __GNUC__ __inline @@ -48,39 +48,39 @@ is_reserved_hash (register const char *str, register unsigned int len) { static const unsigned char asso_values[] = { - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 5, - 65, 65, 65, 65, 65, 65, 35, 65, 65, 65, - 0, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 0, 65, 0, 65, 5, - 20, 15, 10, 30, 65, 15, 65, 65, 20, 0, - 10, 35, 20, 65, 10, 5, 0, 10, 5, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65 + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 0, + 67, 67, 67, 67, 67, 67, 15, 67, 67, 67, + 0, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 0, 67, 0, 67, 5, + 25, 20, 15, 30, 67, 15, 67, 67, 10, 0, + 10, 40, 20, 67, 10, 5, 0, 10, 15, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67 }; return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]]; } #ifdef __GNUC__ __inline -#ifdef __GNUC_STDC_INLINE__ +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ __attribute__ ((__gnu_inline__)) #endif #endif @@ -89,116 +89,119 @@ is_reserved_word (register const char *str, register unsigned int len) { enum { - TOTAL_KEYWORDS = 43, + TOTAL_KEYWORDS = 45, MIN_WORD_LENGTH = 3, MAX_WORD_LENGTH = 24, MIN_HASH_VALUE = 3, - MAX_HASH_VALUE = 64 + MAX_HASH_VALUE = 66 }; static const struct resword wordlist[] = { {""}, {""}, {""}, -#line 28 "scripts/genksyms/keywords.gperf" +#line 30 "scripts/genksyms/keywords.gperf" {"asm", ASM_KEYW}, {""}, -#line 10 "scripts/genksyms/keywords.gperf" +#line 12 "scripts/genksyms/keywords.gperf" {"__asm", ASM_KEYW}, {""}, -#line 11 "scripts/genksyms/keywords.gperf" +#line 13 "scripts/genksyms/keywords.gperf" {"__asm__", ASM_KEYW}, {""}, {""}, -#line 54 "scripts/genksyms/keywords.gperf" +#line 56 "scripts/genksyms/keywords.gperf" {"__typeof__", TYPEOF_KEYW}, {""}, -#line 14 "scripts/genksyms/keywords.gperf" +#line 16 "scripts/genksyms/keywords.gperf" {"__const", CONST_KEYW}, -#line 13 "scripts/genksyms/keywords.gperf" - {"__attribute__", ATTRIBUTE_KEYW}, #line 15 "scripts/genksyms/keywords.gperf" + {"__attribute__", ATTRIBUTE_KEYW}, +#line 17 "scripts/genksyms/keywords.gperf" {"__const__", CONST_KEYW}, -#line 20 "scripts/genksyms/keywords.gperf" +#line 22 "scripts/genksyms/keywords.gperf" {"__signed__", SIGNED_KEYW}, -#line 46 "scripts/genksyms/keywords.gperf" +#line 48 "scripts/genksyms/keywords.gperf" {"static", STATIC_KEYW}, -#line 22 "scripts/genksyms/keywords.gperf" - {"__volatile__", VOLATILE_KEYW}, -#line 41 "scripts/genksyms/keywords.gperf" + {""}, +#line 43 "scripts/genksyms/keywords.gperf" {"int", INT_KEYW}, -#line 34 "scripts/genksyms/keywords.gperf" +#line 36 "scripts/genksyms/keywords.gperf" {"char", CHAR_KEYW}, -#line 35 "scripts/genksyms/keywords.gperf" +#line 37 "scripts/genksyms/keywords.gperf" {"const", CONST_KEYW}, -#line 47 "scripts/genksyms/keywords.gperf" +#line 49 "scripts/genksyms/keywords.gperf" {"struct", STRUCT_KEYW}, -#line 26 "scripts/genksyms/keywords.gperf" +#line 28 "scripts/genksyms/keywords.gperf" {"__restrict__", RESTRICT_KEYW}, -#line 27 "scripts/genksyms/keywords.gperf" +#line 29 "scripts/genksyms/keywords.gperf" {"restrict", RESTRICT_KEYW}, -#line 25 "scripts/genksyms/keywords.gperf" - {"_restrict", RESTRICT_KEYW}, -#line 18 "scripts/genksyms/keywords.gperf" +#line 9 "scripts/genksyms/keywords.gperf" + {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, +#line 20 "scripts/genksyms/keywords.gperf" {"__inline__", INLINE_KEYW}, -#line 12 "scripts/genksyms/keywords.gperf" - {"__attribute", ATTRIBUTE_KEYW}, {""}, -#line 16 "scripts/genksyms/keywords.gperf" +#line 24 "scripts/genksyms/keywords.gperf" + {"__volatile__", VOLATILE_KEYW}, +#line 7 "scripts/genksyms/keywords.gperf" + {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, +#line 27 "scripts/genksyms/keywords.gperf" + {"_restrict", RESTRICT_KEYW}, + {""}, +#line 14 "scripts/genksyms/keywords.gperf" + {"__attribute", ATTRIBUTE_KEYW}, +#line 8 "scripts/genksyms/keywords.gperf" + {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, +#line 18 "scripts/genksyms/keywords.gperf" {"__extension__", EXTENSION_KEYW}, -#line 37 "scripts/genksyms/keywords.gperf" +#line 39 "scripts/genksyms/keywords.gperf" {"enum", ENUM_KEYW}, -#line 21 "scripts/genksyms/keywords.gperf" - {"__volatile", VOLATILE_KEYW}, -#line 38 "scripts/genksyms/keywords.gperf" +#line 10 "scripts/genksyms/keywords.gperf" + {"EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW}, +#line 40 "scripts/genksyms/keywords.gperf" {"extern", EXTERN_KEYW}, {""}, -#line 19 "scripts/genksyms/keywords.gperf" +#line 21 "scripts/genksyms/keywords.gperf" {"__signed", SIGNED_KEYW}, -#line 9 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, - {""}, -#line 53 "scripts/genksyms/keywords.gperf" +#line 11 "scripts/genksyms/keywords.gperf" + {"EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, +#line 51 "scripts/genksyms/keywords.gperf" + {"union", UNION_KEYW}, +#line 55 "scripts/genksyms/keywords.gperf" {"typeof", TYPEOF_KEYW}, -#line 48 "scripts/genksyms/keywords.gperf" +#line 50 "scripts/genksyms/keywords.gperf" {"typedef", TYPEDEF_KEYW}, -#line 17 "scripts/genksyms/keywords.gperf" +#line 19 "scripts/genksyms/keywords.gperf" {"__inline", INLINE_KEYW}, -#line 33 "scripts/genksyms/keywords.gperf" +#line 35 "scripts/genksyms/keywords.gperf" {"auto", AUTO_KEYW}, -#line 49 "scripts/genksyms/keywords.gperf" - {"union", UNION_KEYW}, - {""}, {""}, -#line 50 "scripts/genksyms/keywords.gperf" - {"unsigned", UNSIGNED_KEYW}, -#line 51 "scripts/genksyms/keywords.gperf" - {"void", VOID_KEYW}, -#line 44 "scripts/genksyms/keywords.gperf" - {"short", SHORT_KEYW}, +#line 23 "scripts/genksyms/keywords.gperf" + {"__volatile", VOLATILE_KEYW}, {""}, {""}, #line 52 "scripts/genksyms/keywords.gperf" - {"volatile", VOLATILE_KEYW}, - {""}, -#line 39 "scripts/genksyms/keywords.gperf" - {"float", FLOAT_KEYW}, -#line 36 "scripts/genksyms/keywords.gperf" - {"double", DOUBLE_KEYW}, + {"unsigned", UNSIGNED_KEYW}, {""}, -#line 7 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, - {""}, {""}, -#line 40 "scripts/genksyms/keywords.gperf" +#line 46 "scripts/genksyms/keywords.gperf" + {"short", SHORT_KEYW}, +#line 42 "scripts/genksyms/keywords.gperf" {"inline", INLINE_KEYW}, -#line 8 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, -#line 43 "scripts/genksyms/keywords.gperf" - {"register", REGISTER_KEYW}, {""}, -#line 24 "scripts/genksyms/keywords.gperf" +#line 54 "scripts/genksyms/keywords.gperf" + {"volatile", VOLATILE_KEYW}, +#line 44 "scripts/genksyms/keywords.gperf" + {"long", LONG_KEYW}, +#line 26 "scripts/genksyms/keywords.gperf" {"_Bool", BOOL_KEYW}, -#line 45 "scripts/genksyms/keywords.gperf" - {"signed", SIGNED_KEYW}, {""}, {""}, -#line 42 "scripts/genksyms/keywords.gperf" - {"long", LONG_KEYW} +#line 45 "scripts/genksyms/keywords.gperf" + {"register", REGISTER_KEYW}, +#line 53 "scripts/genksyms/keywords.gperf" + {"void", VOID_KEYW}, +#line 41 "scripts/genksyms/keywords.gperf" + {"float", FLOAT_KEYW}, +#line 38 "scripts/genksyms/keywords.gperf" + {"double", DOUBLE_KEYW}, + {""}, {""}, {""}, {""}, +#line 47 "scripts/genksyms/keywords.gperf" + {"signed", SIGNED_KEYW} }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf index 8fe977a..e6349ac 100644 --- a/scripts/genksyms/keywords.gperf +++ b/scripts/genksyms/keywords.gperf @@ -7,6 +7,8 @@ struct resword { const char *name; int token; } EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW +EXPORT_UNUSED_SYMBOL, EXPORT_SYMBOL_KEYW +EXPORT_UNUSED_SYMBOL_GPL, EXPORT_SYMBOL_KEYW __asm, ASM_KEYW __asm__, ASM_KEYW __attribute, ATTRIBUTE_KEYW -- cgit v0.10.2 From bc081dd6e9f622c73334dc465359168543ccaabf Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Mon, 7 Dec 2009 16:38:33 +0100 Subject: kbuild: generate modules.builtin To make it easier for module-init-tools and scripts like mkinitrd to distinguish builtin and missing modules, install a modules.builtin file listing all builtin modules. This is done by generating an additional config file (tristate.conf) with tristate options set to uppercase 'Y' or 'M'. If we source that config file, the builtin modules appear in obj-Y. Signed-off-by: Michal Marek diff --git a/.gitignore b/.gitignore index 002d530..fb2190c 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ *.lst *.symtypes *.order +modules.builtin *.elf *.bin *.gz diff --git a/Documentation/kbuild/kbuild.txt b/Documentation/kbuild/kbuild.txt index bb3bf38..6f8c1ca 100644 --- a/Documentation/kbuild/kbuild.txt +++ b/Documentation/kbuild/kbuild.txt @@ -1,3 +1,17 @@ +Output files + +modules.order +-------------------------------------------------- +This file records the order in which modules appear in Makefiles. This +is used by modprobe to deterministically resolve aliases that match +multiple modules. + +modules.builtin +-------------------------------------------------- +This file lists all modules that are built into the kernel. This is used +by modprobe to not fail when trying to load something builtin. + + Environment variables KCPPFLAGS diff --git a/Documentation/kbuild/kconfig.txt b/Documentation/kbuild/kconfig.txt index ab8dc35..49efae7 100644 --- a/Documentation/kbuild/kconfig.txt +++ b/Documentation/kbuild/kconfig.txt @@ -103,6 +103,11 @@ KCONFIG_AUTOCONFIG This environment variable can be set to specify the path & name of the "auto.conf" file. Its default value is "include/config/auto.conf". +KCONFIG_TRISTATE +-------------------------------------------------- +This environment variable can be set to specify the path & name of the +"tristate.conf" file. Its default value is "include/config/tristate.conf". + KCONFIG_AUTOHEADER -------------------------------------------------- This environment variable can be set to specify the path & name of the diff --git a/Makefile b/Makefile index aa608c2..391fcb3 100644 --- a/Makefile +++ b/Makefile @@ -464,7 +464,7 @@ ifeq ($(KBUILD_EXTMOD),) # Carefully list dependencies so we do not try to build scripts twice # in parallel PHONY += scripts -scripts: scripts_basic include/config/auto.conf +scripts: scripts_basic include/config/auto.conf include/config/tristate.conf $(Q)$(MAKE) $(build)=$(@) # Objects we will link into vmlinux / subdirs we need to visit @@ -491,7 +491,7 @@ $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; # with it and forgot to run make oldconfig. # if auto.conf.cmd is missing then we are probably in a cleaned tree so # we execute the config step to be sure to catch updated Kconfig files -include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd +include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig else # external modules needs include/generated/autoconf.h and include/config/auto.conf @@ -876,6 +876,9 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ; PHONY += $(vmlinux-dirs) $(vmlinux-dirs): prepare scripts $(Q)$(MAKE) $(build)=$@ +ifdef CONFIG_MODULES + $(Q)$(MAKE) $(modbuiltin)=$@ +endif # Build the kernel release string # @@ -1080,6 +1083,7 @@ all: modules PHONY += modules modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order + $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.builtin) > $(objtree)/modules.builtin @$(kecho) ' Building modules, stage 2.'; $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild @@ -1109,6 +1113,7 @@ _modinst_: ln -s $(objtree) $(MODLIB)/build ; \ fi @cp -f $(objtree)/modules.order $(MODLIB)/ + @cp -f $(objtree)/modules.builtin $(MODLIB)/ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst # This depmod is only for convenience to give the initial @@ -1169,7 +1174,7 @@ clean: archclean $(clean-dirs) \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '*.symtypes' -o -name 'modules.order' \ - -o -name '.tmp_*.o.*' \ + -o modules.order -o -name '.tmp_*.o.*' \ -o -name '*.gcno' \) -type f -print | xargs rm -f # mrproper - Delete all generated files, including .config @@ -1367,7 +1372,8 @@ $(clean-dirs): clean: rm-dirs := $(MODVERDIR) clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers \ - $(KBUILD_EXTMOD)/modules.order + $(KBUILD_EXTMOD)/modules.order \ + $(KBUILD_EXTMOD)/modules.builtin clean: $(clean-dirs) $(call cmd,rmdirs) $(call cmd,rmfiles) diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index c67e73e..ed2773e 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -149,6 +149,12 @@ ld-option = $(call try-run,\ # $(Q)$(MAKE) $(build)=dir build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj +### +# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.modbuiltin obj= +# Usage: +# $(Q)$(MAKE) $(modbuiltin)=dir +modbuiltin := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.modbuiltin obj + # Prefix -I with $(srctree) if it is not an absolute path. # skip if -I has no parameter addtree = $(if $(patsubst -I%,%,$(1)), \ diff --git a/scripts/Makefile.modbuiltin b/scripts/Makefile.modbuiltin new file mode 100644 index 0000000..102a276 --- /dev/null +++ b/scripts/Makefile.modbuiltin @@ -0,0 +1,55 @@ +# ========================================================================== +# Generating modules.builtin +# ========================================================================== + +src := $(obj) + +PHONY := __modbuiltin +__modbuiltin: + +-include include/config/auto.conf +# tristate.conf sets tristate variables to uppercase 'Y' or 'M' +# That way, we get the list of built-in modules in obj-Y +-include include/config/tristate.conf + +include scripts/Kbuild.include + +# The filename Kbuild has precedence over Makefile +kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) +kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile) +include $(kbuild-file) + +include scripts/Makefile.lib +__subdir-Y := $(patsubst %/,%,$(filter %/, $(obj-Y))) +subdir-Y += $(__subdir-Y) +subdir-ym := $(sort $(subdir-y) $(subdir-Y) $(subdir-m)) +subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) +obj-Y := $(addprefix $(obj)/,$(obj-Y)) + +modbuiltin-subdirs := $(patsubst %,%/modules.builtin, $(subdir-ym)) +modbuiltin-mods := $(filter %.ko, $(obj-Y:.o=.ko)) +modbuiltin-target := $(obj)/modules.builtin + +__modbuiltin: $(modbuiltin-target) $(subdir-ym) + @: + +$(modbuiltin-target): $(subdir-ym) FORCE + $(Q)(for m in $(modbuiltin-mods); do echo kernel/$$m; done; \ + cat /dev/null $(modbuiltin-subdirs)) > $@ + +PHONY += FORCE + +FORCE: + +# Descending +# --------------------------------------------------------------------------- + +PHONY += $(subdir-ym) +$(subdir-ym): + $(Q)$(MAKE) $(modbuiltin)=$@ + + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable se we can use it in if_changed and friends. + +.PHONY: $(PHONY) diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 797a741..c4dec80 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -677,7 +677,7 @@ int conf_write_autoconf(void) struct symbol *sym; const char *str; const char *name; - FILE *out, *out_h; + FILE *out, *tristate, *out_h; time_t now; int i, l; @@ -692,9 +692,16 @@ int conf_write_autoconf(void) if (!out) return 1; + tristate = fopen(".tmpconfig_tristate", "w"); + if (!tristate) { + fclose(out); + return 1; + } + out_h = fopen(".tmpconfig.h", "w"); if (!out_h) { fclose(out); + fclose(tristate); return 1; } @@ -707,6 +714,9 @@ int conf_write_autoconf(void) "# %s" "#\n", sym_get_string_value(sym), ctime(&now)); + fprintf(tristate, "#\n" + "# Automatically generated - do not edit\n" + "\n"); fprintf(out_h, "/*\n" " * Automatically generated C config: don't edit\n" " * Linux kernel version: %s\n" @@ -727,10 +737,14 @@ int conf_write_autoconf(void) break; case mod: fprintf(out, "CONFIG_%s=m\n", sym->name); + fprintf(tristate, "CONFIG_%s=M\n", sym->name); fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); break; case yes: fprintf(out, "CONFIG_%s=y\n", sym->name); + if (sym->type == S_TRISTATE) + fprintf(tristate, "CONFIG_%s=Y\n", + sym->name); fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); break; } @@ -772,6 +786,7 @@ int conf_write_autoconf(void) } } fclose(out); + fclose(tristate); fclose(out_h); name = getenv("KCONFIG_AUTOHEADER"); @@ -779,6 +794,11 @@ int conf_write_autoconf(void) name = "include/generated/autoconf.h"; if (rename(".tmpconfig.h", name)) return 1; + name = getenv("KCONFIG_TRISTATE"); + if (!name) + name = "include/config/tristate.conf"; + if (rename(".tmpconfig_tristate", name)) + return 1; name = conf_get_autoconfig_name(); /* * This must be the last step, kbuild has a dependency on auto.conf -- cgit v0.10.2 From d9bdcc72ecf055f97ed736a6c0309bd41baf10a7 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 8 Dec 2009 16:03:10 +0100 Subject: kbuild: fix make clean after mismerge Fix typo / thinko in commit bc081dd. Signed-off-by: Michal Marek diff --git a/Makefile b/Makefile index 391fcb3..8491b21 100644 --- a/Makefile +++ b/Makefile @@ -1174,7 +1174,7 @@ clean: archclean $(clean-dirs) \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '*.symtypes' -o -name 'modules.order' \ - -o modules.order -o -name '.tmp_*.o.*' \ + -o -name modules.builtin -o -name '.tmp_*.o.*' \ -o -name '*.gcno' \) -type f -print | xargs rm -f # mrproper - Delete all generated files, including .config -- cgit v0.10.2 From 6d87fea4dd7152df4a4605a3846c3bf10f869e0c Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 9 Dec 2009 06:55:19 -0500 Subject: gen_init_cpio: fixed fwrite warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On compilers with security warnings enabled by default, we get: usr/gen_init_cpio.c: In function ‘cpio_mkfile’: usr/gen_init_cpio.c:357: warning: ignoring return value of ‘fwrite’, declared with attribute warn_unused_result So check the return value and handle errors accordingly. Signed-off-by: Mike Frysinger Signed-off-by: Michal Marek diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c index 83b3dde..b2b3c2d 100644 --- a/usr/gen_init_cpio.c +++ b/usr/gen_init_cpio.c @@ -354,7 +354,10 @@ static int cpio_mkfile(const char *name, const char *location, push_pad(); if (size) { - fwrite(filebuf, size, 1, stdout); + if (fwrite(filebuf, size, 1, stdout) != 1) { + fprintf(stderr, "writing filebuf failed\n"); + goto error; + } offset += size; push_pad(); } -- cgit v0.10.2 From 46e75f66677f5094bb51e91f9473128c4e907c7d Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 7 Dec 2009 19:56:42 +1100 Subject: net: fix for utsrelease.h moving to generated Signed-off-by: Stephen Rothwell Signed-off-by: Michal Marek diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 675b7df..27ca859 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -63,7 +63,7 @@ #ifndef __iwl_core_h__ #define __iwl_core_h__ -#include +#include /************************ * forward declarations * -- cgit v0.10.2 From 5543c72e2bbb30e5ba5938b18ec26617b8b3fb04 Mon Sep 17 00:00:00 2001 From: Abhijeet Joglekar Date: Thu, 10 Dec 2009 09:59:20 -0800 Subject: [SCSI] libfc: remote port gets stuck in restart state without really restarting We ran into a scenario where a remote port goes into RESTART state, but never gets added to scsi transport. The running vmcore showed the following: a) Port was in RESTART state b) rdata->event was STOP c) no work gets scheduled for the remote work to fc_rport_work After this point, shut/no-shut of the remote port did not cause the port to get re-discovered. The port would move betwen DELETE and RESTART states, but the event would always be STOP, no work would get scheduled to fc_rport_work and the port would not get added to scsi_transport. The problem is that rdata->event is not set to NONE after a port is restarted. After this point, no more work gets scheduled for the remote port since new work is scheduled only if rdata->event is non-NONE. So, the event and state keep changing, but fc_rport_work does not get scheduled to actually handle the event. Here's a transition of states that explains the above observation: ) Port is first in READY State, event is NONE 2) RSCN on shut, port goes to DELETED, event is stop 3) Before fc_rport_work runs, RSCN on no-shut, port goes to RESTART, event is still STOP 4) fc_rport_work gets scheduled, removes the port from transport, sees state as RESTART, begins the PLOGI state machine, event remains as STOP (event NOT changed to NONE, this is the bug) 5) Plogi state machine completes, port state goes to READY, event goes to READY, but no work is scheduled since event was STOP (non-NONE) before. Fc_rport_work is not scheduled, port remains in READY state, but is not added to transport. Things are broken at this point. Libfc rport is ready, but no transport rport created. 6) now a shut causes port state to change to DELETE, event to change to STOP, no work gets scheduled 7) no-shut causes port state to change to RESTART, event remains at STOP, no work gets scheduled (6) and (7) now get repeated everytime we do shut/no-shut. No way to get out of this state. Fcc reset does not help too. Only way to get out is to load/unload module. Fix is to set rdata->event to NONE while processing the STOP/LOGO/FAILED events, inside the discovery and rport locks. Signed-off-by: Abhijeet Joglekar Signed-off-by: Robert Love Signed-off-by: James Bottomley diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 35ca0e7..0230052 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -310,6 +310,7 @@ static void fc_rport_work(struct work_struct *work) restart = 1; else list_del(&rdata->peers); + rdata->event = RPORT_EV_NONE; mutex_unlock(&rdata->rp_mutex); mutex_unlock(&lport->disc.disc_mutex); } -- cgit v0.10.2 From c1ecb90a66c5afc7cc5c9349f9c3714eef4a5cfb Mon Sep 17 00:00:00 2001 From: Chris Leech Date: Thu, 10 Dec 2009 09:59:26 -0800 Subject: [SCSI] libfc: reduce hold time on SCSI host lock Introduce a new lock to protect the list of fc_fcp_pkt structs in libfc instead of using the host lock. This reduces the contention of this heavily used lock, and I see up to a 25% performance gain in CPU bound small I/O tests when scaling out across multiple quad-core CPUs. The big win is in removing the host lock from the completion path completely, as it does not need to be held around the call to scsi_done. Signed-off-by: Chris Leech Signed-off-by: Robert Love Signed-off-by: James Bottomley diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index c4b58d0..881d5df 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -68,18 +68,20 @@ struct kmem_cache *scsi_pkt_cachep; /** * struct fc_fcp_internal - FCP layer internal data - * @scsi_pkt_pool: Memory pool to draw FCP packets from + * @scsi_pkt_pool: Memory pool to draw FCP packets from + * @scsi_queue_lock: Protects the scsi_pkt_queue * @scsi_pkt_queue: Current FCP packets * @last_can_queue_ramp_down_time: ramp down time * @last_can_queue_ramp_up_time: ramp up time * @max_can_queue: max can_queue size */ struct fc_fcp_internal { - mempool_t *scsi_pkt_pool; - struct list_head scsi_pkt_queue; - unsigned long last_can_queue_ramp_down_time; - unsigned long last_can_queue_ramp_up_time; - int max_can_queue; + mempool_t *scsi_pkt_pool; + spinlock_t scsi_queue_lock; + struct list_head scsi_pkt_queue; + unsigned long last_can_queue_ramp_down_time; + unsigned long last_can_queue_ramp_up_time; + int max_can_queue; }; #define fc_get_scsi_internal(x) ((struct fc_fcp_internal *)(x)->scsi_priv) @@ -410,12 +412,14 @@ static inline struct fc_frame *fc_fcp_frame_alloc(struct fc_lport *lport, unsigned long flags; fp = fc_frame_alloc(lport, len); - if (!fp) { - spin_lock_irqsave(lport->host->host_lock, flags); - fc_fcp_can_queue_ramp_down(lport); - spin_unlock_irqrestore(lport->host->host_lock, flags); - } - return fp; + if (likely(fp)) + return fp; + + /* error case */ + spin_lock_irqsave(lport->host->host_lock, flags); + fc_fcp_can_queue_ramp_down(lport); + spin_unlock_irqrestore(lport->host->host_lock, flags); + return NULL; } /** @@ -990,7 +994,7 @@ static void fc_fcp_cleanup_each_cmd(struct fc_lport *lport, unsigned int id, struct scsi_cmnd *sc_cmd; unsigned long flags; - spin_lock_irqsave(lport->host->host_lock, flags); + spin_lock_irqsave(&si->scsi_queue_lock, flags); restart: list_for_each_entry(fsp, &si->scsi_pkt_queue, list) { sc_cmd = fsp->cmd; @@ -1001,7 +1005,7 @@ restart: continue; fc_fcp_pkt_hold(fsp); - spin_unlock_irqrestore(lport->host->host_lock, flags); + spin_unlock_irqrestore(&si->scsi_queue_lock, flags); if (!fc_fcp_lock_pkt(fsp)) { fc_fcp_cleanup_cmd(fsp, error); @@ -1010,14 +1014,14 @@ restart: } fc_fcp_pkt_release(fsp); - spin_lock_irqsave(lport->host->host_lock, flags); + spin_lock_irqsave(&si->scsi_queue_lock, flags); /* * while we dropped the lock multiple pkts could * have been released, so we have to start over. */ goto restart; } - spin_unlock_irqrestore(lport->host->host_lock, flags); + spin_unlock_irqrestore(&si->scsi_queue_lock, flags); } /** @@ -1035,11 +1039,12 @@ static void fc_fcp_abort_io(struct fc_lport *lport) * @fsp: The FCP packet to send * * Return: Zero for success and -1 for failure - * Locks: Called with the host lock and irqs disabled. + * Locks: Called without locks held */ static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp) { struct fc_fcp_internal *si = fc_get_scsi_internal(lport); + unsigned long flags; int rc; fsp->cmd->SCp.ptr = (char *)fsp; @@ -1049,13 +1054,16 @@ static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp) int_to_scsilun(fsp->cmd->device->lun, (struct scsi_lun *)fsp->cdb_cmd.fc_lun); memcpy(fsp->cdb_cmd.fc_cdb, fsp->cmd->cmnd, fsp->cmd->cmd_len); - list_add_tail(&fsp->list, &si->scsi_pkt_queue); - spin_unlock_irq(lport->host->host_lock); + spin_lock_irqsave(&si->scsi_queue_lock, flags); + list_add_tail(&fsp->list, &si->scsi_pkt_queue); + spin_unlock_irqrestore(&si->scsi_queue_lock, flags); rc = lport->tt.fcp_cmd_send(lport, fsp, fc_fcp_recv); - spin_lock_irq(lport->host->host_lock); - if (rc) + if (unlikely(rc)) { + spin_lock_irqsave(&si->scsi_queue_lock, flags); list_del(&fsp->list); + spin_unlock_irqrestore(&si->scsi_queue_lock, flags); + } return rc; } @@ -1752,6 +1760,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *)) struct fcoe_dev_stats *stats; lport = shost_priv(sc_cmd->device->host); + spin_unlock_irq(lport->host->host_lock); rval = fc_remote_port_chkready(rport); if (rval) { @@ -1834,6 +1843,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *)) rc = SCSI_MLQUEUE_HOST_BUSY; } out: + spin_lock_irq(lport->host->host_lock); return rc; } EXPORT_SYMBOL(fc_queuecommand); @@ -1864,11 +1874,8 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) lport = fsp->lp; si = fc_get_scsi_internal(lport); - spin_lock_irqsave(lport->host->host_lock, flags); - if (!fsp->cmd) { - spin_unlock_irqrestore(lport->host->host_lock, flags); + if (!fsp->cmd) return; - } /* * if can_queue ramp down is done then try can_queue ramp up @@ -1880,10 +1887,8 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) sc_cmd = fsp->cmd; fsp->cmd = NULL; - if (!sc_cmd->SCp.ptr) { - spin_unlock_irqrestore(lport->host->host_lock, flags); + if (!sc_cmd->SCp.ptr) return; - } CMD_SCSI_STATUS(sc_cmd) = fsp->cdb_status; switch (fsp->status_code) { @@ -1945,10 +1950,11 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) break; } + spin_lock_irqsave(&si->scsi_queue_lock, flags); list_del(&fsp->list); + spin_unlock_irqrestore(&si->scsi_queue_lock, flags); sc_cmd->SCp.ptr = NULL; sc_cmd->scsi_done(sc_cmd); - spin_unlock_irqrestore(lport->host->host_lock, flags); /* release ref from initial allocation in queue command */ fc_fcp_pkt_release(fsp); @@ -2216,6 +2222,7 @@ int fc_fcp_init(struct fc_lport *lport) lport->scsi_priv = si; si->max_can_queue = lport->host->can_queue; INIT_LIST_HEAD(&si->scsi_pkt_queue); + spin_lock_init(&si->scsi_queue_lock); si->scsi_pkt_pool = mempool_create_slab_pool(2, scsi_pkt_cachep); if (!si->scsi_pkt_pool) { -- cgit v0.10.2 From 55a66d3c1e57f7e3e554d6ec8011e840f3802f20 Mon Sep 17 00:00:00 2001 From: Vasu Dev Date: Thu, 10 Dec 2009 09:59:31 -0800 Subject: [SCSI] fcoe, libfc: adds enable/disable for fcoe interface This is to allow fcoemon util to enable or disable a fcoe interface according to DCB link state change. Adds sysfs module param enable and disable for this and also updates existing other module param description to be consistent and more accurate since older description had double "fcoe" word with less meaningful netdev reference to user space. Adds code to ignore redundant fc_lport_enter_reset handling for a already disabled fcoe interface by checking LPORT_ST_DISABLED or LPORT_ST_LOGO states, this also prevents lport state transition on link flap on a disabled interface. Above changes required lport state transition to get out of disabled or logo state on call to fc_fabric_login. Signed-off-by: Vasu Dev Signed-off-by: Robert Love Signed-off-by: James Bottomley diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 9b6aebb..e3896fc 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -101,6 +101,8 @@ static int fcoe_cpu_callback(struct notifier_block *, unsigned long, void *); static int fcoe_create(const char *, struct kernel_param *); static int fcoe_destroy(const char *, struct kernel_param *); +static int fcoe_enable(const char *, struct kernel_param *); +static int fcoe_disable(const char *, struct kernel_param *); static struct fc_seq *fcoe_elsct_send(struct fc_lport *, u32 did, struct fc_frame *, @@ -115,10 +117,16 @@ static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *); module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR); __MODULE_PARM_TYPE(create, "string"); -MODULE_PARM_DESC(create, "Create fcoe fcoe using net device passed in."); +MODULE_PARM_DESC(create, " Creates fcoe instance on a ethernet interface"); module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR); __MODULE_PARM_TYPE(destroy, "string"); -MODULE_PARM_DESC(destroy, "Destroy fcoe fcoe"); +MODULE_PARM_DESC(destroy, " Destroys fcoe instance on a ethernet interface"); +module_param_call(enable, fcoe_enable, NULL, NULL, S_IWUSR); +__MODULE_PARM_TYPE(enable, "string"); +MODULE_PARM_DESC(enable, " Enables fcoe on a ethernet interface."); +module_param_call(disable, fcoe_disable, NULL, NULL, S_IWUSR); +__MODULE_PARM_TYPE(disable, "string"); +MODULE_PARM_DESC(disable, " Disables fcoe on a ethernet interface."); /* notification function for packets from net device */ static struct notifier_block fcoe_notifier = { @@ -1859,6 +1867,104 @@ static struct net_device *fcoe_if_to_netdev(const char *buffer) } /** + * fcoe_disable() - Disables a FCoE interface + * @buffer: The name of the Ethernet interface to be disabled + * @kp: The associated kernel parameter + * + * Called from sysfs. + * + * Returns: 0 for success + */ +static int fcoe_disable(const char *buffer, struct kernel_param *kp) +{ + struct fcoe_interface *fcoe; + struct net_device *netdev; + int rc = 0; + + mutex_lock(&fcoe_config_mutex); +#ifdef CONFIG_FCOE_MODULE + /* + * Make sure the module has been initialized, and is not about to be + * removed. Module paramter sysfs files are writable before the + * module_init function is called and after module_exit. + */ + if (THIS_MODULE->state != MODULE_STATE_LIVE) { + rc = -ENODEV; + goto out_nodev; + } +#endif + + netdev = fcoe_if_to_netdev(buffer); + if (!netdev) { + rc = -ENODEV; + goto out_nodev; + } + + rtnl_lock(); + fcoe = fcoe_hostlist_lookup_port(netdev); + rtnl_unlock(); + + if (fcoe) + fc_fabric_logoff(fcoe->ctlr.lp); + else + rc = -ENODEV; + + dev_put(netdev); +out_nodev: + mutex_unlock(&fcoe_config_mutex); + return rc; +} + +/** + * fcoe_enable() - Enables a FCoE interface + * @buffer: The name of the Ethernet interface to be enabled + * @kp: The associated kernel parameter + * + * Called from sysfs. + * + * Returns: 0 for success + */ +static int fcoe_enable(const char *buffer, struct kernel_param *kp) +{ + struct fcoe_interface *fcoe; + struct net_device *netdev; + int rc = 0; + + mutex_lock(&fcoe_config_mutex); +#ifdef CONFIG_FCOE_MODULE + /* + * Make sure the module has been initialized, and is not about to be + * removed. Module paramter sysfs files are writable before the + * module_init function is called and after module_exit. + */ + if (THIS_MODULE->state != MODULE_STATE_LIVE) { + rc = -ENODEV; + goto out_nodev; + } +#endif + + netdev = fcoe_if_to_netdev(buffer); + if (!netdev) { + rc = -ENODEV; + goto out_nodev; + } + + rtnl_lock(); + fcoe = fcoe_hostlist_lookup_port(netdev); + rtnl_unlock(); + + if (fcoe) + rc = fc_fabric_login(fcoe->ctlr.lp); + else + rc = -ENODEV; + + dev_put(netdev); +out_nodev: + mutex_unlock(&fcoe_config_mutex); + return rc; +} + +/** * fcoe_destroy() - Destroy a FCoE interface * @buffer: The name of the Ethernet interface to be destroyed * @kp: The associated kernel parameter diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index 74338c8..0b16502 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -537,7 +537,9 @@ int fc_fabric_login(struct fc_lport *lport) int rc = -1; mutex_lock(&lport->lp_mutex); - if (lport->state == LPORT_ST_DISABLED) { + if (lport->state == LPORT_ST_DISABLED || + lport->state == LPORT_ST_LOGO) { + fc_lport_state_enter(lport, LPORT_ST_RESET); fc_lport_enter_reset(lport); rc = 0; } @@ -967,6 +969,9 @@ static void fc_lport_enter_reset(struct fc_lport *lport) FC_LPORT_DBG(lport, "Entered RESET state from %s state\n", fc_lport_state(lport)); + if (lport->state == LPORT_ST_DISABLED || lport->state == LPORT_ST_LOGO) + return; + if (lport->vport) { if (lport->link_up) fc_vport_set_state(lport->vport, FC_VPORT_INITIALIZING); -- cgit v0.10.2 From 53ca353594a254e6bd45ccf2d405aa31bcbb7091 Mon Sep 17 00:00:00 2001 From: adam radford Date: Thu, 10 Dec 2009 11:53:31 -0800 Subject: [SCSI] 3w-9xxx fix bug in sgl loading This small patch fixes a bug in the 3w-9xxx driver where it would load an invalid sgl address in the ioctl path even if request length was zero. Signed-off-by: Adam Radford Signed-off-by: James Bottomley diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 3bf7592..84d3bba 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -76,6 +76,7 @@ Fix bug in twa_get_param() on 4GB+. Use pci_resource_len() for ioremap(). 2.26.02.012 - Add power management support. + 2.26.02.013 - Fix bug in twa_load_sgl(). */ #include @@ -100,7 +101,7 @@ #include "3w-9xxx.h" /* Globals */ -#define TW_DRIVER_VERSION "2.26.02.012" +#define TW_DRIVER_VERSION "2.26.02.013" static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; static unsigned int twa_device_extension_count; static int twa_major = -1; @@ -1382,10 +1383,12 @@ static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_comm newcommand = &full_command_packet->command.newcommand; newcommand->request_id__lunl = cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id)); - newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); - newcommand->sg_list[0].length = cpu_to_le32(length); + if (length) { + newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); + newcommand->sg_list[0].length = cpu_to_le32(length); + } newcommand->sgl_entries__lunh = - cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), 1)); + cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), length ? 1 : 0)); } else { oldcommand = &full_command_packet->command.oldcommand; oldcommand->request_id = request_id; -- cgit v0.10.2 From 26054c9541ccc562e0aec05e8c1f19bf85328bcf Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:34 +0000 Subject: powerpc: gamecube/wii: usbgecko bootwrapper console support Add support for using the USB Gecko adapter as a bootwrapper console on the Nintendo GameCube and Wii video game consoles. The USB Gecko is a 3rd party memory card interface adapter that provides a EXI (External Interface) to USB serial converter. Signed-off-by: Albert Herranz Acked-by: Segher Boessenkool Signed-off-by: Grant Likely diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 7bfc8ad..44bce21 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -66,7 +66,7 @@ src-wlib := string.S crt0.S crtsavres.S stdio.c main.c \ gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \ 4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \ cpm-serial.c stdlib.c mpc52xx-psc.c planetcore.c uartlite.c \ - fsl-soc.c mpc8xx.c pq2.c + fsl-soc.c mpc8xx.c pq2.c ugecon.c src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \ cuboot-ebony.c cuboot-hotfoot.c treeboot-ebony.c prpmc2800.c \ ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \ diff --git a/arch/powerpc/boot/ugecon.c b/arch/powerpc/boot/ugecon.c new file mode 100644 index 0000000..50609ea --- /dev/null +++ b/arch/powerpc/boot/ugecon.c @@ -0,0 +1,147 @@ +/* + * arch/powerpc/boot/ugecon.c + * + * USB Gecko bootwrapper console. + * Copyright (C) 2008-2009 The GameCube Linux Team + * Copyright (C) 2008,2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ + +#include +#include "stdio.h" +#include "types.h" +#include "io.h" +#include "ops.h" + + +#define EXI_CLK_32MHZ 5 + +#define EXI_CSR 0x00 +#define EXI_CSR_CLKMASK (0x7<<4) +#define EXI_CSR_CLK_32MHZ (EXI_CLK_32MHZ<<4) +#define EXI_CSR_CSMASK (0x7<<7) +#define EXI_CSR_CS_0 (0x1<<7) /* Chip Select 001 */ + +#define EXI_CR 0x0c +#define EXI_CR_TSTART (1<<0) +#define EXI_CR_WRITE (1<<2) +#define EXI_CR_READ_WRITE (2<<2) +#define EXI_CR_TLEN(len) (((len)-1)<<4) + +#define EXI_DATA 0x10 + + +/* virtual address base for input/output, retrieved from device tree */ +static void *ug_io_base; + + +static u32 ug_io_transaction(u32 in) +{ + u32 *csr_reg = ug_io_base + EXI_CSR; + u32 *data_reg = ug_io_base + EXI_DATA; + u32 *cr_reg = ug_io_base + EXI_CR; + u32 csr, data, cr; + + /* select */ + csr = EXI_CSR_CLK_32MHZ | EXI_CSR_CS_0; + out_be32(csr_reg, csr); + + /* read/write */ + data = in; + out_be32(data_reg, data); + cr = EXI_CR_TLEN(2) | EXI_CR_READ_WRITE | EXI_CR_TSTART; + out_be32(cr_reg, cr); + + while (in_be32(cr_reg) & EXI_CR_TSTART) + barrier(); + + /* deselect */ + out_be32(csr_reg, 0); + + data = in_be32(data_reg); + return data; +} + +static int ug_is_txfifo_ready(void) +{ + return ug_io_transaction(0xc0000000) & 0x04000000; +} + +static void ug_raw_putc(char ch) +{ + ug_io_transaction(0xb0000000 | (ch << 20)); +} + +static void ug_putc(char ch) +{ + int count = 16; + + if (!ug_io_base) + return; + + while (!ug_is_txfifo_ready() && count--) + barrier(); + if (count) + ug_raw_putc(ch); +} + +void ug_console_write(const char *buf, int len) +{ + char *b = (char *)buf; + + while (len--) { + if (*b == '\n') + ug_putc('\r'); + ug_putc(*b++); + } +} + +static int ug_is_adapter_present(void) +{ + if (!ug_io_base) + return 0; + return ug_io_transaction(0x90000000) == 0x04700000; +} + +static void *ug_grab_exi_io_base(void) +{ + u32 v; + void *devp; + + devp = find_node_by_compatible(NULL, "nintendo,flipper-exi"); + if (devp == NULL) + goto err_out; + if (getprop(devp, "virtual-reg", &v, sizeof(v)) != sizeof(v)) + goto err_out; + + return (void *)v; + +err_out: + return NULL; +} + +void *ug_probe(void) +{ + void *exi_io_base; + int i; + + exi_io_base = ug_grab_exi_io_base(); + if (!exi_io_base) + return NULL; + + /* look for a usbgecko on memcard slots A and B */ + for (i = 0; i < 2; i++) { + ug_io_base = exi_io_base + 0x14 * i; + if (ug_is_adapter_present()) + break; + } + if (i == 2) + ug_io_base = NULL; + return ug_io_base; +} + diff --git a/arch/powerpc/boot/ugecon.h b/arch/powerpc/boot/ugecon.h new file mode 100644 index 0000000..4373753 --- /dev/null +++ b/arch/powerpc/boot/ugecon.h @@ -0,0 +1,24 @@ +/* + * arch/powerpc/boot/ugecon.h + * + * USB Gecko early bootwrapper console. + * Copyright (C) 2008-2009 The GameCube Linux Team + * Copyright (C) 2008,2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ + +#ifndef __UGECON_H +#define __UGECON_H + +extern void *ug_probe(void); + +extern void ug_putc(char ch); +extern void ug_console_write(const char *buf, int len); + +#endif /* __UGECON_H */ + -- cgit v0.10.2 From 86ad53f8aa051f5cf8783e28a804adc3ebc391f7 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:35 +0000 Subject: powerpc: gamecube: device tree Add a device tree source file for the Nintendo GameCube video game console. Signed-off-by: Albert Herranz Acked-by: Segher Boessenkool Signed-off-by: Grant Likely diff --git a/Documentation/powerpc/dts-bindings/nintendo/gamecube.txt b/Documentation/powerpc/dts-bindings/nintendo/gamecube.txt new file mode 100644 index 0000000..b558585 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/nintendo/gamecube.txt @@ -0,0 +1,109 @@ + +Nintendo GameCube device tree +============================= + +1) The "flipper" node + + This node represents the multi-function "Flipper" chip, which packages + many of the devices found in the Nintendo GameCube. + + Required properties: + + - compatible : Should be "nintendo,flipper" + +1.a) The Video Interface (VI) node + + Represents the interface between the graphics processor and a external + video encoder. + + Required properties: + + - compatible : should be "nintendo,flipper-vi" + - reg : should contain the VI registers location and length + - interrupts : should contain the VI interrupt + +1.b) The Processor Interface (PI) node + + Represents the data and control interface between the main processor + and graphics and audio processor. + + Required properties: + + - compatible : should be "nintendo,flipper-pi" + - reg : should contain the PI registers location and length + +1.b.i) The "Flipper" interrupt controller node + + Represents the interrupt controller within the "Flipper" chip. + The node for the "Flipper" interrupt controller must be placed under + the PI node. + + Required properties: + + - compatible : should be "nintendo,flipper-pic" + +1.c) The Digital Signal Procesor (DSP) node + + Represents the digital signal processor interface, designed to offload + audio related tasks. + + Required properties: + + - compatible : should be "nintendo,flipper-dsp" + - reg : should contain the DSP registers location and length + - interrupts : should contain the DSP interrupt + +1.c.i) The Auxiliary RAM (ARAM) node + + Represents the non cpu-addressable ram designed mainly to store audio + related information. + The ARAM node must be placed under the DSP node. + + Required properties: + + - compatible : should be "nintendo,flipper-aram" + - reg : should contain the ARAM start (zero-based) and length + +1.d) The Disk Interface (DI) node + + Represents the interface used to communicate with mass storage devices. + + Required properties: + + - compatible : should be "nintendo,flipper-di" + - reg : should contain the DI registers location and length + - interrupts : should contain the DI interrupt + +1.e) The Audio Interface (AI) node + + Represents the interface to the external 16-bit stereo digital-to-analog + converter. + + Required properties: + + - compatible : should be "nintendo,flipper-ai" + - reg : should contain the AI registers location and length + - interrupts : should contain the AI interrupt + +1.f) The Serial Interface (SI) node + + Represents the interface to the four single bit serial interfaces. + The SI is a proprietary serial interface used normally to control gamepads. + It's NOT a RS232-type interface. + + Required properties: + + - compatible : should be "nintendo,flipper-si" + - reg : should contain the SI registers location and length + - interrupts : should contain the SI interrupt + +1.g) The External Interface (EXI) node + + Represents the multi-channel SPI-like interface. + + Required properties: + + - compatible : should be "nintendo,flipper-exi" + - reg : should contain the EXI registers location and length + - interrupts : should contain the EXI interrupt + diff --git a/arch/powerpc/boot/dts/gamecube.dts b/arch/powerpc/boot/dts/gamecube.dts new file mode 100644 index 0000000..ef3be0e --- /dev/null +++ b/arch/powerpc/boot/dts/gamecube.dts @@ -0,0 +1,114 @@ +/* + * arch/powerpc/boot/dts/gamecube.dts + * + * Nintendo GameCube platform device tree source + * Copyright (C) 2007-2009 The GameCube Linux Team + * Copyright (C) 2007,2008,2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ + +/dts-v1/; + +/ { + model = "nintendo,gamecube"; + compatible = "nintendo,gamecube"; + #address-cells = <1>; + #size-cells = <1>; + + chosen { + bootargs = "root=/dev/gcnsda2 rootwait udbg-immortal"; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x01800000>; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,gekko@0 { + device_type = "cpu"; + reg = <0>; + clock-frequency = <486000000>; /* 486MHz */ + bus-frequency = <162000000>; /* 162MHz core-to-bus 3x */ + timebase-frequency = <40500000>; /* 162MHz / 4 */ + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; + }; + }; + + /* devices contained int the flipper chipset */ + flipper { + #address-cells = <1>; + #size-cells = <1>; + compatible = "nintendo,flipper"; + ranges = <0x0c000000 0x0c000000 0x00010000>; + interrupt-parent = <&PIC>; + + video@0c002000 { + compatible = "nintendo,flipper-vi"; + reg = <0x0c002000 0x100>; + interrupts = <8>; + }; + + processor-interface@0c003000 { + compatible = "nintendo,flipper-pi"; + reg = <0x0c003000 0x100>; + + PIC: pic { + #interrupt-cells = <1>; + compatible = "nintendo,flipper-pic"; + interrupt-controller; + }; + }; + + dsp@0c005000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "nintendo,flipper-dsp"; + reg = <0x0c005000 0x200>; + interrupts = <6>; + + memory@0 { + compatible = "nintendo,flipper-aram"; + reg = <0 0x1000000>; /* 16MB */ + }; + }; + + disk@0c006000 { + compatible = "nintendo,flipper-di"; + reg = <0x0c006000 0x40>; + interrupts = <2>; + }; + + audio@0c006c00 { + compatible = "nintendo,flipper-ai"; + reg = <0x0c006c00 0x20>; + interrupts = <6>; + }; + + gamepad-controller@0c006400 { + compatible = "nintendo,flipper-si"; + reg = <0x0c006400 0x100>; + interrupts = <3>; + }; + + /* External Interface bus */ + exi@0c006800 { + compatible = "nintendo,flipper-exi"; + reg = <0x0c006800 0x40>; + virtual-reg = <0x0c006800>; + interrupts = <4>; + }; + }; +}; + -- cgit v0.10.2 From b68a24bc783e9ed76549d738907c45d4799e6cb7 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:36 +0000 Subject: powerpc: gamecube: bootwrapper bits Add support for the Nintendo GameCube video game console to the powerpc bootwrapper. dtbImage.gamecube is a wrapped image that contains a flat device tree, an entry point compatible with SDload, and an optional initrd. Signed-off-by: Albert Herranz Acked-by: Segher Boessenkool Signed-off-by: Grant Likely diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 44bce21..3e70aab 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -76,7 +76,8 @@ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \ cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \ virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \ - cuboot-acadia.c cuboot-amigaone.c cuboot-kilauea.c + cuboot-acadia.c cuboot-amigaone.c cuboot-kilauea.c \ + gamecube-head.S gamecube.c src-boot := $(src-wlib) $(src-plat) empty.c src-boot := $(addprefix $(obj)/, $(src-boot)) @@ -254,6 +255,7 @@ image-$(CONFIG_KSI8560) += cuImage.ksi8560 image-$(CONFIG_STORCENTER) += cuImage.storcenter image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2 image-$(CONFIG_PPC_C2K) += cuImage.c2k +image-$(CONFIG_GAMECUBE) += dtbImage.gamecube # Board port in arch/powerpc/platform/amigaone/Kconfig image-$(CONFIG_AMIGAONE) += cuImage.amigaone diff --git a/arch/powerpc/boot/gamecube-head.S b/arch/powerpc/boot/gamecube-head.S new file mode 100644 index 0000000..65a9b2a --- /dev/null +++ b/arch/powerpc/boot/gamecube-head.S @@ -0,0 +1,111 @@ +/* + * arch/powerpc/boot/gamecube-head.S + * + * Nintendo GameCube bootwrapper entry. + * Copyright (C) 2004-2009 The GameCube Linux Team + * Copyright (C) 2008,2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ + +#include "ppc_asm.h" + +/* + * The entry code does no assumptions regarding: + * - if the data and instruction caches are enabled or not + * - if the MMU is enabled or not + * + * We enable the caches if not already enabled, enable the MMU with an + * identity mapping scheme and jump to the start code. + */ + + .text + + .globl _zimage_start +_zimage_start: + + /* turn the MMU off */ + mfmsr 9 + rlwinm 9, 9, 0, ~((1<<4)|(1<<5)) /* MSR_DR|MSR_IR */ + bcl 20, 31, 1f +1: + mflr 8 + clrlwi 8, 8, 3 /* convert to a real address */ + addi 8, 8, _mmu_off - 1b + mtsrr0 8 + mtsrr1 9 + rfi +_mmu_off: + /* MMU disabled */ + + /* setup BATs */ + isync + li 8, 0 + mtspr 0x210, 8 /* IBAT0U */ + mtspr 0x212, 8 /* IBAT1U */ + mtspr 0x214, 8 /* IBAT2U */ + mtspr 0x216, 8 /* IBAT3U */ + mtspr 0x218, 8 /* DBAT0U */ + mtspr 0x21a, 8 /* DBAT1U */ + mtspr 0x21c, 8 /* DBAT2U */ + mtspr 0x21e, 8 /* DBAT3U */ + + li 8, 0x01ff /* first 16MiB */ + li 9, 0x0002 /* rw */ + mtspr 0x211, 9 /* IBAT0L */ + mtspr 0x210, 8 /* IBAT0U */ + mtspr 0x219, 9 /* DBAT0L */ + mtspr 0x218, 8 /* DBAT0U */ + + lis 8, 0x0c00 /* I/O mem */ + ori 8, 8, 0x3ff /* 32MiB */ + lis 9, 0x0c00 + ori 9, 9, 0x002a /* uncached, guarded, rw */ + mtspr 0x21b, 9 /* DBAT1L */ + mtspr 0x21a, 8 /* DBAT1U */ + + lis 8, 0x0100 /* next 8MiB */ + ori 8, 8, 0x00ff /* 8MiB */ + lis 9, 0x0100 + ori 9, 9, 0x0002 /* rw */ + mtspr 0x215, 9 /* IBAT2L */ + mtspr 0x214, 8 /* IBAT2U */ + mtspr 0x21d, 9 /* DBAT2L */ + mtspr 0x21c, 8 /* DBAT2U */ + + /* enable and invalidate the caches if not already enabled */ + mfspr 8, 0x3f0 /* HID0 */ + andi. 0, 8, (1<<15) /* HID0_ICE */ + bne 1f + ori 8, 8, (1<<15)|(1<<11) /* HID0_ICE|HID0_ICFI*/ +1: + andi. 0, 8, (1<<14) /* HID0_DCE */ + bne 1f + ori 8, 8, (1<<14)|(1<<10) /* HID0_DCE|HID0_DCFI*/ +1: + mtspr 0x3f0, 8 /* HID0 */ + isync + + /* initialize arguments */ + li 3, 0 + li 4, 0 + li 5, 0 + + /* turn the MMU on */ + bcl 20, 31, 1f +1: + mflr 8 + addi 8, 8, _mmu_on - 1b + mfmsr 9 + ori 9, 9, (1<<4)|(1<<5) /* MSR_DR|MSR_IR */ + mtsrr0 8 + mtsrr1 9 + sync + rfi +_mmu_on: + b _zimage_start_lib + diff --git a/arch/powerpc/boot/gamecube.c b/arch/powerpc/boot/gamecube.c new file mode 100644 index 0000000..28ae705 --- /dev/null +++ b/arch/powerpc/boot/gamecube.c @@ -0,0 +1,35 @@ +/* + * arch/powerpc/boot/gamecube.c + * + * Nintendo GameCube bootwrapper support + * Copyright (C) 2004-2009 The GameCube Linux Team + * Copyright (C) 2008,2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ + +#include +#include "stdio.h" +#include "types.h" +#include "io.h" +#include "ops.h" + +#include "ugecon.h" + +BSS_STACK(8192); + +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5) +{ + u32 heapsize = 16*1024*1024 - (u32)_end; + + simple_alloc_init(_end, heapsize, 32, 64); + fdt_init(_dtb_start); + + if (ug_probe()) + console_ops.write = ug_console_write; +} + diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index ac9e9a5..5b9206f 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -230,6 +230,10 @@ xpedite52*) link_address='0x1400000' platformo=$object/cuboot-85xx.o ;; +gamecube) + link_address='0x600000' + platformo="$object/$platform-head.o $object/$platform.o" + ;; esac vmz="$tmpdir/`basename \"$kernel\"`.$ext" -- cgit v0.10.2 From bc161c7a670352222120cb104b0b280fe586fa30 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:37 +0000 Subject: powerpc: gamecube/wii: introduce GAMECUBE_COMMON Add a config option GAMECUBE_COMMON to be used as a dependency for all options common to the Nintendo GameCube and Wii video game consoles. Signed-off-by: Albert Herranz Acked-by: Grant Likely Signed-off-by: Grant Likely diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 291ac9d..97a2dbc 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -90,3 +90,7 @@ config MPC10X_OPENPIC config MPC10X_STORE_GATHERING bool "Enable MPC10x store gathering" depends on MPC10X_BRIDGE + +config GAMECUBE_COMMON + bool + -- cgit v0.10.2 From b91a143b1041d69dbadc0f694b8c9ab96659705e Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:38 +0000 Subject: powerpc: gamecube/wii: declare as non-coherent platforms The processors bundled in the Nintendo GameCube and Wii video game consoles require explicit cache handling when DMA engines are used. Signed-off-by: Albert Herranz Signed-off-by: Grant Likely diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index e382cae..80d934b 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -312,7 +312,7 @@ config NR_CPUS config NOT_COHERENT_CACHE bool - depends on 4xx || 8xx || E200 || PPC_MPC512x + depends on 4xx || 8xx || E200 || PPC_MPC512x || GAMECUBE_COMMON default y config CHECK_CACHE_COHERENCY -- cgit v0.10.2 From bcc48591f58a0e022edc7c641bf2b25a7c483c73 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:39 +0000 Subject: powerpc: gamecube/wii: do not include PCI support The Nintendo GameCube and Wii video game consoles do not have PCI hardware. Avoid wasting their scarce memory by not including PCI support into the kernel. Signed-off-by: Albert Herranz Acked-by: Grant Likely Signed-off-by: Grant Likely diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 2ba14e7..84b2566 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -679,7 +679,7 @@ config PPC_PCI_CHOICE config PCI bool "PCI support" if PPC_PCI_CHOICE default y if !40x && !CPM2 && !8xx && !PPC_83xx \ - && !PPC_85xx && !PPC_86xx + && !PPC_85xx && !PPC_86xx && !GAMECUBE_COMMON default PCI_PERMEDIA if !4xx && !CPM2 && !8xx default PCI_QSPAN if !4xx && !CPM2 && 8xx select ARCH_SUPPORTS_MSI -- cgit v0.10.2 From a166df08248cf78631507bb444ab72ba31cbef1e Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:40 +0000 Subject: powerpc: gamecube/wii: udbg support for usbgecko Add support for using the USB Gecko adapter via the udbg facility on the Nintendo GameCube and Wii video game consoles. The USB Gecko is a 3rd party memory card interface adapter that provides a EXI (External Interface) to USB serial converter. Signed-off-by: Albert Herranz Acked-by: Segher Boessenkool Signed-off-by: Grant Likely diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 97a2dbc..464e414 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -94,3 +94,16 @@ config MPC10X_STORE_GATHERING config GAMECUBE_COMMON bool +config USBGECKO_UDBG + bool "USB Gecko udbg console for the Nintendo GameCube/Wii" + depends on GAMECUBE_COMMON + help + If you say yes to this option, support will be included for the + USB Gecko adapter as an udbg console. + The USB Gecko is a EXI to USB Serial converter that can be plugged + into a memcard slot in the Nintendo GameCube/Wii. + + This driver bypasses the EXI layer completely. + + If in doubt, say N here. + diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile index 0773c08..0ab7492 100644 --- a/arch/powerpc/platforms/embedded6xx/Makefile +++ b/arch/powerpc/platforms/embedded6xx/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_STORCENTER) += storcenter.o obj-$(CONFIG_PPC_HOLLY) += holly.o obj-$(CONFIG_PPC_PRPMC2800) += prpmc2800.o obj-$(CONFIG_PPC_C2K) += c2k.o +obj-$(CONFIG_USBGECKO_UDBG) += usbgecko_udbg.o diff --git a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c new file mode 100644 index 0000000..ba4c7cc --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c @@ -0,0 +1,272 @@ +/* + * arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c + * + * udbg serial input/output routines for the USB Gecko adapter. + * Copyright (C) 2008-2009 The GameCube Linux Team + * Copyright (C) 2008,2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ + +#include + +#include +#include +#include + +#include "usbgecko_udbg.h" + + +#define EXI_CLK_32MHZ 5 + +#define EXI_CSR 0x00 +#define EXI_CSR_CLKMASK (0x7<<4) +#define EXI_CSR_CLK_32MHZ (EXI_CLK_32MHZ<<4) +#define EXI_CSR_CSMASK (0x7<<7) +#define EXI_CSR_CS_0 (0x1<<7) /* Chip Select 001 */ + +#define EXI_CR 0x0c +#define EXI_CR_TSTART (1<<0) +#define EXI_CR_WRITE (1<<2) +#define EXI_CR_READ_WRITE (2<<2) +#define EXI_CR_TLEN(len) (((len)-1)<<4) + +#define EXI_DATA 0x10 + +#define UG_READ_ATTEMPTS 100 +#define UG_WRITE_ATTEMPTS 100 + + +static void __iomem *ug_io_base; + +/* + * Performs one input/output transaction between the exi host and the usbgecko. + */ +static u32 ug_io_transaction(u32 in) +{ + u32 __iomem *csr_reg = ug_io_base + EXI_CSR; + u32 __iomem *data_reg = ug_io_base + EXI_DATA; + u32 __iomem *cr_reg = ug_io_base + EXI_CR; + u32 csr, data, cr; + + /* select */ + csr = EXI_CSR_CLK_32MHZ | EXI_CSR_CS_0; + out_be32(csr_reg, csr); + + /* read/write */ + data = in; + out_be32(data_reg, data); + cr = EXI_CR_TLEN(2) | EXI_CR_READ_WRITE | EXI_CR_TSTART; + out_be32(cr_reg, cr); + + while (in_be32(cr_reg) & EXI_CR_TSTART) + barrier(); + + /* deselect */ + out_be32(csr_reg, 0); + + /* result */ + data = in_be32(data_reg); + + return data; +} + +/* + * Returns true if an usbgecko adapter is found. + */ +static int ug_is_adapter_present(void) +{ + if (!ug_io_base) + return 0; + + return ug_io_transaction(0x90000000) == 0x04700000; +} + +/* + * Returns true if the TX fifo is ready for transmission. + */ +static int ug_is_txfifo_ready(void) +{ + return ug_io_transaction(0xc0000000) & 0x04000000; +} + +/* + * Tries to transmit a character. + * If the TX fifo is not ready the result is undefined. + */ +static void ug_raw_putc(char ch) +{ + ug_io_transaction(0xb0000000 | (ch << 20)); +} + +/* + * Transmits a character. + * It silently fails if the TX fifo is not ready after a number of retries. + */ +static void ug_putc(char ch) +{ + int count = UG_WRITE_ATTEMPTS; + + if (!ug_io_base) + return; + + if (ch == '\n') + ug_putc('\r'); + + while (!ug_is_txfifo_ready() && count--) + barrier(); + if (count) + ug_raw_putc(ch); +} + +/* + * Returns true if the RX fifo is ready for transmission. + */ +static int ug_is_rxfifo_ready(void) +{ + return ug_io_transaction(0xd0000000) & 0x04000000; +} + +/* + * Tries to receive a character. + * If a character is unavailable the function returns -1. + */ +static int ug_raw_getc(void) +{ + u32 data = ug_io_transaction(0xa0000000); + if (data & 0x08000000) + return (data >> 16) & 0xff; + else + return -1; +} + +/* + * Receives a character. + * It fails if the RX fifo is not ready after a number of retries. + */ +static int ug_getc(void) +{ + int count = UG_READ_ATTEMPTS; + + if (!ug_io_base) + return -1; + + while (!ug_is_rxfifo_ready() && count--) + barrier(); + return ug_raw_getc(); +} + +/* + * udbg functions. + * + */ + +/* + * Transmits a character. + */ +void ug_udbg_putc(char ch) +{ + ug_putc(ch); +} + +/* + * Receives a character. Waits until a character is available. + */ +static int ug_udbg_getc(void) +{ + int ch; + + while ((ch = ug_getc()) == -1) + barrier(); + return ch; +} + +/* + * Receives a character. If a character is not available, returns -1. + */ +static int ug_udbg_getc_poll(void) +{ + if (!ug_is_rxfifo_ready()) + return -1; + return ug_getc(); +} + +/* + * Retrieves and prepares the virtual address needed to access the hardware. + */ +static void __iomem *ug_udbg_setup_exi_io_base(struct device_node *np) +{ + void __iomem *exi_io_base = NULL; + phys_addr_t paddr; + const unsigned int *reg; + + reg = of_get_property(np, "reg", NULL); + if (reg) { + paddr = of_translate_address(np, reg); + if (paddr) + exi_io_base = ioremap(paddr, reg[1]); + } + return exi_io_base; +} + +/* + * Checks if a USB Gecko adapter is inserted in any memory card slot. + */ +static void __iomem *ug_udbg_probe(void __iomem *exi_io_base) +{ + int i; + + /* look for a usbgecko on memcard slots A and B */ + for (i = 0; i < 2; i++) { + ug_io_base = exi_io_base + 0x14 * i; + if (ug_is_adapter_present()) + break; + } + if (i == 2) + ug_io_base = NULL; + return ug_io_base; + +} + +/* + * USB Gecko udbg support initialization. + */ +void __init ug_udbg_init(void) +{ + struct device_node *np; + void __iomem *exi_io_base; + + if (ug_io_base) + udbg_printf("%s: early -> final\n", __func__); + + np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-exi"); + if (!np) { + udbg_printf("%s: EXI node not found\n", __func__); + goto done; + } + + exi_io_base = ug_udbg_setup_exi_io_base(np); + if (!exi_io_base) { + udbg_printf("%s: failed to setup EXI io base\n", __func__); + goto done; + } + + if (!ug_udbg_probe(exi_io_base)) { + udbg_printf("usbgecko_udbg: not found\n"); + iounmap(exi_io_base); + } else { + udbg_putc = ug_udbg_putc; + udbg_getc = ug_udbg_getc; + udbg_getc_poll = ug_udbg_getc_poll; + udbg_printf("usbgecko_udbg: ready\n"); + } + +done: + if (np) + of_node_put(np); + return; +} diff --git a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h new file mode 100644 index 0000000..3929de3 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h @@ -0,0 +1,30 @@ +/* + * arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h + * + * udbg serial input/output routines for the USB Gecko adapter. + * Copyright (C) 2008-2009 The GameCube Linux Team + * Copyright (C) 2008,2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ + +#ifndef __USBGECKO_UDBG_H +#define __USBGECKO_UDBG_H + +#ifdef CONFIG_USBGECKO_UDBG + +extern void __init ug_udbg_init(void); + +#else + +static inline void __init ug_udbg_init(void) +{ +} + +#endif /* CONFIG_USBGECKO_UDBG */ + +#endif /* __USBGECKO_UDBG_H */ -- cgit v0.10.2 From 028ee972f032b636b5776b779c0f085ba9cfd30f Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:41 +0000 Subject: powerpc: gamecube/wii: flipper interrupt controller support Add support for the interrupt controller included in the "Flipper" chipset of the Nintendo GameCube video game console. The same interrupt controller is also present in the "Hollywood" chipset of the Nintendo Wii. Signed-off-by: Albert Herranz Acked-by: Segher Boessenkool Signed-off-by: Grant Likely diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile index 0ab7492..b80f47c 100644 --- a/arch/powerpc/platforms/embedded6xx/Makefile +++ b/arch/powerpc/platforms/embedded6xx/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_PPC_HOLLY) += holly.o obj-$(CONFIG_PPC_PRPMC2800) += prpmc2800.o obj-$(CONFIG_PPC_C2K) += c2k.o obj-$(CONFIG_USBGECKO_UDBG) += usbgecko_udbg.o +obj-$(CONFIG_GAMECUBE_COMMON) += flipper-pic.o diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c new file mode 100644 index 0000000..d596328 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c @@ -0,0 +1,263 @@ +/* + * arch/powerpc/platforms/embedded6xx/flipper-pic.c + * + * Nintendo GameCube/Wii "Flipper" interrupt controller support. + * Copyright (C) 2004-2009 The GameCube Linux Team + * Copyright (C) 2007,2008,2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ +#define DRV_MODULE_NAME "flipper-pic" +#define pr_fmt(fmt) DRV_MODULE_NAME ": " fmt + +#include +#include +#include +#include +#include + +#include "flipper-pic.h" + +#define FLIPPER_NR_IRQS 32 + +/* + * Each interrupt has a corresponding bit in both + * the Interrupt Cause (ICR) and Interrupt Mask (IMR) registers. + * + * Enabling/disabling an interrupt line involves setting/clearing + * the corresponding bit in IMR. + * Except for the RSW interrupt, all interrupts get deasserted automatically + * when the source deasserts the interrupt. + */ +#define FLIPPER_ICR 0x00 +#define FLIPPER_ICR_RSS (1<<16) /* reset switch state */ + +#define FLIPPER_IMR 0x04 + +#define FLIPPER_RESET 0x24 + + +/* + * IRQ chip hooks. + * + */ + +static void flipper_pic_mask_and_ack(unsigned int virq) +{ + int irq = virq_to_hw(virq); + void __iomem *io_base = get_irq_chip_data(virq); + u32 mask = 1 << irq; + + clrbits32(io_base + FLIPPER_IMR, mask); + /* this is at least needed for RSW */ + out_be32(io_base + FLIPPER_ICR, mask); +} + +static void flipper_pic_ack(unsigned int virq) +{ + int irq = virq_to_hw(virq); + void __iomem *io_base = get_irq_chip_data(virq); + + /* this is at least needed for RSW */ + out_be32(io_base + FLIPPER_ICR, 1 << irq); +} + +static void flipper_pic_mask(unsigned int virq) +{ + int irq = virq_to_hw(virq); + void __iomem *io_base = get_irq_chip_data(virq); + + clrbits32(io_base + FLIPPER_IMR, 1 << irq); +} + +static void flipper_pic_unmask(unsigned int virq) +{ + int irq = virq_to_hw(virq); + void __iomem *io_base = get_irq_chip_data(virq); + + setbits32(io_base + FLIPPER_IMR, 1 << irq); +} + + +static struct irq_chip flipper_pic = { + .name = "flipper-pic", + .ack = flipper_pic_ack, + .mask_ack = flipper_pic_mask_and_ack, + .mask = flipper_pic_mask, + .unmask = flipper_pic_unmask, +}; + +/* + * IRQ host hooks. + * + */ + +static struct irq_host *flipper_irq_host; + +static int flipper_pic_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hwirq) +{ + set_irq_chip_data(virq, h->host_data); + get_irq_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &flipper_pic, handle_level_irq); + return 0; +} + +static void flipper_pic_unmap(struct irq_host *h, unsigned int irq) +{ + set_irq_chip_data(irq, NULL); + set_irq_chip(irq, NULL); +} + +static int flipper_pic_match(struct irq_host *h, struct device_node *np) +{ + return 1; +} + + +static struct irq_host_ops flipper_irq_host_ops = { + .map = flipper_pic_map, + .unmap = flipper_pic_unmap, + .match = flipper_pic_match, +}; + +/* + * Platform hooks. + * + */ + +static void __flipper_quiesce(void __iomem *io_base) +{ + /* mask and ack all IRQs */ + out_be32(io_base + FLIPPER_IMR, 0x00000000); + out_be32(io_base + FLIPPER_ICR, 0xffffffff); +} + +struct irq_host * __init flipper_pic_init(struct device_node *np) +{ + struct device_node *pi; + struct irq_host *irq_host = NULL; + struct resource res; + void __iomem *io_base; + int retval; + + pi = of_get_parent(np); + if (!pi) { + pr_err("no parent found\n"); + goto out; + } + if (!of_device_is_compatible(pi, "nintendo,flipper-pi")) { + pr_err("unexpected parent compatible\n"); + goto out; + } + + retval = of_address_to_resource(pi, 0, &res); + if (retval) { + pr_err("no io memory range found\n"); + goto out; + } + io_base = ioremap(res.start, resource_size(&res)); + + pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base); + + __flipper_quiesce(io_base); + + irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, FLIPPER_NR_IRQS, + &flipper_irq_host_ops, -1); + if (!irq_host) { + pr_err("failed to allocate irq_host\n"); + return NULL; + } + + irq_host->host_data = io_base; + +out: + return irq_host; +} + +unsigned int flipper_pic_get_irq(void) +{ + void __iomem *io_base = flipper_irq_host->host_data; + int irq; + u32 irq_status; + + irq_status = in_be32(io_base + FLIPPER_ICR) & + in_be32(io_base + FLIPPER_IMR); + if (irq_status == 0) + return NO_IRQ; /* no more IRQs pending */ + + irq = __ffs(irq_status); + return irq_linear_revmap(flipper_irq_host, irq); +} + +/* + * Probe function. + * + */ + +void __init flipper_pic_probe(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-pic"); + BUG_ON(!np); + + flipper_irq_host = flipper_pic_init(np); + BUG_ON(!flipper_irq_host); + + irq_set_default_host(flipper_irq_host); + + of_node_put(np); +} + +/* + * Misc functions related to the flipper chipset. + * + */ + +/** + * flipper_quiesce() - quiesce flipper irq controller + * + * Mask and ack all interrupt sources. + * + */ +void flipper_quiesce(void) +{ + void __iomem *io_base = flipper_irq_host->host_data; + + __flipper_quiesce(io_base); +} + +/* + * Resets the platform. + */ +void flipper_platform_reset(void) +{ + void __iomem *io_base; + + if (flipper_irq_host && flipper_irq_host->host_data) { + io_base = flipper_irq_host->host_data; + out_8(io_base + FLIPPER_RESET, 0x00); + } +} + +/* + * Returns non-zero if the reset button is pressed. + */ +int flipper_is_reset_button_pressed(void) +{ + void __iomem *io_base; + u32 icr; + + if (flipper_irq_host && flipper_irq_host->host_data) { + io_base = flipper_irq_host->host_data; + icr = in_be32(io_base + FLIPPER_ICR); + return !(icr & FLIPPER_ICR_RSS); + } + return 0; +} + diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.h b/arch/powerpc/platforms/embedded6xx/flipper-pic.h new file mode 100644 index 0000000..e339186 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.h @@ -0,0 +1,25 @@ +/* + * arch/powerpc/platforms/embedded6xx/flipper-pic.h + * + * Nintendo GameCube/Wii "Flipper" interrupt controller support. + * Copyright (C) 2004-2009 The GameCube Linux Team + * Copyright (C) 2007,2008,2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ + +#ifndef __FLIPPER_PIC_H +#define __FLIPPER_PIC_H + +unsigned int flipper_pic_get_irq(void); +void __init flipper_pic_probe(void); + +void flipper_quiesce(void); +void flipper_platform_reset(void); +int flipper_is_reset_button_pressed(void); + +#endif -- cgit v0.10.2 From e90d71d0f52fb3d619b96ba92b7614fed7cb819e Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:42 +0000 Subject: powerpc: gamecube: platform support Add platform support for the Nintendo GameCube video game console. Signed-off-by: Albert Herranz Signed-off-by: Grant Likely diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 464e414..e318ced 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -107,3 +107,11 @@ config USBGECKO_UDBG If in doubt, say N here. +config GAMECUBE + bool "Nintendo-GameCube" + depends on EMBEDDED6xx + select GAMECUBE_COMMON + help + Select GAMECUBE if configuring for the Nintendo GameCube. + More information at: + diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile index b80f47c..9365edd 100644 --- a/arch/powerpc/platforms/embedded6xx/Makefile +++ b/arch/powerpc/platforms/embedded6xx/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_PPC_PRPMC2800) += prpmc2800.o obj-$(CONFIG_PPC_C2K) += c2k.o obj-$(CONFIG_USBGECKO_UDBG) += usbgecko_udbg.o obj-$(CONFIG_GAMECUBE_COMMON) += flipper-pic.o +obj-$(CONFIG_GAMECUBE) += gamecube.o diff --git a/arch/powerpc/platforms/embedded6xx/gamecube.c b/arch/powerpc/platforms/embedded6xx/gamecube.c new file mode 100644 index 0000000..1106fd9 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/gamecube.c @@ -0,0 +1,118 @@ +/* + * arch/powerpc/platforms/embedded6xx/gamecube.c + * + * Nintendo GameCube board-specific support + * Copyright (C) 2004-2009 The GameCube Linux Team + * Copyright (C) 2007,2008,2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "flipper-pic.h" +#include "usbgecko_udbg.h" + + +static void gamecube_spin(void) +{ + /* spin until power button pressed */ + for (;;) + cpu_relax(); +} + +static void gamecube_restart(char *cmd) +{ + local_irq_disable(); + flipper_platform_reset(); + gamecube_spin(); +} + +static void gamecube_power_off(void) +{ + local_irq_disable(); + gamecube_spin(); +} + +static void gamecube_halt(void) +{ + gamecube_restart(NULL); +} + +static void __init gamecube_init_early(void) +{ + ug_udbg_init(); +} + +static int __init gamecube_probe(void) +{ + unsigned long dt_root; + + dt_root = of_get_flat_dt_root(); + if (!of_flat_dt_is_compatible(dt_root, "nintendo,gamecube")) + return 0; + + return 1; +} + +static void gamecube_shutdown(void) +{ + flipper_quiesce(); +} + +#ifdef CONFIG_KEXEC +static int gamecube_kexec_prepare(struct kimage *image) +{ + return 0; +} +#endif /* CONFIG_KEXEC */ + + +define_machine(gamecube) { + .name = "gamecube", + .probe = gamecube_probe, + .init_early = gamecube_init_early, + .restart = gamecube_restart, + .power_off = gamecube_power_off, + .halt = gamecube_halt, + .init_IRQ = flipper_pic_probe, + .get_irq = flipper_pic_get_irq, + .calibrate_decr = generic_calibrate_decr, + .progress = udbg_progress, + .machine_shutdown = gamecube_shutdown, +#ifdef CONFIG_KEXEC + .machine_kexec_prepare = gamecube_kexec_prepare, +#endif +}; + + +static struct of_device_id gamecube_of_bus[] = { + { .compatible = "nintendo,flipper", }, + { }, +}; + +static int __init gamecube_device_probe(void) +{ + if (!machine_is(gamecube)) + return 0; + + of_platform_bus_probe(NULL, gamecube_of_bus, NULL); + return 0; +} +device_initcall(gamecube_device_probe); + -- cgit v0.10.2 From 86c3d131ce72a8ea82107c1113e30fc97583f8dd Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:43 +0000 Subject: powerpc: gamecube: default config Add a default configuration for the Nintendo GameCube video game console. Signed-off-by: Albert Herranz Signed-off-by: Grant Likely diff --git a/arch/powerpc/configs/gamecube_defconfig b/arch/powerpc/configs/gamecube_defconfig new file mode 100644 index 0000000..942e119 --- /dev/null +++ b/arch/powerpc/configs/gamecube_defconfig @@ -0,0 +1,1061 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.32-rc8 +# Sun Nov 22 21:07:30 2009 +# +# CONFIG_PPC64 is not set + +# +# Processor support +# +CONFIG_PPC_BOOK3S_32=y +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_8xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_E200 is not set +CONFIG_PPC_BOOK3S=y +CONFIG_6xx=y +CONFIG_PPC_FPU=y +# CONFIG_ALTIVEC is not set +CONFIG_PPC_STD_MMU=y +CONFIG_PPC_STD_MMU_32=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_PPC_HAVE_PMU_SUPPORT=y +CONFIG_PPC_PERF_CTRS=y +# CONFIG_SMP is not set +CONFIG_NOT_COHERENT_CACHE=y +CONFIG_PPC32=y +CONFIG_WORD_SIZE=32 +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_MMU=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set +# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set +CONFIG_IRQ_PER_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_ILOG2_U32=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +# CONFIG_ARCH_NO_VIRT_TO_BUS is not set +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_OF=y +# CONFIG_PPC_UDBG_16550 is not set +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_BUG=y +CONFIG_DTC=y +# CONFIG_DEFAULT_UIMAGE is not set +# CONFIG_PPC_DCR_NATIVE is not set +# CONFIG_PPC_DCR_MMIO is not set +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="-gcn" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +CONFIG_EVENT_PROFILE=y +CONFIG_PERF_COUNTERS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +# CONFIG_VM_EVENT_COUNTERS is not set +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_TRACEPOINTS=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_API_DEBUG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +# CONFIG_FREEZER is not set + +# +# Platform support +# +# CONFIG_PPC_CHRP is not set +# CONFIG_MPC5121_ADS is not set +# CONFIG_MPC5121_GENERIC is not set +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_PMAC is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PPC_82xx is not set +# CONFIG_PQ2ADS is not set +# CONFIG_PPC_83xx is not set +# CONFIG_PPC_86xx is not set +CONFIG_EMBEDDED6xx=y +# CONFIG_LINKSTATION is not set +# CONFIG_STORCENTER is not set +# CONFIG_MPC7448HPC2 is not set +# CONFIG_PPC_HOLLY is not set +# CONFIG_PPC_PRPMC2800 is not set +# CONFIG_PPC_C2K is not set +CONFIG_GAMECUBE_COMMON=y +CONFIG_USBGECKO_UDBG=y +CONFIG_FLIPPER_PIC=y +CONFIG_GAMECUBE=y +# CONFIG_WII is not set +# CONFIG_AMIGAONE is not set +# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set +# CONFIG_IPIC is not set +# CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_TAU is not set +# CONFIG_FSL_ULI1575 is not set +# CONFIG_SIMPLE_GPIO is not set + +# +# Kernel options +# +# CONFIG_HIGHMEM is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_BINFMT_ELF=y +# CONFIG_HAVE_AOUT is not set +CONFIG_BINFMT_MISC=m +# CONFIG_IOMMU_HELPER is not set +# CONFIG_SWIOTLB is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_KEXEC=y +# CONFIG_CRASH_DUMP is not set +CONFIG_MAX_ACTIVE_REGIONS=32 +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_MIGRATION is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_PPC_4K_PAGES=y +# CONFIG_PPC_16K_PAGES is not set +# CONFIG_PPC_64K_PAGES is not set +# CONFIG_PPC_256K_PAGES is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +CONFIG_EXTRA_TARGETS="" +# CONFIG_PM is not set +# CONFIG_SECCOMP is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_ZONE_DMA=y +CONFIG_GENERIC_ISA_DMA=y +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set +# CONFIG_HAS_RAPIDIO is not set + +# +# Advanced setup +# +CONFIG_ADVANCED_OPTIONS=y +# CONFIG_LOWMEM_SIZE_BOOL is not set +CONFIG_LOWMEM_SIZE=0x30000000 +# CONFIG_PAGE_OFFSET_BOOL is not set +CONFIG_PAGE_OFFSET=0xc0000000 +# CONFIG_KERNEL_START_BOOL is not set +CONFIG_KERNEL_START=0xc0000000 +CONFIG_PHYSICAL_START=0x00000000 +# CONFIG_TASK_SIZE_BOOL is not set +CONFIG_TASK_SIZE=0xc0000000 +# CONFIG_CONSISTENT_SIZE_BOOL is not set +CONFIG_CONSISTENT_SIZE=0x00200000 +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +CONFIG_OF_DEVICE=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=2 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_ETHOC is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_XILINX_EMACLITE is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT_JOYDEV=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_XILINX_XPS_PS2 is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_DEVKMEM is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=64 +# CONFIG_HVC_UDBG is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +# CONFIG_GPIOLIB is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_OF is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_SEQUENCER=y +# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_PPC=y +# CONFIG_SND_SOC is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set +# CONFIG_HID_PID is not set + +# +# Special HID drivers +# +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_EDAC is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_GENERIC=y +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +# CONFIG_PROC_PAGE_MONITOR is not set +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +CONFIG_CIFS=y +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_HAVE_LMB=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +# CONFIG_DETECT_HUNG_TASK is not set +CONFIG_SCHED_DEBUG=y +CONFIG_SCHEDSTATS=y +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_LATENCYTOP=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACER_MAX_TRACE=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +CONFIG_SCHED_TRACER=y +CONFIG_BOOT_TRACER=y +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set +CONFIG_DMA_API_DEBUG=y +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_PPC_DISABLE_WERROR is not set +CONFIG_PPC_WERROR=y +CONFIG_PRINT_STACK_DEPTH=64 +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_PPC_EMULATED_STATS is not set +# CONFIG_CODE_PATCHING_SELFTEST is not set +# CONFIG_FTR_FIXUP_SELFTEST is not set +# CONFIG_MSI_BITMAP_SELFTEST is not set +# CONFIG_XMON is not set +# CONFIG_IRQSTACKS is not set +# CONFIG_VIRQ_DEBUG is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_BOOTX_TEXT is not set +CONFIG_PPC_EARLY_DEBUG=y +# CONFIG_PPC_EARLY_DEBUG_LPAR is not set +# CONFIG_PPC_EARLY_DEBUG_G5 is not set +# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set +# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set +# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set +# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set +# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set +# CONFIG_PPC_EARLY_DEBUG_BEAT is not set +# CONFIG_PPC_EARLY_DEBUG_44x is not set +# CONFIG_PPC_EARLY_DEBUG_40x is not set +# CONFIG_PPC_EARLY_DEBUG_CPM is not set +CONFIG_PPC_EARLY_DEBUG_USBGECKO=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set +# CONFIG_PPC_CLOCK is not set +# CONFIG_VIRTUALIZATION is not set -- cgit v0.10.2 From 7a09116c016611effe7037c8346c5f42a7416718 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:44 +0000 Subject: powerpc: wii: device tree Add a device tree source file for the Nintendo Wii video game console. Signed-off-by: Albert Herranz Acked-by: Segher Boessenkool Acked-by: Benjamin Herrenschmidt Signed-off-by: Grant Likely diff --git a/Documentation/powerpc/dts-bindings/nintendo/wii.txt b/Documentation/powerpc/dts-bindings/nintendo/wii.txt new file mode 100644 index 0000000..a7e155a --- /dev/null +++ b/Documentation/powerpc/dts-bindings/nintendo/wii.txt @@ -0,0 +1,184 @@ + +Nintendo Wii device tree +======================== + +0) The root node + + This node represents the Nintendo Wii video game console. + + Required properties: + + - model : Should be "nintendo,wii" + - compatible : Should be "nintendo,wii" + +1) The "hollywood" node + + This node represents the multi-function "Hollywood" chip, which packages + many of the devices found in the Nintendo Wii. + + Required properties: + + - compatible : Should be "nintendo,hollywood" + +1.a) The Video Interface (VI) node + + Represents the interface between the graphics processor and a external + video encoder. + + Required properties: + + - compatible : should be "nintendo,hollywood-vi","nintendo,flipper-vi" + - reg : should contain the VI registers location and length + - interrupts : should contain the VI interrupt + +1.b) The Processor Interface (PI) node + + Represents the data and control interface between the main processor + and graphics and audio processor. + + Required properties: + + - compatible : should be "nintendo,hollywood-pi","nintendo,flipper-pi" + - reg : should contain the PI registers location and length + +1.b.i) The "Flipper" interrupt controller node + + Represents the "Flipper" interrupt controller within the "Hollywood" chip. + The node for the "Flipper" interrupt controller must be placed under + the PI node. + + Required properties: + + - #interrupt-cells : <1> + - compatible : should be "nintendo,flipper-pic" + - interrupt-controller + +1.c) The Digital Signal Procesor (DSP) node + + Represents the digital signal processor interface, designed to offload + audio related tasks. + + Required properties: + + - compatible : should be "nintendo,hollywood-dsp","nintendo,flipper-dsp" + - reg : should contain the DSP registers location and length + - interrupts : should contain the DSP interrupt + +1.d) The Serial Interface (SI) node + + Represents the interface to the four single bit serial interfaces. + The SI is a proprietary serial interface used normally to control gamepads. + It's NOT a RS232-type interface. + + Required properties: + + - compatible : should be "nintendo,hollywood-si","nintendo,flipper-si" + - reg : should contain the SI registers location and length + - interrupts : should contain the SI interrupt + +1.e) The Audio Interface (AI) node + + Represents the interface to the external 16-bit stereo digital-to-analog + converter. + + Required properties: + + - compatible : should be "nintendo,hollywood-ai","nintendo,flipper-ai" + - reg : should contain the AI registers location and length + - interrupts : should contain the AI interrupt + +1.f) The External Interface (EXI) node + + Represents the multi-channel SPI-like interface. + + Required properties: + + - compatible : should be "nintendo,hollywood-exi","nintendo,flipper-exi" + - reg : should contain the EXI registers location and length + - interrupts : should contain the EXI interrupt + +1.g) The Open Host Controller Interface (OHCI) nodes + + Represent the USB 1.x Open Host Controller Interfaces. + + Required properties: + + - compatible : should be "nintendo,hollywood-usb-ohci","usb-ohci" + - reg : should contain the OHCI registers location and length + - interrupts : should contain the OHCI interrupt + +1.h) The Enhanced Host Controller Interface (EHCI) node + + Represents the USB 2.0 Enhanced Host Controller Interface. + + Required properties: + + - compatible : should be "nintendo,hollywood-usb-ehci","usb-ehci" + - reg : should contain the EHCI registers location and length + - interrupts : should contain the EHCI interrupt + +1.i) The Secure Digital Host Controller Interface (SDHCI) nodes + + Represent the Secure Digital Host Controller Interfaces. + + Required properties: + + - compatible : should be "nintendo,hollywood-sdhci","sdhci" + - reg : should contain the SDHCI registers location and length + - interrupts : should contain the SDHCI interrupt + +1.j) The Inter-Processsor Communication (IPC) node + + Represent the Inter-Processor Communication interface. This interface + enables communications between the Broadway and the Starlet processors. + + - compatible : should be "nintendo,hollywood-ipc" + - reg : should contain the IPC registers location and length + - interrupts : should contain the IPC interrupt + +1.k) The "Hollywood" interrupt controller node + + Represents the "Hollywood" interrupt controller within the + "Hollywood" chip. + + Required properties: + + - #interrupt-cells : <1> + - compatible : should be "nintendo,hollywood-pic" + - reg : should contain the controller registers location and length + - interrupt-controller + - interrupts : should contain the cascade interrupt of the "flipper" pic + - interrupt-parent: should contain the phandle of the "flipper" pic + +1.l) The General Purpose I/O (GPIO) controller node + + Represents the dual access 32 GPIO controller interface. + + Required properties: + + - #gpio-cells : <2> + - compatible : should be "nintendo,hollywood-gpio" + - reg : should contain the IPC registers location and length + - gpio-controller + +1.m) The control node + + Represents the control interface used to setup several miscellaneous + settings of the "Hollywood" chip like boot memory mappings, resets, + disk interface mode, etc. + + Required properties: + + - compatible : should be "nintendo,hollywood-control" + - reg : should contain the control registers location and length + +1.n) The Disk Interface (DI) node + + Represents the interface used to communicate with mass storage devices. + + Required properties: + + - compatible : should be "nintendo,hollywood-di" + - reg : should contain the DI registers location and length + - interrupts : should contain the DI interrupt + diff --git a/arch/powerpc/boot/dts/wii.dts b/arch/powerpc/boot/dts/wii.dts new file mode 100644 index 0000000..77528c9 --- /dev/null +++ b/arch/powerpc/boot/dts/wii.dts @@ -0,0 +1,218 @@ +/* + * arch/powerpc/boot/dts/wii.dts + * + * Nintendo Wii platform device tree source + * Copyright (C) 2008-2009 The GameCube Linux Team + * Copyright (C) 2008,2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ + +/dts-v1/; + +/* + * This is commented-out for now. + * Until a later patch is merged, the kernel can use only the first + * contiguous RAM range and will BUG() if the memreserve is outside + * that range. + */ +/*/memreserve/ 0x10000000 0x0004000;*/ /* DSP RAM */ + +/ { + model = "nintendo,wii"; + compatible = "nintendo,wii"; + #address-cells = <1>; + #size-cells = <1>; + + chosen { + bootargs = "root=/dev/mmcblk0p2 rootwait udbg-immortal"; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x01800000 /* MEM1 24MB 1T-SRAM */ + 0x10000000 0x04000000>; /* MEM2 64MB GDDR3 */ + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,broadway@0 { + device_type = "cpu"; + reg = <0>; + clock-frequency = <729000000>; /* 729MHz */ + bus-frequency = <243000000>; /* 243MHz core-to-bus 3x */ + timebase-frequency = <60750000>; /* 243MHz / 4 */ + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; + }; + }; + + /* devices contained in the hollywood chipset */ + hollywood { + #address-cells = <1>; + #size-cells = <1>; + compatible = "nintendo,hollywood"; + ranges = <0x0c000000 0x0c000000 0x01000000 + 0x0d000000 0x0d000000 0x00800000 + 0x0d800000 0x0d800000 0x00800000>; + interrupt-parent = <&PIC0>; + + video@0c002000 { + compatible = "nintendo,hollywood-vi", + "nintendo,flipper-vi"; + reg = <0x0c002000 0x100>; + interrupts = <8>; + }; + + processor-interface@0c003000 { + compatible = "nintendo,hollywood-pi", + "nintendo,flipper-pi"; + reg = <0x0c003000 0x100>; + + PIC0: pic0 { + #interrupt-cells = <1>; + compatible = "nintendo,flipper-pic"; + interrupt-controller; + }; + }; + + dsp@0c005000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "nintendo,hollywood-dsp", + "nintendo,flipper-dsp"; + reg = <0x0c005000 0x200>; + interrupts = <6>; + }; + + gamepad-controller@0d006400 { + compatible = "nintendo,hollywood-si", + "nintendo,flipper-si"; + reg = <0x0d006400 0x100>; + interrupts = <3>; + }; + + audio@0c006c00 { + compatible = "nintendo,hollywood-ai", + "nintendo,flipper-ai"; + reg = <0x0d006c00 0x20>; + interrupts = <6>; + }; + + /* External Interface bus */ + exi@0d006800 { + compatible = "nintendo,hollywood-exi", + "nintendo,flipper-exi"; + reg = <0x0d006800 0x40>; + virtual-reg = <0x0d006800>; + interrupts = <4>; + }; + + usb@0d040000 { + compatible = "nintendo,hollywood-usb-ehci", + "usb-ehci"; + reg = <0x0d040000 0x100>; + interrupts = <4>; + interrupt-parent = <&PIC1>; + }; + + usb@0d050000 { + compatible = "nintendo,hollywood-usb-ohci", + "usb-ohci"; + reg = <0x0d050000 0x100>; + interrupts = <5>; + interrupt-parent = <&PIC1>; + }; + + usb@0d060000 { + compatible = "nintendo,hollywood-usb-ohci", + "usb-ohci"; + reg = <0x0d060000 0x100>; + interrupts = <6>; + interrupt-parent = <&PIC1>; + }; + + sd@0d070000 { + compatible = "nintendo,hollywood-sdhci", + "sdhci"; + reg = <0x0d070000 0x200>; + interrupts = <7>; + interrupt-parent = <&PIC1>; + }; + + sdio@0d080000 { + compatible = "nintendo,hollywood-sdhci", + "sdhci"; + reg = <0x0d080000 0x200>; + interrupts = <8>; + interrupt-parent = <&PIC1>; + }; + + ipc@0d000000 { + compatible = "nintendo,hollywood-ipc"; + reg = <0x0d000000 0x10>; + interrupts = <30>; + interrupt-parent = <&PIC1>; + }; + + PIC1: pic1@0d800030 { + #interrupt-cells = <1>; + compatible = "nintendo,hollywood-pic"; + reg = <0x0d800030 0x10>; + interrupt-controller; + interrupts = <14>; + }; + + GPIO: gpio@0d8000c0 { + #gpio-cells = <2>; + compatible = "nintendo,hollywood-gpio"; + reg = <0x0d8000c0 0x40>; + gpio-controller; + + /* + * This is commented out while a standard binding + * for i2c over gpio is defined. + */ + /* + i2c-video { + #address-cells = <1>; + #size-cells = <0>; + compatible = "i2c-gpio"; + + gpios = <&GPIO 15 0 + &GPIO 14 0>; + clock-frequency = <250000>; + no-clock-stretching; + scl-is-open-drain; + sda-is-open-drain; + sda-enforce-dir; + + AVE: audio-video-encoder@70 { + compatible = "nintendo,wii-audio-video-encoder"; + reg = <0x70>; + }; + }; + */ + }; + + control@0d800100 { + compatible = "nintendo,hollywood-control"; + reg = <0x0d800100 0x300>; + }; + + disk@0d806000 { + compatible = "nintendo,hollywood-di"; + reg = <0x0d806000 0x40>; + interrupts = <2>; + }; + }; +}; + -- cgit v0.10.2 From 6cdd24179d31b5e9beaea01f8ac5a1ba77415e33 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:45 +0000 Subject: powerpc: wii: bootwrapper bits Add support for the Nintendo Wii video game console to the powerpc bootwrapper. dtbImage.wii is a wrapped image that contains a flat device tree, an entry point compatible with the Homebrew Channel and BootMii, and an optional initrd. Signed-off-by: Albert Herranz Acked-by: Segher Boessenkool Acked-by: Benjamin Herrenschmidt Signed-off-by: Grant Likely diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 3e70aab..bb2465b 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -77,7 +77,7 @@ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \ virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \ cuboot-acadia.c cuboot-amigaone.c cuboot-kilauea.c \ - gamecube-head.S gamecube.c + gamecube-head.S gamecube.c wii-head.S wii.c src-boot := $(src-wlib) $(src-plat) empty.c src-boot := $(addprefix $(obj)/, $(src-boot)) @@ -256,6 +256,7 @@ image-$(CONFIG_STORCENTER) += cuImage.storcenter image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2 image-$(CONFIG_PPC_C2K) += cuImage.c2k image-$(CONFIG_GAMECUBE) += dtbImage.gamecube +image-$(CONFIG_WII) += dtbImage.wii # Board port in arch/powerpc/platform/amigaone/Kconfig image-$(CONFIG_AMIGAONE) += cuImage.amigaone diff --git a/arch/powerpc/boot/wii-head.S b/arch/powerpc/boot/wii-head.S new file mode 100644 index 0000000..edd79b8 --- /dev/null +++ b/arch/powerpc/boot/wii-head.S @@ -0,0 +1,142 @@ +/* + * arch/powerpc/boot/wii-head.S + * + * Nintendo Wii bootwrapper entry. + * Copyright (C) 2008-2009 The GameCube Linux Team + * Copyright (C) 2008,2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ + +#include "ppc_asm.h" + +/* + * The entry code does no assumptions regarding: + * - if the data and instruction caches are enabled or not + * - if the MMU is enabled or not + * - if the high BATs are enabled or not + * + * We enable the high BATs, enable the caches if not already enabled, + * enable the MMU with an identity mapping scheme and jump to the start code. + */ + + .text + + .globl _zimage_start +_zimage_start: + + /* turn the MMU off */ + mfmsr 9 + rlwinm 9, 9, 0, ~((1<<4)|(1<<5)) /* MSR_DR|MSR_IR */ + bcl 20, 31, 1f +1: + mflr 8 + clrlwi 8, 8, 3 /* convert to a real address */ + addi 8, 8, _mmu_off - 1b + mtsrr0 8 + mtsrr1 9 + rfi +_mmu_off: + /* MMU disabled */ + + /* setup BATs */ + isync + li 8, 0 + mtspr 0x210, 8 /* IBAT0U */ + mtspr 0x212, 8 /* IBAT1U */ + mtspr 0x214, 8 /* IBAT2U */ + mtspr 0x216, 8 /* IBAT3U */ + mtspr 0x218, 8 /* DBAT0U */ + mtspr 0x21a, 8 /* DBAT1U */ + mtspr 0x21c, 8 /* DBAT2U */ + mtspr 0x21e, 8 /* DBAT3U */ + + mtspr 0x230, 8 /* IBAT4U */ + mtspr 0x232, 8 /* IBAT5U */ + mtspr 0x234, 8 /* IBAT6U */ + mtspr 0x236, 8 /* IBAT7U */ + mtspr 0x238, 8 /* DBAT4U */ + mtspr 0x23a, 8 /* DBAT5U */ + mtspr 0x23c, 8 /* DBAT6U */ + mtspr 0x23e, 8 /* DBAT7U */ + + li 8, 0x01ff /* first 16MiB */ + li 9, 0x0002 /* rw */ + mtspr 0x211, 9 /* IBAT0L */ + mtspr 0x210, 8 /* IBAT0U */ + mtspr 0x219, 9 /* DBAT0L */ + mtspr 0x218, 8 /* DBAT0U */ + + lis 8, 0x0c00 /* I/O mem */ + ori 8, 8, 0x3ff /* 32MiB */ + lis 9, 0x0c00 + ori 9, 9, 0x002a /* uncached, guarded, rw */ + mtspr 0x21b, 9 /* DBAT1L */ + mtspr 0x21a, 8 /* DBAT1U */ + + lis 8, 0x0100 /* next 8MiB */ + ori 8, 8, 0x00ff /* 8MiB */ + lis 9, 0x0100 + ori 9, 9, 0x0002 /* rw */ + mtspr 0x215, 9 /* IBAT2L */ + mtspr 0x214, 8 /* IBAT2U */ + mtspr 0x21d, 9 /* DBAT2L */ + mtspr 0x21c, 8 /* DBAT2U */ + + lis 8, 0x1000 /* MEM2 */ + ori 8, 8, 0x07ff /* 64MiB */ + lis 9, 0x1000 + ori 9, 9, 0x0002 /* rw */ + mtspr 0x216, 8 /* IBAT3U */ + mtspr 0x217, 9 /* IBAT3L */ + mtspr 0x21e, 8 /* DBAT3U */ + mtspr 0x21f, 9 /* DBAT3L */ + + /* enable the high BATs */ + mfspr 8, 0x3f3 /* HID4 */ + oris 8, 8, 0x0200 + mtspr 0x3f3, 8 /* HID4 */ + + /* enable and invalidate the caches if not already enabled */ + mfspr 8, 0x3f0 /* HID0 */ + andi. 0, 8, (1<<15) /* HID0_ICE */ + bne 1f + ori 8, 8, (1<<15)|(1<<11) /* HID0_ICE|HID0_ICFI*/ +1: + andi. 0, 8, (1<<14) /* HID0_DCE */ + bne 1f + ori 8, 8, (1<<14)|(1<<10) /* HID0_DCE|HID0_DCFI*/ +1: + mtspr 0x3f0, 8 /* HID0 */ + isync + + /* initialize arguments */ + li 3, 0 + li 4, 0 + li 5, 0 + + /* turn the MMU on */ + bcl 20, 31, 1f +1: + mflr 8 + addi 8, 8, _mmu_on - 1b + mfmsr 9 + ori 9, 9, (1<<4)|(1<<5) /* MSR_DR|MSR_IR */ + mtsrr0 8 + mtsrr1 9 + sync + rfi +_mmu_on: + /* turn on the front blue led (aka: yay! we got here!) */ + lis 8, 0x0d00 + ori 8, 8, 0x00c0 + lwz 9, 0(8) + ori 9, 9, 0x20 + stw 9, 0(8) + + b _zimage_start_lib + diff --git a/arch/powerpc/boot/wii.c b/arch/powerpc/boot/wii.c new file mode 100644 index 0000000..d0e2625 --- /dev/null +++ b/arch/powerpc/boot/wii.c @@ -0,0 +1,46 @@ +/* + * arch/powerpc/boot/wii.c + * + * Nintendo Wii bootwrapper support + * Copyright (C) 2008-2009 The GameCube Linux Team + * Copyright (C) 2008,2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ + +#include +#include "stdio.h" +#include "types.h" +#include "io.h" +#include "ops.h" + +#include "ugecon.h" + +BSS_STACK(8192); + +#define HW_REG(x) ((void *)(x)) + +#define EXI_CTRL HW_REG(0x0d800070) +#define EXI_CTRL_ENABLE (1<<0) + +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5) +{ + u32 heapsize = 24*1024*1024 - (u32)_end; + + simple_alloc_init(_end, heapsize, 32, 64); + fdt_init(_dtb_start); + + /* + * 'mini' boots the Broadway processor with EXI disabled. + * We need it enabled before probing for the USB Gecko. + */ + out_be32(EXI_CTRL, in_be32(EXI_CTRL) | EXI_CTRL_ENABLE); + + if (ug_probe()) + console_ops.write = ug_console_write; +} + diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index 5b9206f..390512a 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -230,7 +230,7 @@ xpedite52*) link_address='0x1400000' platformo=$object/cuboot-85xx.o ;; -gamecube) +gamecube|wii) link_address='0x600000' platformo="$object/$platform-head.o $object/$platform.o" ;; -- cgit v0.10.2 From 45158dc7d68972de919c24130b784b548df06546 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:46 +0000 Subject: powerpc: broadway processor support This patch extends the cputable entry of the 750CL to also match the 750CL-based "Broadway" cpu found on the Nintendo Wii. As of this patch, the following "Broadway" design revision levels have been seen in the wild: - DD1.2 (87102) - DD2.0 (87200) Signed-off-by: Albert Herranz Acked-by: Benjamin Herrenschmidt Signed-off-by: Grant Likely diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 03c862b..2fc82ba 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -697,9 +697,9 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_generic, .platform = "ppc750", }, - { /* 750CL */ - .pvr_mask = 0xfffff0f0, - .pvr_value = 0x00087010, + { /* 750CL (and "Broadway") */ + .pvr_mask = 0xfffff0e0, + .pvr_value = 0x00087000, .cpu_name = "750CL", .cpu_features = CPU_FTRS_750CL, .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, -- cgit v0.10.2 From 9c21025c7845bd32fb76eb38cb512c911930d85d Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:47 +0000 Subject: powerpc: wii: hollywood interrupt controller support Add support for the dual interrupt controller included in the "Hollywood" chipset of the Nintendo Wii video game console. This interrupt controller serves both the Broadway processor (as a cascade) and the Starlet processor, and is used to manage interrupts for the non-classic hardware. Signed-off-by: Albert Herranz Acked-by: Benjamin Herrenschmidt Acked-by: Segher Boessenkool Signed-off-by: Grant Likely diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile index 9365edd..f75b9e4 100644 --- a/arch/powerpc/platforms/embedded6xx/Makefile +++ b/arch/powerpc/platforms/embedded6xx/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_PPC_C2K) += c2k.o obj-$(CONFIG_USBGECKO_UDBG) += usbgecko_udbg.o obj-$(CONFIG_GAMECUBE_COMMON) += flipper-pic.o obj-$(CONFIG_GAMECUBE) += gamecube.o +obj-$(CONFIG_WII) += hlwd-pic.o diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c new file mode 100644 index 0000000..dd20bff --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c @@ -0,0 +1,241 @@ +/* + * arch/powerpc/platforms/embedded6xx/hlwd-pic.c + * + * Nintendo Wii "Hollywood" interrupt controller support. + * Copyright (C) 2009 The GameCube Linux Team + * Copyright (C) 2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ +#define DRV_MODULE_NAME "hlwd-pic" +#define pr_fmt(fmt) DRV_MODULE_NAME ": " fmt + +#include +#include +#include +#include +#include + +#include "hlwd-pic.h" + +#define HLWD_NR_IRQS 32 + +/* + * Each interrupt has a corresponding bit in both + * the Interrupt Cause (ICR) and Interrupt Mask (IMR) registers. + * + * Enabling/disabling an interrupt line involves asserting/clearing + * the corresponding bit in IMR. ACK'ing a request simply involves + * asserting the corresponding bit in ICR. + */ +#define HW_BROADWAY_ICR 0x00 +#define HW_BROADWAY_IMR 0x04 + + +/* + * IRQ chip hooks. + * + */ + +static void hlwd_pic_mask_and_ack(unsigned int virq) +{ + int irq = virq_to_hw(virq); + void __iomem *io_base = get_irq_chip_data(virq); + u32 mask = 1 << irq; + + clrbits32(io_base + HW_BROADWAY_IMR, mask); + out_be32(io_base + HW_BROADWAY_ICR, mask); +} + +static void hlwd_pic_ack(unsigned int virq) +{ + int irq = virq_to_hw(virq); + void __iomem *io_base = get_irq_chip_data(virq); + + out_be32(io_base + HW_BROADWAY_ICR, 1 << irq); +} + +static void hlwd_pic_mask(unsigned int virq) +{ + int irq = virq_to_hw(virq); + void __iomem *io_base = get_irq_chip_data(virq); + + clrbits32(io_base + HW_BROADWAY_IMR, 1 << irq); +} + +static void hlwd_pic_unmask(unsigned int virq) +{ + int irq = virq_to_hw(virq); + void __iomem *io_base = get_irq_chip_data(virq); + + setbits32(io_base + HW_BROADWAY_IMR, 1 << irq); +} + + +static struct irq_chip hlwd_pic = { + .name = "hlwd-pic", + .ack = hlwd_pic_ack, + .mask_ack = hlwd_pic_mask_and_ack, + .mask = hlwd_pic_mask, + .unmask = hlwd_pic_unmask, +}; + +/* + * IRQ host hooks. + * + */ + +static struct irq_host *hlwd_irq_host; + +static int hlwd_pic_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hwirq) +{ + set_irq_chip_data(virq, h->host_data); + get_irq_desc(virq)->status |= IRQ_LEVEL; + set_irq_chip_and_handler(virq, &hlwd_pic, handle_level_irq); + return 0; +} + +static void hlwd_pic_unmap(struct irq_host *h, unsigned int irq) +{ + set_irq_chip_data(irq, NULL); + set_irq_chip(irq, NULL); +} + +static struct irq_host_ops hlwd_irq_host_ops = { + .map = hlwd_pic_map, + .unmap = hlwd_pic_unmap, +}; + +static unsigned int __hlwd_pic_get_irq(struct irq_host *h) +{ + void __iomem *io_base = h->host_data; + int irq; + u32 irq_status; + + irq_status = in_be32(io_base + HW_BROADWAY_ICR) & + in_be32(io_base + HW_BROADWAY_IMR); + if (irq_status == 0) + return NO_IRQ; /* no more IRQs pending */ + + irq = __ffs(irq_status); + return irq_linear_revmap(h, irq); +} + +static void hlwd_pic_irq_cascade(unsigned int cascade_virq, + struct irq_desc *desc) +{ + struct irq_host *irq_host = get_irq_data(cascade_virq); + unsigned int virq; + + spin_lock(&desc->lock); + desc->chip->mask(cascade_virq); /* IRQ_LEVEL */ + spin_unlock(&desc->lock); + + virq = __hlwd_pic_get_irq(irq_host); + if (virq != NO_IRQ) + generic_handle_irq(virq); + else + pr_err("spurious interrupt!\n"); + + spin_lock(&desc->lock); + desc->chip->ack(cascade_virq); /* IRQ_LEVEL */ + if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) + desc->chip->unmask(cascade_virq); + spin_unlock(&desc->lock); +} + +/* + * Platform hooks. + * + */ + +static void __hlwd_quiesce(void __iomem *io_base) +{ + /* mask and ack all IRQs */ + out_be32(io_base + HW_BROADWAY_IMR, 0); + out_be32(io_base + HW_BROADWAY_ICR, 0xffffffff); +} + +struct irq_host *hlwd_pic_init(struct device_node *np) +{ + struct irq_host *irq_host; + struct resource res; + void __iomem *io_base; + int retval; + + retval = of_address_to_resource(np, 0, &res); + if (retval) { + pr_err("no io memory range found\n"); + return NULL; + } + io_base = ioremap(res.start, resource_size(&res)); + if (!io_base) { + pr_err("ioremap failed\n"); + return NULL; + } + + pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base); + + __hlwd_quiesce(io_base); + + irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, HLWD_NR_IRQS, + &hlwd_irq_host_ops, -1); + if (!irq_host) { + pr_err("failed to allocate irq_host\n"); + return NULL; + } + irq_host->host_data = io_base; + + return irq_host; +} + +unsigned int hlwd_pic_get_irq(void) +{ + return __hlwd_pic_get_irq(hlwd_irq_host); +} + +/* + * Probe function. + * + */ + +void hlwd_pic_probe(void) +{ + struct irq_host *host; + struct device_node *np; + const u32 *interrupts; + int cascade_virq; + + for_each_compatible_node(np, NULL, "nintendo,hollywood-pic") { + interrupts = of_get_property(np, "interrupts", NULL); + if (interrupts) { + host = hlwd_pic_init(np); + BUG_ON(!host); + cascade_virq = irq_of_parse_and_map(np, 0); + set_irq_data(cascade_virq, host); + set_irq_chained_handler(cascade_virq, + hlwd_pic_irq_cascade); + hlwd_irq_host = host; + break; + } + } +} + +/** + * hlwd_quiesce() - quiesce hollywood irq controller + * + * Mask and ack all interrupt sources. + * + */ +void hlwd_quiesce(void) +{ + void __iomem *io_base = hlwd_irq_host->host_data; + + __hlwd_quiesce(io_base); +} + diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.h b/arch/powerpc/platforms/embedded6xx/hlwd-pic.h new file mode 100644 index 0000000..d2e5a09 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.h @@ -0,0 +1,22 @@ +/* + * arch/powerpc/platforms/embedded6xx/hlwd-pic.h + * + * Nintendo Wii "Hollywood" interrupt controller support. + * Copyright (C) 2009 The GameCube Linux Team + * Copyright (C) 2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ + +#ifndef __HLWD_PIC_H +#define __HLWD_PIC_H + +extern unsigned int hlwd_pic_get_irq(void); +extern void hlwd_pic_probe(void); +extern void hlwd_quiesce(void); + +#endif -- cgit v0.10.2 From 5a7ee3198dfade8eaea260399fd168e4e9c1a3a9 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:48 +0000 Subject: powerpc: wii: platform support Add platform support for the Nintendo Wii video game console. Signed-off-by: Albert Herranz Acked-by: Benjamin Herrenschmidt Acked-by: Segher Boessenkool Signed-off-by: Grant Likely diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index e318ced..524d971 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -115,3 +115,11 @@ config GAMECUBE Select GAMECUBE if configuring for the Nintendo GameCube. More information at: +config WII + bool "Nintendo-Wii" + depends on EMBEDDED6xx + select GAMECUBE_COMMON + help + Select WII if configuring for the Nintendo Wii. + More information at: + diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile index f75b9e4..66c23e4 100644 --- a/arch/powerpc/platforms/embedded6xx/Makefile +++ b/arch/powerpc/platforms/embedded6xx/Makefile @@ -10,4 +10,4 @@ obj-$(CONFIG_PPC_C2K) += c2k.o obj-$(CONFIG_USBGECKO_UDBG) += usbgecko_udbg.o obj-$(CONFIG_GAMECUBE_COMMON) += flipper-pic.o obj-$(CONFIG_GAMECUBE) += gamecube.o -obj-$(CONFIG_WII) += hlwd-pic.o +obj-$(CONFIG_WII) += wii.o hlwd-pic.o diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c new file mode 100644 index 0000000..1bd41cc --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/wii.c @@ -0,0 +1,202 @@ +/* + * arch/powerpc/platforms/embedded6xx/wii.c + * + * Nintendo Wii board-specific support + * Copyright (C) 2008-2009 The GameCube Linux Team + * Copyright (C) 2008,2009 Albert Herranz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + */ +#define DRV_MODULE_NAME "wii" +#define pr_fmt(fmt) DRV_MODULE_NAME ": " fmt + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "flipper-pic.h" +#include "hlwd-pic.h" +#include "usbgecko_udbg.h" + +/* control block */ +#define HW_CTRL_COMPATIBLE "nintendo,hollywood-control" + +#define HW_CTRL_RESETS 0x94 +#define HW_CTRL_RESETS_SYS (1<<0) + +/* gpio */ +#define HW_GPIO_COMPATIBLE "nintendo,hollywood-gpio" + +#define HW_GPIO_BASE(idx) (idx * 0x20) +#define HW_GPIO_OUT(idx) (HW_GPIO_BASE(idx) + 0) +#define HW_GPIO_DIR(idx) (HW_GPIO_BASE(idx) + 4) + +#define HW_GPIO_SHUTDOWN (1<<1) +#define HW_GPIO_SLOT_LED (1<<5) +#define HW_GPIO_SENSOR_BAR (1<<8) + + +static void __iomem *hw_ctrl; +static void __iomem *hw_gpio; + +static void wii_spin(void) +{ + local_irq_disable(); + for (;;) + cpu_relax(); +} + +static void __iomem *wii_ioremap_hw_regs(char *name, char *compatible) +{ + void __iomem *hw_regs = NULL; + struct device_node *np; + struct resource res; + int error = -ENODEV; + + np = of_find_compatible_node(NULL, NULL, compatible); + if (!np) { + pr_err("no compatible node found for %s\n", compatible); + goto out; + } + error = of_address_to_resource(np, 0, &res); + if (error) { + pr_err("no valid reg found for %s\n", np->name); + goto out_put; + } + + hw_regs = ioremap(res.start, resource_size(&res)); + if (hw_regs) { + pr_info("%s at 0x%08x mapped to 0x%p\n", name, + res.start, hw_regs); + } + +out_put: + of_node_put(np); +out: + return hw_regs; +} + +static void __init wii_setup_arch(void) +{ + hw_ctrl = wii_ioremap_hw_regs("hw_ctrl", HW_CTRL_COMPATIBLE); + hw_gpio = wii_ioremap_hw_regs("hw_gpio", HW_GPIO_COMPATIBLE); + if (hw_gpio) { + /* turn off the front blue led and IR light */ + clrbits32(hw_gpio + HW_GPIO_OUT(0), + HW_GPIO_SLOT_LED | HW_GPIO_SENSOR_BAR); + } +} + +static void wii_restart(char *cmd) +{ + local_irq_disable(); + + if (hw_ctrl) { + /* clear the system reset pin to cause a reset */ + clrbits32(hw_ctrl + HW_CTRL_RESETS, HW_CTRL_RESETS_SYS); + } + wii_spin(); +} + +static void wii_power_off(void) +{ + local_irq_disable(); + + if (hw_gpio) { + /* make sure that the poweroff GPIO is configured as output */ + setbits32(hw_gpio + HW_GPIO_DIR(1), HW_GPIO_SHUTDOWN); + + /* drive the poweroff GPIO high */ + setbits32(hw_gpio + HW_GPIO_OUT(1), HW_GPIO_SHUTDOWN); + } + wii_spin(); +} + +static void wii_halt(void) +{ + if (ppc_md.restart) + ppc_md.restart(NULL); + wii_spin(); +} + +static void __init wii_init_early(void) +{ + ug_udbg_init(); +} + +static void __init wii_pic_probe(void) +{ + flipper_pic_probe(); + hlwd_pic_probe(); +} + +static int __init wii_probe(void) +{ + unsigned long dt_root; + + dt_root = of_get_flat_dt_root(); + if (!of_flat_dt_is_compatible(dt_root, "nintendo,wii")) + return 0; + + return 1; +} + +static void wii_shutdown(void) +{ + hlwd_quiesce(); + flipper_quiesce(); +} + +#ifdef CONFIG_KEXEC +static int wii_machine_kexec_prepare(struct kimage *image) +{ + return 0; +} +#endif /* CONFIG_KEXEC */ + +define_machine(wii) { + .name = "wii", + .probe = wii_probe, + .init_early = wii_init_early, + .setup_arch = wii_setup_arch, + .restart = wii_restart, + .power_off = wii_power_off, + .halt = wii_halt, + .init_IRQ = wii_pic_probe, + .get_irq = flipper_pic_get_irq, + .calibrate_decr = generic_calibrate_decr, + .progress = udbg_progress, + .machine_shutdown = wii_shutdown, +#ifdef CONFIG_KEXEC + .machine_kexec_prepare = wii_machine_kexec_prepare, +#endif +}; + +static struct of_device_id wii_of_bus[] = { + { .compatible = "nintendo,hollywood", }, + { }, +}; + +static int __init wii_device_probe(void) +{ + if (!machine_is(wii)) + return 0; + + of_platform_bus_probe(NULL, wii_of_bus, NULL); + return 0; +} +device_initcall(wii_device_probe); + -- cgit v0.10.2 From 08b95a7adba71a342aa152a695e75607102f484f Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:49 +0000 Subject: powerpc: wii: default config Add a default configuration for the Nintendo Wii video game console. Signed-off-by: Albert Herranz Acked-by: Benjamin Herrenschmidt Signed-off-by: Grant Likely diff --git a/arch/powerpc/configs/wii_defconfig b/arch/powerpc/configs/wii_defconfig new file mode 100644 index 0000000..c386828 --- /dev/null +++ b/arch/powerpc/configs/wii_defconfig @@ -0,0 +1,1406 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.32-rc8 +# Sun Nov 22 20:37:21 2009 +# +# CONFIG_PPC64 is not set + +# +# Processor support +# +CONFIG_PPC_BOOK3S_32=y +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_8xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_E200 is not set +CONFIG_PPC_BOOK3S=y +CONFIG_6xx=y +CONFIG_PPC_FPU=y +# CONFIG_ALTIVEC is not set +CONFIG_PPC_STD_MMU=y +CONFIG_PPC_STD_MMU_32=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_PPC_HAVE_PMU_SUPPORT=y +CONFIG_PPC_PERF_CTRS=y +# CONFIG_SMP is not set +CONFIG_NOT_COHERENT_CACHE=y +CONFIG_PPC32=y +CONFIG_WORD_SIZE=32 +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_MMU=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set +# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set +CONFIG_IRQ_PER_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_ILOG2_U32=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_GPIO=y +# CONFIG_ARCH_NO_VIRT_TO_BUS is not set +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_OF=y +# CONFIG_PPC_UDBG_16550 is not set +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_BUG=y +CONFIG_DTC=y +# CONFIG_DEFAULT_UIMAGE is not set +# CONFIG_PPC_DCR_NATIVE is not set +# CONFIG_PPC_DCR_MMIO is not set +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="-wii" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +CONFIG_RELAY=y +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +CONFIG_EVENT_PROFILE=y +CONFIG_PERF_COUNTERS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +# CONFIG_VM_EVENT_COUNTERS is not set +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_TRACEPOINTS=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_API_DEBUG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +# CONFIG_FREEZER is not set + +# +# Platform support +# +# CONFIG_PPC_CHRP is not set +# CONFIG_MPC5121_ADS is not set +# CONFIG_MPC5121_GENERIC is not set +# CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_PMAC is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PPC_82xx is not set +# CONFIG_PQ2ADS is not set +# CONFIG_PPC_83xx is not set +# CONFIG_PPC_86xx is not set +CONFIG_EMBEDDED6xx=y +# CONFIG_LINKSTATION is not set +# CONFIG_STORCENTER is not set +# CONFIG_MPC7448HPC2 is not set +# CONFIG_PPC_HOLLY is not set +# CONFIG_PPC_PRPMC2800 is not set +# CONFIG_PPC_C2K is not set +CONFIG_GAMECUBE_COMMON=y +CONFIG_USBGECKO_UDBG=y +CONFIG_FLIPPER_PIC=y +# CONFIG_GAMECUBE is not set +CONFIG_HLWD_PIC=y +CONFIG_STARLET_MINI=y +CONFIG_WII=y +# CONFIG_AMIGAONE is not set +# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set +# CONFIG_IPIC is not set +# CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_TAU is not set +# CONFIG_FSL_ULI1575 is not set +# CONFIG_SIMPLE_GPIO is not set + +# +# Kernel options +# +# CONFIG_HIGHMEM is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_BINFMT_ELF=y +# CONFIG_HAVE_AOUT is not set +CONFIG_BINFMT_MISC=m +# CONFIG_IOMMU_HELPER is not set +# CONFIG_SWIOTLB is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_KEXEC=y +# CONFIG_CRASH_DUMP is not set +CONFIG_MAX_ACTIVE_REGIONS=32 +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_MIGRATION is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_PPC_4K_PAGES=y +# CONFIG_PPC_16K_PAGES is not set +# CONFIG_PPC_64K_PAGES is not set +# CONFIG_PPC_256K_PAGES is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +CONFIG_EXTRA_TARGETS="" +# CONFIG_PM is not set +# CONFIG_SECCOMP is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_ZONE_DMA=y +CONFIG_GENERIC_ISA_DMA=y +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set +# CONFIG_HAS_RAPIDIO is not set + +# +# Advanced setup +# +CONFIG_ADVANCED_OPTIONS=y +# CONFIG_LOWMEM_SIZE_BOOL is not set +CONFIG_LOWMEM_SIZE=0x30000000 +# CONFIG_PAGE_OFFSET_BOOL is not set +CONFIG_PAGE_OFFSET=0xc0000000 +# CONFIG_KERNEL_START_BOOL is not set +CONFIG_KERNEL_START=0xc0000000 +CONFIG_PHYSICAL_START=0x00000000 +# CONFIG_TASK_SIZE_BOOL is not set +CONFIG_TASK_SIZE=0xc0000000 +# CONFIG_CONSISTENT_SIZE_BOOL is not set +CONFIG_CONSISTENT_SIZE=0x00200000 +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_L2CAP=y +# CONFIG_BT_SCO is not set +CONFIG_BT_RFCOMM=y +# CONFIG_BT_RFCOMM_TTY is not set +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +# CONFIG_BT_BNEP_PROTO_FILTER is not set +CONFIG_BT_HIDP=y + +# +# Bluetooth device drivers +# +# CONFIG_BT_HCIBTSDIO is not set +# CONFIG_BT_HCIUART is not set +# CONFIG_BT_HCIVHCI is not set +# CONFIG_BT_MRVL is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +CONFIG_CFG80211=y +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_CFG80211_DEFAULT_PS=y +CONFIG_CFG80211_DEFAULT_PS_VALUE=1 +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_WIRELESS_OLD_REGULATORY=y +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_LIB80211 is not set +CONFIG_MAC80211=y +# CONFIG_MAC80211_RC_PID is not set +CONFIG_MAC80211_RC_MINSTREL=y +# CONFIG_MAC80211_RC_DEFAULT_PID is not set +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel" +# CONFIG_MAC80211_MESH is not set +# CONFIG_MAC80211_LEDS is not set +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +CONFIG_OF_DEVICE=y +CONFIG_OF_GPIO=y +CONFIG_OF_I2C=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=2 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_ETHOC is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_XILINX_EMACLITE is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +# CONFIG_WLAN_PRE80211 is not set +CONFIG_WLAN_80211=y +# CONFIG_LIBERTAS is not set +# CONFIG_LIBERTAS_THINFIRM is not set +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_P54_COMMON is not set +# CONFIG_ATH_COMMON is not set +# CONFIG_HOSTAP is not set +CONFIG_B43=y +CONFIG_B43_SDIO=y +CONFIG_B43_PIO=y +# CONFIG_B43_PHY_LP is not set +CONFIG_B43_DEBUG=y +# CONFIG_B43_FORCE_PIO is not set +# CONFIG_B43LEGACY is not set +# CONFIG_RT2X00 is not set +# CONFIG_WL12XX is not set +# CONFIG_IWM is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 +CONFIG_INPUT_JOYDEV=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_MOUSE_SYNAPTICS_I2C is not set +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=y +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_XILINX_XPS_PS2 is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_DEVKMEM is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=64 +# CONFIG_HVC_UDBG is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +CONFIG_NVRAM=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_GPIO=y +# CONFIG_I2C_MPC is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_XILINX is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB=y +CONFIG_SSB_BLOCKIO=y +CONFIG_SSB_SDIOHOST_POSSIBLE=y +CONFIG_SSB_SDIOHOST=y +# CONFIG_SSB_SILENT is not set +CONFIG_SSB_DEBUG=y + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_OF is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_SEQUENCER=y +# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_PPC=y +# CONFIG_SND_SOC is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set +# CONFIG_HID_PID is not set + +# +# Special HID drivers +# +CONFIG_HID_APPLE=m +CONFIG_HID_WACOM=m +CONFIG_USB_SUPPORT=y +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set + +# +# Enable Host or Gadget support to see Inventra options +# + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +CONFIG_MMC_SDHCI=y +# CONFIG_MMC_SDHCI_OF is not set +# CONFIG_MMC_SDHCI_PLTFM is not set +# CONFIG_MMC_WBSD is not set +# CONFIG_MMC_AT91 is not set +# CONFIG_MMC_ATMELMCI is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_EDAC is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_GENERIC=y +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +# CONFIG_PROC_PAGE_MONITOR is not set +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_HAVE_LMB=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +# CONFIG_DETECT_HUNG_TASK is not set +CONFIG_SCHED_DEBUG=y +CONFIG_SCHEDSTATS=y +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_LATENCYTOP=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACER_MAX_TRACE=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +CONFIG_SCHED_TRACER=y +CONFIG_BOOT_TRACER=y +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set +CONFIG_DMA_API_DEBUG=y +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_PPC_DISABLE_WERROR is not set +CONFIG_PPC_WERROR=y +CONFIG_PRINT_STACK_DEPTH=64 +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_PPC_EMULATED_STATS is not set +# CONFIG_CODE_PATCHING_SELFTEST is not set +# CONFIG_FTR_FIXUP_SELFTEST is not set +# CONFIG_MSI_BITMAP_SELFTEST is not set +# CONFIG_XMON is not set +# CONFIG_IRQSTACKS is not set +# CONFIG_VIRQ_DEBUG is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_BOOTX_TEXT is not set +CONFIG_PPC_EARLY_DEBUG=y +# CONFIG_PPC_EARLY_DEBUG_LPAR is not set +# CONFIG_PPC_EARLY_DEBUG_G5 is not set +# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set +# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set +# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set +# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set +# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set +# CONFIG_PPC_EARLY_DEBUG_BEAT is not set +# CONFIG_PPC_EARLY_DEBUG_44x is not set +# CONFIG_PPC_EARLY_DEBUG_40x is not set +# CONFIG_PPC_EARLY_DEBUG_CPM is not set +CONFIG_PPC_EARLY_DEBUG_USBGECKO=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set +# CONFIG_PPC_CLOCK is not set +# CONFIG_VIRTUALIZATION is not set -- cgit v0.10.2 From b8e8efaa86399c4424becd96402993cf230dab57 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:50 +0000 Subject: powerpc: reserve fixmap entries for early debug Add a set of entries to the fixmap table to allow usage of known reserved virtual address space by early debug code. The address space reserved is the top 128K of the 32-bit address space. This allows, if required, the use of a BAT to do the mappings. Signed-off-by: Albert Herranz Acked-by: Benjamin Herrenschmidt Signed-off-by: Grant Likely diff --git a/arch/powerpc/include/asm/fixmap.h b/arch/powerpc/include/asm/fixmap.h index f1f4e23..5c2c023 100644 --- a/arch/powerpc/include/asm/fixmap.h +++ b/arch/powerpc/include/asm/fixmap.h @@ -44,6 +44,9 @@ */ enum fixed_addresses { FIX_HOLE, + /* reserve the top 128K for early debugging purposes */ + FIX_EARLY_DEBUG_TOP = FIX_HOLE, + FIX_EARLY_DEBUG_BASE = FIX_EARLY_DEBUG_TOP+((128*1024)/PAGE_SIZE)-1, #ifdef CONFIG_HIGHMEM FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, -- cgit v0.10.2 From d1d56f8c1d5a622228177eca47e9dcff0498bddb Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:51 +0000 Subject: powerpc: gamecube/wii: early debugging using usbgecko Add support for using the USB Gecko adapter as an early debugging console on the Nintendo GameCube and Wii video game consoles. The USB Gecko is a 3rd party memory card interface adapter that provides a EXI (External Interface) to USB serial converter. Signed-off-by: Albert Herranz Acked-by: Benjamin Herrenschmidt Signed-off-by: Grant Likely diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 3b10051..11e385b 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -254,6 +254,14 @@ config PPC_EARLY_DEBUG_CPM using a CPM-based serial port. This assumes that the bootwrapper has run, and set up the CPM in a particular way. +config PPC_EARLY_DEBUG_USBGECKO + bool "Early debugging through the USB Gecko adapter" + depends on GAMECUBE_COMMON + select USBGECKO_UDBG + help + Select this to enable early debugging for Nintendo GameCube/Wii + consoles via an external USB Gecko adapter. + endchoice config PPC_EARLY_DEBUG_44x_PHYSLOW diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h index cd21e5e..11ae699 100644 --- a/arch/powerpc/include/asm/udbg.h +++ b/arch/powerpc/include/asm/udbg.h @@ -51,6 +51,7 @@ extern void __init udbg_init_btext(void); extern void __init udbg_init_44x_as1(void); extern void __init udbg_init_40x_realmode(void); extern void __init udbg_init_cpm(void); +extern void __init udbg_init_usbgecko(void); #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_UDBG_H */ diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index 829c3fe..e025e89 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -164,6 +164,9 @@ __after_mmu_off: #ifdef CONFIG_PPC_EARLY_DEBUG_CPM bl setup_cpm_bat #endif +#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO + bl setup_usbgecko_bat +#endif /* * Call setup_cpu for CPU 0 and initialize 6xx Idle @@ -1203,6 +1206,28 @@ setup_cpm_bat: blr #endif +#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO +setup_usbgecko_bat: + /* prepare a BAT for early io */ +#if defined(CONFIG_GAMECUBE) + lis r8, 0x0c00 +#elif defined(CONFIG_WII) + lis r8, 0x0d00 +#else +#error Invalid platform for USB Gecko based early debugging. +#endif + /* + * The virtual address used must match the virtual address + * associated to the fixmap entry FIX_EARLY_DEBUG_BASE. + */ + lis r11, 0xfffe /* top 128K */ + ori r8, r8, 0x002a /* uncached, guarded ,rw */ + ori r11, r11, 0x2 /* 128K, Vs=1, Vp=0 */ + mtspr SPRN_DBAT1L, r8 + mtspr SPRN_DBAT1U, r11 + blr +#endif + #ifdef CONFIG_8260 /* Jump into the system reset for the rom. * We first disable the MMU, and then jump to the ROM reset address. diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index fc9af47..e39cad8 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c @@ -60,6 +60,8 @@ void __init udbg_early_init(void) udbg_init_40x_realmode(); #elif defined(CONFIG_PPC_EARLY_DEBUG_CPM) udbg_init_cpm(); +#elif defined(CONFIG_PPC_EARLY_DEBUG_USBGECKO) + udbg_init_usbgecko(); #endif #ifdef CONFIG_PPC_EARLY_DEBUG diff --git a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c index ba4c7cc..edc956c 100644 --- a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c +++ b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "usbgecko_udbg.h" @@ -270,3 +271,58 @@ done: of_node_put(np); return; } + +#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO + +static phys_addr_t __init ug_early_grab_io_addr(void) +{ +#if defined(CONFIG_GAMECUBE) + return 0x0c000000; +#elif defined(CONFIG_WII) + return 0x0d000000; +#else +#error Invalid platform for USB Gecko based early debugging. +#endif +} + +/* + * USB Gecko early debug support initialization for udbg. + */ +void __init udbg_init_usbgecko(void) +{ + void __iomem *early_debug_area; + void __iomem *exi_io_base; + + /* + * At this point we have a BAT already setup that enables I/O + * to the EXI hardware. + * + * The BAT uses a virtual address range reserved at the fixmap. + * This must match the virtual address configured in + * head_32.S:setup_usbgecko_bat(). + */ + early_debug_area = (void __iomem *)__fix_to_virt(FIX_EARLY_DEBUG_BASE); + exi_io_base = early_debug_area + 0x00006800; + + /* try to detect a USB Gecko */ + if (!ug_udbg_probe(exi_io_base)) + return; + + /* we found a USB Gecko, load udbg hooks */ + udbg_putc = ug_udbg_putc; + udbg_getc = ug_udbg_getc; + udbg_getc_poll = ug_udbg_getc_poll; + + /* + * Prepare again the same BAT for MMU_init. + * This allows udbg I/O to continue working after the MMU is + * turned on for real. + * It is safe to continue using the same virtual address as it is + * a reserved fixmap area. + */ + setbat(1, (unsigned long)early_debug_area, + ug_early_grab_io_addr(), 128*1024, PAGE_KERNEL_NCG); +} + +#endif /* CONFIG_PPC_EARLY_DEBUG_USBGECKO */ + diff --git a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h index 3929de3..bb6cde4 100644 --- a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h +++ b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.h @@ -27,4 +27,6 @@ static inline void __init ug_udbg_init(void) #endif /* CONFIG_USBGECKO_UDBG */ +void __init udbg_init_usbgecko(void); + #endif /* __USBGECKO_UDBG_H */ -- cgit v0.10.2 From 02d748a9ee56735641bade9b734dc2fa9be4df4c Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:52 +0000 Subject: wii: bootwrapper: add fixup to calc useable mem2 The top portion of MEM2 (the second 64MB memory block) in the Nintendo Wii video game console is used by the firmware running on the Starlet processor. Add code to calculate the portion of MEM2 safely useable by the Broadway processor. When running under the 'mini' firmware this is easily determined from an in-memory header. Otherwise, a safe default is used. Signed-off-by: Albert Herranz Acked-by: Benjamin Herrenschmidt Signed-off-by: Grant Likely diff --git a/arch/powerpc/boot/wii.c b/arch/powerpc/boot/wii.c index d0e2625..2ebaec0 100644 --- a/arch/powerpc/boot/wii.c +++ b/arch/powerpc/boot/wii.c @@ -22,10 +22,120 @@ BSS_STACK(8192); -#define HW_REG(x) ((void *)(x)) +#define HW_REG(x) ((void *)(x)) -#define EXI_CTRL HW_REG(0x0d800070) -#define EXI_CTRL_ENABLE (1<<0) +#define EXI_CTRL HW_REG(0x0d800070) +#define EXI_CTRL_ENABLE (1<<0) + +#define MEM2_TOP (0x10000000 + 64*1024*1024) +#define FIRMWARE_DEFAULT_SIZE (12*1024*1024) + + +struct mipc_infohdr { + char magic[3]; + u8 version; + u32 mem2_boundary; + u32 ipc_in; + size_t ipc_in_size; + u32 ipc_out; + size_t ipc_out_size; +}; + +static int mipc_check_address(u32 pa) +{ + /* only MEM2 addresses */ + if (pa < 0x10000000 || pa > 0x14000000) + return -EINVAL; + return 0; +} + +static struct mipc_infohdr *mipc_get_infohdr(void) +{ + struct mipc_infohdr **hdrp, *hdr; + + /* 'mini' header pointer is the last word of MEM2 memory */ + hdrp = (struct mipc_infohdr **)0x13fffffc; + if (mipc_check_address((u32)hdrp)) { + printf("mini: invalid hdrp %08X\n", (u32)hdrp); + hdr = NULL; + goto out; + } + + hdr = *hdrp; + if (mipc_check_address((u32)hdr)) { + printf("mini: invalid hdr %08X\n", (u32)hdr); + hdr = NULL; + goto out; + } + if (memcmp(hdr->magic, "IPC", 3)) { + printf("mini: invalid magic\n"); + hdr = NULL; + goto out; + } + +out: + return hdr; +} + +static int mipc_get_mem2_boundary(u32 *mem2_boundary) +{ + struct mipc_infohdr *hdr; + int error; + + hdr = mipc_get_infohdr(); + if (!hdr) { + error = -1; + goto out; + } + + if (mipc_check_address(hdr->mem2_boundary)) { + printf("mini: invalid mem2_boundary %08X\n", + hdr->mem2_boundary); + error = -EINVAL; + goto out; + } + *mem2_boundary = hdr->mem2_boundary; + error = 0; +out: + return error; + +} + +static void platform_fixups(void) +{ + void *mem; + u32 reg[4]; + u32 mem2_boundary; + int len; + int error; + + mem = finddevice("/memory"); + if (!mem) + fatal("Can't find memory node\n"); + + /* two ranges of (address, size) words */ + len = getprop(mem, "reg", reg, sizeof(reg)); + if (len != sizeof(reg)) { + /* nothing to do */ + goto out; + } + + /* retrieve MEM2 boundary from 'mini' */ + error = mipc_get_mem2_boundary(&mem2_boundary); + if (error) { + /* if that fails use a sane value */ + mem2_boundary = MEM2_TOP - FIRMWARE_DEFAULT_SIZE; + } + + if (mem2_boundary > reg[2] && mem2_boundary < reg[2] + reg[3]) { + reg[3] = mem2_boundary - reg[2]; + printf("top of MEM2 @ %08X\n", reg[2] + reg[3]); + setprop(mem, "reg", reg, sizeof(reg)); + } + +out: + return; +} void platform_init(unsigned long r3, unsigned long r4, unsigned long r5) { @@ -42,5 +152,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5) if (ug_probe()) console_ops.write = ug_console_write; + + platform_ops.fixups = platform_fixups; } -- cgit v0.10.2 From de32400dd26e743c5d500aa42d8d6818b79edb73 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:53 +0000 Subject: wii: use both mem1 and mem2 as ram The Nintendo Wii video game console has two discontiguous RAM regions: - MEM1: 24MB @ 0x00000000 - MEM2: 64MB @ 0x10000000 Unfortunately, the kernel currently does not support discontiguous RAM memory regions on 32-bit PowerPC platforms. This patch adds a series of workarounds to allow the use of the second memory region (MEM2) as RAM by the kernel. Basically, a single range of memory from the beginning of MEM1 to the end of MEM2 is reported to the kernel, and a memory reservation is created for the hole between MEM1 and MEM2. With this patch the system is able to use all the available RAM and not just ~27% of it. This will no longer be needed when proper discontig memory support for 32-bit PowerPC is added to the kernel. Signed-off-by: Albert Herranz Acked-by: Benjamin Herrenschmidt Signed-off-by: Grant Likely diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 9ddcfb4..703c7c2 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -131,9 +131,13 @@ void __init MMU_init(void) MMU_setup(); if (lmb.memory.cnt > 1) { +#ifndef CONFIG_WII lmb.memory.cnt = 1; lmb_analyze(); printk(KERN_WARNING "Only using first contiguous memory region"); +#else + wii_memory_fixups(); +#endif } total_lowmem = total_memory = lmb_end_of_DRAM() - memstart_addr; diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index d2e5321..9aa39fe 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -136,6 +136,14 @@ extern phys_addr_t total_lowmem; extern phys_addr_t memstart_addr; extern phys_addr_t lowmem_end_addr; +#ifdef CONFIG_WII +extern unsigned long wii_hole_start; +extern unsigned long wii_hole_size; + +extern unsigned long wii_mmu_mapin_mem2(unsigned long top); +extern void wii_memory_fixups(void); +#endif + /* ...and now those things that may be slightly different between processor * architectures. -- Dan */ @@ -155,5 +163,5 @@ extern void adjust_total_lowmem(void); #elif defined(CONFIG_PPC32) /* anything 32-bit except 4xx or 8xx */ extern void MMU_init_hw(void); -extern unsigned long mmu_mapin_ram(void); +extern unsigned long mmu_mapin_ram(unsigned long top); #endif diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index cb96cb2..b55bbe8 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -283,18 +283,18 @@ int map_page(unsigned long va, phys_addr_t pa, int flags) } /* - * Map in a big chunk of physical memory starting at PAGE_OFFSET. + * Map in a chunk of physical memory starting at start. */ -void __init mapin_ram(void) +void __init __mapin_ram_chunk(unsigned long offset, unsigned long top) { unsigned long v, s, f; phys_addr_t p; int ktext; - s = mmu_mapin_ram(); + s = offset; v = PAGE_OFFSET + s; p = memstart_addr + s; - for (; s < total_lowmem; s += PAGE_SIZE) { + for (; s < top; s += PAGE_SIZE) { ktext = ((char *) v >= _stext && (char *) v < etext); f = ktext ? PAGE_KERNEL_TEXT : PAGE_KERNEL; map_page(v, p, f); @@ -307,6 +307,30 @@ void __init mapin_ram(void) } } +void __init mapin_ram(void) +{ + unsigned long s, top; + +#ifndef CONFIG_WII + top = total_lowmem; + s = mmu_mapin_ram(top); + __mapin_ram_chunk(s, top); +#else + if (!wii_hole_size) { + s = mmu_mapin_ram(total_lowmem); + __mapin_ram_chunk(s, total_lowmem); + } else { + top = wii_hole_start; + s = mmu_mapin_ram(top); + __mapin_ram_chunk(s, top); + + top = lmb_end_of_DRAM(); + s = wii_mmu_mapin_mem2(top); + __mapin_ram_chunk(s, top); + } +#endif +} + /* Scan the real Linux page tables and return a PTE pointer for * a virtual address in a context. * Returns true (1) if PTE was found, zero otherwise. The pointer to diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c index 2d2a87e..f11c2cd 100644 --- a/arch/powerpc/mm/ppc_mmu_32.c +++ b/arch/powerpc/mm/ppc_mmu_32.c @@ -72,7 +72,7 @@ unsigned long p_mapped_by_bats(phys_addr_t pa) return 0; } -unsigned long __init mmu_mapin_ram(void) +unsigned long __init mmu_mapin_ram(unsigned long top) { unsigned long tot, bl, done; unsigned long max_size = (256<<20); @@ -86,7 +86,7 @@ unsigned long __init mmu_mapin_ram(void) /* Make sure we don't map a block larger than the smallest alignment of the physical address. */ - tot = total_lowmem; + tot = top; for (bl = 128<<10; bl < max_size; bl <<= 1) { if (bl * 2 > tot) break; diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c index 1bd41cc..de0c1e3 100644 --- a/arch/powerpc/platforms/embedded6xx/wii.c +++ b/arch/powerpc/platforms/embedded6xx/wii.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include @@ -52,6 +54,67 @@ static void __iomem *hw_ctrl; static void __iomem *hw_gpio; +unsigned long wii_hole_start; +unsigned long wii_hole_size; + + +static int __init page_aligned(unsigned long x) +{ + return !(x & (PAGE_SIZE-1)); +} + +void __init wii_memory_fixups(void) +{ + struct lmb_property *p = lmb.memory.region; + + /* + * This is part of a workaround to allow the use of two + * discontiguous RAM ranges on the Wii, even if this is + * currently unsupported on 32-bit PowerPC Linux. + * + * We coealesce the two memory ranges of the Wii into a + * single range, then create a reservation for the "hole" + * between both ranges. + */ + + BUG_ON(lmb.memory.cnt != 2); + BUG_ON(!page_aligned(p[0].base) || !page_aligned(p[1].base)); + + p[0].size = _ALIGN_DOWN(p[0].size, PAGE_SIZE); + p[1].size = _ALIGN_DOWN(p[1].size, PAGE_SIZE); + + wii_hole_start = p[0].base + p[0].size; + wii_hole_size = p[1].base - wii_hole_start; + + pr_info("MEM1: <%08llx %08llx>\n", p[0].base, p[0].size); + pr_info("HOLE: <%08lx %08lx>\n", wii_hole_start, wii_hole_size); + pr_info("MEM2: <%08llx %08llx>\n", p[1].base, p[1].size); + + p[0].size += wii_hole_size + p[1].size; + + lmb.memory.cnt = 1; + lmb_analyze(); + + /* reserve the hole */ + lmb_reserve(wii_hole_start, wii_hole_size); +} + +unsigned long __init wii_mmu_mapin_mem2(unsigned long top) +{ + unsigned long delta, size, bl; + unsigned long max_size = (256<<20); + + /* MEM2 64MB@0x10000000 */ + delta = wii_hole_start + wii_hole_size; + size = top - delta; + for (bl = 128<<10; bl < max_size; bl <<= 1) { + if (bl * 2 > size) + break; + } + setbat(4, PAGE_OFFSET+delta, delta, bl, PAGE_KERNEL_X); + return delta + bl; +} + static void wii_spin(void) { local_irq_disable(); -- cgit v0.10.2 From c5df7f775148723de39274537a886e9502eef336 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:54 +0000 Subject: powerpc: allow ioremap within reserved memory regions Add a flag to let a platform ioremap memory regions marked as reserved. This flag will be used later by the Nintendo Wii support code to allow ioremapping the I/O region sitting between MEM1 and MEM2 and marked as reserved RAM in the patch "wii: use both mem1 and mem2 as ram". This will no longer be needed when proper discontig memory support for 32-bit PowerPC is added to the kernel. Signed-off-by: Albert Herranz Acked-by: Benjamin Herrenschmidt Signed-off-by: Grant Likely diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 703c7c2..4ec900a 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -82,6 +82,11 @@ extern struct task_struct *current_set[NR_CPUS]; int __map_without_bats; int __map_without_ltlbs; +/* + * This tells the system to allow ioremapping memory marked as reserved. + */ +int __allow_ioremap_reserved; + /* max amount of low RAM to map in */ unsigned long __max_low_memory = MAX_LOW_MEM; diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 9aa39fe..34dacc3 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -115,6 +115,7 @@ extern void settlbcam(int index, unsigned long virt, phys_addr_t phys, extern void invalidate_tlbcam_entry(int index); extern int __map_without_bats; +extern int __allow_ioremap_reserved; extern unsigned long ioremap_base; extern unsigned int rtas_data, rtas_size; diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index b55bbe8..177e403 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -191,7 +192,8 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags, * Don't allow anybody to remap normal RAM that we're using. * mem_init() sets high_memory so only do the check after that. */ - if (mem_init_done && (p < virt_to_phys(high_memory))) { + if (mem_init_done && (p < virt_to_phys(high_memory)) && + !(__allow_ioremap_reserved && lmb_is_region_reserved(p, size))) { printk("__ioremap(): phys addr 0x%llx is RAM lr %p\n", (unsigned long long)p, __builtin_return_address(0)); return NULL; diff --git a/include/linux/lmb.h b/include/linux/lmb.h index 2442e3f..ef82b8f 100644 --- a/include/linux/lmb.h +++ b/include/linux/lmb.h @@ -54,6 +54,7 @@ extern u64 __init lmb_phys_mem_size(void); extern u64 lmb_end_of_DRAM(void); extern void __init lmb_enforce_memory_limit(u64 memory_limit); extern int __init lmb_is_reserved(u64 addr); +extern int lmb_is_region_reserved(u64 base, u64 size); extern int lmb_find(struct lmb_property *res); extern void lmb_dump_all(void); diff --git a/lib/lmb.c b/lib/lmb.c index 0343c05..9cee171 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -263,7 +263,7 @@ long __init lmb_reserve(u64 base, u64 size) return lmb_add_region(_rgn, base, size); } -long __init lmb_overlaps_region(struct lmb_region *rgn, u64 base, u64 size) +long lmb_overlaps_region(struct lmb_region *rgn, u64 base, u64 size) { unsigned long i; @@ -493,6 +493,11 @@ int __init lmb_is_reserved(u64 addr) return 0; } +int lmb_is_region_reserved(u64 base, u64 size) +{ + return lmb_overlaps_region(&lmb.reserved, base, size); +} + /* * Given a , find which memory regions belong to this range. * Adjust the request and return a contiguous chunk. -- cgit v0.10.2 From c0577eeee0101433a0d929699f4543a1ff3c3014 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Sat, 12 Dec 2009 06:31:55 +0000 Subject: powerpc: wii: allow ioremap within the memory hole Enable the flag that allows a platform to ioremap memory marked as reserved. This is currently needed on the Nintendo Wii video game console due to the workaround introduced in "wii: use both mem1 and mem2 as ram". This will no longer be needed when proper discontig memory support for 32-bit PowerPC is added to the kernel. Signed-off-by: Albert Herranz Acked-by: Benjamin Herrenschmidt Signed-off-by: Grant Likely diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c index de0c1e3..57e5b60 100644 --- a/arch/powerpc/platforms/embedded6xx/wii.c +++ b/arch/powerpc/platforms/embedded6xx/wii.c @@ -97,6 +97,9 @@ void __init wii_memory_fixups(void) /* reserve the hole */ lmb_reserve(wii_hole_start, wii_hole_size); + + /* allow ioremapping the address space in the hole */ + __allow_ioremap_reserved = 1; } unsigned long __init wii_mmu_mapin_mem2(unsigned long top) -- cgit v0.10.2 From 7539a3b3d1f892dd97eaf094134d7de55c13befe Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 13 Dec 2009 00:07:30 +0100 Subject: sched: Make wakeup side and atomic variants of completion API irq safe Alan Stern noticed that all the wakeup side (and atomic) variants of the completion APIs should be irq safe, but the newly introduced completion_done() and try_wait_for_completion() aren't. The use of the irq unsafe variants in IRQ contexts can cause crashes/hangs. Fix the problem by making them use spin_lock_irqsave() and spin_lock_irqrestore(). Reported-by: Alan Stern Signed-off-by: Rafael J. Wysocki Cc: Linus Torvalds Cc: Zhang Rui Cc: pm list Cc: Peter Zijlstra Cc: David Chinner Cc: Lachlan McIlroy LKML-Reference: <200912130007.30541.rjw@sisk.pl> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index ff39cad..8b3532f 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5908,14 +5908,15 @@ EXPORT_SYMBOL(wait_for_completion_killable); */ bool try_wait_for_completion(struct completion *x) { + unsigned long flags; int ret = 1; - spin_lock_irq(&x->wait.lock); + spin_lock_irqsave(&x->wait.lock, flags); if (!x->done) ret = 0; else x->done--; - spin_unlock_irq(&x->wait.lock); + spin_unlock_irqrestore(&x->wait.lock, flags); return ret; } EXPORT_SYMBOL(try_wait_for_completion); @@ -5930,12 +5931,13 @@ EXPORT_SYMBOL(try_wait_for_completion); */ bool completion_done(struct completion *x) { + unsigned long flags; int ret = 1; - spin_lock_irq(&x->wait.lock); + spin_lock_irqsave(&x->wait.lock, flags); if (!x->done) ret = 0; - spin_unlock_irq(&x->wait.lock); + spin_unlock_irqrestore(&x->wait.lock, flags); return ret; } EXPORT_SYMBOL(completion_done); -- cgit v0.10.2 From 663997d417330a59a566452f52cfa04c8ffd190b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 12 Dec 2009 13:57:27 -0800 Subject: sched: Use pr_fmt() and pr_() - Convert printk(KERN_ to pr_ (not KERN_DEBUG) - Add #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - Coalesce long format strings - Add missing \n to "ERROR: !SD_LOAD_BALANCE domain has parent" Signed-off-by: Joe Perches Cc: Peter Zijlstra LKML-Reference: <1260655047.2637.7.camel@Joe-Laptop.home> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 8b3532f..258c73c 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -26,6 +26,8 @@ * Thomas Gleixner, Mike Kravetz */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -5337,8 +5339,8 @@ static noinline void __schedule_bug(struct task_struct *prev) { struct pt_regs *regs = get_irq_regs(); - printk(KERN_ERR "BUG: scheduling while atomic: %s/%d/0x%08x\n", - prev->comm, prev->pid, preempt_count()); + pr_err("BUG: scheduling while atomic: %s/%d/0x%08x\n", + prev->comm, prev->pid, preempt_count()); debug_show_held_locks(prev); print_modules(); @@ -6906,23 +6908,23 @@ void sched_show_task(struct task_struct *p) unsigned state; state = p->state ? __ffs(p->state) + 1 : 0; - printk(KERN_INFO "%-13.13s %c", p->comm, + pr_info("%-13.13s %c", p->comm, state < sizeof(stat_nam) - 1 ? stat_nam[state] : '?'); #if BITS_PER_LONG == 32 if (state == TASK_RUNNING) - printk(KERN_CONT " running "); + pr_cont(" running "); else - printk(KERN_CONT " %08lx ", thread_saved_pc(p)); + pr_cont(" %08lx ", thread_saved_pc(p)); #else if (state == TASK_RUNNING) - printk(KERN_CONT " running task "); + pr_cont(" running task "); else - printk(KERN_CONT " %016lx ", thread_saved_pc(p)); + pr_cont(" %016lx ", thread_saved_pc(p)); #endif #ifdef CONFIG_DEBUG_STACK_USAGE free = stack_not_used(p); #endif - printk(KERN_CONT "%5lu %5d %6d 0x%08lx\n", free, + pr_cont("%5lu %5d %6d 0x%08lx\n", free, task_pid_nr(p), task_pid_nr(p->real_parent), (unsigned long)task_thread_info(p)->flags); @@ -6934,11 +6936,9 @@ void show_state_filter(unsigned long state_filter) struct task_struct *g, *p; #if BITS_PER_LONG == 32 - printk(KERN_INFO - " task PC stack pid father\n"); + pr_info(" task PC stack pid father\n"); #else - printk(KERN_INFO - " task PC stack pid father\n"); + pr_info(" task PC stack pid father\n"); #endif read_lock(&tasklist_lock); do_each_thread(g, p) { @@ -7296,9 +7296,8 @@ again: * leave kernel. */ if (p->mm && printk_ratelimit()) { - printk(KERN_INFO "process %d (%s) no " - "longer affine to cpu%d\n", - task_pid_nr(p), p->comm, dead_cpu); + pr_info("process %d (%s) no longer affine to cpu%d\n", + task_pid_nr(p), p->comm, dead_cpu); } } @@ -7805,48 +7804,44 @@ static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level, printk(KERN_DEBUG "%*s domain %d: ", level, "", level); if (!(sd->flags & SD_LOAD_BALANCE)) { - printk("does not load-balance\n"); + pr_cont("does not load-balance\n"); if (sd->parent) - printk(KERN_ERR "ERROR: !SD_LOAD_BALANCE domain" - " has parent"); + pr_err("ERROR: !SD_LOAD_BALANCE domain has parent\n"); return -1; } - printk(KERN_CONT "span %s level %s\n", str, sd->name); + pr_cont("span %s level %s\n", str, sd->name); if (!cpumask_test_cpu(cpu, sched_domain_span(sd))) { - printk(KERN_ERR "ERROR: domain->span does not contain " - "CPU%d\n", cpu); + pr_err("ERROR: domain->span does not contain CPU%d\n", cpu); } if (!cpumask_test_cpu(cpu, sched_group_cpus(group))) { - printk(KERN_ERR "ERROR: domain->groups does not contain" - " CPU%d\n", cpu); + pr_err("ERROR: domain->groups does not contain CPU%d\n", cpu); } printk(KERN_DEBUG "%*s groups:", level + 1, ""); do { if (!group) { - printk("\n"); - printk(KERN_ERR "ERROR: group is NULL\n"); + pr_cont("\n"); + pr_err("ERROR: group is NULL\n"); break; } if (!group->cpu_power) { - printk(KERN_CONT "\n"); - printk(KERN_ERR "ERROR: domain->cpu_power not " - "set\n"); + pr_cont("\n"); + pr_err("ERROR: domain->cpu_power not set\n"); break; } if (!cpumask_weight(sched_group_cpus(group))) { - printk(KERN_CONT "\n"); - printk(KERN_ERR "ERROR: empty group\n"); + pr_cont("\n"); + pr_err("ERROR: empty group\n"); break; } if (cpumask_intersects(groupmask, sched_group_cpus(group))) { - printk(KERN_CONT "\n"); - printk(KERN_ERR "ERROR: repeated CPUs\n"); + pr_cont("\n"); + pr_err("ERROR: repeated CPUs\n"); break; } @@ -7854,23 +7849,21 @@ static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level, cpulist_scnprintf(str, sizeof(str), sched_group_cpus(group)); - printk(KERN_CONT " %s", str); + pr_cont(" %s", str); if (group->cpu_power != SCHED_LOAD_SCALE) { - printk(KERN_CONT " (cpu_power = %d)", - group->cpu_power); + pr_cont(" (cpu_power = %d)", group->cpu_power); } group = group->next; } while (group != sd->groups); - printk(KERN_CONT "\n"); + pr_cont("\n"); if (!cpumask_equal(sched_domain_span(sd), groupmask)) - printk(KERN_ERR "ERROR: groups don't span domain->span\n"); + pr_err("ERROR: groups don't span domain->span\n"); if (sd->parent && !cpumask_subset(groupmask, sched_domain_span(sd->parent))) - printk(KERN_ERR "ERROR: parent span is not a superset " - "of domain->span\n"); + pr_err("ERROR: parent span is not a superset of domain->span\n"); return 0; } @@ -8426,8 +8419,7 @@ static int build_numa_sched_groups(struct s_data *d, sg = kmalloc_node(sizeof(struct sched_group) + cpumask_size(), GFP_KERNEL, num); if (!sg) { - printk(KERN_WARNING "Can not alloc domain group for node %d\n", - num); + pr_warning("Can not alloc domain group for node %d\n", num); return -ENOMEM; } d->sched_group_nodes[num] = sg; @@ -8456,8 +8448,8 @@ static int build_numa_sched_groups(struct s_data *d, sg = kmalloc_node(sizeof(struct sched_group) + cpumask_size(), GFP_KERNEL, num); if (!sg) { - printk(KERN_WARNING - "Can not alloc domain group for node %d\n", j); + pr_warning("Can not alloc domain group for node %d\n", + j); return -ENOMEM; } sg->cpu_power = 0; @@ -8685,7 +8677,7 @@ static enum s_alloc __visit_domain_allocation_hell(struct s_data *d, d->sched_group_nodes = kcalloc(nr_node_ids, sizeof(struct sched_group *), GFP_KERNEL); if (!d->sched_group_nodes) { - printk(KERN_WARNING "Can not alloc sched group node list\n"); + pr_warning("Can not alloc sched group node list\n"); return sa_notcovered; } sched_group_nodes_bycpu[cpumask_first(cpu_map)] = d->sched_group_nodes; @@ -8702,7 +8694,7 @@ static enum s_alloc __visit_domain_allocation_hell(struct s_data *d, return sa_send_covered; d->rd = alloc_rootdomain(); if (!d->rd) { - printk(KERN_WARNING "Cannot alloc root domain\n"); + pr_warning("Cannot alloc root domain\n"); return sa_tmpmask; } return sa_rootdomain; @@ -9684,13 +9676,11 @@ void __might_sleep(char *file, int line, int preempt_offset) return; prev_jiffy = jiffies; - printk(KERN_ERR - "BUG: sleeping function called from invalid context at %s:%d\n", - file, line); - printk(KERN_ERR - "in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s\n", - in_atomic(), irqs_disabled(), - current->pid, current->comm); + pr_err("BUG: sleeping function called from invalid context at %s:%d\n", + file, line); + pr_err("in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s\n", + in_atomic(), irqs_disabled(), + current->pid, current->comm); debug_show_held_locks(current); if (irqs_disabled()) diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c index 33d5384..b810e22 100644 --- a/kernel/sched_idletask.c +++ b/kernel/sched_idletask.c @@ -35,7 +35,7 @@ static void dequeue_task_idle(struct rq *rq, struct task_struct *p, int sleep) { spin_unlock_irq(&rq->lock); - printk(KERN_ERR "bad: scheduling from the idle thread!\n"); + pr_err("bad: scheduling from the idle thread!\n"); dump_stack(); spin_lock_irq(&rq->lock); } -- cgit v0.10.2 From 4819568f23a8bef0ca99b740ca60fe2450ab0aac Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 12 Dec 2009 13:06:13 -0800 Subject: ftrace.h: Use common pr_info fmt string Reduces fmt string space a bit. Signed-off-by: Joe Perches Cc: Frederic Weisbecker Cc: Steven Rostedt LKML-Reference: <1260651974.2637.4.camel@Joe-Laptop.home> Signed-off-by: Ingo Molnar diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index d1b3de9..c4eca38 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -733,7 +733,7 @@ static int ftrace_raw_reg_event_##call(struct ftrace_event_call *unused)\ ret = register_trace_##call(ftrace_raw_event_##call); \ if (ret) \ pr_info("event trace: Could not activate trace point " \ - "probe to " #call "\n"); \ + "probe to %s\n", #call); \ return ret; \ } \ \ -- cgit v0.10.2 From 87d9b4e1c52867a45331a9a5495f6448e0c68b23 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 8 Dec 2009 11:14:20 +0800 Subject: tracing: Extract duplicate ftrace_raw_init_event_foo() Use a generic trace_event_raw_init() function for all event's raw_init callbacks (but kprobes) instead of defining the same version for each of these. This shrinks the kernel code: text data bss dec hex filename 5355293 1961928 7103260 14420481 dc0a01 vmlinux.o.old 5346802 1961864 7103260 14411926 dbe896 vmlinux.o raw_init can't be removed, because ftrace events and kprobe events use different raw_init callbacks. Though it's possible to totally remove raw_init, I choose to leave it as it is for now. Signed-off-by: Li Zefan Acked-by: Steven Rostedt Cc: Jason Baron Cc: Ingo Molnar LKML-Reference: <4B1DC48C.7080603@cn.fujitsu.com> Signed-off-by: Frederic Weisbecker diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 38f8d65..ea44b89 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -158,6 +158,7 @@ enum { FILTER_PTR_STRING, }; +extern int trace_event_raw_init(struct ftrace_event_call *call); extern int trace_define_common_fields(struct ftrace_event_call *call); extern int trace_define_field(struct ftrace_event_call *call, const char *type, const char *name, int offset, int size, diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index bc70c58..94ac284 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -145,7 +145,7 @@ struct perf_event_attr; .name = "sys_enter"#sname, \ .system = "syscalls", \ .event = &enter_syscall_print_##sname, \ - .raw_init = init_syscall_trace, \ + .raw_init = trace_event_raw_init, \ .show_format = syscall_enter_format, \ .define_fields = syscall_enter_define_fields, \ .regfunc = reg_event_syscall_enter, \ @@ -167,7 +167,7 @@ struct perf_event_attr; .name = "sys_exit"#sname, \ .system = "syscalls", \ .event = &exit_syscall_print_##sname, \ - .raw_init = init_syscall_trace, \ + .raw_init = trace_event_raw_init, \ .show_format = syscall_exit_format, \ .define_fields = syscall_exit_define_fields, \ .regfunc = reg_event_syscall_exit, \ diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index c4eca38..6055b06 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -623,23 +623,12 @@ static void ftrace_profile_disable_##name(struct ftrace_event_call *unused)\ * .trace = ftrace_raw_output_, <-- stage 2 * }; * - * static int ftrace_raw_init_event_(struct ftrace_event_call *unused) - * { - * int id; - * - * id = register_ftrace_event(&ftrace_event_type_); - * if (!id) - * return -ENODEV; - * event_.id = id; - * return 0; - * } - * * static struct ftrace_event_call __used * __attribute__((__aligned__(4))) * __attribute__((section("_ftrace_events"))) event_ = { * .name = "", * .system = "", - * .raw_init = ftrace_raw_init_event_, + * .raw_init = trace_event_raw_init, * .regfunc = ftrace_reg_event_, * .unregfunc = ftrace_unreg_event_, * .show_format = ftrace_format_, @@ -647,9 +636,6 @@ static void ftrace_profile_disable_##name(struct ftrace_event_call *unused)\ * */ -#undef TP_FMT -#define TP_FMT(fmt, args...) fmt "\n", ##args - #ifdef CONFIG_EVENT_PROFILE #define _TRACE_PROFILE_INIT(call) \ @@ -744,19 +730,7 @@ static void ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused)\ \ static struct trace_event ftrace_event_type_##call = { \ .trace = ftrace_raw_output_##call, \ -}; \ - \ -static int ftrace_raw_init_event_##call(struct ftrace_event_call *unused)\ -{ \ - int id; \ - \ - id = register_ftrace_event(&ftrace_event_type_##call); \ - if (!id) \ - return -ENODEV; \ - event_##call.id = id; \ - INIT_LIST_HEAD(&event_##call.fields); \ - return 0; \ -} +}; #undef DEFINE_EVENT_PRINT #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ @@ -776,7 +750,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ .name = #call, \ .system = __stringify(TRACE_SYSTEM), \ .event = &ftrace_event_type_##call, \ - .raw_init = ftrace_raw_init_event_##call, \ + .raw_init = trace_event_raw_init, \ .regfunc = ftrace_raw_reg_event_##call, \ .unregfunc = ftrace_raw_unreg_event_##call, \ .show_format = ftrace_format_##template, \ @@ -793,7 +767,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ .name = #call, \ .system = __stringify(TRACE_SYSTEM), \ .event = &ftrace_event_type_##call, \ - .raw_init = ftrace_raw_init_event_##call, \ + .raw_init = trace_event_raw_init, \ .regfunc = ftrace_raw_reg_event_##call, \ .unregfunc = ftrace_raw_unreg_event_##call, \ .show_format = ftrace_format_##call, \ @@ -953,7 +927,6 @@ end: \ perf_swevent_put_recursion_context(rctx); \ end_recursion: \ local_irq_restore(irq_flags); \ - \ } #undef DEFINE_EVENT diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 1d18315..8ed66e0 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -105,6 +105,20 @@ void trace_destroy_fields(struct ftrace_event_call *call) } } +int trace_event_raw_init(struct ftrace_event_call *call) +{ + int id; + + id = register_ftrace_event(call->event); + if (!id) + return -ENODEV; + call->id = id; + INIT_LIST_HEAD(&call->fields); + + return 0; +} +EXPORT_SYMBOL_GPL(trace_event_raw_init); + static void ftrace_event_enable_disable(struct ftrace_event_call *call, int enable) { -- cgit v0.10.2 From 614a71a26ba3d97e9fa85649db69a682b78e407d Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 8 Dec 2009 11:14:36 +0800 Subject: tracing: Pull up calls to trace_define_common_fields() Call trace_define_common_fields() in event_create_dir() only. This avoids trace events to handle it from their define_fields callbacks and shrinks the kernel code size: text data bss dec hex filename 5346802 1961864 7103260 14411926 dbe896 vmlinux.o.old 5345151 1961864 7103260 14410275 dbe223 vmlinux.o Signed-off-by: Li Zefan Acked-by: Steven Rostedt Cc: Ingo Molnar Cc: Jason Baron Cc: Masami Hiramatsu LKML-Reference: <4B1DC49C.8000107@cn.fujitsu.com> Signed-off-by: Frederic Weisbecker diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index ea44b89..db97c64 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -159,7 +159,6 @@ enum { }; extern int trace_event_raw_init(struct ftrace_event_call *call); -extern int trace_define_common_fields(struct ftrace_event_call *call); extern int trace_define_field(struct ftrace_event_call *call, const char *type, const char *name, int offset, int size, int is_signed, int filter_type); diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 6055b06..2af2f7a 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -436,10 +436,6 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ struct ftrace_raw_##call field; \ int ret; \ \ - ret = trace_define_common_fields(event_call); \ - if (ret) \ - return ret; \ - \ tstruct; \ \ return ret; \ diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 8ed66e0..97b0b3a 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -78,7 +78,7 @@ EXPORT_SYMBOL_GPL(trace_define_field); if (ret) \ return ret; -int trace_define_common_fields(struct ftrace_event_call *call) +static int trace_define_common_fields(struct ftrace_event_call *call) { int ret; struct trace_entry ent; @@ -91,7 +91,6 @@ int trace_define_common_fields(struct ftrace_event_call *call) return ret; } -EXPORT_SYMBOL_GPL(trace_define_common_fields); void trace_destroy_fields(struct ftrace_event_call *call) { @@ -927,7 +926,9 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, id); if (call->define_fields) { - ret = call->define_fields(call); + ret = trace_define_common_fields(call); + if (!ret) + ret = call->define_fields(call); if (ret < 0) { pr_warning("Could not initialize trace point" " events/%s\n", call->name); diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index dff8c84..458e5bf 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c @@ -184,10 +184,6 @@ ftrace_define_fields_##name(struct ftrace_event_call *event_call) \ struct struct_name field; \ int ret; \ \ - ret = trace_define_common_fields(event_call); \ - if (ret) \ - return ret; \ - \ tstruct; \ \ return ret; \ diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index aff5f80..e3c80e9 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1113,10 +1113,6 @@ static int kprobe_event_define_fields(struct ftrace_event_call *event_call) struct kprobe_trace_entry field; struct trace_probe *tp = (struct trace_probe *)event_call->data; - ret = trace_define_common_fields(event_call); - if (!ret) - return ret; - DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0); DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1); /* Set argument names as fields */ @@ -1131,10 +1127,6 @@ static int kretprobe_event_define_fields(struct ftrace_event_call *event_call) struct kretprobe_trace_entry field; struct trace_probe *tp = (struct trace_probe *)event_call->data; - ret = trace_define_common_fields(event_call); - if (!ret) - return ret; - DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0); DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0); DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1); diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 57501d9..b957edd 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -217,10 +217,6 @@ int syscall_enter_define_fields(struct ftrace_event_call *call) int i; int offset = offsetof(typeof(trace), args); - ret = trace_define_common_fields(call); - if (ret) - return ret; - ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER); if (ret) return ret; @@ -241,10 +237,6 @@ int syscall_exit_define_fields(struct ftrace_event_call *call) struct syscall_trace_exit trace; int ret; - ret = trace_define_common_fields(call); - if (ret) - return ret; - ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER); if (ret) return ret; -- cgit v0.10.2 From 3b8e4273814a7f9e9a74ece517d9206fea919aaa Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 8 Dec 2009 11:14:52 +0800 Subject: tracing: Move a printk out of ftrace_raw_reg_event_foo() Move the printk from each ftrace_raw_reg_event_foo() to its caller ftrace_event_enable_disable(). This avoids each regfunc trace event callbacks to handle a same error report that can be carried from the caller. See how much space this saves: text data bss dec hex filename 5345151 1961864 7103260 14410275 dbe223 vmlinux.o.old 5331487 1961864 7103260 14396611 dbacc3 vmlinux.o Signed-off-by: Li Zefan Acked-by: Steven Rostedt Cc: Jason Baron LKML-Reference: <4B1DC4AC.802@cn.fujitsu.com> [start cmdline record before calling regfunc to avoid lost window of pid to comm resolution] Signed-off-by: Frederic Weisbecker diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 2af2f7a..0c21af8 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -555,13 +555,7 @@ static void ftrace_profile_disable_##name(struct ftrace_event_call *unused)\ * * static int ftrace_reg_event_(struct ftrace_event_call *unused) * { - * int ret; - * - * ret = register_trace_(ftrace_event_); - * if (!ret) - * pr_info("event trace: Could not activate trace point " - * "probe to "); - * return ret; + * return register_trace_(ftrace_event_); * } * * static void ftrace_unreg_event_(struct ftrace_event_call *unused) @@ -710,13 +704,7 @@ static void ftrace_raw_event_##call(proto) \ \ static int ftrace_raw_reg_event_##call(struct ftrace_event_call *unused)\ { \ - int ret; \ - \ - ret = register_trace_##call(ftrace_raw_event_##call); \ - if (ret) \ - pr_info("event trace: Could not activate trace point " \ - "probe to %s\n", #call); \ - return ret; \ + return register_trace_##call(ftrace_raw_event_##call); \ } \ \ static void ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused)\ diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 97b0b3a..189b09b 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -118,9 +118,11 @@ int trace_event_raw_init(struct ftrace_event_call *call) } EXPORT_SYMBOL_GPL(trace_event_raw_init); -static void ftrace_event_enable_disable(struct ftrace_event_call *call, +static int ftrace_event_enable_disable(struct ftrace_event_call *call, int enable) { + int ret = 0; + switch (enable) { case 0: if (call->enabled) { @@ -131,12 +133,20 @@ static void ftrace_event_enable_disable(struct ftrace_event_call *call, break; case 1: if (!call->enabled) { - call->enabled = 1; tracing_start_cmdline_record(); - call->regfunc(call); + ret = call->regfunc(call); + if (ret) { + tracing_stop_cmdline_record(); + pr_info("event trace: Could not enable event " + "%s\n", call->name); + break; + } + call->enabled = 1; } break; } + + return ret; } static void ftrace_clear_events(void) @@ -415,7 +425,7 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, case 0: case 1: mutex_lock(&event_mutex); - ftrace_event_enable_disable(call, val); + ret = ftrace_event_enable_disable(call, val); mutex_unlock(&event_mutex); break; @@ -425,7 +435,7 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, *ppos += cnt; - return cnt; + return ret ? ret : cnt; } static ssize_t diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index b957edd..75289f3 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -325,10 +325,7 @@ int reg_event_syscall_enter(struct ftrace_event_call *call) mutex_lock(&syscall_trace_lock); if (!sys_refcount_enter) ret = register_trace_sys_enter(ftrace_syscall_enter); - if (ret) { - pr_info("event trace: Could not activate" - "syscall entry trace point"); - } else { + if (!ret) { set_bit(num, enabled_enter_syscalls); sys_refcount_enter++; } @@ -362,10 +359,7 @@ int reg_event_syscall_exit(struct ftrace_event_call *call) mutex_lock(&syscall_trace_lock); if (!sys_refcount_exit) ret = register_trace_sys_exit(ftrace_syscall_exit); - if (ret) { - pr_info("event trace: Could not activate" - "syscall exit trace point"); - } else { + if (!ret) { set_bit(num, enabled_exit_syscalls); sys_refcount_exit++; } -- cgit v0.10.2 From 311d16da575f53c3367099579736c1d233efe0dc Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 8 Dec 2009 11:15:11 +0800 Subject: ftrace: Return EINVAL when writing invalid val to set_ftrace_filter Currently it doesn't warn user on invald value: # echo nonexist_symbol > set_ftrace_filter or: # echo 'nonexist_symbol:mod:fuse' > set_ftrace_filter Better make it return failure. Signed-off-by: Li Zefan Acked-by: Steven Rostedt LKML-Reference: <4B1DC4BF.2070003@cn.fujitsu.com> Signed-off-by: Frederic Weisbecker diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index e51a1bc..08a3fb5 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1724,7 +1724,7 @@ ftrace_match_record(struct dyn_ftrace *rec, char *regex, int len, int type) return ftrace_match(str, regex, len, type); } -static void ftrace_match_records(char *buff, int len, int enable) +static int ftrace_match_records(char *buff, int len, int enable) { unsigned int search_len; struct ftrace_page *pg; @@ -1733,6 +1733,7 @@ static void ftrace_match_records(char *buff, int len, int enable) char *search; int type; int not; + int found = 0; flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; type = filter_parse_regex(buff, len, &search, ¬); @@ -1750,6 +1751,7 @@ static void ftrace_match_records(char *buff, int len, int enable) rec->flags &= ~flag; else rec->flags |= flag; + found = 1; } /* * Only enable filtering if we have a function that @@ -1759,6 +1761,8 @@ static void ftrace_match_records(char *buff, int len, int enable) ftrace_filtered = 1; } while_for_each_ftrace_rec(); mutex_unlock(&ftrace_lock); + + return found; } static int @@ -1780,7 +1784,7 @@ ftrace_match_module_record(struct dyn_ftrace *rec, char *mod, return 1; } -static void ftrace_match_module_records(char *buff, char *mod, int enable) +static int ftrace_match_module_records(char *buff, char *mod, int enable) { unsigned search_len = 0; struct ftrace_page *pg; @@ -1789,6 +1793,7 @@ static void ftrace_match_module_records(char *buff, char *mod, int enable) char *search = buff; unsigned long flag; int not = 0; + int found = 0; flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE; @@ -1819,12 +1824,15 @@ static void ftrace_match_module_records(char *buff, char *mod, int enable) rec->flags &= ~flag; else rec->flags |= flag; + found = 1; } if (enable && (rec->flags & FTRACE_FL_FILTER)) ftrace_filtered = 1; } while_for_each_ftrace_rec(); mutex_unlock(&ftrace_lock); + + return found; } /* @@ -1853,8 +1861,9 @@ ftrace_mod_callback(char *func, char *cmd, char *param, int enable) if (!strlen(mod)) return -EINVAL; - ftrace_match_module_records(func, mod, enable); - return 0; + if (ftrace_match_module_records(func, mod, enable)) + return 0; + return -EINVAL; } static struct ftrace_func_command ftrace_mod_cmd = { @@ -2151,8 +2160,9 @@ static int ftrace_process_regex(char *buff, int len, int enable) func = strsep(&next, ":"); if (!next) { - ftrace_match_records(func, len, enable); - return 0; + if (ftrace_match_records(func, len, enable)) + return 0; + return ret; } /* command found */ -- cgit v0.10.2 From 313254a9400d388b46150c0f355e216418a2f598 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 8 Dec 2009 11:15:30 +0800 Subject: ftrace: Call trace_parser_clear() properly I found a weird behavior: # echo 'fuse:*' > set_ftrace_filter bash: echo: write error: Invalid argument # cat set_ftrace_filter fuse_dev_fasync fuse_dev_poll fuse_copy_do We should call trace_parser_clear() no matter ftrace_process_regex() returns 0 or -errno, otherwise we will actually take the unaccepted records from ftrace_regex_release(). Signed-off-by: Li Zefan Acked-by: Steven Rostedt LKML-Reference: <4B1DC4D2.3000406@cn.fujitsu.com> Signed-off-by: Frederic Weisbecker diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 08a3fb5..ff8aecd 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2208,10 +2208,9 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, !trace_parser_cont(parser)) { ret = ftrace_process_regex(parser->buffer, parser->idx, enable); + trace_parser_clear(parser); if (ret) goto out_unlock; - - trace_parser_clear(parser); } ret = read; -- cgit v0.10.2 From 91baf6285be7282cfa487de92f836c50749dffb9 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 8 Dec 2009 11:15:45 +0800 Subject: function-graph: Allow writing the same val to set_graph_function # echo 'do_open' > set_graph_function # echo 'do_open' >> set_graph_function bash: echo: write error: Invalid argument Make it valid to write the same value to set_graph_function, which is consistent with set_ftrace_filter interface. Signed-off-by: Li Zefan Acked-by: Steven Rostedt LKML-reference: <4B1DC4E1.1060303@cn.fujitsu.com> Signed-off-by: Frederic Weisbecker diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index ff8aecd..7968762 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2552,10 +2552,9 @@ ftrace_set_func(unsigned long *array, int *idx, char *buffer) exists = true; break; } - if (!exists) { + if (!exists) array[(*idx)++] = rec->ip; - found = 1; - } + found = 1; } } while_for_each_ftrace_rec(); -- cgit v0.10.2 From fdb372ed4cadbfe9dbba0e932a77d0523682e690 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 8 Dec 2009 11:15:59 +0800 Subject: tracing: Use seq file for trace_options Code simplification for reading trace_options. Signed-off-by: Li Zefan Acked-by: Steven Rostedt LKML-reference: <4B1DC4EF.3090106@cn.fujitsu.com> Signed-off-by: Frederic Weisbecker diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 88bd9ae..a6c41cc 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2316,67 +2316,32 @@ static const struct file_operations tracing_cpumask_fops = { .write = tracing_cpumask_write, }; -static ssize_t -tracing_trace_options_read(struct file *filp, char __user *ubuf, - size_t cnt, loff_t *ppos) +static int tracing_trace_options_show(struct seq_file *m, void *v) { struct tracer_opt *trace_opts; u32 tracer_flags; - int len = 0; - char *buf; - int r = 0; int i; - - /* calculate max size */ - for (i = 0; trace_options[i]; i++) { - len += strlen(trace_options[i]); - len += 3; /* "no" and newline */ - } - mutex_lock(&trace_types_lock); tracer_flags = current_trace->flags->val; trace_opts = current_trace->flags->opts; - /* - * Increase the size with names of options specific - * of the current tracer. - */ - for (i = 0; trace_opts[i].name; i++) { - len += strlen(trace_opts[i].name); - len += 3; /* "no" and newline */ - } - - /* +1 for \0 */ - buf = kmalloc(len + 1, GFP_KERNEL); - if (!buf) { - mutex_unlock(&trace_types_lock); - return -ENOMEM; - } - for (i = 0; trace_options[i]; i++) { if (trace_flags & (1 << i)) - r += sprintf(buf + r, "%s\n", trace_options[i]); + seq_printf(m, "%s\n", trace_options[i]); else - r += sprintf(buf + r, "no%s\n", trace_options[i]); + seq_printf(m, "no%s\n", trace_options[i]); } for (i = 0; trace_opts[i].name; i++) { if (tracer_flags & trace_opts[i].bit) - r += sprintf(buf + r, "%s\n", - trace_opts[i].name); + seq_printf(m, "%s\n", trace_opts[i].name); else - r += sprintf(buf + r, "no%s\n", - trace_opts[i].name); + seq_printf(m, "no%s\n", trace_opts[i].name); } mutex_unlock(&trace_types_lock); - WARN_ON(r >= len + 1); - - r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r); - - kfree(buf); - return r; + return 0; } /* Try to assign a tracer specific option */ @@ -2471,9 +2436,18 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, return cnt; } +static int tracing_trace_options_open(struct inode *inode, struct file *file) +{ + if (tracing_disabled) + return -ENODEV; + return single_open(file, tracing_trace_options_show, NULL); +} + static const struct file_operations tracing_iter_fops = { - .open = tracing_open_generic, - .read = tracing_trace_options_read, + .open = tracing_trace_options_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, .write = tracing_trace_options_write, }; -- cgit v0.10.2 From 13f16d209161c95e92aef40e350cc6cf56ac440b Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 8 Dec 2009 11:16:11 +0800 Subject: tracing: Use seq file for trace_clock The buffer for the output is as small as 64 bytes, so it'll overflow if we add more clock type. Use seq file instead. Signed-off-by: Li Zefan Acked-by: Steven Rostedt LKML-Reference: <4B1DC4FB.5030407@cn.fujitsu.com> Signed-off-by: Frederic Weisbecker diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index a6c41cc..886268e 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -3366,21 +3366,18 @@ tracing_mark_write(struct file *filp, const char __user *ubuf, return cnt; } -static ssize_t tracing_clock_read(struct file *filp, char __user *ubuf, - size_t cnt, loff_t *ppos) +static int tracing_clock_show(struct seq_file *m, void *v) { - char buf[64]; - int bufiter = 0; int i; for (i = 0; i < ARRAY_SIZE(trace_clocks); i++) - bufiter += snprintf(buf + bufiter, sizeof(buf) - bufiter, + seq_printf(m, "%s%s%s%s", i ? " " : "", i == trace_clock_id ? "[" : "", trace_clocks[i].name, i == trace_clock_id ? "]" : ""); - bufiter += snprintf(buf + bufiter, sizeof(buf) - bufiter, "\n"); + seq_putc(m, '\n'); - return simple_read_from_buffer(ubuf, cnt, ppos, buf, bufiter); + return 0; } static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf, @@ -3422,6 +3419,13 @@ static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf, return cnt; } +static int tracing_clock_open(struct inode *inode, struct file *file) +{ + if (tracing_disabled) + return -ENODEV; + return single_open(file, tracing_clock_show, NULL); +} + static const struct file_operations tracing_max_lat_fops = { .open = tracing_open_generic, .read = tracing_max_lat_read, @@ -3460,8 +3464,10 @@ static const struct file_operations tracing_mark_fops = { }; static const struct file_operations trace_clock_fops = { - .open = tracing_open_generic, - .read = tracing_clock_read, + .open = tracing_clock_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, .write = tracing_clock_write, }; -- cgit v0.10.2 From 2cbafd68b826f8e0471875cf33cdfb8a1478aef1 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 8 Dec 2009 11:16:26 +0800 Subject: tracing: Remove useless trace option Since commit 4d9493c90f8e6e1b164aede3814010a290161abb ("ftrace: remove add-hoc code"), option "sched-tree" has become useless. Signed-off-by: Li Zefan Acked-by: Steven Rostedt LKML-Reference: <4B1DC50A.7040402@cn.fujitsu.com> Signed-off-by: Frederic Weisbecker diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 886268e..898409d 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -313,7 +313,6 @@ static const char *trace_options[] = { "bin", "block", "stacktrace", - "sched-tree", "trace_printk", "ftrace_preempt", "branch", diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 7fa33ca..1b18cb2 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -597,18 +597,17 @@ enum trace_iterator_flags { TRACE_ITER_BIN = 0x40, TRACE_ITER_BLOCK = 0x80, TRACE_ITER_STACKTRACE = 0x100, - TRACE_ITER_SCHED_TREE = 0x200, - TRACE_ITER_PRINTK = 0x400, - TRACE_ITER_PREEMPTONLY = 0x800, - TRACE_ITER_BRANCH = 0x1000, - TRACE_ITER_ANNOTATE = 0x2000, - TRACE_ITER_USERSTACKTRACE = 0x4000, - TRACE_ITER_SYM_USEROBJ = 0x8000, - TRACE_ITER_PRINTK_MSGONLY = 0x10000, - TRACE_ITER_CONTEXT_INFO = 0x20000, /* Print pid/cpu/time */ - TRACE_ITER_LATENCY_FMT = 0x40000, - TRACE_ITER_SLEEP_TIME = 0x80000, - TRACE_ITER_GRAPH_TIME = 0x100000, + TRACE_ITER_PRINTK = 0x200, + TRACE_ITER_PREEMPTONLY = 0x400, + TRACE_ITER_BRANCH = 0x800, + TRACE_ITER_ANNOTATE = 0x1000, + TRACE_ITER_USERSTACKTRACE = 0x2000, + TRACE_ITER_SYM_USEROBJ = 0x4000, + TRACE_ITER_PRINTK_MSGONLY = 0x8000, + TRACE_ITER_CONTEXT_INFO = 0x10000, /* Print pid/cpu/time */ + TRACE_ITER_LATENCY_FMT = 0x20000, + TRACE_ITER_SLEEP_TIME = 0x40000, + TRACE_ITER_GRAPH_TIME = 0x80000, }; /* -- cgit v0.10.2 From 8d18eaaff5acaa58369be342c86e607643ce10c7 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 8 Dec 2009 11:17:06 +0800 Subject: tracing: Simplify trace_option_write() - remove duplicate code inside trace_options_write() - extract duplicate code in trace_options_write() and set_tracer_option() Signed-off-by: Li Zefan Acked-by: Steven Rostedt LKML-Reference: <4B1DC532.9010802@cn.fujitsu.com> Signed-off-by: Frederic Weisbecker diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 898409d..0507600 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2343,38 +2343,39 @@ static int tracing_trace_options_show(struct seq_file *m, void *v) return 0; } +static int __set_tracer_option(struct tracer *trace, + struct tracer_flags *tracer_flags, + struct tracer_opt *opts, int neg) +{ + int ret; + + ret = trace->set_flag(tracer_flags->val, opts->bit, !neg); + if (ret) + return ret; + + if (neg) + tracer_flags->val &= ~opts->bit; + else + tracer_flags->val |= opts->bit; + return 0; +} + /* Try to assign a tracer specific option */ static int set_tracer_option(struct tracer *trace, char *cmp, int neg) { struct tracer_flags *tracer_flags = trace->flags; struct tracer_opt *opts = NULL; - int ret = 0, i = 0; - int len; + int i; for (i = 0; tracer_flags->opts[i].name; i++) { opts = &tracer_flags->opts[i]; - len = strlen(opts->name); - if (strncmp(cmp, opts->name, len) == 0) { - ret = trace->set_flag(tracer_flags->val, - opts->bit, !neg); - break; - } + if (strcmp(cmp, opts->name) == 0) + return __set_tracer_option(trace, trace->flags, + opts, neg); } - /* Not found */ - if (!tracer_flags->opts[i].name) - return -EINVAL; - /* Refused to handle */ - if (ret) - return ret; - - if (neg) - tracer_flags->val &= ~opts->bit; - else - tracer_flags->val |= opts->bit; - - return 0; + return -EINVAL; } static void set_tracer_flags(unsigned int mask, int enabled) @@ -2394,7 +2395,7 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[64]; - char *cmp = buf; + char *cmp; int neg = 0; int ret; int i; @@ -2406,16 +2407,15 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, return -EFAULT; buf[cnt] = 0; + cmp = strstrip(buf); - if (strncmp(buf, "no", 2) == 0) { + if (strncmp(cmp, "no", 2) == 0) { neg = 1; cmp += 2; } for (i = 0; trace_options[i]; i++) { - int len = strlen(trace_options[i]); - - if (strncmp(cmp, trace_options[i], len) == 0) { + if (strcmp(cmp, trace_options[i]) == 0) { set_tracer_flags(1 << i, !neg); break; } @@ -3927,39 +3927,16 @@ trace_options_write(struct file *filp, const char __user *ubuf, size_t cnt, if (ret < 0) return ret; - ret = 0; - switch (val) { - case 0: - /* do nothing if already cleared */ - if (!(topt->flags->val & topt->opt->bit)) - break; - - mutex_lock(&trace_types_lock); - if (current_trace->set_flag) - ret = current_trace->set_flag(topt->flags->val, - topt->opt->bit, 0); - mutex_unlock(&trace_types_lock); - if (ret) - return ret; - topt->flags->val &= ~topt->opt->bit; - break; - case 1: - /* do nothing if already set */ - if (topt->flags->val & topt->opt->bit) - break; + if (val != 0 && val != 1) + return -EINVAL; + if (!!(topt->flags->val & topt->opt->bit) != val) { mutex_lock(&trace_types_lock); - if (current_trace->set_flag) - ret = current_trace->set_flag(topt->flags->val, - topt->opt->bit, 1); + ret = __set_tracer_option(current_trace, topt->flags, + topt->opt, val); mutex_unlock(&trace_types_lock); if (ret) return ret; - topt->flags->val |= topt->opt->bit; - break; - - default: - return -EINVAL; } *ppos += cnt; -- cgit v0.10.2 From e00bf2ec60605eb95687b7a0c3b83c87c48541dc Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 8 Dec 2009 11:17:29 +0800 Subject: tracing: Change event->profile_count to be int type Like total_profile_count, struct ftrace_event_call::profile_count is protected by event_mutex, so it doesn't need to be atomic_t. Signed-off-by: Li Zefan Acked-by: Steven Rostedt Cc: Jason Baron Cc: Masami Hiramatsu Cc: Peter Zijlstra LKML-Reference: <4B1DC549.5010705@cn.fujitsu.com> Signed-off-by: Frederic Weisbecker diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index db97c64..2233c98 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -131,7 +131,7 @@ struct ftrace_event_call { void *mod; void *data; - atomic_t profile_count; + int profile_count; int (*profile_enable)(struct ftrace_event_call *); void (*profile_disable)(struct ftrace_event_call *); }; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 94ac284..72d6986 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -102,12 +102,10 @@ struct perf_event_attr; #ifdef CONFIG_EVENT_PROFILE #define TRACE_SYS_ENTER_PROFILE_INIT(sname) \ - .profile_count = ATOMIC_INIT(-1), \ .profile_enable = prof_sysenter_enable, \ .profile_disable = prof_sysenter_disable, #define TRACE_SYS_EXIT_PROFILE_INIT(sname) \ - .profile_count = ATOMIC_INIT(-1), \ .profile_enable = prof_sysexit_enable, \ .profile_disable = prof_sysexit_disable, #else diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 0c21af8..73523151 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -629,7 +629,6 @@ static void ftrace_profile_disable_##name(struct ftrace_event_call *unused)\ #ifdef CONFIG_EVENT_PROFILE #define _TRACE_PROFILE_INIT(call) \ - .profile_count = ATOMIC_INIT(-1), \ .profile_enable = ftrace_profile_enable_##call, \ .profile_disable = ftrace_profile_disable_##call, diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c index d9c60f8..9e25573 100644 --- a/kernel/trace/trace_event_profile.c +++ b/kernel/trace/trace_event_profile.c @@ -25,7 +25,7 @@ static int ftrace_profile_enable_event(struct ftrace_event_call *event) char *buf; int ret = -ENOMEM; - if (atomic_inc_return(&event->profile_count)) + if (event->profile_count++ > 0) return 0; if (!total_profile_count) { @@ -56,7 +56,7 @@ fail_buf_nmi: perf_trace_buf = NULL; } fail_buf: - atomic_dec(&event->profile_count); + event->profile_count--; return ret; } @@ -83,7 +83,7 @@ static void ftrace_profile_disable_event(struct ftrace_event_call *event) { char *buf, *nmi_buf; - if (!atomic_add_negative(-1, &event->profile_count)) + if (--event->profile_count > 0) return; event->profile_disable(event); diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index e3c80e9..6ed2234 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1426,7 +1426,6 @@ static int register_probe_event(struct trace_probe *tp) call->unregfunc = probe_event_disable; #ifdef CONFIG_EVENT_PROFILE - atomic_set(&call->profile_count, -1); call->profile_enable = probe_profile_enable; call->profile_disable = probe_profile_disable; #endif -- cgit v0.10.2 From 472bbe02c92a7a8299d7b16946277d98bb8f4bb7 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 8 Dec 2009 11:17:51 +0800 Subject: tracing/power: Remove two exports trace_power_start and trace_power_end are used in arch/x86/kernel/power.c, and this file can't be compiled as a module, so these two tracepoints don't need to be exported. Signed-off-by: Li Zefan Acked-by: Arjan van de Ven Acked-by: Steven Rostedt LKML-Reference: <4B1DC55F.7060305@cn.fujitsu.com> Signed-off-by: Frederic Weisbecker diff --git a/kernel/trace/power-traces.c b/kernel/trace/power-traces.c index e06c6e3..9f4f565 100644 --- a/kernel/trace/power-traces.c +++ b/kernel/trace/power-traces.c @@ -14,7 +14,5 @@ #define CREATE_TRACE_POINTS #include -EXPORT_TRACEPOINT_SYMBOL_GPL(power_start); -EXPORT_TRACEPOINT_SYMBOL_GPL(power_end); EXPORT_TRACEPOINT_SYMBOL_GPL(power_frequency); -- cgit v0.10.2 From 16620e0f1990fa6d896a639449c4b3d678458464 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 8 Dec 2009 11:18:16 +0800 Subject: ksym_tracer: Fix bad cast Fix this warning: kernel/trace/trace_ksym.c: In function 'ksym_trace_filter_read': kernel/trace/trace_ksym.c:239: warning: cast to pointer from integer of different size Signed-off-by: Li Zefan Acked-by: Steven Rostedt Cc: "K.Prasad" LKML-Reference: <4B1DC578.9020909@cn.fujitsu.com> [remove the strstrip fix as tglx already fixed that] Signed-off-by: Frederic Weisbecker diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c index 64e7a5b..48f1c6c 100644 --- a/kernel/trace/trace_ksym.c +++ b/kernel/trace/trace_ksym.c @@ -235,7 +235,8 @@ static ssize_t ksym_trace_filter_read(struct file *filp, char __user *ubuf, mutex_lock(&ksym_tracer_mutex); hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) { - ret = trace_seq_printf(s, "%pS:", (void *)entry->attr.bp_addr); + ret = trace_seq_printf(s, "%pS:", + (void *)(unsigned long)entry->attr.bp_addr); if (entry->attr.bp_type == HW_BREAKPOINT_R) ret = trace_seq_puts(s, "r--\n"); else if (entry->attr.bp_type == HW_BREAKPOINT_W) @@ -298,8 +299,8 @@ static ssize_t ksym_trace_filter_write(struct file *file, * 2: echo 0 > ksym_trace_filter * 3: echo "*:---" > ksym_trace_filter */ - if (!input_string[0] || !strcmp(input_string, "0") || - !strcmp(input_string, "*:---")) { + if (!buf[0] || !strcmp(buf, "0") || + !strcmp(buf, "*:---")) { __ksym_trace_reset(); ret = 0; goto out; -- cgit v0.10.2 From fcb4ebd678858850e8b029909064175cb627868d Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 11 Dec 2009 22:58:17 +0000 Subject: sh: Couple kernel and user write page perm bits for CONFIG_X2TLB pte_write() should check whether the permissions include either the user or kernel write permission bits. Likewise, pte_wrprotect() needs to remove both the kernel and user write bits. Without this patch handle_tlbmiss() doesn't handle faulting in pages from the P3 area (our vmalloc space) because of a write. Mappings of the P3 space have the _PAGE_EXT_KERN_WRITE bit but not _PAGE_EXT_USER_WRITE. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h index b354355..5003ee8 100644 --- a/arch/sh/include/asm/pgtable_32.h +++ b/arch/sh/include/asm/pgtable_32.h @@ -344,7 +344,8 @@ static inline void set_pte(pte_t *ptep, pte_t pte) #define pte_special(pte) ((pte).pte_low & _PAGE_SPECIAL) #ifdef CONFIG_X2TLB -#define pte_write(pte) ((pte).pte_high & _PAGE_EXT_USER_WRITE) +#define pte_write(pte) \ + ((pte).pte_high & (_PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE)) #else #define pte_write(pte) ((pte).pte_low & _PAGE_RW) #endif @@ -358,7 +359,7 @@ static inline pte_t pte_##fn(pte_t pte) { pte.pte_##h op; return pte; } * individually toggled (and user permissions are entirely decoupled from * kernel permissions), we attempt to couple them a bit more sanely here. */ -PTE_BIT_FUNC(high, wrprotect, &= ~_PAGE_EXT_USER_WRITE); +PTE_BIT_FUNC(high, wrprotect, &= ~(_PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE)); PTE_BIT_FUNC(high, mkwrite, |= _PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE); PTE_BIT_FUNC(high, mkhuge, |= _PAGE_SZHUGE); #else -- cgit v0.10.2 From 1232d88a47626cad13ba82f3a9ea814820bc1c65 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 14 Dec 2009 11:46:09 +0900 Subject: sh: Make the unaligned trap handler always obey notification levels. Presently there are a couple of paths in to the alignment handler, where only the address error path presently quiets the notificiation messages based on the configuration settings. We carry over the notification level tests to the default alignment handler itself incase so that they behave uniformly. Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index 3da5a12..86639be 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c @@ -452,12 +452,18 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, rm = regs->regs[index]; /* shout about fixups */ - if (!expected && printk_ratelimit()) - printk(KERN_NOTICE "Fixing up unaligned %s access " - "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", - user_mode(regs) ? "userspace" : "kernel", - current->comm, task_pid_nr(current), - (void *)regs->pc, instruction); + if (!expected) { + if (user_mode(regs) && (se_usermode & 1) && printk_ratelimit()) + pr_notice("Fixing up unaligned userspace access " + "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", + current->comm, task_pid_nr(current), + (void *)regs->pc, instruction); + else if (se_kernmode_warn && printk_ratelimit()) + pr_notice("Fixing up unaligned kernel access " + "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", + current->comm, task_pid_nr(current), + (void *)regs->pc, instruction); + } ret = -EFAULT; switch (instruction&0xF000) { -- cgit v0.10.2 From 5781b2356cbecb0b73b06ec8c3897cabdfdd0928 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 13 Dec 2009 19:32:39 -0800 Subject: udp: udp_lib_get_port() fix Now we can have a large udp hash table, udp_lib_get_port() loop should be converted to a do {} while (cond) form, or we dont enter it at all if hash table size is exactly 65536. Reported-by: Yinghai Lu Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 1f95348..f0126fd 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -216,9 +216,8 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum, * force rand to be an odd multiple of UDP_HTABLE_SIZE */ rand = (rand | 1) * (udptable->mask + 1); - for (last = first + udptable->mask + 1; - first != last; - first++) { + last = first + udptable->mask + 1; + do { hslot = udp_hashslot(udptable, net, first); bitmap_zero(bitmap, PORTS_PER_CHAIN); spin_lock_bh(&hslot->lock); @@ -238,7 +237,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum, snum += rand; } while (snum != first); spin_unlock_bh(&hslot->lock); - } + } while (++first != last); goto fail; } else { hslot = udp_hashslot(udptable, net, snum); -- cgit v0.10.2 From d90a909e1f3e006a1d57fe11fd417173b6494701 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 12 Dec 2009 22:11:15 +0000 Subject: net: Fix userspace RTM_NEWLINK notifications. I received some bug reports about userspace programs having problems because after RTM_NEWLINK was received they could not immediate access files under /proc/sys/net/ because they had not been registered yet. The original problem was trivially fixed by moving the userspace notification from rtnetlink_event() to the end of register_netdevice(). When testing that change I discovered I was still getting RTM_NEWLINK events before I could access proc and I was also getting RTM_NEWLINK events after I was seeing RTM_DELLINK. Things practically guaranteed to confuse userspace. After a little more investigation these extra notifications proved to be from the new notifiers NETDEV_POST_INIT and NETDEV_UNREGISTER_BATCH hitting the default case in rtnetlink_event, and triggering unnecessary RTM_NEWLINK messages. rtnetlink_event now explicitly handles NETDEV_UNREGISTER_BATCH and NETDEV_POST_INIT to avoid sending the incorrect userspace notifications. Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller diff --git a/net/core/dev.c b/net/core/dev.c index 6fe7d73..be9924f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5035,6 +5035,11 @@ int register_netdevice(struct net_device *dev) rollback_registered(dev); dev->reg_state = NETREG_UNREGISTERED; } + /* + * Prevent userspace races by waiting until the network + * device is fully setup before sending notifications. + */ + rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); out: return ret; @@ -5597,6 +5602,12 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char /* Notify protocols, that a new device appeared. */ call_netdevice_notifiers(NETDEV_REGISTER, dev); + /* + * Prevent userspace races by waiting until the network + * device is fully setup before sending notifications. + */ + rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); + synchronize_net(); err = 0; out: diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 33148a5..794bcb8 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1364,15 +1364,15 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi case NETDEV_UNREGISTER: rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); break; - case NETDEV_REGISTER: - rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); - break; case NETDEV_UP: case NETDEV_DOWN: rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); break; + case NETDEV_POST_INIT: + case NETDEV_REGISTER: case NETDEV_CHANGE: case NETDEV_GOING_DOWN: + case NETDEV_UNREGISTER_BATCH: break; default: rtmsg_ifinfo(RTM_NEWLINK, dev, 0); -- cgit v0.10.2 From c7cd606f60e7679c7f9eee7010f02a6f000209c1 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Sat, 12 Dec 2009 04:13:21 +0000 Subject: can: Fix data length code handling in rx path A valid CAN dataframe can have a data length code (DLC) of 0 .. 8 data bytes. When reading the CAN controllers register the 4-bit value may contain values from 0 .. 15 which may exceed the reserved space in the socket buffer! The ISO 11898-1 Chapter 8.4.2.3 (DLC field) says that register values > 8 should be reduced to 8 without any error reporting or frame drop. This patch introduces a new helper macro to cast a given 4-bit data length code (dlc) to __u8 and ensure the DLC value to be max. 8 bytes. The different handlings in the rx path of the CAN netdevice drivers are fixed. Signed-off-by: Oliver Hartkopp Signed-off-by: Wolfgang Grandegger Signed-off-by: David S. Miller diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index cbe3fce..d0ec178 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -474,7 +474,7 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb, reg_msr = at91_read(priv, AT91_MSR(mb)); if (reg_msr & AT91_MSR_MRTR) cf->can_id |= CAN_RTR_FLAG; - cf->can_dlc = min_t(__u8, (reg_msr >> 16) & 0xf, 8); + cf->can_dlc = get_can_dlc((reg_msr >> 16) & 0xf); *(u32 *)(cf->data + 0) = at91_read(priv, AT91_MDL(mb)); *(u32 *)(cf->data + 4) = at91_read(priv, AT91_MDH(mb)); diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index c7fc1de..0ec1524 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c @@ -392,7 +392,7 @@ static void bfin_can_rx(struct net_device *dev, u16 isrc) cf->can_id |= CAN_RTR_FLAG; /* get data length code */ - cf->can_dlc = bfin_read16(®->chl[obj].dlc); + cf->can_dlc = get_can_dlc(bfin_read16(®->chl[obj].dlc) & 0xF); /* get payload */ for (i = 0; i < 8; i += 2) { diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 78b1b69..9c5a153 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -403,9 +403,8 @@ static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, for (i = 1; i < RXBDAT_OFF; i++) buf[i] = mcp251x_read_reg(spi, RXBCTRL(buf_idx) + i); - len = buf[RXBDLC_OFF] & RXBDLC_LEN_MASK; - if (len > 8) - len = 8; + + len = get_can_dlc(buf[RXBDLC_OFF] & RXBDLC_LEN_MASK); for (; i < (RXBDAT_OFF + len); i++) buf[i] = mcp251x_read_reg(spi, RXBCTRL(buf_idx) + i); } else { @@ -455,13 +454,7 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx) (buf[RXBSIDL_OFF] >> RXBSIDL_SHIFT); } /* Data length */ - frame->can_dlc = buf[RXBDLC_OFF] & RXBDLC_LEN_MASK; - if (frame->can_dlc > 8) { - dev_warn(&spi->dev, "invalid frame recevied\n"); - priv->net->stats.rx_errors++; - dev_kfree_skb(skb); - return; - } + frame->can_dlc = get_can_dlc(buf[RXBDLC_OFF] & RXBDLC_LEN_MASK); memcpy(frame->data, buf + RXBDAT_OFF, frame->can_dlc); priv->net->stats.rx_packets++; diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c index bb06dfb..07346f88 100644 --- a/drivers/net/can/mscan/mscan.c +++ b/drivers/net/can/mscan/mscan.c @@ -297,7 +297,8 @@ static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame) frame->can_id |= can_id >> 1; if (can_id & 1) frame->can_id |= CAN_RTR_FLAG; - frame->can_dlc = in_8(®s->rx.dlr) & 0xf; + + frame->can_dlc = get_can_dlc(in_8(®s->rx.dlr) & 0xf); if (!(frame->can_id & CAN_RTR_FLAG)) { void __iomem *data = ®s->rx.dsr1_0; diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index b4ba88a..542a4f7 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c @@ -293,15 +293,14 @@ static void sja1000_rx(struct net_device *dev) uint8_t fi; uint8_t dreg; canid_t id; - uint8_t dlc; int i; + /* create zero'ed CAN frame buffer */ skb = alloc_can_skb(dev, &cf); if (skb == NULL) return; fi = priv->read_reg(priv, REG_FI); - dlc = fi & 0x0F; if (fi & FI_FF) { /* extended frame format (EFF) */ @@ -318,16 +317,15 @@ static void sja1000_rx(struct net_device *dev) | (priv->read_reg(priv, REG_ID2) >> 5); } - if (fi & FI_RTR) + if (fi & FI_RTR) { id |= CAN_RTR_FLAG; + } else { + cf->can_dlc = get_can_dlc(fi & 0x0F); + for (i = 0; i < cf->can_dlc; i++) + cf->data[i] = priv->read_reg(priv, dreg++); + } cf->can_id = id; - cf->can_dlc = dlc; - for (i = 0; i < dlc; i++) - cf->data[i] = priv->read_reg(priv, dreg++); - - while (i < 8) - cf->data[i++] = 0; /* release receive buffer */ priv->write_reg(priv, REG_CMR, CMD_RRB); @@ -335,7 +333,7 @@ static void sja1000_rx(struct net_device *dev) netif_rx(skb); stats->rx_packets++; - stats->rx_bytes += dlc; + stats->rx_bytes += cf->can_dlc; } static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index 07e8016..5c993c2 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -552,7 +552,7 @@ static int ti_hecc_rx_pkt(struct ti_hecc_priv *priv, int mbxno) data = hecc_read_mbx(priv, mbxno, HECC_CANMCF); if (data & HECC_CANMCF_RTR) cf->can_id |= CAN_RTR_FLAG; - cf->can_dlc = data & 0xF; + cf->can_dlc = get_can_dlc(data & 0xF); data = hecc_read_mbx(priv, mbxno, HECC_CANMDL); *(u32 *)(cf->data) = cpu_to_be32(data); if (cf->can_dlc > 4) { diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 591eb0eb..efbb05c 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -316,7 +316,7 @@ static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg) return; cf->can_id = le32_to_cpu(msg->msg.can_msg.id); - cf->can_dlc = min_t(u8, msg->msg.can_msg.length, 8); + cf->can_dlc = get_can_dlc(msg->msg.can_msg.length & 0xF); if (msg->type == CPC_MSG_TYPE_EXT_CAN_FRAME || msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME) diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index 1ed2a5c..3db7767 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -51,6 +51,15 @@ struct can_priv { struct sk_buff **echo_skb; }; +/* + * get_can_dlc(value) - helper macro to cast a given data length code (dlc) + * to __u8 and ensure the dlc value to be max. 8 bytes. + * + * To be used in the CAN netdriver receive path to ensure conformance with + * ISO 11898-1 Chapter 8.4.2.3 (DLC field) + */ +#define get_can_dlc(i) (min_t(__u8, (i), 8)) + struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max); void free_candev(struct net_device *dev); -- cgit v0.10.2 From e0802793f6f65242760089d8d85a50098706dd26 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Sat, 12 Dec 2009 09:09:05 +0000 Subject: mlx4_core: return a negative error value The return value should be negative. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller diff --git a/drivers/net/mlx4/sense.c b/drivers/net/mlx4/sense.c index f36ae69..015fbe7 100644 --- a/drivers/net/mlx4/sense.c +++ b/drivers/net/mlx4/sense.c @@ -53,7 +53,7 @@ static int mlx4_SENSE_PORT(struct mlx4_dev *dev, int port, if (out_param > 2) { mlx4_err(dev, "Sense returned illegal value: 0x%llx\n", out_param); - return EINVAL; + return -EINVAL; } *type = out_param; -- cgit v0.10.2 From 671c8806c25d06407e348690c09d7c37521eda32 Mon Sep 17 00:00:00 2001 From: Ken Kawasaki Date: Sat, 12 Dec 2009 14:44:11 +0000 Subject: 3c574_cs: disable irq before calling el3_interrupt 3c574_cs, 3c589_cs: disable irq before calling el3_interrupt in the media_check function. Signed-off-by: Ken Kawasaki Signed-off-by: David S. Miller diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 17a2722..98938ea 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -912,7 +912,11 @@ static void media_check(unsigned long arg) if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + Timer) == 0xff)) { if (!lp->fast_poll) printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); + + local_irq_save(flags); el3_interrupt(dev->irq, dev); + local_irq_restore(flags); + lp->fast_poll = HZ; } if (lp->fast_poll) { diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 6f8d7e2..322e11d 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -711,7 +711,11 @@ static void media_check(unsigned long arg) (inb(ioaddr + EL3_TIMER) == 0xff)) { if (!lp->fast_poll) printk(KERN_WARNING "%s: interrupt(s) dropped!\n", dev->name); + + local_irq_save(flags); el3_interrupt(dev->irq, dev); + local_irq_restore(flags); + lp->fast_poll = HZ; } if (lp->fast_poll) { -- cgit v0.10.2 From 710708e82bfbdd392ebdef5743e68fef0fde91a6 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 13 Dec 2009 01:40:55 +0000 Subject: drivers/atm: Correct code taking the size of a pointer sizeof(TstSchedTbl) is just the size of the pointer. Change it to the size of the referenced data. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression *x; expression f; type T; @@ *f(...,(T)x,...) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index f734b34..25a4c86 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -557,7 +557,7 @@ static int ia_cbr_setup (IADEV *dev, struct atm_vcc *vcc) { memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(cbrVC)); } /* while */ // Move this VCI number into this location of the CBR Sched table. - memcpy((caddr_t)TstSchedTbl, (caddr_t)&vcIndex,sizeof(TstSchedTbl)); + memcpy((caddr_t)TstSchedTbl, (caddr_t)&vcIndex, sizeof(*TstSchedTbl)); dev->CbrRemEntries--; toBeAssigned--; } /* while */ -- cgit v0.10.2 From 94de803db748b902a9442fcfd7aad31a2fde43b7 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 13 Dec 2009 01:41:29 +0000 Subject: drivers/net/sfc: Correct code taking the size of a pointer The function efx_iterate_state contains the code memcpy(&payload->msg, payload_msg, sizeof(payload_msg)); This is the only use of payload_msg. The type of payload_msg is changed from a pointer to an array, so that the result of sizeof really is the length of the string. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression *x; expression f; type T; @@ *f(...,(T)x,...) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index 14949bb..af39335 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c @@ -47,7 +47,7 @@ static const unsigned char payload_source[ETH_ALEN] = { 0x00, 0x0f, 0x53, 0x1b, 0x1b, 0x1b, }; -static const char *payload_msg = +static const char payload_msg[] = "Hello world! This is an Efx loopback test in progress!"; /** -- cgit v0.10.2 From 2447f2f3c38d3058d50de93df225ee6ad295932b Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 13 Dec 2009 05:35:45 +0000 Subject: drivers/net/cpmac.c: Correct code taking the size of a pointer sizeof(dev->dev_addr) is the size of a pointer. On the other hand, sizeof(pdata->dev_addr) is the size of an array, so use that instead. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression *x; expression f; type T; @@ *f(...,(T)x,...) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 6782223..8d0be26 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -1163,7 +1163,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev) priv->dev = dev; priv->ring_size = 64; priv->msg_enable = netif_msg_init(debug_level, 0xff); - memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr)); + memcpy(dev->dev_addr, pdata->dev_addr, sizeof(pdata->dev_addr)); snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id); -- cgit v0.10.2 From 6057912d7baad31be9819518674ffad349a065b1 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 13 Dec 2009 05:47:04 +0000 Subject: drivers/net/usb: Correct code taking the size of a pointer sizeof(dev->dev_addr) is the size of a pointer. A few lines above, the size of this field is obtained using netdev->addr_len for a call to memcpy, so do the same here. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression *x; expression f; type T; @@ *f(...,(T)x,...) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index b091e20..f14d225 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -324,7 +324,7 @@ static int rtl8150_set_mac_address(struct net_device *netdev, void *p) dbg("%02X:", netdev->dev_addr[i]); dbg("%02X\n", netdev->dev_addr[i]); /* Set the IDR registers. */ - set_registers(dev, IDR, sizeof(netdev->dev_addr), netdev->dev_addr); + set_registers(dev, IDR, netdev->addr_len, netdev->dev_addr); #ifdef EEPROM_WRITE { u8 cr; -- cgit v0.10.2 From 231d52a7bec6d141883d81dbb5516bff4a07533b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 13 Dec 2009 09:11:06 +0000 Subject: can: CAN_MCP251X should depend on HAS_DMA When building for Sun 3: drivers/net/can/mcp251x.c:1074: undefined reference to `dma_free_coherent' drivers/net/can/mcp251x.c:976: undefined reference to `dma_alloc_coherent' drivers/net/can/mcp251x.c:1050: undefined reference to `dma_free_coherent' Signed-off-by: Geert Uytterhoeven Signed-off-by: David S. Miller diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 8c485aa..05b7517 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -50,7 +50,7 @@ config CAN_TI_HECC config CAN_MCP251X tristate "Microchip MCP251x SPI CAN controllers" - depends on CAN_DEV && SPI + depends on CAN_DEV && SPI && HAS_DMA ---help--- Driver for the Microchip MCP251x SPI CAN controllers. -- cgit v0.10.2 From a4aee5c808fc5bf6889c9012217841eb3fd91a6a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 13 Dec 2009 20:06:07 -0800 Subject: drivers/net/bonding/: : use pr_fmt Add #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt Remove DRV_NAME from pr_s Consolidate long format strings Remove some extra tab indents Remove some unnecessary ()s from pr_s arguments Align pr_ arguments Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index d69e683..0fb7a49 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -20,6 +20,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -352,7 +354,8 @@ static u16 __get_link_speed(struct port *port) } } - pr_debug("Port %d Received link speed %d update from adapter\n", port->actor_port_number, speed); + pr_debug("Port %d Received link speed %d update from adapter\n", + port->actor_port_number, speed); return speed; } @@ -378,12 +381,14 @@ static u8 __get_duplex(struct port *port) switch (slave->duplex) { case DUPLEX_FULL: retval=0x1; - pr_debug("Port %d Received status full duplex update from adapter\n", port->actor_port_number); + pr_debug("Port %d Received status full duplex update from adapter\n", + port->actor_port_number); break; case DUPLEX_HALF: default: retval=0x0; - pr_debug("Port %d Received status NOT full duplex update from adapter\n", port->actor_port_number); + pr_debug("Port %d Received status NOT full duplex update from adapter\n", + port->actor_port_number); break; } } @@ -980,7 +985,9 @@ static void ad_mux_machine(struct port *port) // check if the state machine was changed if (port->sm_mux_state != last_state) { - pr_debug("Mux Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_mux_state); + pr_debug("Mux Machine: Port=%d, Last State=%d, Curr State=%d\n", + port->actor_port_number, last_state, + port->sm_mux_state); switch (port->sm_mux_state) { case AD_MUX_DETACHED: __detach_bond_from_agg(port); @@ -1079,7 +1086,9 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) // check if the State machine was changed or new lacpdu arrived if ((port->sm_rx_state != last_state) || (lacpdu)) { - pr_debug("Rx Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_rx_state); + pr_debug("Rx Machine: Port=%d, Last State=%d, Curr State=%d\n", + port->actor_port_number, last_state, + port->sm_rx_state); switch (port->sm_rx_state) { case AD_RX_INITIALIZE: if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) { @@ -1126,9 +1135,8 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) // detect loopback situation if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) { // INFO_RECEIVED_LOOPBACK_FRAMES - pr_err(DRV_NAME ": %s: An illegal loopback occurred on " - "adapter (%s). Check the configuration to verify that all " - "Adapters are connected to 802.3ad compliant switch ports\n", + pr_err("%s: An illegal loopback occurred on adapter (%s).\n" + "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n", port->slave->dev->master->name, port->slave->dev->name); __release_rx_machine_lock(port); return; @@ -1166,7 +1174,8 @@ static void ad_tx_machine(struct port *port) __update_lacpdu_from_port(port); if (ad_lacpdu_send(port) >= 0) { - pr_debug("Sent LACPDU on port %d\n", port->actor_port_number); + pr_debug("Sent LACPDU on port %d\n", + port->actor_port_number); /* mark ntt as false, so it will not be sent again until demanded */ @@ -1241,7 +1250,9 @@ static void ad_periodic_machine(struct port *port) // check if the state machine was changed if (port->sm_periodic_state != last_state) { - pr_debug("Periodic Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_periodic_state); + pr_debug("Periodic Machine: Port=%d, Last State=%d, Curr State=%d\n", + port->actor_port_number, last_state, + port->sm_periodic_state); switch (port->sm_periodic_state) { case AD_NO_PERIODIC: port->sm_periodic_timer_counter = 0; // zero timer @@ -1298,7 +1309,9 @@ static void ad_port_selection_logic(struct port *port) port->next_port_in_aggregator=NULL; port->actor_port_aggregator_identifier=0; - pr_debug("Port %d left LAG %d\n", port->actor_port_number, temp_aggregator->aggregator_identifier); + pr_debug("Port %d left LAG %d\n", + port->actor_port_number, + temp_aggregator->aggregator_identifier); // if the aggregator is empty, clear its parameters, and set it ready to be attached if (!temp_aggregator->lag_ports) { ad_clear_agg(temp_aggregator); @@ -1307,9 +1320,7 @@ static void ad_port_selection_logic(struct port *port) } } if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list - pr_warning(DRV_NAME ": %s: Warning: Port %d (on %s) " - "was related to aggregator %d but was not " - "on its port list\n", + pr_warning("%s: Warning: Port %d (on %s) was related to aggregator %d but was not on its port list\n", port->slave->dev->master->name, port->actor_port_number, port->slave->dev->name, @@ -1343,7 +1354,9 @@ static void ad_port_selection_logic(struct port *port) port->next_port_in_aggregator=aggregator->lag_ports; port->aggregator->num_of_ports++; aggregator->lag_ports=port; - pr_debug("Port %d joined LAG %d(existing LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier); + pr_debug("Port %d joined LAG %d(existing LAG)\n", + port->actor_port_number, + port->aggregator->aggregator_identifier); // mark this port as selected port->sm_vars |= AD_PORT_SELECTED; @@ -1380,10 +1393,11 @@ static void ad_port_selection_logic(struct port *port) // mark this port as selected port->sm_vars |= AD_PORT_SELECTED; - pr_debug("Port %d joined LAG %d(new LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier); + pr_debug("Port %d joined LAG %d(new LAG)\n", + port->actor_port_number, + port->aggregator->aggregator_identifier); } else { - pr_err(DRV_NAME ": %s: Port %d (on %s) did not find " - "a suitable aggregator\n", + pr_err("%s: Port %d (on %s) did not find a suitable aggregator\n", port->slave->dev->master->name, port->actor_port_number, port->slave->dev->name); } @@ -1460,8 +1474,7 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best, break; default: - pr_warning(DRV_NAME - ": %s: Impossible agg select mode %d\n", + pr_warning("%s: Impossible agg select mode %d\n", curr->slave->dev->master->name, __get_agg_selection_mode(curr->lag_ports)); break; @@ -1546,40 +1559,38 @@ static void ad_agg_selection_logic(struct aggregator *agg) // if there is new best aggregator, activate it if (best) { pr_debug("best Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n", - best->aggregator_identifier, best->num_of_ports, - best->actor_oper_aggregator_key, - best->partner_oper_aggregator_key, - best->is_individual, best->is_active); + best->aggregator_identifier, best->num_of_ports, + best->actor_oper_aggregator_key, + best->partner_oper_aggregator_key, + best->is_individual, best->is_active); pr_debug("best ports %p slave %p %s\n", - best->lag_ports, best->slave, - best->slave ? best->slave->dev->name : "NULL"); + best->lag_ports, best->slave, + best->slave ? best->slave->dev->name : "NULL"); for (agg = __get_first_agg(best->lag_ports); agg; agg = __get_next_agg(agg)) { pr_debug("Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n", - agg->aggregator_identifier, agg->num_of_ports, - agg->actor_oper_aggregator_key, - agg->partner_oper_aggregator_key, - agg->is_individual, agg->is_active); + agg->aggregator_identifier, agg->num_of_ports, + agg->actor_oper_aggregator_key, + agg->partner_oper_aggregator_key, + agg->is_individual, agg->is_active); } // check if any partner replys if (best->is_individual) { - pr_warning(DRV_NAME ": %s: Warning: No 802.3ad" - " response from the link partner for any" - " adapters in the bond\n", - best->slave->dev->master->name); + pr_warning("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n", + best->slave->dev->master->name); } best->is_active = 1; pr_debug("LAG %d chosen as the active LAG\n", - best->aggregator_identifier); + best->aggregator_identifier); pr_debug("Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n", - best->aggregator_identifier, best->num_of_ports, - best->actor_oper_aggregator_key, - best->partner_oper_aggregator_key, - best->is_individual, best->is_active); + best->aggregator_identifier, best->num_of_ports, + best->actor_oper_aggregator_key, + best->partner_oper_aggregator_key, + best->is_individual, best->is_active); // disable the ports that were related to the former active_aggregator if (active) { @@ -1633,7 +1644,8 @@ static void ad_clear_agg(struct aggregator *aggregator) aggregator->lag_ports = NULL; aggregator->is_active = 0; aggregator->num_of_ports = 0; - pr_debug("LAG %d was cleared\n", aggregator->aggregator_identifier); + pr_debug("LAG %d was cleared\n", + aggregator->aggregator_identifier); } } @@ -1728,7 +1740,9 @@ static void ad_initialize_port(struct port *port, int lacp_fast) static void ad_enable_collecting_distributing(struct port *port) { if (port->aggregator->is_active) { - pr_debug("Enabling port %d(LAG %d)\n", port->actor_port_number, port->aggregator->aggregator_identifier); + pr_debug("Enabling port %d(LAG %d)\n", + port->actor_port_number, + port->aggregator->aggregator_identifier); __enable_port(port); } } @@ -1741,7 +1755,9 @@ static void ad_enable_collecting_distributing(struct port *port) static void ad_disable_collecting_distributing(struct port *port) { if (port->aggregator && MAC_ADDRESS_COMPARE(&(port->aggregator->partner_system), &(null_mac_addr))) { - pr_debug("Disabling port %d(LAG %d)\n", port->actor_port_number, port->aggregator->aggregator_identifier); + pr_debug("Disabling port %d(LAG %d)\n", + port->actor_port_number, + port->aggregator->aggregator_identifier); __disable_port(port); } } @@ -1779,7 +1795,8 @@ static void ad_marker_info_send(struct port *port) // send the marker information if (ad_marker_send(port, &marker) >= 0) { - pr_debug("Sent Marker Information on port %d\n", port->actor_port_number); + pr_debug("Sent Marker Information on port %d\n", + port->actor_port_number); } } #endif @@ -1803,7 +1820,8 @@ static void ad_marker_info_received(struct bond_marker *marker_info, // send the marker response if (ad_marker_send(port, &marker) >= 0) { - pr_debug("Sent Marker Response on port %d\n", port->actor_port_number); + pr_debug("Sent Marker Response on port %d\n", + port->actor_port_number); } } @@ -1889,8 +1907,7 @@ int bond_3ad_bind_slave(struct slave *slave) struct aggregator *aggregator; if (bond == NULL) { - pr_err(DRV_NAME ": %s: The slave %s is not attached to " - "its bond\n", + pr_err("%s: The slave %s is not attached to its bond\n", slave->dev->master->name, slave->dev->name); return -1; } @@ -1966,13 +1983,13 @@ void bond_3ad_unbind_slave(struct slave *slave) // if slave is null, the whole port is not initialized if (!port->slave) { - pr_warning(DRV_NAME ": Warning: %s: Trying to " - "unbind an uninitialized port on %s\n", + pr_warning("Warning: %s: Trying to unbind an uninitialized port on %s\n", slave->dev->master->name, slave->dev->name); return; } - pr_debug("Unbinding Link Aggregation Group %d\n", aggregator->aggregator_identifier); + pr_debug("Unbinding Link Aggregation Group %d\n", + aggregator->aggregator_identifier); /* Tell the partner that this port is not suitable for aggregation */ port->actor_oper_port_state &= ~AD_STATE_AGGREGATION; @@ -1996,10 +2013,12 @@ void bond_3ad_unbind_slave(struct slave *slave) // if new aggregator found, copy the aggregator's parameters // and connect the related lag_ports to the new aggregator if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) { - pr_debug("Some port(s) related to LAG %d - replaceing with LAG %d\n", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier); + pr_debug("Some port(s) related to LAG %d - replaceing with LAG %d\n", + aggregator->aggregator_identifier, + new_aggregator->aggregator_identifier); if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) { - pr_info(DRV_NAME ": %s: Removing an active aggregator\n", + pr_info("%s: Removing an active aggregator\n", aggregator->slave->dev->master->name); // select new active aggregator select_new_active_agg = 1; @@ -2030,8 +2049,7 @@ void bond_3ad_unbind_slave(struct slave *slave) ad_agg_selection_logic(__get_first_agg(port)); } } else { - pr_warning(DRV_NAME ": %s: Warning: unbinding aggregator, " - "and could not find a new aggregator for its ports\n", + pr_warning("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n", slave->dev->master->name); } } else { // in case that the only port related to this aggregator is the one we want to remove @@ -2039,7 +2057,7 @@ void bond_3ad_unbind_slave(struct slave *slave) // clear the aggregator ad_clear_agg(aggregator); if (select_new_active_agg) { - pr_info(DRV_NAME ": %s: Removing an active aggregator\n", + pr_info("%s: Removing an active aggregator\n", slave->dev->master->name); // select new active aggregator ad_agg_selection_logic(__get_first_agg(port)); @@ -2066,7 +2084,7 @@ void bond_3ad_unbind_slave(struct slave *slave) // clear the aggregator ad_clear_agg(temp_aggregator); if (select_new_active_agg) { - pr_info(DRV_NAME ": %s: Removing an active aggregator\n", + pr_info("%s: Removing an active aggregator\n", slave->dev->master->name); // select new active aggregator ad_agg_selection_logic(__get_first_agg(port)); @@ -2115,8 +2133,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work) // select the active aggregator for the bond if ((port = __get_first_port(bond))) { if (!port->slave) { - pr_warning(DRV_NAME ": %s: Warning: bond's first port is " - "uninitialized\n", bond->dev->name); + pr_warning("%s: Warning: bond's first port is uninitialized\n", + bond->dev->name); goto re_arm; } @@ -2129,8 +2147,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work) // for each port run the state machines for (port = __get_first_port(bond); port; port = __get_next_port(port)) { if (!port->slave) { - pr_warning(DRV_NAME ": %s: Warning: Found an uninitialized " - "port\n", bond->dev->name); + pr_warning("%s: Warning: Found an uninitialized port\n", + bond->dev->name); goto re_arm; } @@ -2171,15 +2189,15 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u port = &(SLAVE_AD_INFO(slave).port); if (!port->slave) { - pr_warning(DRV_NAME ": %s: Warning: port of slave %s " - "is uninitialized\n", + pr_warning("%s: Warning: port of slave %s is uninitialized\n", slave->dev->name, slave->dev->master->name); return; } switch (lacpdu->subtype) { case AD_TYPE_LACPDU: - pr_debug("Received LACPDU on port %d\n", port->actor_port_number); + pr_debug("Received LACPDU on port %d\n", + port->actor_port_number); ad_rx_machine(lacpdu, port); break; @@ -2188,17 +2206,20 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u switch (((struct bond_marker *)lacpdu)->tlv_type) { case AD_MARKER_INFORMATION_SUBTYPE: - pr_debug("Received Marker Information on port %d\n", port->actor_port_number); + pr_debug("Received Marker Information on port %d\n", + port->actor_port_number); ad_marker_info_received((struct bond_marker *)lacpdu, port); break; case AD_MARKER_RESPONSE_SUBTYPE: - pr_debug("Received Marker Response on port %d\n", port->actor_port_number); + pr_debug("Received Marker Response on port %d\n", + port->actor_port_number); ad_marker_response_received((struct bond_marker *)lacpdu, port); break; default: - pr_debug("Received an unknown Marker subtype on slot %d\n", port->actor_port_number); + pr_debug("Received an unknown Marker subtype on slot %d\n", + port->actor_port_number); } } } @@ -2218,8 +2239,7 @@ void bond_3ad_adapter_speed_changed(struct slave *slave) // if slave is null, the whole port is not initialized if (!port->slave) { - pr_warning(DRV_NAME ": Warning: %s: speed " - "changed for uninitialized port on %s\n", + pr_warning("Warning: %s: speed changed for uninitialized port on %s\n", slave->dev->master->name, slave->dev->name); return; } @@ -2246,8 +2266,7 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave) // if slave is null, the whole port is not initialized if (!port->slave) { - pr_warning(DRV_NAME ": %s: Warning: duplex changed " - "for uninitialized port on %s\n", + pr_warning("%s: Warning: duplex changed for uninitialized port on %s\n", slave->dev->master->name, slave->dev->name); return; } @@ -2275,8 +2294,7 @@ void bond_3ad_handle_link_change(struct slave *slave, char link) // if slave is null, the whole port is not initialized if (!port->slave) { - pr_warning(DRV_NAME ": Warning: %s: link status changed for " - "uninitialized port on %s\n", + pr_warning("Warning: %s: link status changed for uninitialized port on %s\n", slave->dev->master->name, slave->dev->name); return; } @@ -2381,8 +2399,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) } if (bond_3ad_get_active_agg_info(bond, &ad_info)) { - pr_debug(DRV_NAME ": %s: Error: " - "bond_3ad_get_active_agg_info failed\n", dev->name); + pr_debug("%s: Error: bond_3ad_get_active_agg_info failed\n", + dev->name); goto out; } @@ -2391,8 +2409,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) if (slaves_in_agg == 0) { /*the aggregator is empty*/ - pr_debug(DRV_NAME ": %s: Error: active aggregator is empty\n", - dev->name); + pr_debug("%s: Error: active aggregator is empty\n", dev->name); goto out; } @@ -2410,8 +2427,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) } if (slave_agg_no >= 0) { - pr_err(DRV_NAME ": %s: Error: Couldn't find a slave to tx on " - "for aggregator ID %d\n", dev->name, agg_id); + pr_err("%s: Error: Couldn't find a slave to tx on for aggregator ID %d\n", + dev->name, agg_id); goto out; } diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 00ab51e..40fdc41 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -20,6 +20,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -201,8 +203,7 @@ static int tlb_initialize(struct bonding *bond) new_hashtbl = kzalloc(size, GFP_KERNEL); if (!new_hashtbl) { - pr_err(DRV_NAME - ": %s: Error: Failed to allocate TLB hash table\n", + pr_err("%s: Error: Failed to allocate TLB hash table\n", bond->dev->name); return -1; } @@ -514,8 +515,7 @@ static void rlb_update_client(struct rlb_client_info *client_info) client_info->slave->dev->dev_addr, client_info->mac_dst); if (!skb) { - pr_err(DRV_NAME - ": %s: Error: failed to create an ARP packet\n", + pr_err("%s: Error: failed to create an ARP packet\n", client_info->slave->dev->master->name); continue; } @@ -525,8 +525,7 @@ static void rlb_update_client(struct rlb_client_info *client_info) if (client_info->tag) { skb = vlan_put_tag(skb, client_info->vlan_id); if (!skb) { - pr_err(DRV_NAME - ": %s: Error: failed to insert VLAN tag\n", + pr_err("%s: Error: failed to insert VLAN tag\n", client_info->slave->dev->master->name); continue; } @@ -609,9 +608,7 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip) client_info = &(bond_info->rx_hashtbl[hash_index]); if (!client_info->slave) { - pr_err(DRV_NAME - ": %s: Error: found a client with no channel in " - "the client's hash table\n", + pr_err("%s: Error: found a client with no channel in the client's hash table\n", bond->dev->name); continue; } @@ -806,8 +803,7 @@ static int rlb_initialize(struct bonding *bond) new_hashtbl = kmalloc(size, GFP_KERNEL); if (!new_hashtbl) { - pr_err(DRV_NAME - ": %s: Error: Failed to allocate RLB hash table\n", + pr_err("%s: Error: Failed to allocate RLB hash table\n", bond->dev->name); return -1; } @@ -928,8 +924,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]) skb = vlan_put_tag(skb, vlan->vlan_id); if (!skb) { - pr_err(DRV_NAME - ": %s: Error: failed to insert VLAN tag\n", + pr_err("%s: Error: failed to insert VLAN tag\n", bond->dev->name); continue; } @@ -958,11 +953,8 @@ static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw) memcpy(s_addr.sa_data, addr, dev->addr_len); s_addr.sa_family = dev->type; if (dev_set_mac_address(dev, &s_addr)) { - pr_err(DRV_NAME - ": %s: Error: dev_set_mac_address of dev %s failed! ALB " - "mode requires that the base driver support setting " - "the hw address also when the network device's " - "interface is open\n", + pr_err("%s: Error: dev_set_mac_address of dev %s failed!\n" + "ALB mode requires that the base driver support setting the hw address also when the network device's interface is open\n", dev->master->name, dev->name); return -EOPNOTSUPP; } @@ -1169,18 +1161,12 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr, bond->alb_info.rlb_enabled); - pr_warning(DRV_NAME - ": %s: Warning: the hw address of slave %s is " - "in use by the bond; giving it the hw address " - "of %s\n", + pr_warning("%s: Warning: the hw address of slave %s is in use by the bond; giving it the hw address of %s\n", bond->dev->name, slave->dev->name, free_mac_slave->dev->name); } else if (has_bond_addr) { - pr_err(DRV_NAME - ": %s: Error: the hw address of slave %s is in use by the " - "bond; couldn't find a slave with a free hw address to " - "give it (this should not have happened)\n", + pr_err("%s: Error: the hw address of slave %s is in use by the bond; couldn't find a slave with a free hw address to give it (this should not have happened)\n", bond->dev->name, slave->dev->name); return -EFAULT; } diff --git a/drivers/net/bonding/bond_ipv6.c b/drivers/net/bonding/bond_ipv6.c index b72e1dc..6dd64cf 100644 --- a/drivers/net/bonding/bond_ipv6.c +++ b/drivers/net/bonding/bond_ipv6.c @@ -20,6 +20,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -74,20 +76,20 @@ static void bond_na_send(struct net_device *slave_dev, addrconf_addr_solict_mult(daddr, &mcaddr); pr_debug("ipv6 na on slave %s: dest %pI6, src %pI6\n", - slave_dev->name, &mcaddr, daddr); + slave_dev->name, &mcaddr, daddr); skb = ndisc_build_skb(slave_dev, &mcaddr, daddr, &icmp6h, daddr, ND_OPT_TARGET_LL_ADDR); if (!skb) { - pr_err(DRV_NAME ": NA packet allocation failed\n"); + pr_err("NA packet allocation failed\n"); return; } if (vlan_id) { skb = vlan_put_tag(skb, vlan_id); if (!skb) { - pr_err(DRV_NAME ": failed to insert VLAN tag\n"); + pr_err("failed to insert VLAN tag\n"); return; } } @@ -109,8 +111,8 @@ void bond_send_unsolicited_na(struct bonding *bond) struct inet6_dev *idev; int is_router; - pr_debug("bond_send_unsol_na: bond %s slave %s\n", bond->dev->name, - slave ? slave->dev->name : "NULL"); + pr_debug("%s: bond %s slave %s\n", bond->dev->name, + __func__, slave ? slave->dev->name : "NULL"); if (!slave || !bond->send_unsol_na || test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state)) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index af9b9c4..3f0071c 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -31,6 +31,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -260,7 +262,7 @@ static int bond_add_vlan(struct bonding *bond, unsigned short vlan_id) struct vlan_entry *vlan; pr_debug("bond: %s, vlan id %d\n", - (bond ? bond->dev->name : "None"), vlan_id); + (bond ? bond->dev->name : "None"), vlan_id); vlan = kzalloc(sizeof(struct vlan_entry), GFP_KERNEL); if (!vlan) @@ -303,8 +305,8 @@ static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id) if (bond_is_lb(bond)) bond_alb_clear_vlan(bond, vlan_id); - pr_debug("removed VLAN ID %d from bond %s\n", vlan_id, - bond->dev->name); + pr_debug("removed VLAN ID %d from bond %s\n", + vlan_id, bond->dev->name); kfree(vlan); @@ -323,8 +325,8 @@ static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id) } } - pr_debug("couldn't find VLAN ID %d in bond %s\n", vlan_id, - bond->dev->name); + pr_debug("couldn't find VLAN ID %d in bond %s\n", + vlan_id, bond->dev->name); out: write_unlock_bh(&bond->lock); @@ -348,7 +350,7 @@ static int bond_has_challenged_slaves(struct bonding *bond) bond_for_each_slave(bond, slave, i) { if (slave->dev->features & NETIF_F_VLAN_CHALLENGED) { pr_debug("found VLAN challenged slave - %s\n", - slave->dev->name); + slave->dev->name); return 1; } } @@ -499,8 +501,7 @@ static void bond_vlan_rx_add_vid(struct net_device *bond_dev, uint16_t vid) res = bond_add_vlan(bond, vid); if (res) { - pr_err(DRV_NAME - ": %s: Error: Failed to add vlan id %d\n", + pr_err("%s: Error: Failed to add vlan id %d\n", bond_dev->name, vid); } } @@ -534,8 +535,7 @@ static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid) res = bond_del_vlan(bond, vid); if (res) { - pr_err(DRV_NAME - ": %s: Error: Failed to remove vlan id %d\n", + pr_err("%s: Error: Failed to remove vlan id %d\n", bond_dev->name, vid); } } @@ -1053,8 +1053,7 @@ static void bond_do_fail_over_mac(struct bonding *bond, rv = dev_set_mac_address(new_active->dev, &saddr); if (rv) { - pr_err(DRV_NAME - ": %s: Error %d setting MAC of slave %s\n", + pr_err("%s: Error %d setting MAC of slave %s\n", bond->dev->name, -rv, new_active->dev->name); goto out; } @@ -1067,16 +1066,14 @@ static void bond_do_fail_over_mac(struct bonding *bond, rv = dev_set_mac_address(old_active->dev, &saddr); if (rv) - pr_err(DRV_NAME - ": %s: Error %d setting MAC of slave %s\n", + pr_err("%s: Error %d setting MAC of slave %s\n", bond->dev->name, -rv, new_active->dev->name); out: read_lock(&bond->lock); write_lock_bh(&bond->curr_slave_lock); break; default: - pr_err(DRV_NAME - ": %s: bond_do_fail_over_mac impossible: bad policy %d\n", + pr_err("%s: bond_do_fail_over_mac impossible: bad policy %d\n", bond->dev->name, bond->params.fail_over_mac); break; } @@ -1178,11 +1175,9 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) if (new_active->link == BOND_LINK_BACK) { if (USES_PRIMARY(bond->params.mode)) { - pr_info(DRV_NAME - ": %s: making interface %s the new " - "active one %d ms earlier.\n", - bond->dev->name, new_active->dev->name, - (bond->params.updelay - new_active->delay) * bond->params.miimon); + pr_info("%s: making interface %s the new active one %d ms earlier.\n", + bond->dev->name, new_active->dev->name, + (bond->params.updelay - new_active->delay) * bond->params.miimon); } new_active->delay = 0; @@ -1195,10 +1190,8 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP); } else { if (USES_PRIMARY(bond->params.mode)) { - pr_info(DRV_NAME - ": %s: making interface %s the new " - "active one.\n", - bond->dev->name, new_active->dev->name); + pr_info("%s: making interface %s the new active one.\n", + bond->dev->name, new_active->dev->name); } } } @@ -1268,13 +1261,11 @@ void bond_select_active_slave(struct bonding *bond) return; if (netif_carrier_ok(bond->dev)) { - pr_info(DRV_NAME - ": %s: first active interface up!\n", - bond->dev->name); + pr_info("%s: first active interface up!\n", + bond->dev->name); } else { - pr_info(DRV_NAME ": %s: " - "now running without any active interface !\n", - bond->dev->name); + pr_info("%s: now running without any active interface !\n", + bond->dev->name); } } } @@ -1423,16 +1414,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL && slave_ops->ndo_do_ioctl == NULL) { - pr_warning(DRV_NAME - ": %s: Warning: no link monitoring support for %s\n", - bond_dev->name, slave_dev->name); + pr_warning("%s: Warning: no link monitoring support for %s\n", + bond_dev->name, slave_dev->name); } /* bond must be initialized by bond_open() before enslaving */ if (!(bond_dev->flags & IFF_UP)) { - pr_warning(DRV_NAME - " %s: master_dev is not up in bond_enslave\n", - bond_dev->name); + pr_warning("%s: master_dev is not up in bond_enslave\n", + bond_dev->name); } /* already enslaved */ @@ -1446,19 +1435,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) { pr_debug("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name); if (!list_empty(&bond->vlan_list)) { - pr_err(DRV_NAME - ": %s: Error: cannot enslave VLAN " - "challenged slave %s on VLAN enabled " - "bond %s\n", bond_dev->name, slave_dev->name, - bond_dev->name); + pr_err("%s: Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n", + bond_dev->name, slave_dev->name, bond_dev->name); return -EPERM; } else { - pr_warning(DRV_NAME - ": %s: Warning: enslaved VLAN challenged " - "slave %s. Adding VLANs will be blocked as " - "long as %s is part of bond %s\n", - bond_dev->name, slave_dev->name, slave_dev->name, - bond_dev->name); + pr_warning("%s: Warning: enslaved VLAN challenged slave %s. Adding VLANs will be blocked as long as %s is part of bond %s\n", + bond_dev->name, slave_dev->name, + slave_dev->name, bond_dev->name); bond_dev->features |= NETIF_F_VLAN_CHALLENGED; } } else { @@ -1478,8 +1461,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) * enslaving it; the old ifenslave will not. */ if ((slave_dev->flags & IFF_UP)) { - pr_err(DRV_NAME ": %s is up. " - "This may be due to an out of date ifenslave.\n", + pr_err("%s is up. This may be due to an out of date ifenslave.\n", slave_dev->name); res = -EPERM; goto err_undo_flags; @@ -1495,7 +1477,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) if (bond->slave_cnt == 0) { if (bond_dev->type != slave_dev->type) { pr_debug("%s: change device type from %d to %d\n", - bond_dev->name, bond_dev->type, slave_dev->type); + bond_dev->name, + bond_dev->type, slave_dev->type); netdev_bonding_change(bond_dev, NETDEV_BONDING_OLDTYPE); @@ -1507,28 +1490,21 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) netdev_bonding_change(bond_dev, NETDEV_BONDING_NEWTYPE); } } else if (bond_dev->type != slave_dev->type) { - pr_err(DRV_NAME ": %s ether type (%d) is different " - "from other slaves (%d), can not enslave it.\n", - slave_dev->name, - slave_dev->type, bond_dev->type); - res = -EINVAL; - goto err_undo_flags; + pr_err("%s ether type (%d) is different from other slaves (%d), can not enslave it.\n", + slave_dev->name, + slave_dev->type, bond_dev->type); + res = -EINVAL; + goto err_undo_flags; } if (slave_ops->ndo_set_mac_address == NULL) { if (bond->slave_cnt == 0) { - pr_warning(DRV_NAME - ": %s: Warning: The first slave device " - "specified does not support setting the MAC " - "address. Setting fail_over_mac to active.", - bond_dev->name); + pr_warning("%s: Warning: The first slave device specified does not support setting the MAC address. Setting fail_over_mac to active.", + bond_dev->name); bond->params.fail_over_mac = BOND_FOM_ACTIVE; } else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { - pr_err(DRV_NAME - ": %s: Error: The slave device specified " - "does not support setting the MAC address, " - "but fail_over_mac is not set to active.\n" - , bond_dev->name); + pr_err("%s: Error: The slave device specified does not support setting the MAC address, but fail_over_mac is not set to active.\n", + bond_dev->name); res = -EOPNOTSUPP; goto err_undo_flags; } @@ -1655,22 +1631,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) * supported); thus, we don't need to change * the messages for netif_carrier. */ - pr_warning(DRV_NAME - ": %s: Warning: MII and ETHTOOL support not " - "available for interface %s, and " - "arp_interval/arp_ip_target module parameters " - "not specified, thus bonding will not detect " - "link failures! see bonding.txt for details.\n", + pr_warning("%s: Warning: MII and ETHTOOL support not available for interface %s, and arp_interval/arp_ip_target module parameters not specified, thus bonding will not detect link failures! see bonding.txt for details.\n", bond_dev->name, slave_dev->name); } else if (link_reporting == -1) { /* unable get link status using mii/ethtool */ - pr_warning(DRV_NAME - ": %s: Warning: can't get link status from " - "interface %s; the network driver associated " - "with this interface does not support MII or " - "ETHTOOL link status reporting, thus miimon " - "has no effect on this interface.\n", - bond_dev->name, slave_dev->name); + pr_warning("%s: Warning: can't get link status from interface %s; the network driver associated with this interface does not support MII or ETHTOOL link status reporting, thus miimon has no effect on this interface.\n", + bond_dev->name, slave_dev->name); } } @@ -1678,34 +1644,27 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) if (!bond->params.miimon || (bond_check_dev_link(bond, slave_dev, 0) == BMSR_LSTATUS)) { if (bond->params.updelay) { - pr_debug("Initial state of slave_dev is " - "BOND_LINK_BACK\n"); + pr_debug("Initial state of slave_dev is BOND_LINK_BACK\n"); new_slave->link = BOND_LINK_BACK; new_slave->delay = bond->params.updelay; } else { - pr_debug("Initial state of slave_dev is " - "BOND_LINK_UP\n"); + pr_debug("Initial state of slave_dev is BOND_LINK_UP\n"); new_slave->link = BOND_LINK_UP; } new_slave->jiffies = jiffies; } else { - pr_debug("Initial state of slave_dev is " - "BOND_LINK_DOWN\n"); + pr_debug("Initial state of slave_dev is BOND_LINK_DOWN\n"); new_slave->link = BOND_LINK_DOWN; } if (bond_update_speed_duplex(new_slave) && (new_slave->link != BOND_LINK_DOWN)) { - pr_warning(DRV_NAME - ": %s: Warning: failed to get speed and duplex from %s, " - "assumed to be 100Mb/sec and Full.\n", - bond_dev->name, new_slave->dev->name); + pr_warning("%s: Warning: failed to get speed and duplex from %s, assumed to be 100Mb/sec and Full.\n", + bond_dev->name, new_slave->dev->name); if (bond->params.mode == BOND_MODE_8023AD) { - pr_warning(DRV_NAME - ": %s: Warning: Operation of 802.3ad mode requires ETHTOOL " - "support in base driver for proper aggregator " - "selection.\n", bond_dev->name); + pr_warning("%s: Warning: Operation of 802.3ad mode requires ETHTOOL support in base driver for proper aggregator selection.\n", + bond_dev->name); } } @@ -1777,11 +1736,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) if (res) goto err_close; - pr_info(DRV_NAME - ": %s: enslaving %s as a%s interface with a%s link.\n", - bond_dev->name, slave_dev->name, - new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup", - new_slave->link != BOND_LINK_DOWN ? "n up" : " down"); + pr_info("%s: enslaving %s as a%s interface with a%s link.\n", + bond_dev->name, slave_dev->name, + new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup", + new_slave->link != BOND_LINK_DOWN ? "n up" : " down"); /* enslave is successful */ return 0; @@ -1833,8 +1791,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) /* slave is not a slave or master is not master of this slave */ if (!(slave_dev->flags & IFF_SLAVE) || (slave_dev->master != bond_dev)) { - pr_err(DRV_NAME - ": %s: Error: cannot release %s.\n", + pr_err("%s: Error: cannot release %s.\n", bond_dev->name, slave_dev->name); return -EINVAL; } @@ -1844,9 +1801,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) slave = bond_get_slave_by_dev(bond, slave_dev); if (!slave) { /* not a slave of this bond */ - pr_info(DRV_NAME - ": %s: %s not enslaved\n", - bond_dev->name, slave_dev->name); + pr_info("%s: %s not enslaved\n", + bond_dev->name, slave_dev->name); write_unlock_bh(&bond->lock); return -EINVAL; } @@ -1854,14 +1810,10 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) if (!bond->params.fail_over_mac) { if (!compare_ether_addr(bond_dev->dev_addr, slave->perm_hwaddr) && bond->slave_cnt > 1) - pr_warning(DRV_NAME - ": %s: Warning: the permanent HWaddr of %s - " - "%pM - is still in use by %s. " - "Set the HWaddr of %s to a different address " - "to avoid conflicts.\n", - bond_dev->name, slave_dev->name, - slave->perm_hwaddr, - bond_dev->name, slave_dev->name); + pr_warning("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s. Set the HWaddr of %s to a different address to avoid conflicts.\n", + bond_dev->name, slave_dev->name, + slave->perm_hwaddr, + bond_dev->name, slave_dev->name); } /* Inform AD package of unbinding of slave. */ @@ -1872,12 +1824,10 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) bond_3ad_unbind_slave(slave); } - pr_info(DRV_NAME - ": %s: releasing %s interface %s\n", - bond_dev->name, - (slave->state == BOND_STATE_ACTIVE) - ? "active" : "backup", - slave_dev->name); + pr_info("%s: releasing %s interface %s\n", + bond_dev->name, + (slave->state == BOND_STATE_ACTIVE) ? "active" : "backup", + slave_dev->name); oldcurrent = bond->curr_active_slave; @@ -1934,21 +1884,15 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) if (list_empty(&bond->vlan_list)) { bond_dev->features |= NETIF_F_VLAN_CHALLENGED; } else { - pr_warning(DRV_NAME - ": %s: Warning: clearing HW address of %s while it " - "still has VLANs.\n", - bond_dev->name, bond_dev->name); - pr_warning(DRV_NAME - ": %s: When re-adding slaves, make sure the bond's " - "HW address matches its VLANs'.\n", - bond_dev->name); + pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n", + bond_dev->name, bond_dev->name); + pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n", + bond_dev->name); } } else if ((bond_dev->features & NETIF_F_VLAN_CHALLENGED) && !bond_has_challenged_slaves(bond)) { - pr_info(DRV_NAME - ": %s: last VLAN challenged slave %s " - "left bond %s. VLAN blocking is removed\n", - bond_dev->name, slave_dev->name, bond_dev->name); + pr_info("%s: last VLAN challenged slave %s left bond %s. VLAN blocking is removed\n", + bond_dev->name, slave_dev->name, bond_dev->name); bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED; } @@ -2011,8 +1955,8 @@ int bond_release_and_destroy(struct net_device *bond_dev, ret = bond_release(bond_dev, slave_dev); if ((ret == 0) && (bond->slave_cnt == 0)) { - pr_info(DRV_NAME ": %s: destroying bond %s.\n", - bond_dev->name, bond_dev->name); + pr_info("%s: destroying bond %s.\n", + bond_dev->name, bond_dev->name); unregister_netdevice(bond_dev); } return ret; @@ -2116,19 +2060,13 @@ static int bond_release_all(struct net_device *bond_dev) if (list_empty(&bond->vlan_list)) bond_dev->features |= NETIF_F_VLAN_CHALLENGED; else { - pr_warning(DRV_NAME - ": %s: Warning: clearing HW address of %s while it " - "still has VLANs.\n", - bond_dev->name, bond_dev->name); - pr_warning(DRV_NAME - ": %s: When re-adding slaves, make sure the bond's " - "HW address matches its VLANs'.\n", - bond_dev->name); + pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n", + bond_dev->name, bond_dev->name); + pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n", + bond_dev->name); } - pr_info(DRV_NAME - ": %s: released all slaves\n", - bond_dev->name); + pr_info("%s: released all slaves\n", bond_dev->name); out: write_unlock_bh(&bond->lock); @@ -2254,16 +2192,14 @@ static int bond_miimon_inspect(struct bonding *bond) slave->link = BOND_LINK_FAIL; slave->delay = bond->params.downdelay; if (slave->delay) { - pr_info(DRV_NAME - ": %s: link status down for %s" - "interface %s, disabling it in %d ms.\n", - bond->dev->name, - (bond->params.mode == - BOND_MODE_ACTIVEBACKUP) ? - ((slave->state == BOND_STATE_ACTIVE) ? - "active " : "backup ") : "", - slave->dev->name, - bond->params.downdelay * bond->params.miimon); + pr_info("%s: link status down for %sinterface %s, disabling it in %d ms.\n", + bond->dev->name, + (bond->params.mode == + BOND_MODE_ACTIVEBACKUP) ? + ((slave->state == BOND_STATE_ACTIVE) ? + "active " : "backup ") : "", + slave->dev->name, + bond->params.downdelay * bond->params.miimon); } /*FALLTHRU*/ case BOND_LINK_FAIL: @@ -2273,13 +2209,11 @@ static int bond_miimon_inspect(struct bonding *bond) */ slave->link = BOND_LINK_UP; slave->jiffies = jiffies; - pr_info(DRV_NAME - ": %s: link status up again after %d " - "ms for interface %s.\n", - bond->dev->name, - (bond->params.downdelay - slave->delay) * - bond->params.miimon, - slave->dev->name); + pr_info("%s: link status up again after %d ms for interface %s.\n", + bond->dev->name, + (bond->params.downdelay - slave->delay) * + bond->params.miimon, + slave->dev->name); continue; } @@ -2300,25 +2234,21 @@ static int bond_miimon_inspect(struct bonding *bond) slave->delay = bond->params.updelay; if (slave->delay) { - pr_info(DRV_NAME - ": %s: link status up for " - "interface %s, enabling it in %d ms.\n", - bond->dev->name, slave->dev->name, - ignore_updelay ? 0 : - bond->params.updelay * - bond->params.miimon); + pr_info("%s: link status up for interface %s, enabling it in %d ms.\n", + bond->dev->name, slave->dev->name, + ignore_updelay ? 0 : + bond->params.updelay * + bond->params.miimon); } /*FALLTHRU*/ case BOND_LINK_BACK: if (!link_state) { slave->link = BOND_LINK_DOWN; - pr_info(DRV_NAME - ": %s: link status down again after %d " - "ms for interface %s.\n", - bond->dev->name, - (bond->params.updelay - slave->delay) * - bond->params.miimon, - slave->dev->name); + pr_info("%s: link status down again after %d ms for interface %s.\n", + bond->dev->name, + (bond->params.updelay - slave->delay) * + bond->params.miimon, + slave->dev->name); continue; } @@ -2366,10 +2296,8 @@ static void bond_miimon_commit(struct bonding *bond) slave->state = BOND_STATE_BACKUP; } - pr_info(DRV_NAME - ": %s: link status definitely " - "up for interface %s.\n", - bond->dev->name, slave->dev->name); + pr_info("%s: link status definitely up for interface %s.\n", + bond->dev->name, slave->dev->name); /* notify ad that the link status has changed */ if (bond->params.mode == BOND_MODE_8023AD) @@ -2395,10 +2323,8 @@ static void bond_miimon_commit(struct bonding *bond) bond->params.mode == BOND_MODE_8023AD) bond_set_slave_inactive_flags(slave); - pr_info(DRV_NAME - ": %s: link status definitely down for " - "interface %s, disabling it\n", - bond->dev->name, slave->dev->name); + pr_info("%s: link status definitely down for interface %s, disabling it\n", + bond->dev->name, slave->dev->name); if (bond->params.mode == BOND_MODE_8023AD) bond_3ad_handle_link_change(slave, @@ -2414,8 +2340,7 @@ static void bond_miimon_commit(struct bonding *bond) continue; default: - pr_err(DRV_NAME - ": %s: invalid new link %d on slave %s\n", + pr_err("%s: invalid new link %d on slave %s\n", bond->dev->name, slave->new_link, slave->dev->name); slave->new_link = BOND_LINK_NOCHANGE; @@ -2534,19 +2459,19 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_ struct sk_buff *skb; pr_debug("arp %d on slave %s: dst %x src %x vid %d\n", arp_op, - slave_dev->name, dest_ip, src_ip, vlan_id); + slave_dev->name, dest_ip, src_ip, vlan_id); skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip, NULL, slave_dev->dev_addr, NULL); if (!skb) { - pr_err(DRV_NAME ": ARP packet allocation failed\n"); + pr_err("ARP packet allocation failed\n"); return; } if (vlan_id) { skb = vlan_put_tag(skb, vlan_id); if (!skb) { - pr_err(DRV_NAME ": failed to insert VLAN tag\n"); + pr_err("failed to insert VLAN tag\n"); return; } } @@ -2586,9 +2511,8 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) rv = ip_route_output_key(dev_net(bond->dev), &rt, &fl); if (rv) { if (net_ratelimit()) { - pr_warning(DRV_NAME - ": %s: no route to arp_ip_target %pI4\n", - bond->dev->name, &fl.fl4_dst); + pr_warning("%s: no route to arp_ip_target %pI4\n", + bond->dev->name, &fl.fl4_dst); } continue; } @@ -2623,10 +2547,9 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) } if (net_ratelimit()) { - pr_warning(DRV_NAME - ": %s: no path to arp_ip_target %pI4 via rt.dev %s\n", - bond->dev->name, &fl.fl4_dst, - rt->u.dst.dev ? rt->u.dst.dev->name : "NULL"); + pr_warning("%s: no path to arp_ip_target %pI4 via rt.dev %s\n", + bond->dev->name, &fl.fl4_dst, + rt->u.dst.dev ? rt->u.dst.dev->name : "NULL"); } ip_rt_put(rt); } @@ -2644,8 +2567,8 @@ static void bond_send_gratuitous_arp(struct bonding *bond) struct vlan_entry *vlan; struct net_device *vlan_dev; - pr_debug("bond_send_grat_arp: bond %s slave %s\n", bond->dev->name, - slave ? slave->dev->name : "NULL"); + pr_debug("bond_send_grat_arp: bond %s slave %s\n", + bond->dev->name, slave ? slave->dev->name : "NULL"); if (!slave || !bond->send_grat_arp || test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state)) @@ -2674,7 +2597,8 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) { pr_debug("bva: sip %pI4 tip %pI4 t[%d] %pI4 bhti(tip) %d\n", - &sip, &tip, i, &targets[i], bond_has_this_ip(bond, tip)); + &sip, &tip, i, &targets[i], + bond_has_this_ip(bond, tip)); if (sip == targets[i]) { if (bond_has_this_ip(bond, tip)) slave->last_arp_rx = jiffies; @@ -2698,8 +2622,8 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack read_lock(&bond->lock); pr_debug("bond_arp_rcv: bond %s skb->dev %s orig_dev %s\n", - bond->dev->name, skb->dev ? skb->dev->name : "NULL", - orig_dev ? orig_dev->name : "NULL"); + bond->dev->name, skb->dev ? skb->dev->name : "NULL", + orig_dev ? orig_dev->name : "NULL"); slave = bond_get_slave_by_dev(bond, orig_dev); if (!slave || !slave_do_arp_validate(bond, slave)) @@ -2724,9 +2648,9 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack memcpy(&tip, arp_ptr, 4); pr_debug("bond_arp_rcv: %s %s/%d av %d sv %d sip %pI4 tip %pI4\n", - bond->dev->name, slave->dev->name, slave->state, - bond->params.arp_validate, slave_do_arp_validate(bond, slave), - &sip, &tip); + bond->dev->name, slave->dev->name, slave->state, + bond->params.arp_validate, slave_do_arp_validate(bond, slave), + &sip, &tip); /* * Backup slaves won't see the ARP reply, but do come through @@ -2800,17 +2724,14 @@ void bond_loadbalance_arp_mon(struct work_struct *work) * is closed. */ if (!oldcurrent) { - pr_info(DRV_NAME - ": %s: link status definitely " - "up for interface %s, ", - bond->dev->name, - slave->dev->name); + pr_info("%s: link status definitely up for interface %s, ", + bond->dev->name, + slave->dev->name); do_failover = 1; } else { - pr_info(DRV_NAME - ": %s: interface %s is now up\n", - bond->dev->name, - slave->dev->name); + pr_info("%s: interface %s is now up\n", + bond->dev->name, + slave->dev->name); } } } else { @@ -2829,10 +2750,9 @@ void bond_loadbalance_arp_mon(struct work_struct *work) if (slave->link_failure_count < UINT_MAX) slave->link_failure_count++; - pr_info(DRV_NAME - ": %s: interface %s is now down.\n", - bond->dev->name, - slave->dev->name); + pr_info("%s: interface %s is now down.\n", + bond->dev->name, + slave->dev->name); if (slave == oldcurrent) do_failover = 1; @@ -2965,9 +2885,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) slave->link = BOND_LINK_UP; bond->current_arp_slave = NULL; - pr_info(DRV_NAME - ": %s: link status definitely " - "up for interface %s.\n", + pr_info("%s: link status definitely up for interface %s.\n", bond->dev->name, slave->dev->name); if (!bond->curr_active_slave || @@ -2985,9 +2903,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) slave->link = BOND_LINK_DOWN; bond_set_slave_inactive_flags(slave); - pr_info(DRV_NAME - ": %s: link status definitely down for " - "interface %s, disabling it\n", + pr_info("%s: link status definitely down for interface %s, disabling it\n", bond->dev->name, slave->dev->name); if (slave == bond->curr_active_slave) { @@ -2998,8 +2914,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) continue; default: - pr_err(DRV_NAME - ": %s: impossible: new_link %d on slave %s\n", + pr_err("%s: impossible: new_link %d on slave %s\n", bond->dev->name, slave->new_link, slave->dev->name); continue; @@ -3028,9 +2943,9 @@ static void bond_ab_arp_probe(struct bonding *bond) read_lock(&bond->curr_slave_lock); if (bond->current_arp_slave && bond->curr_active_slave) - pr_info(DRV_NAME "PROBE: c_arp %s && cas %s BAD\n", - bond->current_arp_slave->dev->name, - bond->curr_active_slave->dev->name); + pr_info("PROBE: c_arp %s && cas %s BAD\n", + bond->current_arp_slave->dev->name, + bond->curr_active_slave->dev->name); if (bond->curr_active_slave) { bond_arp_send_all(bond, bond->curr_active_slave); @@ -3078,9 +2993,8 @@ static void bond_ab_arp_probe(struct bonding *bond) bond_set_slave_inactive_flags(slave); - pr_info(DRV_NAME - ": %s: backup interface %s is now down.\n", - bond->dev->name, slave->dev->name); + pr_info("%s: backup interface %s is now down.\n", + bond->dev->name, slave->dev->name); } } } @@ -3360,9 +3274,8 @@ static void bond_create_proc_entry(struct bonding *bond) S_IRUGO, bn->proc_dir, &bond_info_fops, bond); if (bond->proc_entry == NULL) - pr_warning(DRV_NAME - ": Warning: Cannot create /proc/net/%s/%s\n", - DRV_NAME, bond_dev->name); + pr_warning("Warning: Cannot create /proc/net/%s/%s\n", + DRV_NAME, bond_dev->name); else memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ); } @@ -3388,9 +3301,8 @@ static void bond_create_proc_dir(struct bond_net *bn) if (!bn->proc_dir) { bn->proc_dir = proc_mkdir(DRV_NAME, bn->net->proc_net); if (!bn->proc_dir) - pr_warning(DRV_NAME - ": Warning: cannot create /proc/net/%s\n", - DRV_NAME); + pr_warning("Warning: cannot create /proc/net/%s\n", + DRV_NAME); } } @@ -3539,8 +3451,8 @@ static int bond_netdev_event(struct notifier_block *this, struct net_device *event_dev = (struct net_device *)ptr; pr_debug("event_dev: %s, event: %lx\n", - (event_dev ? event_dev->name : "None"), - event); + event_dev ? event_dev->name : "None", + event); if (!(event_dev->priv_flags & IFF_BONDING)) return NOTIFY_DONE; @@ -3875,8 +3787,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd struct mii_ioctl_data *mii = NULL; int res = 0; - pr_debug("bond_ioctl: master=%s, cmd=%d\n", - bond_dev->name, cmd); + pr_debug("bond_ioctl: master=%s, cmd=%d\n", bond_dev->name, cmd); switch (cmd) { case SIOCGMIIPHY: @@ -3945,12 +3856,12 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd slave_dev = dev_get_by_name(dev_net(bond_dev), ifr->ifr_slave); - pr_debug("slave_dev=%p: \n", slave_dev); + pr_debug("slave_dev=%p:\n", slave_dev); if (!slave_dev) res = -ENODEV; else { - pr_debug("slave_dev->name=%s: \n", slave_dev->name); + pr_debug("slave_dev->name=%s:\n", slave_dev->name); switch (cmd) { case BOND_ENSLAVE_OLD: case SIOCBONDENSLAVE: @@ -4059,7 +3970,7 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu) int i; pr_debug("bond=%p, name=%s, new_mtu=%d\n", bond, - (bond_dev ? bond_dev->name : "None"), new_mtu); + (bond_dev ? bond_dev->name : "None"), new_mtu); /* Can't hold bond->lock with bh disabled here since * some base drivers panic. On the other hand we can't @@ -4077,8 +3988,10 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu) */ bond_for_each_slave(bond, slave, i) { - pr_debug("s %p s->p %p c_m %p\n", slave, - slave->prev, slave->dev->netdev_ops->ndo_change_mtu); + pr_debug("s %p s->p %p c_m %p\n", + slave, + slave->prev, + slave->dev->netdev_ops->ndo_change_mtu); res = dev_set_mtu(slave->dev, new_mtu); @@ -4108,8 +4021,8 @@ unwind: tmp_res = dev_set_mtu(slave->dev, bond_dev->mtu); if (tmp_res) { - pr_debug("unwind err %d dev %s\n", tmp_res, - slave->dev->name); + pr_debug("unwind err %d dev %s\n", + tmp_res, slave->dev->name); } } @@ -4135,7 +4048,8 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr) return bond_alb_set_mac_address(bond_dev, addr); - pr_debug("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None")); + pr_debug("bond=%p, name=%s\n", + bond, bond_dev ? bond_dev->name : "None"); /* * If fail_over_mac is set to active, do nothing and return @@ -4200,8 +4114,8 @@ unwind: tmp_res = dev_set_mac_address(slave->dev, &tmp_sa); if (tmp_res) { - pr_debug("unwind err %d dev %s\n", tmp_res, - slave->dev->name); + pr_debug("unwind err %d dev %s\n", + tmp_res, slave->dev->name); } } @@ -4357,9 +4271,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) if (tx_dev) { struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); if (!skb2) { - pr_err(DRV_NAME - ": %s: Error: bond_xmit_broadcast(): " - "skb_clone() failed\n", + pr_err("%s: Error: bond_xmit_broadcast(): skb_clone() failed\n", bond_dev->name); continue; } @@ -4425,8 +4337,8 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) return bond_alb_xmit(skb, dev); default: /* Should never happen, mode already checked */ - pr_err(DRV_NAME ": %s: Error: Unknown bonding mode %d\n", - dev->name, bond->params.mode); + pr_err("%s: Error: Unknown bonding mode %d\n", + dev->name, bond->params.mode); WARN_ON_ONCE(1); dev_kfree_skb(skb); return NETDEV_TX_OK; @@ -4462,10 +4374,8 @@ void bond_set_mode_ops(struct bonding *bond, int mode) break; default: /* Should never happen, mode already checked */ - pr_err(DRV_NAME - ": %s: Error: Unknown bonding mode %d\n", - bond_dev->name, - mode); + pr_err("%s: Error: Unknown bonding mode %d\n", + bond_dev->name, mode); break; } } @@ -4650,8 +4560,7 @@ static int bond_check_params(struct bond_params *params) if (mode) { bond_mode = bond_parse_parm(mode, bond_mode_tbl); if (bond_mode == -1) { - pr_err(DRV_NAME - ": Error: Invalid bonding mode \"%s\"\n", + pr_err("Error: Invalid bonding mode \"%s\"\n", mode == NULL ? "NULL" : mode); return -EINVAL; } @@ -4660,16 +4569,13 @@ static int bond_check_params(struct bond_params *params) if (xmit_hash_policy) { if ((bond_mode != BOND_MODE_XOR) && (bond_mode != BOND_MODE_8023AD)) { - pr_info(DRV_NAME - ": xmit_hash_policy param is irrelevant in" - " mode %s\n", + pr_info("xmit_hash_policy param is irrelevant in mode %s\n", bond_mode_name(bond_mode)); } else { xmit_hashtype = bond_parse_parm(xmit_hash_policy, xmit_hashtype_tbl); if (xmit_hashtype == -1) { - pr_err(DRV_NAME - ": Error: Invalid xmit_hash_policy \"%s\"\n", + pr_err("Error: Invalid xmit_hash_policy \"%s\"\n", xmit_hash_policy == NULL ? "NULL" : xmit_hash_policy); return -EINVAL; @@ -4679,14 +4585,12 @@ static int bond_check_params(struct bond_params *params) if (lacp_rate) { if (bond_mode != BOND_MODE_8023AD) { - pr_info(DRV_NAME - ": lacp_rate param is irrelevant in mode %s\n", - bond_mode_name(bond_mode)); + pr_info("lacp_rate param is irrelevant in mode %s\n", + bond_mode_name(bond_mode)); } else { lacp_fast = bond_parse_parm(lacp_rate, bond_lacp_tbl); if (lacp_fast == -1) { - pr_err(DRV_NAME - ": Error: Invalid lacp rate \"%s\"\n", + pr_err("Error: Invalid lacp rate \"%s\"\n", lacp_rate == NULL ? "NULL" : lacp_rate); return -EINVAL; } @@ -4696,82 +4600,64 @@ static int bond_check_params(struct bond_params *params) if (ad_select) { params->ad_select = bond_parse_parm(ad_select, ad_select_tbl); if (params->ad_select == -1) { - pr_err(DRV_NAME - ": Error: Invalid ad_select \"%s\"\n", + pr_err("Error: Invalid ad_select \"%s\"\n", ad_select == NULL ? "NULL" : ad_select); return -EINVAL; } if (bond_mode != BOND_MODE_8023AD) { - pr_warning(DRV_NAME - ": ad_select param only affects 802.3ad mode\n"); + pr_warning("ad_select param only affects 802.3ad mode\n"); } } else { params->ad_select = BOND_AD_STABLE; } if (max_bonds < 0) { - pr_warning(DRV_NAME - ": Warning: max_bonds (%d) not in range %d-%d, so it " - "was reset to BOND_DEFAULT_MAX_BONDS (%d)\n", - max_bonds, 0, INT_MAX, BOND_DEFAULT_MAX_BONDS); + pr_warning("Warning: max_bonds (%d) not in range %d-%d, so it was reset to BOND_DEFAULT_MAX_BONDS (%d)\n", + max_bonds, 0, INT_MAX, BOND_DEFAULT_MAX_BONDS); max_bonds = BOND_DEFAULT_MAX_BONDS; } if (miimon < 0) { - pr_warning(DRV_NAME - ": Warning: miimon module parameter (%d), " - "not in range 0-%d, so it was reset to %d\n", - miimon, INT_MAX, BOND_LINK_MON_INTERV); + pr_warning("Warning: miimon module parameter (%d), not in range 0-%d, so it was reset to %d\n", + miimon, INT_MAX, BOND_LINK_MON_INTERV); miimon = BOND_LINK_MON_INTERV; } if (updelay < 0) { - pr_warning(DRV_NAME - ": Warning: updelay module parameter (%d), " - "not in range 0-%d, so it was reset to 0\n", - updelay, INT_MAX); + pr_warning("Warning: updelay module parameter (%d), not in range 0-%d, so it was reset to 0\n", + updelay, INT_MAX); updelay = 0; } if (downdelay < 0) { - pr_warning(DRV_NAME - ": Warning: downdelay module parameter (%d), " - "not in range 0-%d, so it was reset to 0\n", - downdelay, INT_MAX); + pr_warning("Warning: downdelay module parameter (%d), not in range 0-%d, so it was reset to 0\n", + downdelay, INT_MAX); downdelay = 0; } if ((use_carrier != 0) && (use_carrier != 1)) { - pr_warning(DRV_NAME - ": Warning: use_carrier module parameter (%d), " - "not of valid value (0/1), so it was set to 1\n", - use_carrier); + pr_warning("Warning: use_carrier module parameter (%d), not of valid value (0/1), so it was set to 1\n", + use_carrier); use_carrier = 1; } if (num_grat_arp < 0 || num_grat_arp > 255) { - pr_warning(DRV_NAME - ": Warning: num_grat_arp (%d) not in range 0-255 so it " - "was reset to 1 \n", num_grat_arp); + pr_warning("Warning: num_grat_arp (%d) not in range 0-255 so it was reset to 1 \n", + num_grat_arp); num_grat_arp = 1; } if (num_unsol_na < 0 || num_unsol_na > 255) { - pr_warning(DRV_NAME - ": Warning: num_unsol_na (%d) not in range 0-255 so it " - "was reset to 1 \n", num_unsol_na); + pr_warning("Warning: num_unsol_na (%d) not in range 0-255 so it was reset to 1 \n", + num_unsol_na); num_unsol_na = 1; } /* reset values for 802.3ad */ if (bond_mode == BOND_MODE_8023AD) { if (!miimon) { - pr_warning(DRV_NAME - ": Warning: miimon must be specified, " - "otherwise bonding will not detect link " - "failure, speed and duplex which are " - "essential for 802.3ad operation\n"); + pr_warning("Warning: miimon must be specified, otherwise bonding will not detect link failure, speed and duplex which are essential for 802.3ad operation\n"); pr_warning("Forcing miimon to 100msec\n"); miimon = 100; } @@ -4781,24 +4667,15 @@ static int bond_check_params(struct bond_params *params) if ((bond_mode == BOND_MODE_TLB) || (bond_mode == BOND_MODE_ALB)) { if (!miimon) { - pr_warning(DRV_NAME - ": Warning: miimon must be specified, " - "otherwise bonding will not detect link " - "failure and link speed which are essential " - "for TLB/ALB load balancing\n"); + pr_warning("Warning: miimon must be specified, otherwise bonding will not detect link failure and link speed which are essential for TLB/ALB load balancing\n"); pr_warning("Forcing miimon to 100msec\n"); miimon = 100; } } if (bond_mode == BOND_MODE_ALB) { - pr_notice(DRV_NAME - ": In ALB mode you might experience client " - "disconnections upon reconnection of a link if the " - "bonding module updelay parameter (%d msec) is " - "incompatible with the forwarding delay time of the " - "switch\n", - updelay); + pr_notice("In ALB mode you might experience client disconnections upon reconnection of a link if the bonding module updelay parameter (%d msec) is incompatible with the forwarding delay time of the switch\n", + updelay); } if (!miimon) { @@ -4806,49 +4683,37 @@ static int bond_check_params(struct bond_params *params) /* just warn the user the up/down delay will have * no effect since miimon is zero... */ - pr_warning(DRV_NAME - ": Warning: miimon module parameter not set " - "and updelay (%d) or downdelay (%d) module " - "parameter is set; updelay and downdelay have " - "no effect unless miimon is set\n", - updelay, downdelay); + pr_warning("Warning: miimon module parameter not set and updelay (%d) or downdelay (%d) module parameter is set; updelay and downdelay have no effect unless miimon is set\n", + updelay, downdelay); } } else { /* don't allow arp monitoring */ if (arp_interval) { - pr_warning(DRV_NAME - ": Warning: miimon (%d) and arp_interval (%d) " - "can't be used simultaneously, disabling ARP " - "monitoring\n", - miimon, arp_interval); + pr_warning("Warning: miimon (%d) and arp_interval (%d) can't be used simultaneously, disabling ARP monitoring\n", + miimon, arp_interval); arp_interval = 0; } if ((updelay % miimon) != 0) { - pr_warning(DRV_NAME - ": Warning: updelay (%d) is not a multiple " - "of miimon (%d), updelay rounded to %d ms\n", - updelay, miimon, (updelay / miimon) * miimon); + pr_warning("Warning: updelay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n", + updelay, miimon, + (updelay / miimon) * miimon); } updelay /= miimon; if ((downdelay % miimon) != 0) { - pr_warning(DRV_NAME - ": Warning: downdelay (%d) is not a multiple " - "of miimon (%d), downdelay rounded to %d ms\n", - downdelay, miimon, - (downdelay / miimon) * miimon); + pr_warning("Warning: downdelay (%d) is not a multiple of miimon (%d), downdelay rounded to %d ms\n", + downdelay, miimon, + (downdelay / miimon) * miimon); } downdelay /= miimon; } if (arp_interval < 0) { - pr_warning(DRV_NAME - ": Warning: arp_interval module parameter (%d) " - ", not in range 0-%d, so it was reset to %d\n", - arp_interval, INT_MAX, BOND_LINK_ARP_INTERV); + pr_warning("Warning: arp_interval module parameter (%d) , not in range 0-%d, so it was reset to %d\n", + arp_interval, INT_MAX, BOND_LINK_ARP_INTERV); arp_interval = BOND_LINK_ARP_INTERV; } @@ -4858,10 +4723,8 @@ static int bond_check_params(struct bond_params *params) /* not complete check, but should be good enough to catch mistakes */ if (!isdigit(arp_ip_target[arp_ip_count][0])) { - pr_warning(DRV_NAME - ": Warning: bad arp_ip_target module parameter " - "(%s), ARP monitoring will not be performed\n", - arp_ip_target[arp_ip_count]); + pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", + arp_ip_target[arp_ip_count]); arp_interval = 0; } else { __be32 ip = in_aton(arp_ip_target[arp_ip_count]); @@ -4871,31 +4734,25 @@ static int bond_check_params(struct bond_params *params) if (arp_interval && !arp_ip_count) { /* don't allow arping if no arp_ip_target given... */ - pr_warning(DRV_NAME - ": Warning: arp_interval module parameter (%d) " - "specified without providing an arp_ip_target " - "parameter, arp_interval was reset to 0\n", - arp_interval); + pr_warning("Warning: arp_interval module parameter (%d) specified without providing an arp_ip_target parameter, arp_interval was reset to 0\n", + arp_interval); arp_interval = 0; } if (arp_validate) { if (bond_mode != BOND_MODE_ACTIVEBACKUP) { - pr_err(DRV_NAME - ": arp_validate only supported in active-backup mode\n"); + pr_err("arp_validate only supported in active-backup mode\n"); return -EINVAL; } if (!arp_interval) { - pr_err(DRV_NAME - ": arp_validate requires arp_interval\n"); + pr_err("arp_validate requires arp_interval\n"); return -EINVAL; } arp_validate_value = bond_parse_parm(arp_validate, arp_validate_tbl); if (arp_validate_value == -1) { - pr_err(DRV_NAME - ": Error: invalid arp_validate \"%s\"\n", + pr_err("Error: invalid arp_validate \"%s\"\n", arp_validate == NULL ? "NULL" : arp_validate); return -EINVAL; } @@ -4903,17 +4760,14 @@ static int bond_check_params(struct bond_params *params) arp_validate_value = 0; if (miimon) { - pr_info(DRV_NAME - ": MII link monitoring set to %d ms\n", - miimon); + pr_info("MII link monitoring set to %d ms\n", miimon); } else if (arp_interval) { int i; - pr_info(DRV_NAME ": ARP monitoring set to %d ms," - " validate %s, with %d target(s):", - arp_interval, - arp_validate_tbl[arp_validate_value].modename, - arp_ip_count); + pr_info("ARP monitoring set to %d ms, validate %s, with %d target(s):", + arp_interval, + arp_validate_tbl[arp_validate_value].modename, + arp_ip_count); for (i = 0; i < arp_ip_count; i++) pr_info(" %s", arp_ip_target[i]); @@ -4924,21 +4778,15 @@ static int bond_check_params(struct bond_params *params) /* miimon and arp_interval not set, we need one so things * work as expected, see bonding.txt for details */ - pr_warning(DRV_NAME - ": Warning: either miimon or arp_interval and " - "arp_ip_target module parameters must be specified, " - "otherwise bonding will not detect link failures! see " - "bonding.txt for details.\n"); + pr_warning("Warning: either miimon or arp_interval and arp_ip_target module parameters must be specified, otherwise bonding will not detect link failures! see bonding.txt for details.\n"); } if (primary && !USES_PRIMARY(bond_mode)) { /* currently, using a primary only makes sense * in active backup, TLB or ALB modes */ - pr_warning(DRV_NAME - ": Warning: %s primary device specified but has no " - "effect in %s mode\n", - primary, bond_mode_name(bond_mode)); + pr_warning("Warning: %s primary device specified but has no effect in %s mode\n", + primary, bond_mode_name(bond_mode)); primary = NULL; } @@ -4946,8 +4794,7 @@ static int bond_check_params(struct bond_params *params) primary_reselect_value = bond_parse_parm(primary_reselect, pri_reselect_tbl); if (primary_reselect_value == -1) { - pr_err(DRV_NAME - ": Error: Invalid primary_reselect \"%s\"\n", + pr_err("Error: Invalid primary_reselect \"%s\"\n", primary_reselect == NULL ? "NULL" : primary_reselect); return -EINVAL; @@ -4960,16 +4807,13 @@ static int bond_check_params(struct bond_params *params) fail_over_mac_value = bond_parse_parm(fail_over_mac, fail_over_mac_tbl); if (fail_over_mac_value == -1) { - pr_err(DRV_NAME - ": Error: invalid fail_over_mac \"%s\"\n", + pr_err("Error: invalid fail_over_mac \"%s\"\n", arp_validate == NULL ? "NULL" : arp_validate); return -EINVAL; } if (bond_mode != BOND_MODE_ACTIVEBACKUP) - pr_warning(DRV_NAME - ": Warning: fail_over_mac only affects " - "active-backup mode.\n"); + pr_warning("Warning: fail_over_mac only affects active-backup mode.\n"); } else { fail_over_mac_value = BOND_FOM_NONE; } @@ -5076,8 +4920,7 @@ int bond_create(struct net *net, const char *name) bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "", bond_setup); if (!bond_dev) { - pr_err(DRV_NAME ": %s: eek! can't alloc netdev!\n", - name); + pr_err("%s: eek! can't alloc netdev!\n", name); res = -ENOMEM; goto out; } diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 4e00b4f..5acd557 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -19,6 +19,9 @@ * file called LICENSE. * */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -109,11 +112,10 @@ static ssize_t bonding_store_bonds(struct class *cls, goto err_no_cmd; if (command[0] == '+') { - pr_info(DRV_NAME - ": %s is being created...\n", ifname); + pr_info("%s is being created...\n", ifname); rv = bond_create(net, ifname); if (rv) { - pr_info(DRV_NAME ": Bond creation failed.\n"); + pr_info("Bond creation failed.\n"); res = rv; } } else if (command[0] == '-') { @@ -122,12 +124,10 @@ static ssize_t bonding_store_bonds(struct class *cls, rtnl_lock(); bond_dev = bond_get_by_name(net, ifname); if (bond_dev) { - pr_info(DRV_NAME ": %s is being deleted...\n", - ifname); + pr_info("%s is being deleted...\n", ifname); unregister_netdevice(bond_dev); } else { - pr_err(DRV_NAME ": unable to delete non-existent %s\n", - ifname); + pr_err("unable to delete non-existent %s\n", ifname); res = -ENODEV; } rtnl_unlock(); @@ -140,8 +140,7 @@ static ssize_t bonding_store_bonds(struct class *cls, return res; err_no_cmd: - pr_err(DRV_NAME ": no command found in bonding_masters." - " Use +ifname or -ifname.\n"); + pr_err("no command found in bonding_masters. Use +ifname or -ifname.\n"); return -EPERM; } @@ -225,8 +224,8 @@ static ssize_t bonding_store_slaves(struct device *d, /* Quick sanity check -- is the bond interface up? */ if (!(bond->dev->flags & IFF_UP)) { - pr_warning(DRV_NAME ": %s: doing slave updates when " - "interface is down.\n", bond->dev->name); + pr_warning("%s: doing slave updates when interface is down.\n", + bond->dev->name); } /* Note: We can't hold bond->lock here, as bond_create grabs it. */ @@ -247,17 +246,14 @@ static ssize_t bonding_store_slaves(struct device *d, dev = __dev_get_by_name(dev_net(bond->dev), ifname); if (!dev) { - pr_info(DRV_NAME - ": %s: Interface %s does not exist!\n", - bond->dev->name, ifname); + pr_info("%s: Interface %s does not exist!\n", + bond->dev->name, ifname); ret = -ENODEV; goto out; } if (dev->flags & IFF_UP) { - pr_err(DRV_NAME - ": %s: Error: Unable to enslave %s " - "because it is already up.\n", + pr_err("%s: Error: Unable to enslave %s because it is already up.\n", bond->dev->name, dev->name); ret = -EPERM; goto out; @@ -266,8 +262,7 @@ static ssize_t bonding_store_slaves(struct device *d, read_lock(&bond->lock); bond_for_each_slave(bond, slave, i) if (slave->dev == dev) { - pr_err(DRV_NAME - ": %s: Interface %s is already enslaved!\n", + pr_err("%s: Interface %s is already enslaved!\n", bond->dev->name, ifname); ret = -EPERM; read_unlock(&bond->lock); @@ -275,8 +270,7 @@ static ssize_t bonding_store_slaves(struct device *d, } read_unlock(&bond->lock); - pr_info(DRV_NAME ": %s: Adding slave %s.\n", - bond->dev->name, ifname); + pr_info("%s: Adding slave %s.\n", bond->dev->name, ifname); /* If this is the first slave, then we need to set the master's hardware address to be the same as the @@ -313,7 +307,7 @@ static ssize_t bonding_store_slaves(struct device *d, break; } if (dev) { - pr_info(DRV_NAME ": %s: Removing slave %s\n", + pr_info("%s: Removing slave %s\n", bond->dev->name, dev->name); res = bond_release(bond->dev, dev); if (res) { @@ -323,16 +317,16 @@ static ssize_t bonding_store_slaves(struct device *d, /* set the slave MTU to the default */ dev_set_mtu(dev, original_mtu); } else { - pr_err(DRV_NAME ": unable to remove non-existent" - " slave %s for bond %s.\n", - ifname, bond->dev->name); + pr_err("unable to remove non-existent slave %s for bond %s.\n", + ifname, bond->dev->name); ret = -ENODEV; } goto out; } err_no_cmd: - pr_err(DRV_NAME ": no command found in slaves file for bond %s. Use +ifname or -ifname.\n", bond->dev->name); + pr_err("no command found in slaves file for bond %s. Use +ifname or -ifname.\n", + bond->dev->name); ret = -EPERM; out: @@ -365,18 +359,16 @@ static ssize_t bonding_store_mode(struct device *d, struct bonding *bond = to_bond(d); if (bond->dev->flags & IFF_UP) { - pr_err(DRV_NAME ": unable to update mode of %s" - " because interface is up.\n", bond->dev->name); + pr_err("unable to update mode of %s because interface is up.\n", + bond->dev->name); ret = -EPERM; goto out; } new_value = bond_parse_parm(buf, bond_mode_tbl); if (new_value < 0) { - pr_err(DRV_NAME - ": %s: Ignoring invalid mode value %.*s.\n", - bond->dev->name, - (int)strlen(buf) - 1, buf); + pr_err("%s: Ignoring invalid mode value %.*s.\n", + bond->dev->name, (int)strlen(buf) - 1, buf); ret = -EINVAL; goto out; } else { @@ -388,8 +380,8 @@ static ssize_t bonding_store_mode(struct device *d, bond->params.mode = new_value; bond_set_mode_ops(bond, bond->params.mode); - pr_info(DRV_NAME ": %s: setting mode to %s (%d).\n", - bond->dev->name, bond_mode_tbl[new_value].modename, + pr_info("%s: setting mode to %s (%d).\n", + bond->dev->name, bond_mode_tbl[new_value].modename, new_value); } out: @@ -421,8 +413,7 @@ static ssize_t bonding_store_xmit_hash(struct device *d, struct bonding *bond = to_bond(d); if (bond->dev->flags & IFF_UP) { - pr_err(DRV_NAME - "%s: Interface is up. Unable to update xmit policy.\n", + pr_err("%s: Interface is up. Unable to update xmit policy.\n", bond->dev->name); ret = -EPERM; goto out; @@ -430,8 +421,7 @@ static ssize_t bonding_store_xmit_hash(struct device *d, new_value = bond_parse_parm(buf, xmit_hashtype_tbl); if (new_value < 0) { - pr_err(DRV_NAME - ": %s: Ignoring invalid xmit hash policy value %.*s.\n", + pr_err("%s: Ignoring invalid xmit hash policy value %.*s.\n", bond->dev->name, (int)strlen(buf) - 1, buf); ret = -EINVAL; @@ -439,7 +429,7 @@ static ssize_t bonding_store_xmit_hash(struct device *d, } else { bond->params.xmit_policy = new_value; bond_set_mode_ops(bond, bond->params.mode); - pr_info(DRV_NAME ": %s: setting xmit hash policy to %s (%d).\n", + pr_info("%s: setting xmit hash policy to %s (%d).\n", bond->dev->name, xmit_hashtype_tbl[new_value].modename, new_value); } @@ -472,20 +462,18 @@ static ssize_t bonding_store_arp_validate(struct device *d, new_value = bond_parse_parm(buf, arp_validate_tbl); if (new_value < 0) { - pr_err(DRV_NAME - ": %s: Ignoring invalid arp_validate value %s\n", + pr_err("%s: Ignoring invalid arp_validate value %s\n", bond->dev->name, buf); return -EINVAL; } if (new_value && (bond->params.mode != BOND_MODE_ACTIVEBACKUP)) { - pr_err(DRV_NAME - ": %s: arp_validate only supported in active-backup mode.\n", + pr_err("%s: arp_validate only supported in active-backup mode.\n", bond->dev->name); return -EINVAL; } - pr_info(DRV_NAME ": %s: setting arp_validate to %s (%d).\n", - bond->dev->name, arp_validate_tbl[new_value].modename, - new_value); + pr_info("%s: setting arp_validate to %s (%d).\n", + bond->dev->name, arp_validate_tbl[new_value].modename, + new_value); if (!bond->params.arp_validate && new_value) bond_register_arp(bond); @@ -523,24 +511,22 @@ static ssize_t bonding_store_fail_over_mac(struct device *d, struct bonding *bond = to_bond(d); if (bond->slave_cnt != 0) { - pr_err(DRV_NAME - ": %s: Can't alter fail_over_mac with slaves in bond.\n", + pr_err("%s: Can't alter fail_over_mac with slaves in bond.\n", bond->dev->name); return -EPERM; } new_value = bond_parse_parm(buf, fail_over_mac_tbl); if (new_value < 0) { - pr_err(DRV_NAME - ": %s: Ignoring invalid fail_over_mac value %s.\n", + pr_err("%s: Ignoring invalid fail_over_mac value %s.\n", bond->dev->name, buf); return -EINVAL; } bond->params.fail_over_mac = new_value; - pr_info(DRV_NAME ": %s: Setting fail_over_mac to %s (%d).\n", - bond->dev->name, fail_over_mac_tbl[new_value].modename, - new_value); + pr_info("%s: Setting fail_over_mac to %s (%d).\n", + bond->dev->name, fail_over_mac_tbl[new_value].modename, + new_value); return count; } @@ -571,31 +557,26 @@ static ssize_t bonding_store_arp_interval(struct device *d, struct bonding *bond = to_bond(d); if (sscanf(buf, "%d", &new_value) != 1) { - pr_err(DRV_NAME - ": %s: no arp_interval value specified.\n", + pr_err("%s: no arp_interval value specified.\n", bond->dev->name); ret = -EINVAL; goto out; } if (new_value < 0) { - pr_err(DRV_NAME - ": %s: Invalid arp_interval value %d not in range 1-%d; rejected.\n", + pr_err("%s: Invalid arp_interval value %d not in range 1-%d; rejected.\n", bond->dev->name, new_value, INT_MAX); ret = -EINVAL; goto out; } - pr_info(DRV_NAME - ": %s: Setting ARP monitoring interval to %d.\n", - bond->dev->name, new_value); + pr_info("%s: Setting ARP monitoring interval to %d.\n", + bond->dev->name, new_value); bond->params.arp_interval = new_value; if (bond->params.arp_interval) bond->dev->priv_flags |= IFF_MASTER_ARPMON; if (bond->params.miimon) { - pr_info(DRV_NAME - ": %s: ARP monitoring cannot be used with MII monitoring. " - "%s Disabling MII monitoring.\n", - bond->dev->name, bond->dev->name); + pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", + bond->dev->name, bond->dev->name); bond->params.miimon = 0; if (delayed_work_pending(&bond->mii_work)) { cancel_delayed_work(&bond->mii_work); @@ -603,10 +584,8 @@ static ssize_t bonding_store_arp_interval(struct device *d, } } if (!bond->params.arp_targets[0]) { - pr_info(DRV_NAME - ": %s: ARP monitoring has been set up, " - "but no ARP targets have been specified.\n", - bond->dev->name); + pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", + bond->dev->name); } if (bond->dev->flags & IFF_UP) { /* If the interface is up, we may need to fire off @@ -666,8 +645,7 @@ static ssize_t bonding_store_arp_targets(struct device *d, /* look for adds */ if (buf[0] == '+') { if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) { - pr_err(DRV_NAME - ": %s: invalid ARP target %pI4 specified for addition\n", + pr_err("%s: invalid ARP target %pI4 specified for addition\n", bond->dev->name, &newtarget); ret = -EINVAL; goto out; @@ -675,23 +653,20 @@ static ssize_t bonding_store_arp_targets(struct device *d, /* look for an empty slot to put the target in, and check for dupes */ for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) { if (targets[i] == newtarget) { /* duplicate */ - pr_err(DRV_NAME - ": %s: ARP target %pI4 is already present\n", + pr_err("%s: ARP target %pI4 is already present\n", bond->dev->name, &newtarget); ret = -EINVAL; goto out; } if (targets[i] == 0) { - pr_info(DRV_NAME - ": %s: adding ARP target %pI4.\n", - bond->dev->name, &newtarget); + pr_info("%s: adding ARP target %pI4.\n", + bond->dev->name, &newtarget); done = 1; targets[i] = newtarget; } } if (!done) { - pr_err(DRV_NAME - ": %s: ARP target table is full!\n", + pr_err("%s: ARP target table is full!\n", bond->dev->name); ret = -EINVAL; goto out; @@ -699,8 +674,7 @@ static ssize_t bonding_store_arp_targets(struct device *d, } else if (buf[0] == '-') { if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) { - pr_err(DRV_NAME - ": %s: invalid ARP target %pI4 specified for removal\n", + pr_err("%s: invalid ARP target %pI4 specified for removal\n", bond->dev->name, &newtarget); ret = -EINVAL; goto out; @@ -709,9 +683,8 @@ static ssize_t bonding_store_arp_targets(struct device *d, for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) { if (targets[i] == newtarget) { int j; - pr_info(DRV_NAME - ": %s: removing ARP target %pI4.\n", - bond->dev->name, &newtarget); + pr_info("%s: removing ARP target %pI4.\n", + bond->dev->name, &newtarget); for (j = i; (j < (BOND_MAX_ARP_TARGETS-1)) && targets[j+1]; j++) targets[j] = targets[j+1]; @@ -720,16 +693,14 @@ static ssize_t bonding_store_arp_targets(struct device *d, } } if (!done) { - pr_info(DRV_NAME - ": %s: unable to remove nonexistent ARP target %pI4.\n", - bond->dev->name, &newtarget); + pr_info("%s: unable to remove nonexistent ARP target %pI4.\n", + bond->dev->name, &newtarget); ret = -EINVAL; goto out; } } else { - pr_err(DRV_NAME ": no command found in arp_ip_targets file" - " for bond %s. Use + or -.\n", - bond->dev->name); + pr_err("no command found in arp_ip_targets file for bond %s. Use + or -.\n", + bond->dev->name); ret = -EPERM; goto out; } @@ -761,41 +732,34 @@ static ssize_t bonding_store_downdelay(struct device *d, struct bonding *bond = to_bond(d); if (!(bond->params.miimon)) { - pr_err(DRV_NAME - ": %s: Unable to set down delay as MII monitoring is disabled\n", + pr_err("%s: Unable to set down delay as MII monitoring is disabled\n", bond->dev->name); ret = -EPERM; goto out; } if (sscanf(buf, "%d", &new_value) != 1) { - pr_err(DRV_NAME - ": %s: no down delay value specified.\n", - bond->dev->name); + pr_err("%s: no down delay value specified.\n", bond->dev->name); ret = -EINVAL; goto out; } if (new_value < 0) { - pr_err(DRV_NAME - ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n", + pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", bond->dev->name, new_value, 1, INT_MAX); ret = -EINVAL; goto out; } else { if ((new_value % bond->params.miimon) != 0) { - pr_warning(DRV_NAME - ": %s: Warning: down delay (%d) is not a " - "multiple of miimon (%d), delay rounded " - "to %d ms\n", + pr_warning("%s: Warning: down delay (%d) is not a multiple of miimon (%d), delay rounded to %d ms\n", bond->dev->name, new_value, bond->params.miimon, (new_value / bond->params.miimon) * bond->params.miimon); } bond->params.downdelay = new_value / bond->params.miimon; - pr_info(DRV_NAME ": %s: Setting down delay to %d.\n", - bond->dev->name, - bond->params.downdelay * bond->params.miimon); + pr_info("%s: Setting down delay to %d.\n", + bond->dev->name, + bond->params.downdelay * bond->params.miimon); } @@ -823,41 +787,35 @@ static ssize_t bonding_store_updelay(struct device *d, struct bonding *bond = to_bond(d); if (!(bond->params.miimon)) { - pr_err(DRV_NAME - ": %s: Unable to set up delay as MII monitoring is disabled\n", + pr_err("%s: Unable to set up delay as MII monitoring is disabled\n", bond->dev->name); ret = -EPERM; goto out; } if (sscanf(buf, "%d", &new_value) != 1) { - pr_err(DRV_NAME - ": %s: no up delay value specified.\n", + pr_err("%s: no up delay value specified.\n", bond->dev->name); ret = -EINVAL; goto out; } if (new_value < 0) { - pr_err(DRV_NAME - ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n", + pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", bond->dev->name, new_value, 1, INT_MAX); ret = -EINVAL; goto out; } else { if ((new_value % bond->params.miimon) != 0) { - pr_warning(DRV_NAME - ": %s: Warning: up delay (%d) is not a " - "multiple of miimon (%d), updelay rounded " - "to %d ms\n", + pr_warning("%s: Warning: up delay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n", bond->dev->name, new_value, bond->params.miimon, (new_value / bond->params.miimon) * bond->params.miimon); } bond->params.updelay = new_value / bond->params.miimon; - pr_info(DRV_NAME ": %s: Setting up delay to %d.\n", - bond->dev->name, bond->params.updelay * bond->params.miimon); - + pr_info("%s: Setting up delay to %d.\n", + bond->dev->name, + bond->params.updelay * bond->params.miimon); } out: @@ -889,16 +847,14 @@ static ssize_t bonding_store_lacp(struct device *d, struct bonding *bond = to_bond(d); if (bond->dev->flags & IFF_UP) { - pr_err(DRV_NAME - ": %s: Unable to update LACP rate because interface is up.\n", + pr_err("%s: Unable to update LACP rate because interface is up.\n", bond->dev->name); ret = -EPERM; goto out; } if (bond->params.mode != BOND_MODE_8023AD) { - pr_err(DRV_NAME - ": %s: Unable to update LACP rate because bond is not in 802.3ad mode.\n", + pr_err("%s: Unable to update LACP rate because bond is not in 802.3ad mode.\n", bond->dev->name); ret = -EPERM; goto out; @@ -908,12 +864,11 @@ static ssize_t bonding_store_lacp(struct device *d, if ((new_value == 1) || (new_value == 0)) { bond->params.lacp_fast = new_value; - pr_info(DRV_NAME ": %s: Setting LACP rate to %s (%d).\n", + pr_info("%s: Setting LACP rate to %s (%d).\n", bond->dev->name, bond_lacp_tbl[new_value].modename, new_value); } else { - pr_err(DRV_NAME - ": %s: Ignoring invalid LACP rate value %.*s.\n", + pr_err("%s: Ignoring invalid LACP rate value %.*s.\n", bond->dev->name, (int)strlen(buf) - 1, buf); ret = -EINVAL; } @@ -943,9 +898,8 @@ static ssize_t bonding_store_ad_select(struct device *d, struct bonding *bond = to_bond(d); if (bond->dev->flags & IFF_UP) { - pr_err(DRV_NAME - ": %s: Unable to update ad_select because interface " - "is up.\n", bond->dev->name); + pr_err("%s: Unable to update ad_select because interface is up.\n", + bond->dev->name); ret = -EPERM; goto out; } @@ -954,13 +908,11 @@ static ssize_t bonding_store_ad_select(struct device *d, if (new_value != -1) { bond->params.ad_select = new_value; - pr_info(DRV_NAME - ": %s: Setting ad_select to %s (%d).\n", - bond->dev->name, ad_select_tbl[new_value].modename, - new_value); + pr_info("%s: Setting ad_select to %s (%d).\n", + bond->dev->name, ad_select_tbl[new_value].modename, + new_value); } else { - pr_err(DRV_NAME - ": %s: Ignoring invalid ad_select value %.*s.\n", + pr_err("%s: Ignoring invalid ad_select value %.*s.\n", bond->dev->name, (int)strlen(buf) - 1, buf); ret = -EINVAL; } @@ -990,15 +942,13 @@ static ssize_t bonding_store_n_grat_arp(struct device *d, struct bonding *bond = to_bond(d); if (sscanf(buf, "%d", &new_value) != 1) { - pr_err(DRV_NAME - ": %s: no num_grat_arp value specified.\n", + pr_err("%s: no num_grat_arp value specified.\n", bond->dev->name); ret = -EINVAL; goto out; } if (new_value < 0 || new_value > 255) { - pr_err(DRV_NAME - ": %s: Invalid num_grat_arp value %d not in range 0-255; rejected.\n", + pr_err("%s: Invalid num_grat_arp value %d not in range 0-255; rejected.\n", bond->dev->name, new_value); ret = -EINVAL; goto out; @@ -1031,16 +981,14 @@ static ssize_t bonding_store_n_unsol_na(struct device *d, struct bonding *bond = to_bond(d); if (sscanf(buf, "%d", &new_value) != 1) { - pr_err(DRV_NAME - ": %s: no num_unsol_na value specified.\n", + pr_err("%s: no num_unsol_na value specified.\n", bond->dev->name); ret = -EINVAL; goto out; } if (new_value < 0 || new_value > 255) { - pr_err(DRV_NAME - ": %s: Invalid num_unsol_na value %d not in range 0-255; rejected.\n", + pr_err("%s: Invalid num_unsol_na value %d not in range 0-255; rejected.\n", bond->dev->name, new_value); ret = -EINVAL; goto out; @@ -1075,40 +1023,31 @@ static ssize_t bonding_store_miimon(struct device *d, struct bonding *bond = to_bond(d); if (sscanf(buf, "%d", &new_value) != 1) { - pr_err(DRV_NAME - ": %s: no miimon value specified.\n", + pr_err("%s: no miimon value specified.\n", bond->dev->name); ret = -EINVAL; goto out; } if (new_value < 0) { - pr_err(DRV_NAME - ": %s: Invalid miimon value %d not in range %d-%d; rejected.\n", + pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n", bond->dev->name, new_value, 1, INT_MAX); ret = -EINVAL; goto out; } else { - pr_info(DRV_NAME - ": %s: Setting MII monitoring interval to %d.\n", - bond->dev->name, new_value); + pr_info("%s: Setting MII monitoring interval to %d.\n", + bond->dev->name, new_value); bond->params.miimon = new_value; if (bond->params.updelay) - pr_info(DRV_NAME - ": %s: Note: Updating updelay (to %d) " - "since it is a multiple of the miimon value.\n", - bond->dev->name, - bond->params.updelay * bond->params.miimon); + pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n", + bond->dev->name, + bond->params.updelay * bond->params.miimon); if (bond->params.downdelay) - pr_info(DRV_NAME - ": %s: Note: Updating downdelay (to %d) " - "since it is a multiple of the miimon value.\n", - bond->dev->name, - bond->params.downdelay * bond->params.miimon); + pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n", + bond->dev->name, + bond->params.downdelay * bond->params.miimon); if (bond->params.arp_interval) { - pr_info(DRV_NAME - ": %s: MII monitoring cannot be used with " - "ARP monitoring. Disabling ARP monitoring...\n", - bond->dev->name); + pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n", + bond->dev->name); bond->params.arp_interval = 0; bond->dev->priv_flags &= ~IFF_MASTER_ARPMON; if (bond->params.arp_validate) { @@ -1176,17 +1115,15 @@ static ssize_t bonding_store_primary(struct device *d, write_lock_bh(&bond->curr_slave_lock); if (!USES_PRIMARY(bond->params.mode)) { - pr_info(DRV_NAME - ": %s: Unable to set primary slave; %s is in mode %d\n", - bond->dev->name, bond->dev->name, bond->params.mode); + pr_info("%s: Unable to set primary slave; %s is in mode %d\n", + bond->dev->name, bond->dev->name, bond->params.mode); } else { bond_for_each_slave(bond, slave, i) { if (strnicmp (slave->dev->name, buf, strlen(slave->dev->name)) == 0) { - pr_info(DRV_NAME - ": %s: Setting %s as primary slave.\n", - bond->dev->name, slave->dev->name); + pr_info("%s: Setting %s as primary slave.\n", + bond->dev->name, slave->dev->name); bond->primary_slave = slave; strcpy(bond->params.primary, slave->dev->name); bond_select_active_slave(bond); @@ -1197,15 +1134,13 @@ static ssize_t bonding_store_primary(struct device *d, /* if we got here, then we didn't match the name of any slave */ if (strlen(buf) == 0 || buf[0] == '\n') { - pr_info(DRV_NAME - ": %s: Setting primary slave to None.\n", - bond->dev->name); + pr_info("%s: Setting primary slave to None.\n", + bond->dev->name); bond->primary_slave = NULL; bond_select_active_slave(bond); } else { - pr_info(DRV_NAME - ": %s: Unable to set %.*s as primary slave as it is not a slave.\n", - bond->dev->name, (int)strlen(buf) - 1, buf); + pr_info("%s: Unable to set %.*s as primary slave as it is not a slave.\n", + bond->dev->name, (int)strlen(buf) - 1, buf); } } out: @@ -1244,8 +1179,7 @@ static ssize_t bonding_store_primary_reselect(struct device *d, new_value = bond_parse_parm(buf, pri_reselect_tbl); if (new_value < 0) { - pr_err(DRV_NAME - ": %s: Ignoring invalid primary_reselect value %.*s.\n", + pr_err("%s: Ignoring invalid primary_reselect value %.*s.\n", bond->dev->name, (int) strlen(buf) - 1, buf); ret = -EINVAL; @@ -1253,7 +1187,7 @@ static ssize_t bonding_store_primary_reselect(struct device *d, } bond->params.primary_reselect = new_value; - pr_info(DRV_NAME ": %s: setting primary_reselect to %s (%d).\n", + pr_info("%s: setting primary_reselect to %s (%d).\n", bond->dev->name, pri_reselect_tbl[new_value].modename, new_value); @@ -1291,20 +1225,18 @@ static ssize_t bonding_store_carrier(struct device *d, if (sscanf(buf, "%d", &new_value) != 1) { - pr_err(DRV_NAME - ": %s: no use_carrier value specified.\n", + pr_err("%s: no use_carrier value specified.\n", bond->dev->name); ret = -EINVAL; goto out; } if ((new_value == 0) || (new_value == 1)) { bond->params.use_carrier = new_value; - pr_info(DRV_NAME ": %s: Setting use_carrier to %d.\n", - bond->dev->name, new_value); + pr_info("%s: Setting use_carrier to %d.\n", + bond->dev->name, new_value); } else { - pr_info(DRV_NAME - ": %s: Ignoring invalid use_carrier value %d.\n", - bond->dev->name, new_value); + pr_info("%s: Ignoring invalid use_carrier value %d.\n", + bond->dev->name, new_value); } out: return count; @@ -1349,8 +1281,7 @@ static ssize_t bonding_store_active_slave(struct device *d, write_lock_bh(&bond->curr_slave_lock); if (!USES_PRIMARY(bond->params.mode)) - pr_info(DRV_NAME ": %s: Unable to change active slave;" - " %s is in mode %d\n", + pr_info("%s: Unable to change active slave; %s is in mode %d\n", bond->dev->name, bond->dev->name, bond->params.mode); else { bond_for_each_slave(bond, slave, i) { @@ -1361,9 +1292,9 @@ static ssize_t bonding_store_active_slave(struct device *d, new_active = slave; if (new_active == old_active) { /* do nothing */ - pr_info(DRV_NAME - ": %s: %s is already the current active slave.\n", - bond->dev->name, slave->dev->name); + pr_info("%s: %s is already the current active slave.\n", + bond->dev->name, + slave->dev->name); goto out; } else { @@ -1371,16 +1302,15 @@ static ssize_t bonding_store_active_slave(struct device *d, (old_active) && (new_active->link == BOND_LINK_UP) && IS_UP(new_active->dev)) { - pr_info(DRV_NAME - ": %s: Setting %s as active slave.\n", - bond->dev->name, slave->dev->name); + pr_info("%s: Setting %s as active slave.\n", + bond->dev->name, + slave->dev->name); bond_change_active_slave(bond, new_active); } else { - pr_info(DRV_NAME - ": %s: Could not set %s as active slave; " - "either %s is down or the link is down.\n", - bond->dev->name, slave->dev->name, + pr_info("%s: Could not set %s as active slave; either %s is down or the link is down.\n", + bond->dev->name, + slave->dev->name, slave->dev->name); } goto out; @@ -1391,14 +1321,12 @@ static ssize_t bonding_store_active_slave(struct device *d, /* if we got here, then we didn't match the name of any slave */ if (strlen(buf) == 0 || buf[0] == '\n') { - pr_info(DRV_NAME - ": %s: Setting active slave to None.\n", + pr_info("%s: Setting active slave to None.\n", bond->dev->name); bond->primary_slave = NULL; bond_select_active_slave(bond); } else { - pr_info(DRV_NAME ": %s: Unable to set %.*s" - " as active slave as it is not a slave.\n", + pr_info("%s: Unable to set %.*s as active slave as it is not a slave.\n", bond->dev->name, (int)strlen(buf) - 1, buf); } } @@ -1600,8 +1528,7 @@ int bond_create_sysfs(void) /* Is someone being kinky and naming a device bonding_master? */ if (__dev_get_by_name(&init_net, class_attr_bonding_masters.attr.name)) - pr_err("network device named %s already " - "exists in sysfs", + pr_err("network device named %s already exists in sysfs", class_attr_bonding_masters.attr.name); ret = 0; } -- cgit v0.10.2 From bf3cdeda901c7f42de3cddc8c5aa19f6b8d8f9df Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 14 Dec 2009 14:23:41 +0900 Subject: sh: wire up vmallocinfo support in ioremap() implementations. This wires up the caller information for the ioremap VMA, which allows for more helpful caller tracking via /proc/vmallocinfo. Follows the x86 and powerpc changes of the same nature. Signed-off-by: Paul Mundt diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 512cd3e..988c1be 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -233,11 +233,17 @@ unsigned long long poke_real_address_q(unsigned long long addr, * doesn't exist, so everything must go through page tables. */ #ifdef CONFIG_MMU -void __iomem *__ioremap(unsigned long offset, unsigned long size, - unsigned long flags); +void __iomem *__ioremap_caller(unsigned long offset, unsigned long size, + unsigned long flags, void *caller); void __iounmap(void __iomem *addr); static inline void __iomem * +__ioremap(unsigned long offset, unsigned long size, unsigned long flags) +{ + return __ioremap_caller(offset, size, flags, __builtin_return_address(0)); +} + +static inline void __iomem * __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) { #if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB) diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c index a86eaa9..2141bef 100644 --- a/arch/sh/mm/ioremap_32.c +++ b/arch/sh/mm/ioremap_32.c @@ -33,10 +33,10 @@ * have to convert them into an offset in a page-aligned mapping, but the * caller shouldn't need to know that small detail. */ -void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, - unsigned long flags) +void __iomem *__ioremap_caller(unsigned long phys_addr, unsigned long size, + unsigned long flags, void *caller) { - struct vm_struct * area; + struct vm_struct *area; unsigned long offset, last_addr, addr, orig_addr; pgprot_t pgprot; @@ -67,7 +67,7 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, /* * Ok, go for it.. */ - area = get_vm_area(size, VM_IOREMAP); + area = get_vm_area_caller(size, VM_IOREMAP, caller); if (!area) return NULL; area->phys_addr = phys_addr; @@ -103,7 +103,7 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, return (void __iomem *)(offset + (char *)orig_addr); } -EXPORT_SYMBOL(__ioremap); +EXPORT_SYMBOL(__ioremap_caller); void __iounmap(void __iomem *addr) { diff --git a/arch/sh/mm/ioremap_64.c b/arch/sh/mm/ioremap_64.c index b16843d..ef43465 100644 --- a/arch/sh/mm/ioremap_64.c +++ b/arch/sh/mm/ioremap_64.c @@ -258,15 +258,15 @@ static void shmedia_unmapioaddr(unsigned long vaddr) pte_clear(&init_mm, vaddr, ptep); } -void __iomem *__ioremap(unsigned long offset, unsigned long size, - unsigned long flags) +void __iomem *__ioremap_caller(unsigned long offset, unsigned long size, + unsigned long flags, void *caller) { char name[14]; sprintf(name, "phys_%08x", (u32)offset); return shmedia_alloc_io(offset, size, name, flags); } -EXPORT_SYMBOL(__ioremap); +EXPORT_SYMBOL(__ioremap_caller); void __iounmap(void __iomem *virtual) { -- cgit v0.10.2 From 0eb37e26ed332b2a96630cf7f7ebe9fddb41cc3c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 14 Dec 2009 14:55:45 +0900 Subject: sh: Stub in P3 ioremap support for nommu parts. p3_ioremap() references __ioremap() which is presently undefined on nommu. This provides a trivial stub to fix the build up. Signed-off-by: Paul Mundt diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 988c1be..026dd65 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -277,6 +277,7 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) return __ioremap(offset, size, flags); } #else +#define __ioremap(offset, size, flags) ((void __iomem *)(offset)) #define __ioremap_mode(offset, size, flags) ((void __iomem *)(offset)) #define __iounmap(addr) do { } while (0) #endif /* CONFIG_MMU */ -- cgit v0.10.2 From 950200e2ff11daae1c5d9426703bdd494603f38b Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sun, 13 Dec 2009 14:11:02 -0500 Subject: ALSA: hda: Use ALC260_WILL quirk for another Acer model (0x1025007f) BugLink: https://bugs.launchpad.net/bugs/418627 The original reporter states that this quirk is necessary to obtain reasonable gain for playback. Without it, sound is inaudible. Tested with playback (spkr and hp) and capture. Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index deecdd2..c9e8607 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6248,6 +6248,7 @@ static const char *alc260_models[ALC260_MODEL_LAST] = { static struct snd_pci_quirk alc260_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), + SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), -- cgit v0.10.2 From 01f5966d2f36f08eb6604665eade69c9f38ffaed Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sun, 13 Dec 2009 16:22:58 -0500 Subject: ALSA: hda: Fix max PCM level to 0 dB for AD1981_HP BugLink: https://bugs.launchpad.net/bugs/461062 The original reporter states that PCM maxes at +12 dB and results in very bad distortion. Cap PCM at 0 dB to resolve this symptom. Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 447eda1..1a36137 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1789,6 +1789,14 @@ static int patch_ad1981(struct hda_codec *codec) codec->patch_ops.init = ad1981_hp_init; codec->patch_ops.unsol_event = ad1981_hp_unsol_event; + /* set the upper-limit for mixer amp to 0dB for avoiding the + * possible damage by overloading + */ + snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, + (0x17 << AC_AMPCAP_OFFSET_SHIFT) | + (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | + (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | + (1 << AC_AMPCAP_MUTE_SHIFT)); break; case AD1981_THINKPAD: spec->mixers[0] = ad1981_thinkpad_mixers; -- cgit v0.10.2 From 0d64b568fcd48b133721c1d322e7c51d85eb12df Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 13 Dec 2009 12:42:56 +0100 Subject: ALSA: sound/isa/gus: Correct code taking the size of a pointer sizeof(share_id) is just the size of the pointer. On the other hand, block->share_id is an array, so its size seems more appropriate. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression *x; expression f; type T; @@ *f(...,(T)x,...) // Signed-off-by: Julia Lawall Signed-off-by: Takashi Iwai diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c index 661205c..af888a0 100644 --- a/sound/isa/gus/gus_mem.c +++ b/sound/isa/gus/gus_mem.c @@ -127,7 +127,8 @@ static struct snd_gf1_mem_block *snd_gf1_mem_share(struct snd_gf1_mem * alloc, !share_id[2] && !share_id[3]) return NULL; for (block = alloc->first; block; block = block->next) - if (!memcmp(share_id, block->share_id, sizeof(share_id))) + if (!memcmp(share_id, block->share_id, + sizeof(block->share_id))) return block; return NULL; } -- cgit v0.10.2 From 6dd7dc767e35cfbb38f8c63a50b1c27acad25920 Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Mon, 14 Dec 2009 11:27:11 +0100 Subject: ALSA: hda - Add PCI IDs for Nvidia G2xx-series Signed-off-by: Stefan Ringel Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index e54420e..9b56f93 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2713,6 +2713,9 @@ static struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA }, + { PCI_DEVICE(0x10de, 0x0be2), .driver_data = AZX_DRIVER_NVIDIA }, + { PCI_DEVICE(0x10de, 0x0be3), .driver_data = AZX_DRIVER_NVIDIA }, + { PCI_DEVICE(0x10de, 0x0be4), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA }, -- cgit v0.10.2 From 500f5a0bf5f0624dae34307010e240ec090e4cde Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 13 Dec 2009 22:48:54 +0100 Subject: reiserfs: Fix possible recursive lock While allocating the bitmap using vmalloc, we hold the reiserfs lock, which makes lockdep later reporting a possible deadlock as we may swap out pages to allocate memory and then take the reiserfs lock recursively: inconsistent {RECLAIM_FS-ON-W} -> {IN-RECLAIM_FS-W} usage. kswapd0/312 [HC0[0]:SC0[0]:HE1:SE1] takes: (&REISERFS_SB(s)->lock){+.+.?.}, at: [] reiserfs_write_lock+0x28/0x40 {RECLAIM_FS-ON-W} state was registered at: [] mark_held_locks+0x62/0x90 [] lockdep_trace_alloc+0x9a/0xc0 [] kmem_cache_alloc+0x26/0xf0 [] __get_vm_area_node+0x6c/0xf0 [] __vmalloc_node+0x7e/0xa0 [] vmalloc+0x2b/0x30 [] reiserfs_init_bitmap_cache+0x39/0x70 [] reiserfs_fill_super+0x2e8/0xb90 [] get_sb_bdev+0x145/0x180 [] get_super_block+0x21/0x30 [] vfs_kern_mount+0x40/0xd0 [] do_kern_mount+0x39/0xd0 [] do_mount+0x2c7/0x6b0 [] sys_mount+0x66/0xa0 [] mount_block_root+0xc4/0x245 [] mount_root+0x59/0x5f [] prepare_namespace+0x111/0x14b [] kernel_init+0xcf/0xdb [] kernel_thread_helper+0x7/0x1c This is actually fine for two reasons: we call vmalloc at mount time then it's not in the swapping out path. Also the reiserfs lock can be acquired recursively, but since its implementation depends on a mutex, it's hard and not necessary worth it to teach that to lockdep. The lock is useless at mount time anyway, at least until we replay the journal. But let's remove it from this path later as this needs more thinking and is a sensible change. For now we can just relax the lock around vmalloc, Reported-by: Alexander Beregalov Signed-off-by: Frederic Weisbecker Cc: Chris Mason Cc: Ingo Molnar Cc: Thomas Gleixner diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 6854957..65c8727 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c @@ -1277,7 +1277,10 @@ int reiserfs_init_bitmap_cache(struct super_block *sb) struct reiserfs_bitmap_info *bitmap; unsigned int bmap_nr = reiserfs_bmap_count(sb); + /* Avoid lock recursion in fault case */ + reiserfs_write_unlock(sb); bitmap = vmalloc(sizeof(*bitmap) * bmap_nr); + reiserfs_write_lock(sb); if (bitmap == NULL) return -ENOMEM; -- cgit v0.10.2 From cb1c2e51c5a72f093b5af384b11d2f1c2abd6c13 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 13 Dec 2009 23:32:06 +0100 Subject: reiserfs: Fix reiserfs lock and journal lock inversion dependency When we were using the bkl, we didn't care about dependencies against other locks, but the mutex conversion created new ones, which is why we have reiserfs_mutex_lock_safe(), which unlocks the reiserfs lock before acquiring another mutex. But this trick actually fails if we have acquired the reiserfs lock recursively, as we try to unlock it to acquire the new mutex without inverted dependency, but we eventually only decrease its depth. This happens in the case of a nested inode creation/deletion. Say we have no space left on the device, we create an inode and tak the lock but fail to create its entry, then we release the inode using iput(), which calls reiserfs_delete_inode() that takes the reiserfs lock recursively. The path eventually ends up in journal_begin() where we try to take the journal safely but we fail because of the reiserfs lock recursion: [ INFO: possible circular locking dependency detected ] 2.6.32-06486-g053fe57 #2 ------------------------------------------------------- vi/23454 is trying to acquire lock: (&journal->j_mutex){+.+...}, at: [] do_journal_begin_r+0x64/0x2f0 but task is already holding lock: (&REISERFS_SB(s)->lock){+.+.+.}, at: [] reiserfs_write_lock+0x28/0x40 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&REISERFS_SB(s)->lock){+.+.+.}: [] validate_chain+0xa23/0xf70 [] __lock_acquire+0x4e5/0xa70 [] lock_acquire+0x7a/0xa0 [] mutex_lock_nested+0x5f/0x2b0 [] reiserfs_write_lock+0x28/0x40 [] do_journal_begin_r+0x6b/0x2f0 [] journal_begin+0x7f/0x120 [] reiserfs_remount+0x212/0x4d0 [] do_remount_sb+0x67/0x140 [] do_mount+0x436/0x6b0 [] sys_mount+0x66/0xa0 [] sysenter_do_call+0x12/0x36 -> #0 (&journal->j_mutex){+.+...}: [] validate_chain+0xf68/0xf70 [] __lock_acquire+0x4e5/0xa70 [] lock_acquire+0x7a/0xa0 [] mutex_lock_nested+0x5f/0x2b0 [] do_journal_begin_r+0x64/0x2f0 [] journal_begin+0x7f/0x120 [] reiserfs_delete_inode+0x9f/0x140 [] generic_delete_inode+0x9c/0x150 [] generic_drop_inode+0x3d/0x60 [] iput+0x47/0x50 [] reiserfs_create+0x16c/0x1c0 [] vfs_create+0xc1/0x130 [] do_filp_open+0x81c/0x920 [] do_sys_open+0x4f/0x110 [] sys_open+0x29/0x40 [] sysenter_do_call+0x12/0x36 other info that might help us debug this: 2 locks held by vi/23454: #0: (&sb->s_type->i_mutex_key#5){+.+.+.}, at: [] do_filp_open+0x27e/0x920 #1: (&REISERFS_SB(s)->lock){+.+.+.}, at: [] reiserfs_write_lock+0x28/0x40 stack backtrace: Pid: 23454, comm: vi Not tainted 2.6.32-06486-g053fe57 #2 Call Trace: [] ? printk+0x18/0x1e [] print_circular_bug+0xc0/0xd0 [] validate_chain+0xf68/0xf70 [] ? trace_hardirqs_off+0xb/0x10 [] __lock_acquire+0x4e5/0xa70 [] lock_acquire+0x7a/0xa0 [] ? do_journal_begin_r+0x64/0x2f0 [] mutex_lock_nested+0x5f/0x2b0 [] ? do_journal_begin_r+0x64/0x2f0 [] ? do_journal_begin_r+0x64/0x2f0 [] ? delete_one_xattr+0x0/0x1c0 [] do_journal_begin_r+0x64/0x2f0 [] journal_begin+0x7f/0x120 [] ? reiserfs_delete_xattrs+0x15/0x50 [] reiserfs_delete_inode+0x9f/0x140 [] ? generic_delete_inode+0x5f/0x150 [] ? reiserfs_delete_inode+0x0/0x140 [] generic_delete_inode+0x9c/0x150 [] generic_drop_inode+0x3d/0x60 [] iput+0x47/0x50 [] reiserfs_create+0x16c/0x1c0 [] ? inode_permission+0x7d/0xa0 [] vfs_create+0xc1/0x130 [] ? reiserfs_create+0x0/0x1c0 [] do_filp_open+0x81c/0x920 [] ? trace_hardirqs_off+0xb/0x10 [] ? _spin_unlock+0x1d/0x20 [] ? alloc_fd+0xba/0xf0 [] do_sys_open+0x4f/0x110 [] sys_open+0x29/0x40 [] sysenter_do_call+0x12/0x36 To fix this, use reiserfs_lock_once() from reiserfs_delete_inode() which prevents from adding reiserfs lock recursion. Reported-by: Alexander Beregalov Signed-off-by: Frederic Weisbecker Cc: Chris Mason Cc: Ingo Molnar Cc: Thomas Gleixner diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 3a28e77..bd615df 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -31,11 +31,12 @@ void reiserfs_delete_inode(struct inode *inode) JOURNAL_PER_BALANCE_CNT * 2 + 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb); struct reiserfs_transaction_handle th; + int depth; int err; truncate_inode_pages(&inode->i_data, 0); - reiserfs_write_lock(inode->i_sb); + depth = reiserfs_write_lock_once(inode->i_sb); /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ @@ -74,7 +75,7 @@ void reiserfs_delete_inode(struct inode *inode) out: clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */ inode->i_blocks = 0; - reiserfs_write_unlock(inode->i_sb); + reiserfs_write_unlock_once(inode->i_sb, depth); } static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid, -- cgit v0.10.2 From bc2580061e42c323d7777029f01318f395edac0d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 13 Dec 2009 12:43:15 +0100 Subject: ASoC: Correct code taking the size of a pointer sizeof(codec->reg_cache) is just the size of the pointer. Elsewhere in the file, codec->reg_cache is used with sizeof(wm8900_reg_defaults), so the code is changed to do the same here. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression *x; expression f; type T; @@ *f(...,(T)x,...) // Signed-off-by: Julia Lawall Acked-by: Liam Girdwood Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index c9438dd..dbc368c 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -199,7 +199,7 @@ static void wm8900_reset(struct snd_soc_codec *codec) snd_soc_write(codec, WM8900_REG_RESET, 0); memcpy(codec->reg_cache, wm8900_reg_defaults, - sizeof(codec->reg_cache)); + sizeof(wm8900_reg_defaults)); } static int wm8900_hp_event(struct snd_soc_dapm_widget *w, -- cgit v0.10.2 From 0eb948dd7f7c3cec37440c16a6c738c8e75efcda Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 19 Nov 2009 11:12:15 +0000 Subject: ARM: cache-l2x0: avoid taking spinlock for every iteration Taking the spinlock for every iteration is very expensive; instead, batch iterations up into 4K blocks, releasing and reacquiring the spinlock between each block. Signed-off-by: Russell King Acked-by: Catalin Marinas diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index b480f1d..c1b7bff 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -31,14 +31,10 @@ static DEFINE_SPINLOCK(l2x0_lock); static inline void sync_writel(unsigned long val, unsigned long reg, unsigned long complete_mask) { - unsigned long flags; - - spin_lock_irqsave(&l2x0_lock, flags); writel(val, l2x0_base + reg); /* wait for the operation to complete */ while (readl(l2x0_base + reg) & complete_mask) ; - spin_unlock_irqrestore(&l2x0_lock, flags); } static inline void cache_sync(void) @@ -48,15 +44,20 @@ static inline void cache_sync(void) static inline void l2x0_inv_all(void) { + unsigned long flags; + /* invalidate all ways */ + spin_lock_irqsave(&l2x0_lock, flags); sync_writel(0xff, L2X0_INV_WAY, 0xff); cache_sync(); + spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_inv_range(unsigned long start, unsigned long end) { - unsigned long addr; + unsigned long flags; + spin_lock_irqsave(&l2x0_lock, flags); if (start & (CACHE_LINE_SIZE - 1)) { start &= ~(CACHE_LINE_SIZE - 1); sync_writel(start, L2X0_CLEAN_INV_LINE_PA, 1); @@ -68,29 +69,67 @@ static void l2x0_inv_range(unsigned long start, unsigned long end) sync_writel(end, L2X0_CLEAN_INV_LINE_PA, 1); } - for (addr = start; addr < end; addr += CACHE_LINE_SIZE) - sync_writel(addr, L2X0_INV_LINE_PA, 1); + while (start < end) { + unsigned long blk_end = start + min(end - start, 4096UL); + + while (start < blk_end) { + sync_writel(start, L2X0_INV_LINE_PA, 1); + start += CACHE_LINE_SIZE; + } + + if (blk_end < end) { + spin_unlock_irqrestore(&l2x0_lock, flags); + spin_lock_irqsave(&l2x0_lock, flags); + } + } cache_sync(); + spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_clean_range(unsigned long start, unsigned long end) { - unsigned long addr; + unsigned long flags; + spin_lock_irqsave(&l2x0_lock, flags); start &= ~(CACHE_LINE_SIZE - 1); - for (addr = start; addr < end; addr += CACHE_LINE_SIZE) - sync_writel(addr, L2X0_CLEAN_LINE_PA, 1); + while (start < end) { + unsigned long blk_end = start + min(end - start, 4096UL); + + while (start < blk_end) { + sync_writel(start, L2X0_CLEAN_LINE_PA, 1); + start += CACHE_LINE_SIZE; + } + + if (blk_end < end) { + spin_unlock_irqrestore(&l2x0_lock, flags); + spin_lock_irqsave(&l2x0_lock, flags); + } + } cache_sync(); + spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_flush_range(unsigned long start, unsigned long end) { - unsigned long addr; + unsigned long flags; + spin_lock_irqsave(&l2x0_lock, flags); start &= ~(CACHE_LINE_SIZE - 1); - for (addr = start; addr < end; addr += CACHE_LINE_SIZE) - sync_writel(addr, L2X0_CLEAN_INV_LINE_PA, 1); + while (start < end) { + unsigned long blk_end = start + min(end - start, 4096UL); + + while (start < blk_end) { + sync_writel(start, L2X0_CLEAN_INV_LINE_PA, 1); + start += CACHE_LINE_SIZE; + } + + if (blk_end < end) { + spin_unlock_irqrestore(&l2x0_lock, flags); + spin_lock_irqsave(&l2x0_lock, flags); + } + } cache_sync(); + spin_unlock_irqrestore(&l2x0_lock, flags); } void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) -- cgit v0.10.2 From 3d1074349b22c9653e746282564136c87668c2b8 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 19 Nov 2009 11:41:09 +0000 Subject: ARM: cache-l2x0: make better use of background cache handling There's no point having the hardware support background operations if we issue a cache operation, and then wait for it to complete before calculating the address of the next operation. We gain no advantage in the cache controller stalling the bus until completion. What we should be doing is using the 'wait' time productively by calculating the address of the next operation, and only then waiting for the previous operation to complete. This means that cache operations can occur in parallel with the CPU calculating the next address. Signed-off-by: Russell King Acked-by: Catalin Marinas diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index c1b7bff..ec85dda 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -28,18 +28,18 @@ static void __iomem *l2x0_base; static DEFINE_SPINLOCK(l2x0_lock); -static inline void sync_writel(unsigned long val, unsigned long reg, - unsigned long complete_mask) +static inline void cache_wait(void __iomem *reg, unsigned long mask) { - writel(val, l2x0_base + reg); /* wait for the operation to complete */ - while (readl(l2x0_base + reg) & complete_mask) + while (readl(reg) & mask) ; } static inline void cache_sync(void) { - sync_writel(0, L2X0_CACHE_SYNC, 1); + void __iomem *base = l2x0_base; + writel(0, base + L2X0_CACHE_SYNC); + cache_wait(base + L2X0_CACHE_SYNC, 1); } static inline void l2x0_inv_all(void) @@ -48,32 +48,37 @@ static inline void l2x0_inv_all(void) /* invalidate all ways */ spin_lock_irqsave(&l2x0_lock, flags); - sync_writel(0xff, L2X0_INV_WAY, 0xff); + writel(0xff, l2x0_base + L2X0_INV_WAY); + cache_wait(l2x0_base + L2X0_INV_WAY, 0xff); cache_sync(); spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_inv_range(unsigned long start, unsigned long end) { + void __iomem *base = l2x0_base; unsigned long flags; spin_lock_irqsave(&l2x0_lock, flags); if (start & (CACHE_LINE_SIZE - 1)) { start &= ~(CACHE_LINE_SIZE - 1); - sync_writel(start, L2X0_CLEAN_INV_LINE_PA, 1); + cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); + writel(start, base + L2X0_CLEAN_INV_LINE_PA); start += CACHE_LINE_SIZE; } if (end & (CACHE_LINE_SIZE - 1)) { end &= ~(CACHE_LINE_SIZE - 1); - sync_writel(end, L2X0_CLEAN_INV_LINE_PA, 1); + cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); + writel(end, base + L2X0_CLEAN_INV_LINE_PA); } while (start < end) { unsigned long blk_end = start + min(end - start, 4096UL); while (start < blk_end) { - sync_writel(start, L2X0_INV_LINE_PA, 1); + cache_wait(base + L2X0_INV_LINE_PA, 1); + writel(start, base + L2X0_INV_LINE_PA); start += CACHE_LINE_SIZE; } @@ -82,12 +87,14 @@ static void l2x0_inv_range(unsigned long start, unsigned long end) spin_lock_irqsave(&l2x0_lock, flags); } } + cache_wait(base + L2X0_INV_LINE_PA, 1); cache_sync(); spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_clean_range(unsigned long start, unsigned long end) { + void __iomem *base = l2x0_base; unsigned long flags; spin_lock_irqsave(&l2x0_lock, flags); @@ -96,7 +103,8 @@ static void l2x0_clean_range(unsigned long start, unsigned long end) unsigned long blk_end = start + min(end - start, 4096UL); while (start < blk_end) { - sync_writel(start, L2X0_CLEAN_LINE_PA, 1); + cache_wait(base + L2X0_CLEAN_LINE_PA, 1); + writel(start, base + L2X0_CLEAN_LINE_PA); start += CACHE_LINE_SIZE; } @@ -105,12 +113,14 @@ static void l2x0_clean_range(unsigned long start, unsigned long end) spin_lock_irqsave(&l2x0_lock, flags); } } + cache_wait(base + L2X0_CLEAN_LINE_PA, 1); cache_sync(); spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_flush_range(unsigned long start, unsigned long end) { + void __iomem *base = l2x0_base; unsigned long flags; spin_lock_irqsave(&l2x0_lock, flags); @@ -119,7 +129,8 @@ static void l2x0_flush_range(unsigned long start, unsigned long end) unsigned long blk_end = start + min(end - start, 4096UL); while (start < blk_end) { - sync_writel(start, L2X0_CLEAN_INV_LINE_PA, 1); + cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); + writel(start, base + L2X0_CLEAN_INV_LINE_PA); start += CACHE_LINE_SIZE; } @@ -128,6 +139,7 @@ static void l2x0_flush_range(unsigned long start, unsigned long end) spin_lock_irqsave(&l2x0_lock, flags); } } + cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); cache_sync(); spin_unlock_irqrestore(&l2x0_lock, flags); } -- cgit v0.10.2 From 7a92263705435d046d37a0990d0edfcb517f7ad3 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 14 Dec 2009 14:52:10 +0100 Subject: netfilter: xtables: document minimal required version For both .33 and .32-stable. Signed-off-by: Jan Engelhardt Cc: stable@kernel.org Signed-off-by: Patrick McHardy diff --git a/Documentation/Changes b/Documentation/Changes index 6d0f1ef..f08b313 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -49,6 +49,8 @@ o oprofile 0.9 # oprofiled --version o udev 081 # udevinfo -V o grub 0.93 # grub --version o mcelog 0.6 +o iptables 1.4.1 # iptables -V + Kernel compilation ================== -- cgit v0.10.2 From 149feb00d7c3f4f06896b245533c957b54e3e052 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Mon, 14 Dec 2009 09:24:20 -0500 Subject: ext4: remove unused #include Remove unused #include ('s) in fs/ext4/block_validity.c fs/ext4/mballoc.h Signed-off-by: Huang Weiyi Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c index 4df8621..a60ab9a 100644 --- a/fs/ext4/block_validity.c +++ b/fs/ext4/block_validity.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include "ext4.h" diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h index 0ca8110..436521c 100644 --- a/fs/ext4/mballoc.h +++ b/fs/ext4/mballoc.h @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include "ext4_jbd2.h" -- cgit v0.10.2 From ccaf5f05b218e5eb41e2f5cdfd26b18dce4a0218 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 11 Dec 2009 02:21:57 +0100 Subject: ARM: 5848/1: kill flush_ioremap_region() There is not enough users to warrant its existence, and it is actually an obstacle to progress with the new DMA API which cannot cover this case properly. To keep backward compatibility, let's perform the necessary custom cache maintenance locally in the only driver affected. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 73eceb8..3db7acd 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -465,13 +465,6 @@ static inline void flush_kernel_dcache_page(struct page *page) */ #define flush_icache_page(vma,page) do { } while (0) -static inline void flush_ioremap_region(unsigned long phys, void __iomem *virt, - unsigned offset, size_t size) -{ - const void *start = (void __force *)virt + offset; - dmac_inv_range(start, start + size); -} - /* * flush_cache_vmap() is used when creating mappings (eg, via vmap, * vmalloc, ioremap etc) in kernel space for pages. On non-VIPT diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c index ac5c800..f604aa8 100644 --- a/arch/arm/mm/proc-syms.c +++ b/arch/arm/mm/proc-syms.c @@ -28,7 +28,6 @@ EXPORT_SYMBOL(__cpuc_flush_user_all); EXPORT_SYMBOL(__cpuc_flush_user_range); EXPORT_SYMBOL(__cpuc_coherent_kern_range); EXPORT_SYMBOL(__cpuc_flush_dcache_page); -EXPORT_SYMBOL(dmac_inv_range); /* because of flush_ioremap_region() */ #else EXPORT_SYMBOL(cpu_cache); #endif diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index 74fa075..b13f641 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c @@ -20,14 +20,23 @@ #include #include -#include #include +#define CACHELINESIZE 32 + static void pxa2xx_map_inval_cache(struct map_info *map, unsigned long from, ssize_t len) { - flush_ioremap_region(map->phys, map->cached, from, len); + unsigned long start = (unsigned long)map->cached + from; + unsigned long end = start + len; + + start &= ~(CACHELINESIZE - 1); + while (start < end) { + /* invalidate D cache line */ + asm volatile ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)); + start += CACHELINESIZE; + } } struct pxa2xx_flash_info { -- cgit v0.10.2 From 2c9b9c8490b60428fa2d1c64042f7c7caed93940 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Nov 2009 12:56:21 +0000 Subject: ARM: add size argument to __cpuc_flush_dcache_page ... and rename the function since it no longer operates on just pages. Signed-off-by: Russell King diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 3db7acd..730aefc 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -211,7 +211,7 @@ struct cpu_cache_fns { void (*coherent_kern_range)(unsigned long, unsigned long); void (*coherent_user_range)(unsigned long, unsigned long); - void (*flush_kern_dcache_page)(void *); + void (*flush_kern_dcache_area)(void *, size_t); void (*dma_inv_range)(const void *, const void *); void (*dma_clean_range)(const void *, const void *); @@ -236,7 +236,7 @@ extern struct cpu_cache_fns cpu_cache; #define __cpuc_flush_user_range cpu_cache.flush_user_range #define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range #define __cpuc_coherent_user_range cpu_cache.coherent_user_range -#define __cpuc_flush_dcache_page cpu_cache.flush_kern_dcache_page +#define __cpuc_flush_dcache_area cpu_cache.flush_kern_dcache_area /* * These are private to the dma-mapping API. Do not use directly. @@ -255,14 +255,14 @@ extern struct cpu_cache_fns cpu_cache; #define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range) #define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range) #define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range) -#define __cpuc_flush_dcache_page __glue(_CACHE,_flush_kern_dcache_page) +#define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area) extern void __cpuc_flush_kern_all(void); extern void __cpuc_flush_user_all(void); extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); extern void __cpuc_coherent_kern_range(unsigned long, unsigned long); extern void __cpuc_coherent_user_range(unsigned long, unsigned long); -extern void __cpuc_flush_dcache_page(void *); +extern void __cpuc_flush_dcache_area(void *, size_t); /* * These are private to the dma-mapping API. Do not use directly. @@ -448,7 +448,7 @@ static inline void flush_kernel_dcache_page(struct page *page) { /* highmem pages are always flushed upon kunmap already */ if ((cache_is_vivt() || cache_is_vipt_aliasing()) && !PageHighMem(page)) - __cpuc_flush_dcache_page(page_address(page)); + __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); } #define flush_dcache_mmap_lock(mapping) \ diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S index b63a8f7..a89444a 100644 --- a/arch/arm/mm/cache-fa.S +++ b/arch/arm/mm/cache-fa.S @@ -127,15 +127,16 @@ ENTRY(fa_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(kaddr) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure that the data held in the page kaddr is written back * to the page in question. * - * - kaddr - kernel address (guaranteed to be page aligned) + * - addr - kernel address + * - size - size of region */ -ENTRY(fa_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(fa_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -213,7 +214,7 @@ ENTRY(fa_cache_fns) .long fa_flush_user_cache_range .long fa_coherent_kern_range .long fa_coherent_user_range - .long fa_flush_kern_dcache_page + .long fa_flush_kern_dcache_area .long fa_dma_inv_range .long fa_dma_clean_range .long fa_dma_flush_range diff --git a/arch/arm/mm/cache-v3.S b/arch/arm/mm/cache-v3.S index 8a4abeb..2a48273 100644 --- a/arch/arm/mm/cache-v3.S +++ b/arch/arm/mm/cache-v3.S @@ -72,14 +72,15 @@ ENTRY(v3_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *page, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(v3_flush_kern_dcache_page) +ENTRY(v3_flush_kern_dcache_area) /* FALLTHROUGH */ /* @@ -129,7 +130,7 @@ ENTRY(v3_cache_fns) .long v3_flush_user_cache_range .long v3_coherent_kern_range .long v3_coherent_user_range - .long v3_flush_kern_dcache_page + .long v3_flush_kern_dcache_area .long v3_dma_inv_range .long v3_dma_clean_range .long v3_dma_flush_range diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S index 3668611..5c7da3e 100644 --- a/arch/arm/mm/cache-v4.S +++ b/arch/arm/mm/cache-v4.S @@ -82,14 +82,15 @@ ENTRY(v4_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(v4_flush_kern_dcache_page) +ENTRY(v4_flush_kern_dcache_area) /* FALLTHROUGH */ /* @@ -141,7 +142,7 @@ ENTRY(v4_cache_fns) .long v4_flush_user_cache_range .long v4_coherent_kern_range .long v4_coherent_user_range - .long v4_flush_kern_dcache_page + .long v4_flush_kern_dcache_area .long v4_dma_inv_range .long v4_dma_clean_range .long v4_dma_flush_range diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S index 2ebc1b3..3dbedf1e 100644 --- a/arch/arm/mm/cache-v4wb.S +++ b/arch/arm/mm/cache-v4wb.S @@ -114,15 +114,16 @@ ENTRY(v4wb_flush_user_cache_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(v4wb_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(v4wb_flush_kern_dcache_area) + add r1, r0, r1 /* fall through */ /* @@ -224,7 +225,7 @@ ENTRY(v4wb_cache_fns) .long v4wb_flush_user_cache_range .long v4wb_coherent_kern_range .long v4wb_coherent_user_range - .long v4wb_flush_kern_dcache_page + .long v4wb_flush_kern_dcache_area .long v4wb_dma_inv_range .long v4wb_dma_clean_range .long v4wb_dma_flush_range diff --git a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S index c54fa2c..b3b7410 100644 --- a/arch/arm/mm/cache-v4wt.S +++ b/arch/arm/mm/cache-v4wt.S @@ -117,17 +117,18 @@ ENTRY(v4wt_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(v4wt_flush_kern_dcache_page) +ENTRY(v4wt_flush_kern_dcache_area) mov r2, #0 mcr p15, 0, r2, c7, c5, 0 @ invalidate I cache - add r1, r0, #PAGE_SZ + add r1, r0, r1 /* fallthrough */ /* @@ -180,7 +181,7 @@ ENTRY(v4wt_cache_fns) .long v4wt_flush_user_cache_range .long v4wt_coherent_kern_range .long v4wt_coherent_user_range - .long v4wt_flush_kern_dcache_page + .long v4wt_flush_kern_dcache_area .long v4wt_dma_inv_range .long v4wt_dma_clean_range .long v4wt_dma_flush_range diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 295e25d..4ba0a24 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S @@ -159,15 +159,16 @@ ENDPROC(v6_coherent_user_range) ENDPROC(v6_coherent_kern_range) /* - * v6_flush_kern_dcache_page(kaddr) + * v6_flush_kern_dcache_area(void *addr, size_t size) * * Ensure that the data held in the page kaddr is written back * to the page in question. * - * - kaddr - kernel address (guaranteed to be page aligned) + * - addr - kernel address + * - size - region size */ -ENTRY(v6_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(v6_flush_kern_dcache_area) + add r1, r0, r1 1: #ifdef HARVARD_CACHE mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line @@ -271,7 +272,7 @@ ENTRY(v6_cache_fns) .long v6_flush_user_cache_range .long v6_coherent_kern_range .long v6_coherent_user_range - .long v6_flush_kern_dcache_page + .long v6_flush_kern_dcache_area .long v6_dma_inv_range .long v6_dma_clean_range .long v6_dma_flush_range diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index e1bd975..9073db8 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S @@ -186,16 +186,17 @@ ENDPROC(v7_coherent_kern_range) ENDPROC(v7_coherent_user_range) /* - * v7_flush_kern_dcache_page(kaddr) + * v7_flush_kern_dcache_area(void *addr, size_t size) * * Ensure that the data held in the page kaddr is written back * to the page in question. * - * - kaddr - kernel address (guaranteed to be page aligned) + * - addr - kernel address + * - size - region size */ -ENTRY(v7_flush_kern_dcache_page) +ENTRY(v7_flush_kern_dcache_area) dcache_line_size r2, r3 - add r1, r0, #PAGE_SZ + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line add r0, r0, r2 @@ -203,7 +204,7 @@ ENTRY(v7_flush_kern_dcache_page) blo 1b dsb mov pc, lr -ENDPROC(v7_flush_kern_dcache_page) +ENDPROC(v7_flush_kern_dcache_area) /* * v7_dma_inv_range(start,end) @@ -279,7 +280,7 @@ ENTRY(v7_cache_fns) .long v7_flush_user_cache_range .long v7_coherent_kern_range .long v7_coherent_user_range - .long v7_flush_kern_dcache_page + .long v7_flush_kern_dcache_area .long v7_dma_inv_range .long v7_dma_clean_range .long v7_dma_flush_range diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 329594e..6f3a4b7 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -131,7 +131,7 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page) */ if (addr) #endif - __cpuc_flush_dcache_page(addr); + __cpuc_flush_dcache_area(addr, PAGE_SIZE); /* * If this is a page cache page, and we have an aliasing VIPT cache, @@ -258,5 +258,5 @@ void __flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned l * in this mapping of the page. FIXME: this is overkill * since we actually ask for a write-back and invalidate. */ - __cpuc_flush_dcache_page(page_address(page)); + __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); } diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 30f82fb..2be1ec7 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -79,7 +79,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type) unsigned int idx = type + KM_TYPE_NR * smp_processor_id(); if (kvaddr >= (void *)FIXADDR_START) { - __cpuc_flush_dcache_page((void *)vaddr); + __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); set_pte_ext(TOP_PTE(vaddr), __pte(0), 0); diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 900811c..374a831 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -61,7 +61,7 @@ void setup_mm_for_reboot(char mode) void flush_dcache_page(struct page *page) { - __cpuc_flush_dcache_page(page_address(page)); + __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); } EXPORT_SYMBOL(flush_dcache_page); diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S index d9fb4b9..8012e24 100644 --- a/arch/arm/mm/proc-arm1020.S +++ b/arch/arm/mm/proc-arm1020.S @@ -231,17 +231,18 @@ ENTRY(arm1020_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - page - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm1020_flush_kern_dcache_page) +ENTRY(arm1020_flush_kern_dcache_area) mov ip, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE - add r1, r0, #PAGE_SZ + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry mcr p15, 0, ip, c7, c10, 4 @ drain WB add r0, r0, #CACHE_DLINESIZE @@ -335,7 +336,7 @@ ENTRY(arm1020_cache_fns) .long arm1020_flush_user_cache_range .long arm1020_coherent_kern_range .long arm1020_coherent_user_range - .long arm1020_flush_kern_dcache_page + .long arm1020_flush_kern_dcache_area .long arm1020_dma_inv_range .long arm1020_dma_clean_range .long arm1020_dma_flush_range diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S index 7453b75..41fe25d 100644 --- a/arch/arm/mm/proc-arm1020e.S +++ b/arch/arm/mm/proc-arm1020e.S @@ -225,17 +225,18 @@ ENTRY(arm1020e_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - page - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm1020e_flush_kern_dcache_page) +ENTRY(arm1020e_flush_kern_dcache_area) mov ip, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE - add r1, r0, #PAGE_SZ + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -321,7 +322,7 @@ ENTRY(arm1020e_cache_fns) .long arm1020e_flush_user_cache_range .long arm1020e_coherent_kern_range .long arm1020e_coherent_user_range - .long arm1020e_flush_kern_dcache_page + .long arm1020e_flush_kern_dcache_area .long arm1020e_dma_inv_range .long arm1020e_dma_clean_range .long arm1020e_dma_flush_range diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S index 8eb72d7..20a5b1b 100644 --- a/arch/arm/mm/proc-arm1022.S +++ b/arch/arm/mm/proc-arm1022.S @@ -214,17 +214,18 @@ ENTRY(arm1022_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - page - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm1022_flush_kern_dcache_page) +ENTRY(arm1022_flush_kern_dcache_area) mov ip, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE - add r1, r0, #PAGE_SZ + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -310,7 +311,7 @@ ENTRY(arm1022_cache_fns) .long arm1022_flush_user_cache_range .long arm1022_coherent_kern_range .long arm1022_coherent_user_range - .long arm1022_flush_kern_dcache_page + .long arm1022_flush_kern_dcache_area .long arm1022_dma_inv_range .long arm1022_dma_clean_range .long arm1022_dma_flush_range diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S index 3b59f0d..96aedb1 100644 --- a/arch/arm/mm/proc-arm1026.S +++ b/arch/arm/mm/proc-arm1026.S @@ -208,17 +208,18 @@ ENTRY(arm1026_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - page - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm1026_flush_kern_dcache_page) +ENTRY(arm1026_flush_kern_dcache_area) mov ip, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE - add r1, r0, #PAGE_SZ + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -304,7 +305,7 @@ ENTRY(arm1026_cache_fns) .long arm1026_flush_user_cache_range .long arm1026_coherent_kern_range .long arm1026_coherent_user_range - .long arm1026_flush_kern_dcache_page + .long arm1026_flush_kern_dcache_area .long arm1026_dma_inv_range .long arm1026_dma_clean_range .long arm1026_dma_flush_range diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S index 2b7c197..471669e 100644 --- a/arch/arm/mm/proc-arm920.S +++ b/arch/arm/mm/proc-arm920.S @@ -207,15 +207,16 @@ ENTRY(arm920_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm920_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(arm920_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -293,7 +294,7 @@ ENTRY(arm920_cache_fns) .long arm920_flush_user_cache_range .long arm920_coherent_kern_range .long arm920_coherent_user_range - .long arm920_flush_kern_dcache_page + .long arm920_flush_kern_dcache_area .long arm920_dma_inv_range .long arm920_dma_clean_range .long arm920_dma_flush_range diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S index 06a1aa4..ee111b0 100644 --- a/arch/arm/mm/proc-arm922.S +++ b/arch/arm/mm/proc-arm922.S @@ -209,15 +209,16 @@ ENTRY(arm922_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm922_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(arm922_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -295,7 +296,7 @@ ENTRY(arm922_cache_fns) .long arm922_flush_user_cache_range .long arm922_coherent_kern_range .long arm922_coherent_user_range - .long arm922_flush_kern_dcache_page + .long arm922_flush_kern_dcache_area .long arm922_dma_inv_range .long arm922_dma_clean_range .long arm922_dma_flush_range diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S index cb53435..8deb5bd 100644 --- a/arch/arm/mm/proc-arm925.S +++ b/arch/arm/mm/proc-arm925.S @@ -251,15 +251,16 @@ ENTRY(arm925_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm925_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(arm925_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -346,7 +347,7 @@ ENTRY(arm925_cache_fns) .long arm925_flush_user_cache_range .long arm925_coherent_kern_range .long arm925_coherent_user_range - .long arm925_flush_kern_dcache_page + .long arm925_flush_kern_dcache_area .long arm925_dma_inv_range .long arm925_dma_clean_range .long arm925_dma_flush_range diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S index 1c48487..64db6e2 100644 --- a/arch/arm/mm/proc-arm926.S +++ b/arch/arm/mm/proc-arm926.S @@ -214,15 +214,16 @@ ENTRY(arm926_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm926_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(arm926_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -309,7 +310,7 @@ ENTRY(arm926_cache_fns) .long arm926_flush_user_cache_range .long arm926_coherent_kern_range .long arm926_coherent_user_range - .long arm926_flush_kern_dcache_page + .long arm926_flush_kern_dcache_area .long arm926_dma_inv_range .long arm926_dma_clean_range .long arm926_dma_flush_range diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S index 5b0f846..8196b9f 100644 --- a/arch/arm/mm/proc-arm940.S +++ b/arch/arm/mm/proc-arm940.S @@ -141,14 +141,15 @@ ENTRY(arm940_coherent_user_range) /* FALLTHROUGH */ /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(arm940_flush_kern_dcache_page) +ENTRY(arm940_flush_kern_dcache_area) mov ip, #0 mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments 1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries @@ -238,7 +239,7 @@ ENTRY(arm940_cache_fns) .long arm940_flush_user_cache_range .long arm940_coherent_kern_range .long arm940_coherent_user_range - .long arm940_flush_kern_dcache_page + .long arm940_flush_kern_dcache_area .long arm940_dma_inv_range .long arm940_dma_clean_range .long arm940_dma_flush_range diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S index 40c0449..9a95123 100644 --- a/arch/arm/mm/proc-arm946.S +++ b/arch/arm/mm/proc-arm946.S @@ -183,16 +183,17 @@ ENTRY(arm946_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size * (same as arm926) */ -ENTRY(arm946_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(arm946_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -280,7 +281,7 @@ ENTRY(arm946_cache_fns) .long arm946_flush_user_cache_range .long arm946_coherent_kern_range .long arm946_coherent_user_range - .long arm946_flush_kern_dcache_page + .long arm946_flush_kern_dcache_area .long arm946_dma_inv_range .long arm946_dma_clean_range .long arm946_dma_flush_range diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S index d0d7795..dbc3938 100644 --- a/arch/arm/mm/proc-feroceon.S +++ b/arch/arm/mm/proc-feroceon.S @@ -226,16 +226,17 @@ ENTRY(feroceon_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ .align 5 -ENTRY(feroceon_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(feroceon_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -246,7 +247,7 @@ ENTRY(feroceon_flush_kern_dcache_page) mov pc, lr .align 5 -ENTRY(feroceon_range_flush_kern_dcache_page) +ENTRY(feroceon_range_flush_kern_dcache_area) mrs r2, cpsr add r1, r0, #PAGE_SZ - CACHE_DLINESIZE @ top addr is inclusive orr r3, r2, #PSR_I_BIT @@ -372,7 +373,7 @@ ENTRY(feroceon_cache_fns) .long feroceon_flush_user_cache_range .long feroceon_coherent_kern_range .long feroceon_coherent_user_range - .long feroceon_flush_kern_dcache_page + .long feroceon_flush_kern_dcache_area .long feroceon_dma_inv_range .long feroceon_dma_clean_range .long feroceon_dma_flush_range @@ -383,7 +384,7 @@ ENTRY(feroceon_range_cache_fns) .long feroceon_flush_user_cache_range .long feroceon_coherent_kern_range .long feroceon_coherent_user_range - .long feroceon_range_flush_kern_dcache_page + .long feroceon_range_flush_kern_dcache_area .long feroceon_range_dma_inv_range .long feroceon_range_dma_clean_range .long feroceon_range_dma_flush_range diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S index 52b5fd7..9674d36 100644 --- a/arch/arm/mm/proc-mohawk.S +++ b/arch/arm/mm/proc-mohawk.S @@ -186,15 +186,16 @@ ENTRY(mohawk_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(mohawk_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(mohawk_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -273,7 +274,7 @@ ENTRY(mohawk_cache_fns) .long mohawk_flush_user_cache_range .long mohawk_coherent_kern_range .long mohawk_coherent_user_range - .long mohawk_flush_kern_dcache_page + .long mohawk_flush_kern_dcache_area .long mohawk_dma_inv_range .long mohawk_dma_clean_range .long mohawk_dma_flush_range diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c index f604aa8..3e6210b 100644 --- a/arch/arm/mm/proc-syms.c +++ b/arch/arm/mm/proc-syms.c @@ -27,7 +27,7 @@ EXPORT_SYMBOL(__cpuc_flush_kern_all); EXPORT_SYMBOL(__cpuc_flush_user_all); EXPORT_SYMBOL(__cpuc_flush_user_range); EXPORT_SYMBOL(__cpuc_coherent_kern_range); -EXPORT_SYMBOL(__cpuc_flush_dcache_page); +EXPORT_SYMBOL(__cpuc_flush_dcache_area); #else EXPORT_SYMBOL(cpu_cache); #endif diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index fab134e..96456f5 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S @@ -226,15 +226,16 @@ ENTRY(xsc3_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache. * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(xsc3_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(xsc3_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line add r0, r0, #CACHELINESIZE cmp r0, r1 @@ -309,7 +310,7 @@ ENTRY(xsc3_cache_fns) .long xsc3_flush_user_cache_range .long xsc3_coherent_kern_range .long xsc3_coherent_user_range - .long xsc3_flush_kern_dcache_page + .long xsc3_flush_kern_dcache_area .long xsc3_dma_inv_range .long xsc3_dma_clean_range .long xsc3_dma_flush_range diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index f056c28..93df472 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -284,15 +284,16 @@ ENTRY(xscale_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_page(void *page) + * flush_kern_dcache_area(void *addr, size_t size) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - page aligned address + * - addr - kernel address + * - size - region size */ -ENTRY(xscale_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ +ENTRY(xscale_flush_kern_dcache_area) + add r1, r0, r1 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry add r0, r0, #CACHELINESIZE @@ -368,7 +369,7 @@ ENTRY(xscale_cache_fns) .long xscale_flush_user_cache_range .long xscale_coherent_kern_range .long xscale_coherent_user_range - .long xscale_flush_kern_dcache_page + .long xscale_flush_kern_dcache_area .long xscale_dma_inv_range .long xscale_dma_clean_range .long xscale_dma_flush_range @@ -392,7 +393,7 @@ ENTRY(xscale_80200_A0_A1_cache_fns) .long xscale_flush_user_cache_range .long xscale_coherent_kern_range .long xscale_coherent_user_range - .long xscale_flush_kern_dcache_page + .long xscale_flush_kern_dcache_area .long xscale_dma_flush_range .long xscale_dma_clean_range .long xscale_dma_flush_range -- cgit v0.10.2 From f74f7e57ae9fa12b2951ae62ce3557799b318399 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Nov 2009 12:31:15 +0000 Subject: ARM: use flush_kernel_dcache_area() for dmabounce After copying data from the bounce buffer to the real buffer, use flush_kernel_dcache_page() to ensure that data is written back in manner coherent with future userspace mappings. Signed-off-by: Russell King diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index 5a375e5..bc90364 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c @@ -308,15 +308,11 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr, memcpy(ptr, buf->safe, size); /* - * DMA buffers must have the same cache properties - * as if they were really used for DMA - which means - * data must be written back to RAM. Note that - * we don't use dmac_flush_range() here for the - * bidirectional case because we know the cache - * lines will be coherent with the data written. + * Since we may have written to a page cache page, + * we need to ensure that the data will be coherent + * with user mappings. */ - dmac_clean_range(ptr, ptr + size); - outer_clean_range(__pa(ptr), __pa(ptr) + size); + __cpuc_flush_kernel_dcache_area(ptr, size); } free_safe_buffer(dev->archdata.dmabounce, buf); } -- cgit v0.10.2 From 84c664730374248adaf420c0846a6158d64413c7 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 21 Dec 2009 10:54:09 -0500 Subject: ext4: Don't ask about supporting ext2/3 in ext4 if ext4 is not configured Don't offer to build ext2/3 support into ext4 if ext4 itself is not configured on. Signed-off-by: David Howells Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index 9acf7e8..9ed1bb1 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig @@ -28,6 +28,7 @@ config EXT4_FS config EXT4_USE_FOR_EXT23 bool "Use ext4 for ext2/ext3 file systems" + depends on EXT4_FS depends on EXT3_FS=n || EXT2_FS=n default y help -- cgit v0.10.2 From 51b7e3c9fbe7d22d4e355101e9a73b44fc5c9feb Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 21 Dec 2009 10:56:09 -0500 Subject: ext4: add module aliases for ext2 and ext3 Add module aliases for ext2 and ext3 when CONFIG_EXT4_USE_FOR_EXT23 is set. This makes the existing user-space stuff like mkinitrd working as is. Signed-off-by: Takashi Iwai Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 6ed9aa9..0a06fe6 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -4005,6 +4005,7 @@ static inline void unregister_as_ext2(void) { unregister_filesystem(&ext2_fs_type); } +MODULE_ALIAS("ext2"); #else static inline void register_as_ext2(void) { } static inline void unregister_as_ext2(void) { } @@ -4031,6 +4032,7 @@ static inline void unregister_as_ext3(void) { unregister_filesystem(&ext3_fs_type); } +MODULE_ALIAS("ext3"); #else static inline void register_as_ext3(void) { } static inline void unregister_as_ext3(void) { } -- cgit v0.10.2 From 034fb4c95fc0fed4ec4a50778127b92c6f2aec01 Mon Sep 17 00:00:00 2001 From: Surbhi Palande Date: Mon, 14 Dec 2009 09:53:52 -0500 Subject: ext4: replace BUG() with return -EIO in ext4_ext_get_blocks This patch fixes the Kernel BZ #14286. When the address of an extent corresponding to a valid block is corrupted, a -EIO should be reported instead of a BUG(). This situation should not normally not occur except in the case of a corrupted filesystem. If however it does, then the system should not panic directly but depending on the mount time options appropriate action should be taken. If the mount options so permit, the I/O should be gracefully aborted by returning a -EIO. http://bugzilla.kernel.org/show_bug.cgi?id=14286 Signed-off-by: Surbhi Palande Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 3a7928f..8fd6c56 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3190,7 +3190,13 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, * this situation is possible, though, _during_ tree modification; * this is why assert can't be put in ext4_ext_find_extent() */ - BUG_ON(path[depth].p_ext == NULL && depth != 0); + if (path[depth].p_ext == NULL && depth != 0) { + ext4_error(inode->i_sb, __func__, "bad extent address " + "inode: %lu, iblock: %d, depth: %d", + inode->i_ino, iblock, depth); + err = -EIO; + goto out2; + } eh = path[depth].p_hdr; ex = path[depth].p_ext; -- cgit v0.10.2 From 9abfe315de96aa5c9878b2f627542bc54901c6e9 Mon Sep 17 00:00:00 2001 From: Xiaotian Feng Date: Mon, 14 Dec 2009 16:38:21 +0100 Subject: ipvs: fix synchronization on connection close commit 9d3a0de makes slaves expire as they would do on the master with much shorter timeouts. But it introduces another problem: When we close a connection, on master server the connection became CLOSE_WAIT/TIME_WAIT, it was synced to slaves, but if master is finished within it's timeouts (CLOSE), it will not be synced to slaves. Then slaves will be kept on CLOSE_WAIT/TIME_WAIT until timeout reaches. Thus we should also sync with CLOSE. Cc: Wensong Zhang Cc: Simon Horman Cc: Julian Anastasov Cc: David S. Miller Signed-off-by: Xiaotian Feng Acked-by: Simon Horman Signed-off-by: Patrick McHardy diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index b95699f..847ffca 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -1366,6 +1366,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, == sysctl_ip_vs_sync_threshold[0])) || ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) && ((cp->state == IP_VS_TCP_S_FIN_WAIT) || + (cp->state == IP_VS_TCP_S_CLOSE) || (cp->state == IP_VS_TCP_S_CLOSE_WAIT) || (cp->state == IP_VS_TCP_S_TIME_WAIT))))) ip_vs_sync_conn(cp); -- cgit v0.10.2 From d8f66248d6f25f7c935cc5307c43bf394db07272 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 13 Dec 2009 19:50:24 -0200 Subject: perf session: Pass the perf_session to the event handling operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They will need it to get the right threads list, etc. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260741029-4430-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 21a78d3..2e418b9 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -132,7 +132,7 @@ static int hist_entry__add(struct addr_location *al, u64 count) return 0; } -static int process_sample_event(event_t *event) +static int process_sample_event(event_t *event, struct perf_session *session __used) { struct addr_location al; diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 2071d24..101b268 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -312,7 +312,7 @@ process_raw_event(event_t *raw_event __used, void *data, } } -static int process_sample_event(event_t *event) +static int process_sample_event(event_t *event, struct perf_session *session __used) { struct sample_data data; struct thread *thread; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 4decbd1..b7e15a1 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -123,7 +123,8 @@ static void write_event(event_t *buf, size_t size) write_output(buf, size); } -static int process_synthesized_event(event_t *event) +static int process_synthesized_event(event_t *event, + struct perf_session *self __used) { write_event(event, event->header.size); return 0; @@ -488,9 +489,10 @@ static int __cmd_record(int argc, const char **argv) } if (!system_wide) - event__synthesize_thread(pid, process_synthesized_event); + event__synthesize_thread(pid, process_synthesized_event, + session); else - event__synthesize_threads(process_synthesized_event); + event__synthesize_threads(process_synthesized_event, session); if (target_pid == -1 && argc) { pid = fork(); @@ -510,7 +512,8 @@ static int __cmd_record(int argc, const char **argv) */ usleep(1000); event__synthesize_thread(pid, - process_synthesized_event); + process_synthesized_event, + session); } child_pid = pid; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index e2ec49a..dcd8fed 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -53,8 +53,6 @@ static int exclude_other = 1; static char callchain_default_opt[] = "fractal,0.5"; -static struct perf_session *session; - static u64 sample_type; struct symbol_conf symbol_conf; @@ -604,7 +602,7 @@ static int validate_chain(struct ip_callchain *chain, event_t *event) return 0; } -static int process_sample_event(event_t *event) +static int process_sample_event(event_t *event, struct perf_session *session __used) { struct sample_data data; int cpumode; @@ -683,7 +681,7 @@ static int process_sample_event(event_t *event) return 0; } -static int process_comm_event(event_t *event) +static int process_comm_event(event_t *event, struct perf_session *session __used) { struct thread *thread = threads__findnew(event->comm.pid); @@ -698,7 +696,7 @@ static int process_comm_event(event_t *event) return 0; } -static int process_read_event(event_t *event) +static int process_read_event(event_t *event, struct perf_session *session __used) { struct perf_event_attr *attr; @@ -766,6 +764,7 @@ static int __cmd_report(void) { struct thread *idle; int ret; + struct perf_session *session; session = perf_session__new(input_name, O_RDONLY, force); if (session == NULL) diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 65021fe..48ab283 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1594,7 +1594,8 @@ process_raw_event(event_t *raw_event __used, void *data, process_sched_migrate_task_event(data, event, cpu, timestamp, thread); } -static int process_sample_event(event_t *event) +static int process_sample_event(event_t *event, + struct perf_session *session __used) { struct sample_data data; struct thread *thread; @@ -1632,7 +1633,8 @@ static int process_sample_event(event_t *event) return 0; } -static int process_lost_event(event_t *event __used) +static int process_lost_event(event_t *event __used, + struct perf_session *session __used) { nr_lost_chunks++; nr_lost_events += event->lost.lost; diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 759dd2b..db6caae 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -281,21 +281,19 @@ static int cpus_cstate_state[MAX_CPUS]; static u64 cpus_pstate_start_times[MAX_CPUS]; static u64 cpus_pstate_state[MAX_CPUS]; -static int -process_comm_event(event_t *event) +static int process_comm_event(event_t *event, struct perf_session *session __used) { pid_set_comm(event->comm.pid, event->comm.comm); return 0; } -static int -process_fork_event(event_t *event) + +static int process_fork_event(event_t *event, struct perf_session *session __used) { pid_fork(event->fork.pid, event->fork.ppid, event->fork.time); return 0; } -static int -process_exit_event(event_t *event) +static int process_exit_event(event_t *event, struct perf_session *session __used) { pid_exit(event->fork.pid, event->fork.time); return 0; @@ -594,8 +592,7 @@ static u64 sample_time(event_t *event) * We first queue all events, sorted backwards by insertion. * The order will get flipped later. */ -static int -queue_sample_event(event_t *event) +static int queue_sample_event(event_t *event, struct perf_session *session __used) { struct sample_wrapper *copy, *prev; int size; diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index e0a374d..b13f426 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -965,14 +965,14 @@ static void event__process_sample(const event_t *self, int counter) } } -static int event__process(event_t *event) +static int event__process(event_t *event, struct perf_session *session) { switch (event->header.type) { case PERF_RECORD_COMM: - event__process_comm(event); + event__process_comm(event, session); break; case PERF_RECORD_MMAP: - event__process_mmap(event); + event__process_mmap(event, session); break; default: break; @@ -999,7 +999,8 @@ static unsigned int mmap_read_head(struct mmap_data *md) return head; } -static void mmap_read_counter(struct mmap_data *md) +static void perf_session__mmap_read_counter(struct perf_session *self, + struct mmap_data *md) { unsigned int head = mmap_read_head(md); unsigned int old = md->prev; @@ -1054,7 +1055,7 @@ static void mmap_read_counter(struct mmap_data *md) if (event->header.type == PERF_RECORD_SAMPLE) event__process_sample(event, md->counter); else - event__process(event); + event__process(event, self); old += size; } @@ -1064,13 +1065,13 @@ static void mmap_read_counter(struct mmap_data *md) static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; -static void mmap_read(void) +static void perf_session__mmap_read(struct perf_session *self) { int i, counter; for (i = 0; i < nr_cpus; i++) { for (counter = 0; counter < nr_counters; counter++) - mmap_read_counter(&mmap_array[i][counter]); + perf_session__mmap_read_counter(self, &mmap_array[i][counter]); } } @@ -1155,11 +1156,16 @@ static int __cmd_top(void) pthread_t thread; int i, counter; int ret; + /* + * XXX perf_session__new should allow passing a O_MMAP, so that all this + * mmap reading, etc is encapsulated in it. + */ + struct perf_session *session = NULL; if (target_pid != -1) - event__synthesize_thread(target_pid, event__process); + event__synthesize_thread(target_pid, event__process, session); else - event__synthesize_threads(event__process); + event__synthesize_threads(event__process, session); for (i = 0; i < nr_cpus; i++) { group_fd = -1; @@ -1170,7 +1176,7 @@ static int __cmd_top(void) /* Wait for a minimal set of events before starting the snapshot */ poll(event_array, nr_poll, 100); - mmap_read(); + perf_session__mmap_read(session); if (pthread_create(&thread, NULL, display_thread, NULL)) { printf("Could not create display thread.\n"); @@ -1190,7 +1196,7 @@ static int __cmd_top(void) while (1) { int hits = samples; - mmap_read(); + perf_session__mmap_read(session); if (hits == samples) ret = poll(event_array, nr_poll, 100); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 0756664..3057e1d 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -62,10 +62,9 @@ static int cleanup_scripting(void) static char const *input_name = "perf.data"; -static struct perf_session *session; static u64 sample_type; -static int process_sample_event(event_t *event) +static int process_sample_event(event_t *event, struct perf_session *session __used) { struct sample_data data; struct thread *thread; @@ -125,20 +124,12 @@ static struct perf_file_handler file_handler = { .sample_type_check = sample_type_check, }; -static int __cmd_trace(void) +static int __cmd_trace(struct perf_session *session) { - int err; - - session = perf_session__new(input_name, O_RDONLY, 0); - if (session == NULL) - return -ENOMEM; - register_idle_thread(); register_perf_file_handler(&file_handler); - err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); - perf_session__delete(session); - return err; + return perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); } struct script_spec { @@ -313,6 +304,7 @@ static const struct option options[] = { int cmd_trace(int argc, const char **argv, const char *prefix __used) { int err; + struct perf_session *session; symbol__init(0); @@ -330,6 +322,10 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) setup_pager(); + session = perf_session__new(input_name, O_RDONLY, 0); + if (session == NULL) + return -ENOMEM; + if (generate_script_lang) { struct stat perf_stat; @@ -367,8 +363,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) goto out; } - err = __cmd_trace(); + err = __cmd_trace(session); + perf_session__delete(session); cleanup_scripting(); out: return err; diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index 6d46dda..22bcdfe 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c @@ -8,7 +8,8 @@ static struct perf_file_handler *curr_handler; static unsigned long mmap_window = 32; static char __cwd[PATH_MAX]; -static int process_event_stub(event_t *event __used) +static int process_event_stub(event_t *event __used, + struct perf_session *session __used) { dump_printf(": unhandled!\n"); return 0; @@ -61,8 +62,8 @@ void event__print_totals(void) event__name[i], event__total[i]); } -static int -process_event(event_t *event, unsigned long offset, unsigned long head) +static int process_event(event_t *event, struct perf_session *session, + unsigned long offset, unsigned long head) { trace_event(event); @@ -77,23 +78,23 @@ process_event(event_t *event, unsigned long offset, unsigned long head) switch (event->header.type) { case PERF_RECORD_SAMPLE: - return curr_handler->process_sample_event(event); + return curr_handler->process_sample_event(event, session); case PERF_RECORD_MMAP: - return curr_handler->process_mmap_event(event); + return curr_handler->process_mmap_event(event, session); case PERF_RECORD_COMM: - return curr_handler->process_comm_event(event); + return curr_handler->process_comm_event(event, session); case PERF_RECORD_FORK: - return curr_handler->process_fork_event(event); + return curr_handler->process_fork_event(event, session); case PERF_RECORD_EXIT: - return curr_handler->process_exit_event(event); + return curr_handler->process_exit_event(event, session); case PERF_RECORD_LOST: - return curr_handler->process_lost_event(event); + return curr_handler->process_lost_event(event, session); case PERF_RECORD_READ: - return curr_handler->process_read_event(event); + return curr_handler->process_read_event(event, session); case PERF_RECORD_THROTTLE: - return curr_handler->process_throttle_event(event); + return curr_handler->process_throttle_event(event, session); case PERF_RECORD_UNTHROTTLE: - return curr_handler->process_unthrottle_event(event); + return curr_handler->process_unthrottle_event(event, session); default: curr_handler->total_unknown++; return -1; @@ -209,7 +210,7 @@ more: (void *)(long)event->header.size, event->header.type); - if (!size || process_event(event, offset, head) < 0) { + if (!size || process_event(event, self, offset, head) < 0) { dump_printf("%p [%p]: skipping unknown header type: %d\n", (void *)(offset + head), diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h index 98c5b82..6d4ae52 100644 --- a/tools/perf/util/data_map.h +++ b/tools/perf/util/data_map.h @@ -5,7 +5,10 @@ #include "header.h" #include "session.h" -typedef int (*event_type_handler_t)(event_t *); +struct perf_session; + +typedef int (*event_type_handler_t)(event_t *self, + struct perf_session *session); struct perf_file_handler { event_type_handler_t process_sample_event; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index ba0de90..e2c4895 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -5,7 +5,9 @@ #include "thread.h" static pid_t event__synthesize_comm(pid_t pid, int full, - int (*process)(event_t *event)) + int (*process)(event_t *event, + struct perf_session *session), + struct perf_session *session) { event_t ev; char filename[PATH_MAX]; @@ -54,7 +56,7 @@ out_race: if (!full) { ev.comm.tid = pid; - process(&ev); + process(&ev, session); goto out_fclose; } @@ -72,7 +74,7 @@ out_race: ev.comm.tid = pid; - process(&ev); + process(&ev, session); } closedir(tasks); @@ -86,7 +88,9 @@ out_failure: } static int event__synthesize_mmap_events(pid_t pid, pid_t tgid, - int (*process)(event_t *event)) + int (*process)(event_t *event, + struct perf_session *session), + struct perf_session *session) { char filename[PATH_MAX]; FILE *fp; @@ -141,7 +145,7 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid, ev.mmap.pid = tgid; ev.mmap.tid = pid; - process(&ev); + process(&ev, session); } } @@ -149,15 +153,20 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid, return 0; } -int event__synthesize_thread(pid_t pid, int (*process)(event_t *event)) +int event__synthesize_thread(pid_t pid, + int (*process)(event_t *event, + struct perf_session *session), + struct perf_session *session) { - pid_t tgid = event__synthesize_comm(pid, 1, process); + pid_t tgid = event__synthesize_comm(pid, 1, process, session); if (tgid == -1) return -1; - return event__synthesize_mmap_events(pid, tgid, process); + return event__synthesize_mmap_events(pid, tgid, process, session); } -void event__synthesize_threads(int (*process)(event_t *event)) +void event__synthesize_threads(int (*process)(event_t *event, + struct perf_session *session), + struct perf_session *session) { DIR *proc; struct dirent dirent, *next; @@ -171,7 +180,7 @@ void event__synthesize_threads(int (*process)(event_t *event)) if (*end) /* only interested in proper numerical dirents */ continue; - event__synthesize_thread(pid, process); + event__synthesize_thread(pid, process, session); } closedir(proc); @@ -182,7 +191,7 @@ int event__cwdlen; struct events_stats event__stats; -int event__process_comm(event_t *self) +int event__process_comm(event_t *self, struct perf_session *session __used) { struct thread *thread = threads__findnew(self->comm.pid); @@ -196,14 +205,14 @@ int event__process_comm(event_t *self) return 0; } -int event__process_lost(event_t *self) +int event__process_lost(event_t *self, struct perf_session *session __used) { dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost); event__stats.lost += self->lost.lost; return 0; } -int event__process_mmap(event_t *self) +int event__process_mmap(event_t *self, struct perf_session *session __used) { struct thread *thread = threads__findnew(self->mmap.pid); struct map *map = map__new(&self->mmap, MAP__FUNCTION, @@ -224,7 +233,7 @@ int event__process_mmap(event_t *self) return 0; } -int event__process_task(event_t *self) +int event__process_task(event_t *self, struct perf_session *session __used) { struct thread *thread = threads__findnew(self->fork.pid); struct thread *parent = threads__findnew(self->fork.ppid); diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 51a96c2..6b6429b 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -156,18 +156,25 @@ struct symbol *map__find_symbol_by_name(struct map *self, const char *name, void map__fixup_start(struct map *self); void map__fixup_end(struct map *self); -int event__synthesize_thread(pid_t pid, int (*process)(event_t *event)); -void event__synthesize_threads(int (*process)(event_t *event)); +struct perf_session; + +int event__synthesize_thread(pid_t pid, + int (*process)(event_t *event, + struct perf_session *session), + struct perf_session *session); +void event__synthesize_threads(int (*process)(event_t *event, + struct perf_session *session), + struct perf_session *session); extern char *event__cwd; extern int event__cwdlen; extern struct events_stats event__stats; extern unsigned long event__total[PERF_RECORD_MAX]; -int event__process_comm(event_t *self); -int event__process_lost(event_t *self); -int event__process_mmap(event_t *self); -int event__process_task(event_t *self); +int event__process_comm(event_t *self, struct perf_session *session); +int event__process_lost(event_t *self, struct perf_session *session); +int event__process_mmap(event_t *self, struct perf_session *session); +int event__process_task(event_t *self, struct perf_session *session); struct addr_location; int event__preprocess_sample(const event_t *self, struct addr_location *al, -- cgit v0.10.2 From 301a0b020210360c6e441c7765521248bc87d58e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 13 Dec 2009 19:50:25 -0200 Subject: perf session: Ditch register_perf_file_handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass the event_ops to perf_session__process_events instead. Also move the event_ops definition to session.h, starting to move things around to their right place, trimming the many unneeded headers we have. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260741029-4430-2-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 4069996..a4cb792 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -370,7 +370,6 @@ LIB_H += util/values.h LIB_H += util/sort.h LIB_H += util/hist.h LIB_H += util/thread.h -LIB_H += util/data_map.h LIB_H += util/probe-finder.h LIB_H += util/probe-event.h diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 2e418b9..43e3bb3 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -26,7 +26,6 @@ #include "util/sort.h" #include "util/hist.h" #include "util/session.h" -#include "util/data_map.h" static char const *input_name = "perf.data"; @@ -454,7 +453,7 @@ static void find_annotations(void) } } -static struct perf_file_handler file_handler = { +static struct perf_event_ops event_ops = { .process_sample_event = process_sample_event, .process_mmap_event = event__process_mmap, .process_comm_event = event__process_comm, @@ -463,7 +462,8 @@ static struct perf_file_handler file_handler = { static int __cmd_annotate(void) { - struct perf_session *session = perf_session__new(input_name, O_RDONLY, force); + struct perf_session *session = perf_session__new(input_name, O_RDONLY, + force); struct thread *idle; int ret; @@ -471,9 +471,9 @@ static int __cmd_annotate(void) return -ENOMEM; idle = register_idle_thread(); - register_perf_file_handler(&file_handler); - ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, &event_ops, 0, + &event__cwdlen, &event__cwd); if (ret) goto out_delete; diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index bfd16a1..2629f76 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -9,7 +9,6 @@ #include "builtin.h" #include "perf.h" #include "util/cache.h" -#include "util/data_map.h" #include "util/debug.h" #include "util/parse-options.h" #include "util/session.h" diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 101b268..6f74bd8 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -12,7 +12,6 @@ #include "util/trace-event.h" #include "util/debug.h" -#include "util/data_map.h" #include @@ -359,7 +358,7 @@ static int sample_type_check(u64 type) return 0; } -static struct perf_file_handler file_handler = { +static struct perf_event_ops event_ops = { .process_sample_event = process_sample_event, .process_comm_event = event__process_comm, .sample_type_check = sample_type_check, @@ -374,9 +373,8 @@ static int read_events(void) return -ENOMEM; register_idle_thread(); - register_perf_file_handler(&file_handler); - - err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + err = perf_session__process_events(session, &event_ops, 0, + &event__cwdlen, &event__cwd); perf_session__delete(session); return err; } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index dcd8fed..c203eaf 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -27,7 +27,6 @@ #include "util/parse-options.h" #include "util/parse-events.h" -#include "util/data_map.h" #include "util/thread.h" #include "util/sort.h" #include "util/hist.h" @@ -748,7 +747,7 @@ static int sample_type_check(u64 type) return 0; } -static struct perf_file_handler file_handler = { +static struct perf_event_ops event_ops = { .process_sample_event = process_sample_event, .process_mmap_event = event__process_mmap, .process_comm_event = process_comm_event, @@ -776,9 +775,7 @@ static int __cmd_report(void) if (show_threads) perf_read_values_init(&show_threads_values); - register_perf_file_handler(&file_handler); - - ret = perf_session__process_events(session, full_paths, + ret = perf_session__process_events(session, &event_ops, full_paths, &event__cwdlen, &event__cwd); if (ret) goto out_delete; diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 48ab283..b5b4472 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -12,7 +12,6 @@ #include "util/trace-event.h" #include "util/debug.h" -#include "util/data_map.h" #include @@ -1656,7 +1655,7 @@ static int sample_type_check(u64 type) return 0; } -static struct perf_file_handler file_handler = { +static struct perf_event_ops event_ops = { .process_sample_event = process_sample_event, .process_comm_event = event__process_comm, .process_lost_event = process_lost_event, @@ -1672,9 +1671,9 @@ static int read_events(void) return -ENOMEM; register_idle_thread(); - register_perf_file_handler(&file_handler); - err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + err = perf_session__process_events(session, &event_ops, 0, + &event__cwdlen, &event__cwd); perf_session__delete(session); return err; } diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index db6caae..4b95cec 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -30,7 +30,7 @@ #include "util/parse-options.h" #include "util/parse-events.h" #include "util/event.h" -#include "util/data_map.h" +#include "util/session.h" #include "util/svghelper.h" static char const *input_name = "perf.data"; @@ -1046,7 +1046,7 @@ static int sample_type_check(u64 type) return 0; } -static struct perf_file_handler file_handler = { +static struct perf_event_ops event_ops = { .process_comm_event = process_comm_event, .process_fork_event = process_fork_event, .process_exit_event = process_exit_event, @@ -1062,9 +1062,8 @@ static int __cmd_timechart(void) if (session == NULL) return -ENOMEM; - register_perf_file_handler(&file_handler); - - ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, &event_ops, 0, + &event__cwdlen, &event__cwd); if (ret) goto out_delete; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 3057e1d..c404dec 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -57,7 +57,6 @@ static int cleanup_scripting(void) #include "util/debug.h" #include "util/trace-event.h" -#include "util/data_map.h" #include "util/exec_cmd.h" static char const *input_name = "perf.data"; @@ -118,7 +117,7 @@ static int sample_type_check(u64 type) return 0; } -static struct perf_file_handler file_handler = { +static struct perf_event_ops event_ops = { .process_sample_event = process_sample_event, .process_comm_event = event__process_comm, .sample_type_check = sample_type_check, @@ -127,9 +126,8 @@ static struct perf_file_handler file_handler = { static int __cmd_trace(struct perf_session *session) { register_idle_thread(); - register_perf_file_handler(&file_handler); - - return perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + return perf_session__process_events(session, &event_ops, 0, + &event__cwdlen, &event__cwd); } struct script_spec { diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index 22bcdfe..ba5bcfa 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c @@ -1,10 +1,8 @@ -#include "data_map.h" #include "symbol.h" #include "util.h" #include "debug.h" +#include "session.h" - -static struct perf_file_handler *curr_handler; static unsigned long mmap_window = 32; static char __cwd[PATH_MAX]; @@ -15,7 +13,7 @@ static int process_event_stub(event_t *event __used, return 0; } -void register_perf_file_handler(struct perf_file_handler *handler) +static void perf_event_ops__fill_defaults(struct perf_event_ops *handler) { if (!handler->process_sample_event) handler->process_sample_event = process_event_stub; @@ -35,8 +33,6 @@ void register_perf_file_handler(struct perf_file_handler *handler) handler->process_throttle_event = process_event_stub; if (!handler->process_unthrottle_event) handler->process_unthrottle_event = process_event_stub; - - curr_handler = handler; } static const char *event__name[] = { @@ -63,6 +59,7 @@ void event__print_totals(void) } static int process_event(event_t *event, struct perf_session *session, + struct perf_event_ops *ops, unsigned long offset, unsigned long head) { trace_event(event); @@ -78,25 +75,25 @@ static int process_event(event_t *event, struct perf_session *session, switch (event->header.type) { case PERF_RECORD_SAMPLE: - return curr_handler->process_sample_event(event, session); + return ops->process_sample_event(event, session); case PERF_RECORD_MMAP: - return curr_handler->process_mmap_event(event, session); + return ops->process_mmap_event(event, session); case PERF_RECORD_COMM: - return curr_handler->process_comm_event(event, session); + return ops->process_comm_event(event, session); case PERF_RECORD_FORK: - return curr_handler->process_fork_event(event, session); + return ops->process_fork_event(event, session); case PERF_RECORD_EXIT: - return curr_handler->process_exit_event(event, session); + return ops->process_exit_event(event, session); case PERF_RECORD_LOST: - return curr_handler->process_lost_event(event, session); + return ops->process_lost_event(event, session); case PERF_RECORD_READ: - return curr_handler->process_read_event(event, session); + return ops->process_read_event(event, session); case PERF_RECORD_THROTTLE: - return curr_handler->process_throttle_event(event, session); + return ops->process_throttle_event(event, session); case PERF_RECORD_UNTHROTTLE: - return curr_handler->process_unthrottle_event(event, session); + return ops->process_unthrottle_event(event, session); default: - curr_handler->total_unknown++; + ops->total_unknown++; return -1; } } @@ -131,6 +128,7 @@ out: } int perf_session__process_events(struct perf_session *self, + struct perf_event_ops *ops, int full_paths, int *cwdlen, char **cwd) { int err; @@ -142,10 +140,7 @@ int perf_session__process_events(struct perf_session *self, uint32_t size; char *buf; - if (curr_handler == NULL) { - pr_debug("Forgot to register perf file handler\n"); - return -EINVAL; - } + perf_event_ops__fill_defaults(ops); page_size = getpagesize(); @@ -153,8 +148,8 @@ int perf_session__process_events(struct perf_session *self, sample_type = perf_header__sample_type(&self->header); err = -EINVAL; - if (curr_handler->sample_type_check && - curr_handler->sample_type_check(sample_type) < 0) + if (ops->sample_type_check && + ops->sample_type_check(sample_type) < 0) goto out_err; if (!full_paths) { @@ -210,7 +205,7 @@ more: (void *)(long)event->header.size, event->header.type); - if (!size || process_event(event, self, offset, head) < 0) { + if (!size || process_event(event, self, ops, offset, head) < 0) { dump_printf("%p [%p]: skipping unknown header type: %d\n", (void *)(offset + head), diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h deleted file mode 100644 index 6d4ae52..0000000 --- a/tools/perf/util/data_map.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __PERF_DATAMAP_H -#define __PERF_DATAMAP_H - -#include "event.h" -#include "header.h" -#include "session.h" - -struct perf_session; - -typedef int (*event_type_handler_t)(event_t *self, - struct perf_session *session); - -struct perf_file_handler { - event_type_handler_t process_sample_event; - event_type_handler_t process_mmap_event; - event_type_handler_t process_comm_event; - event_type_handler_t process_fork_event; - event_type_handler_t process_exit_event; - event_type_handler_t process_lost_event; - event_type_handler_t process_read_event; - event_type_handler_t process_throttle_event; - event_type_handler_t process_unthrottle_event; - int (*sample_type_check)(u64 sample_type); - unsigned long total_unknown; -}; - -void register_perf_file_handler(struct perf_file_handler *handler); -int perf_session__process_events(struct perf_session *self, - int full_paths, int *cwdlen, char **cwd); -int perf_header__read_build_ids(int input, u64 offset, u64 file_size); - -#endif diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index f2e8d87..8a0bca5 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -8,8 +8,8 @@ #include "header.h" #include "../perf.h" #include "trace-event.h" +#include "session.h" #include "symbol.h" -#include "data_map.h" #include "debug.h" /* diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 707ce1c..3976686 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -48,7 +48,8 @@ out_close: return -1; } -struct perf_session *perf_session__new(const char *filename, int mode, bool force) +struct perf_session *perf_session__new(const char *filename, int mode, + bool force) { size_t len = strlen(filename) + 1; struct perf_session *self = zalloc(sizeof(*self) + len); diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index f3699c8..7a4c32c 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -1,6 +1,7 @@ #ifndef __PERF_SESSION_H #define __PERF_SESSION_H +#include "event.h" #include "header.h" struct perf_session { @@ -10,7 +11,30 @@ struct perf_session { char filename[0]; }; -struct perf_session *perf_session__new(const char *filename, int mode, bool force); +typedef int (*event_op)(event_t *self, struct perf_session *session); + +struct perf_event_ops { + event_op process_sample_event; + event_op process_mmap_event; + event_op process_comm_event; + event_op process_fork_event; + event_op process_exit_event; + event_op process_lost_event; + event_op process_read_event; + event_op process_throttle_event; + event_op process_unthrottle_event; + int (*sample_type_check)(u64 sample_type); + unsigned long total_unknown; +}; + +struct perf_session *perf_session__new(const char *filename, int mode, + bool force); void perf_session__delete(struct perf_session *self); +int perf_session__process_events(struct perf_session *self, + struct perf_event_ops *event_ops, + int full_paths, int *cwdlen, char **cwd); + +int perf_header__read_build_ids(int input, u64 offset, u64 file_size); + #endif /* __PERF_SESSION_H */ -- cgit v0.10.2 From 13df45ca1c9a430d5f53862854070fcc324e015c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 13 Dec 2009 19:50:26 -0200 Subject: perf session: Register the idle thread in perf_session__process_events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need for all tools to register it and then immediately call perf_session__process_events. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260741029-4430-3-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 43e3bb3..93d765a 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -464,14 +464,11 @@ static int __cmd_annotate(void) { struct perf_session *session = perf_session__new(input_name, O_RDONLY, force); - struct thread *idle; int ret; if (session == NULL) return -ENOMEM; - idle = register_idle_thread(); - ret = perf_session__process_events(session, &event_ops, 0, &event__cwdlen, &event__cwd); if (ret) diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 6f74bd8..37a8499 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -372,7 +372,6 @@ static int read_events(void) if (session == NULL) return -ENOMEM; - register_idle_thread(); err = perf_session__process_events(session, &event_ops, 0, &event__cwdlen, &event__cwd); perf_session__delete(session); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index c203eaf..4b37ac4 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -761,7 +761,6 @@ static struct perf_event_ops event_ops = { static int __cmd_report(void) { - struct thread *idle; int ret; struct perf_session *session; @@ -769,9 +768,6 @@ static int __cmd_report(void) if (session == NULL) return -ENOMEM; - idle = register_idle_thread(); - thread__comm_adjust(idle); - if (show_threads) perf_read_values_init(&show_threads_values); diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index b5b4472..847ed51 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1670,8 +1670,6 @@ static int read_events(void) if (session == NULL) return -ENOMEM; - register_idle_thread(); - err = perf_session__process_events(session, &event_ops, 0, &event__cwdlen, &event__cwd); perf_session__delete(session); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c404dec..40cb896 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -125,7 +125,6 @@ static struct perf_event_ops event_ops = { static int __cmd_trace(struct perf_session *session) { - register_idle_thread(); return perf_session__process_events(session, &event_ops, 0, &event__cwdlen, &event__cwd); } diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index ba5bcfa..36e3bfe 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c @@ -1,6 +1,7 @@ #include "symbol.h" #include "util.h" #include "debug.h" +#include "thread.h" #include "session.h" static unsigned long mmap_window = 32; @@ -127,6 +128,18 @@ out: return err; } +static struct thread *perf_session__register_idle_thread(struct perf_session *self __used) +{ + struct thread *thread = threads__findnew(0); + + if (!thread || thread__set_comm(thread, "swapper")) { + pr_err("problem inserting idle task.\n"); + thread = NULL; + } + + return thread; +} + int perf_session__process_events(struct perf_session *self, struct perf_event_ops *ops, int full_paths, int *cwdlen, char **cwd) @@ -140,6 +153,9 @@ int perf_session__process_events(struct perf_session *self, uint32_t size; char *buf; + if (perf_session__register_idle_thread(self) == NULL) + return -ENOMEM; + perf_event_ops__fill_defaults(ops); page_size = getpagesize(); diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index b68a00e..5c0ab14 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -161,18 +161,6 @@ struct thread *threads__findnew(pid_t pid) return th; } -struct thread *register_idle_thread(void) -{ - struct thread *thread = threads__findnew(0); - - if (!thread || thread__set_comm(thread, "swapper")) { - fprintf(stderr, "problem inserting idle task.\n"); - exit(-1); - } - - return thread; -} - static void map_groups__remove_overlappings(struct map_groups *self, struct map *map) { diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 1751802..2e35e1f 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -24,7 +24,6 @@ void map_groups__init(struct map_groups *self); int thread__set_comm(struct thread *self, const char *comm); int thread__comm_len(struct thread *self); struct thread *threads__findnew(pid_t pid); -struct thread *register_idle_thread(void); void thread__insert_map(struct thread *self, struct map *map); int thread__fork(struct thread *self, struct thread *parent); size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp); -- cgit v0.10.2 From ec913369733923dbfd6bdff5953a918107059701 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 13 Dec 2009 19:50:27 -0200 Subject: perf session: Reduce the number of parms to perf_session__process_events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By having the cwd/cwdlen in the perf_session struct and full_paths in perf_event_ops. Now its just a matter of passing the ops. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260741029-4430-4-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 93d765a..a931b13 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -469,8 +469,7 @@ static int __cmd_annotate(void) if (session == NULL) return -ENOMEM; - ret = perf_session__process_events(session, &event_ops, 0, - &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, &event_ops); if (ret) goto out_delete; diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 37a8499..237155f 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -372,8 +372,7 @@ static int read_events(void) if (session == NULL) return -ENOMEM; - err = perf_session__process_events(session, &event_ops, 0, - &event__cwdlen, &event__cwd); + err = perf_session__process_events(session, &event_ops); perf_session__delete(session); return err; } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 4b37ac4..26b9478 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -39,7 +39,6 @@ static struct strlist *dso_list, *comm_list, *sym_list; static int force; -static int full_paths; static int show_nr_samples; static int show_threads; @@ -771,8 +770,7 @@ static int __cmd_report(void) if (show_threads) perf_read_values_init(&show_threads_values); - ret = perf_session__process_events(session, &event_ops, full_paths, - &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, &event_ops); if (ret) goto out_delete; @@ -877,7 +875,7 @@ static const struct option options[] = { "pretty printing style key: normal raw"), OPT_STRING('s', "sort", &sort_order, "key[,key2...]", "sort by key(s): pid, comm, dso, symbol, parent"), - OPT_BOOLEAN('P', "full-paths", &full_paths, + OPT_BOOLEAN('P', "full-paths", &event_ops.full_paths, "Don't shorten the pathnames taking into account the cwd"), OPT_STRING('p', "parent", &parent_pattern, "regex", "regex filter to identify parent, see: '--sort parent'"), diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 847ed51..1e4e508 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1670,8 +1670,7 @@ static int read_events(void) if (session == NULL) return -ENOMEM; - err = perf_session__process_events(session, &event_ops, 0, - &event__cwdlen, &event__cwd); + err = perf_session__process_events(session, &event_ops); perf_session__delete(session); return err; } diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 4b95cec..b5211fa 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1062,8 +1062,7 @@ static int __cmd_timechart(void) if (session == NULL) return -ENOMEM; - ret = perf_session__process_events(session, &event_ops, 0, - &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, &event_ops); if (ret) goto out_delete; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 40cb896..b7eb3fc 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -125,8 +125,7 @@ static struct perf_event_ops event_ops = { static int __cmd_trace(struct perf_session *session) { - return perf_session__process_events(session, &event_ops, 0, - &event__cwdlen, &event__cwd); + return perf_session__process_events(session, &event_ops); } struct script_spec { diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index 36e3bfe..ba2eb2c 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c @@ -4,9 +4,6 @@ #include "thread.h" #include "session.h" -static unsigned long mmap_window = 32; -static char __cwd[PATH_MAX]; - static int process_event_stub(event_t *event __used, struct perf_session *session __used) { @@ -141,8 +138,7 @@ static struct thread *perf_session__register_idle_thread(struct perf_session *se } int perf_session__process_events(struct perf_session *self, - struct perf_event_ops *ops, - int full_paths, int *cwdlen, char **cwd) + struct perf_event_ops *ops) { int err; unsigned long head, shift; @@ -168,17 +164,21 @@ int perf_session__process_events(struct perf_session *self, ops->sample_type_check(sample_type) < 0) goto out_err; - if (!full_paths) { - if (getcwd(__cwd, sizeof(__cwd)) == NULL) { - pr_err("failed to get the current directory\n"); + if (!ops->full_paths) { + char bf[PATH_MAX]; + + if (getcwd(bf, sizeof(bf)) == NULL) { err = -errno; +out_getcwd_err: + pr_err("failed to get the current directory\n"); goto out_err; } - *cwd = __cwd; - *cwdlen = strlen(*cwd); - } else { - *cwd = NULL; - *cwdlen = 0; + self->cwd = strdup(bf); + if (self->cwd == NULL) { + err = -ENOMEM; + goto out_getcwd_err; + } + self->cwdlen = strlen(self->cwd); } shift = page_size * (head / page_size); @@ -186,7 +186,7 @@ int perf_session__process_events(struct perf_session *self, head -= shift; remap: - buf = mmap(NULL, page_size * mmap_window, PROT_READ, + buf = mmap(NULL, page_size * self->mmap_window, PROT_READ, MAP_SHARED, self->fd, offset); if (buf == MAP_FAILED) { pr_err("failed to mmap file\n"); @@ -201,12 +201,12 @@ more: if (!size) size = 8; - if (head + event->header.size >= page_size * mmap_window) { + if (head + event->header.size >= page_size * self->mmap_window) { int munmap_ret; shift = page_size * (head / page_size); - munmap_ret = munmap(buf, page_size * mmap_window); + munmap_ret = munmap(buf, page_size * self->mmap_window); assert(munmap_ret == 0); offset += shift; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index e2c4895..40d8d84 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1,6 +1,7 @@ #include #include "event.h" #include "debug.h" +#include "session.h" #include "string.h" #include "thread.h" @@ -186,9 +187,6 @@ void event__synthesize_threads(int (*process)(event_t *event, closedir(proc); } -char *event__cwd; -int event__cwdlen; - struct events_stats event__stats; int event__process_comm(event_t *self, struct perf_session *session __used) @@ -212,11 +210,11 @@ int event__process_lost(event_t *self, struct perf_session *session __used) return 0; } -int event__process_mmap(event_t *self, struct perf_session *session __used) +int event__process_mmap(event_t *self, struct perf_session *session) { struct thread *thread = threads__findnew(self->mmap.pid); struct map *map = map__new(&self->mmap, MAP__FUNCTION, - event__cwd, event__cwdlen); + session->cwd, session->cwdlen); dump_printf(" %d/%d: [%p(%p) @ %p]: %s\n", self->mmap.pid, self->mmap.tid, diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 3976686..534a877 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -61,6 +61,9 @@ struct perf_session *perf_session__new(const char *filename, int mode, goto out_delete; memcpy(self->filename, filename, len); + self->mmap_window = 32; + self->cwd = NULL; + self->cwdlen = 0; if (mode == O_RDONLY && perf_session__open(self, force) < 0) { perf_session__delete(self); @@ -77,5 +80,6 @@ void perf_session__delete(struct perf_session *self) { perf_header__exit(&self->header); close(self->fd); + free(self->cwd); free(self); } diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 7a4c32c..1e0da9c 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -7,7 +7,10 @@ struct perf_session { struct perf_header header; unsigned long size; + unsigned long mmap_window; int fd; + int cwdlen; + char *cwd; char filename[0]; }; @@ -25,6 +28,7 @@ struct perf_event_ops { event_op process_unthrottle_event; int (*sample_type_check)(u64 sample_type); unsigned long total_unknown; + bool full_paths; }; struct perf_session *perf_session__new(const char *filename, int mode, @@ -32,8 +36,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, void perf_session__delete(struct perf_session *self); int perf_session__process_events(struct perf_session *self, - struct perf_event_ops *event_ops, - int full_paths, int *cwdlen, char **cwd); + struct perf_event_ops *event_ops); int perf_header__read_build_ids(int input, u64 offset, u64 file_size); -- cgit v0.10.2 From b3165f414416a717f72a376720564012af5a2e01 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 13 Dec 2009 19:50:28 -0200 Subject: perf session: Move the global threads list to perf_session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So that we can process two perf.data files. We still need to add a O_MMAP mode for perf_session so that we can do all the mmap stuff in it. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260741029-4430-5-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index a931b13..795f865 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -131,14 +131,14 @@ static int hist_entry__add(struct addr_location *al, u64 count) return 0; } -static int process_sample_event(event_t *event, struct perf_session *session __used) +static int process_sample_event(event_t *event, struct perf_session *session) { struct addr_location al; dump_printf("(IP, %d): %d: %p\n", event->header.misc, event->ip.pid, (void *)(long)event->ip.ip); - if (event__preprocess_sample(event, &al, symbol_filter) < 0) { + if (event__preprocess_sample(event, session, &al, symbol_filter) < 0) { fprintf(stderr, "problem processing %d event, skipping it.\n", event->header.type); return -1; @@ -479,7 +479,7 @@ static int __cmd_annotate(void) } if (verbose > 3) - threads__fprintf(stdout); + perf_session__fprintf(session, stdout); if (verbose > 2) dsos__fprintf(stdout); diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 237155f..de19495 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -311,7 +311,7 @@ process_raw_event(event_t *raw_event __used, void *data, } } -static int process_sample_event(event_t *event, struct perf_session *session __used) +static int process_sample_event(event_t *event, struct perf_session *session) { struct sample_data data; struct thread *thread; @@ -329,7 +329,7 @@ static int process_sample_event(event_t *event, struct perf_session *session __u (void *)(long)data.ip, (long long)data.period); - thread = threads__findnew(event->ip.pid); + thread = perf_session__findnew(session, event->ip.pid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", event->header.type); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 26b9478..efa8147 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -600,7 +600,7 @@ static int validate_chain(struct ip_callchain *chain, event_t *event) return 0; } -static int process_sample_event(event_t *event, struct perf_session *session __used) +static int process_sample_event(event_t *event, struct perf_session *session) { struct sample_data data; int cpumode; @@ -636,7 +636,7 @@ static int process_sample_event(event_t *event, struct perf_session *session __u } } - thread = threads__findnew(data.pid); + thread = perf_session__findnew(session, data.pid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", event->header.type); @@ -679,9 +679,9 @@ static int process_sample_event(event_t *event, struct perf_session *session __u return 0; } -static int process_comm_event(event_t *event, struct perf_session *session __used) +static int process_comm_event(event_t *event, struct perf_session *session) { - struct thread *thread = threads__findnew(event->comm.pid); + struct thread *thread = perf_session__findnew(session, event->comm.pid); dump_printf(": %s:%d\n", event->comm.comm, event->comm.pid); @@ -780,7 +780,7 @@ static int __cmd_report(void) } if (verbose > 3) - threads__fprintf(stdout); + perf_session__fprintf(session, stdout); if (verbose > 2) dsos__fprintf(stdout); diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 1e4e508..8d58d9e 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -730,18 +730,21 @@ struct trace_migrate_task_event { struct trace_sched_handler { void (*switch_event)(struct trace_switch_event *, + struct perf_session *, struct event *, int cpu, u64 timestamp, struct thread *thread); void (*runtime_event)(struct trace_runtime_event *, + struct perf_session *, struct event *, int cpu, u64 timestamp, struct thread *thread); void (*wakeup_event)(struct trace_wakeup_event *, + struct perf_session *, struct event *, int cpu, u64 timestamp, @@ -754,6 +757,7 @@ struct trace_sched_handler { struct thread *thread); void (*migrate_task_event)(struct trace_migrate_task_event *, + struct perf_session *session, struct event *, int cpu, u64 timestamp, @@ -763,6 +767,7 @@ struct trace_sched_handler { static void replay_wakeup_event(struct trace_wakeup_event *wakeup_event, + struct perf_session *session __used, struct event *event, int cpu __used, u64 timestamp __used, @@ -789,6 +794,7 @@ static u64 cpu_last_switched[MAX_CPUS]; static void replay_switch_event(struct trace_switch_event *switch_event, + struct perf_session *session __used, struct event *event, int cpu, u64 timestamp, @@ -1022,6 +1028,7 @@ add_sched_in_event(struct work_atoms *atoms, u64 timestamp) static void latency_switch_event(struct trace_switch_event *switch_event, + struct perf_session *session, struct event *event __used, int cpu, u64 timestamp, @@ -1045,8 +1052,8 @@ latency_switch_event(struct trace_switch_event *switch_event, die("hm, delta: %Ld < 0 ?\n", delta); - sched_out = threads__findnew(switch_event->prev_pid); - sched_in = threads__findnew(switch_event->next_pid); + sched_out = perf_session__findnew(session, switch_event->prev_pid); + sched_in = perf_session__findnew(session, switch_event->next_pid); out_events = thread_atoms_search(&atom_root, sched_out, &cmp_pid); if (!out_events) { @@ -1074,12 +1081,13 @@ latency_switch_event(struct trace_switch_event *switch_event, static void latency_runtime_event(struct trace_runtime_event *runtime_event, + struct perf_session *session, struct event *event __used, int cpu, u64 timestamp, struct thread *this_thread __used) { - struct thread *thread = threads__findnew(runtime_event->pid); + struct thread *thread = perf_session__findnew(session, runtime_event->pid); struct work_atoms *atoms = thread_atoms_search(&atom_root, thread, &cmp_pid); BUG_ON(cpu >= MAX_CPUS || cpu < 0); @@ -1096,6 +1104,7 @@ latency_runtime_event(struct trace_runtime_event *runtime_event, static void latency_wakeup_event(struct trace_wakeup_event *wakeup_event, + struct perf_session *session, struct event *__event __used, int cpu __used, u64 timestamp, @@ -1109,7 +1118,7 @@ latency_wakeup_event(struct trace_wakeup_event *wakeup_event, if (!wakeup_event->success) return; - wakee = threads__findnew(wakeup_event->pid); + wakee = perf_session__findnew(session, wakeup_event->pid); atoms = thread_atoms_search(&atom_root, wakee, &cmp_pid); if (!atoms) { thread_atoms_insert(wakee); @@ -1143,6 +1152,7 @@ latency_wakeup_event(struct trace_wakeup_event *wakeup_event, static void latency_migrate_task_event(struct trace_migrate_task_event *migrate_task_event, + struct perf_session *session, struct event *__event __used, int cpu __used, u64 timestamp, @@ -1158,7 +1168,7 @@ latency_migrate_task_event(struct trace_migrate_task_event *migrate_task_event, if (profile_cpu == -1) return; - migrant = threads__findnew(migrate_task_event->pid); + migrant = perf_session__findnew(session, migrate_task_event->pid); atoms = thread_atoms_search(&atom_root, migrant, &cmp_pid); if (!atoms) { thread_atoms_insert(migrant); @@ -1353,7 +1363,7 @@ static void sort_lat(void) static struct trace_sched_handler *trace_handler; static void -process_sched_wakeup_event(void *data, +process_sched_wakeup_event(void *data, struct perf_session *session, struct event *event, int cpu __used, u64 timestamp __used, @@ -1370,7 +1380,8 @@ process_sched_wakeup_event(void *data, FILL_FIELD(wakeup_event, cpu, event, data); if (trace_handler->wakeup_event) - trace_handler->wakeup_event(&wakeup_event, event, cpu, timestamp, thread); + trace_handler->wakeup_event(&wakeup_event, session, event, + cpu, timestamp, thread); } /* @@ -1388,6 +1399,7 @@ static char next_shortname2 = '0'; static void map_switch_event(struct trace_switch_event *switch_event, + struct perf_session *session, struct event *event __used, int this_cpu, u64 timestamp, @@ -1415,8 +1427,8 @@ map_switch_event(struct trace_switch_event *switch_event, die("hm, delta: %Ld < 0 ?\n", delta); - sched_out = threads__findnew(switch_event->prev_pid); - sched_in = threads__findnew(switch_event->next_pid); + sched_out = perf_session__findnew(session, switch_event->prev_pid); + sched_in = perf_session__findnew(session, switch_event->next_pid); curr_thread[this_cpu] = sched_in; @@ -1466,7 +1478,7 @@ map_switch_event(struct trace_switch_event *switch_event, static void -process_sched_switch_event(void *data, +process_sched_switch_event(void *data, struct perf_session *session, struct event *event, int this_cpu, u64 timestamp __used, @@ -1493,13 +1505,14 @@ process_sched_switch_event(void *data, nr_context_switch_bugs++; } if (trace_handler->switch_event) - trace_handler->switch_event(&switch_event, event, this_cpu, timestamp, thread); + trace_handler->switch_event(&switch_event, session, event, + this_cpu, timestamp, thread); curr_pid[this_cpu] = switch_event.next_pid; } static void -process_sched_runtime_event(void *data, +process_sched_runtime_event(void *data, struct perf_session *session, struct event *event, int cpu __used, u64 timestamp __used, @@ -1513,7 +1526,7 @@ process_sched_runtime_event(void *data, FILL_FIELD(runtime_event, vruntime, event, data); if (trace_handler->runtime_event) - trace_handler->runtime_event(&runtime_event, event, cpu, timestamp, thread); + trace_handler->runtime_event(&runtime_event, session, event, cpu, timestamp, thread); } static void @@ -1533,7 +1546,8 @@ process_sched_fork_event(void *data, FILL_FIELD(fork_event, child_pid, event, data); if (trace_handler->fork_event) - trace_handler->fork_event(&fork_event, event, cpu, timestamp, thread); + trace_handler->fork_event(&fork_event, event, + cpu, timestamp, thread); } static void @@ -1547,7 +1561,7 @@ process_sched_exit_event(struct event *event, } static void -process_sched_migrate_task_event(void *data, +process_sched_migrate_task_event(void *data, struct perf_session *session, struct event *event, int cpu __used, u64 timestamp __used, @@ -1563,12 +1577,13 @@ process_sched_migrate_task_event(void *data, FILL_FIELD(migrate_task_event, cpu, event, data); if (trace_handler->migrate_task_event) - trace_handler->migrate_task_event(&migrate_task_event, event, cpu, timestamp, thread); + trace_handler->migrate_task_event(&migrate_task_event, session, + event, cpu, timestamp, thread); } static void -process_raw_event(event_t *raw_event __used, void *data, - int cpu, u64 timestamp, struct thread *thread) +process_raw_event(event_t *raw_event __used, struct perf_session *session, + void *data, int cpu, u64 timestamp, struct thread *thread) { struct event *event; int type; @@ -1578,23 +1593,22 @@ process_raw_event(event_t *raw_event __used, void *data, event = trace_find_event(type); if (!strcmp(event->name, "sched_switch")) - process_sched_switch_event(data, event, cpu, timestamp, thread); + process_sched_switch_event(data, session, event, cpu, timestamp, thread); if (!strcmp(event->name, "sched_stat_runtime")) - process_sched_runtime_event(data, event, cpu, timestamp, thread); + process_sched_runtime_event(data, session, event, cpu, timestamp, thread); if (!strcmp(event->name, "sched_wakeup")) - process_sched_wakeup_event(data, event, cpu, timestamp, thread); + process_sched_wakeup_event(data, session, event, cpu, timestamp, thread); if (!strcmp(event->name, "sched_wakeup_new")) - process_sched_wakeup_event(data, event, cpu, timestamp, thread); + process_sched_wakeup_event(data, session, event, cpu, timestamp, thread); if (!strcmp(event->name, "sched_process_fork")) process_sched_fork_event(data, event, cpu, timestamp, thread); if (!strcmp(event->name, "sched_process_exit")) process_sched_exit_event(event, cpu, timestamp, thread); if (!strcmp(event->name, "sched_migrate_task")) - process_sched_migrate_task_event(data, event, cpu, timestamp, thread); + process_sched_migrate_task_event(data, session, event, cpu, timestamp, thread); } -static int process_sample_event(event_t *event, - struct perf_session *session __used) +static int process_sample_event(event_t *event, struct perf_session *session) { struct sample_data data; struct thread *thread; @@ -1615,7 +1629,7 @@ static int process_sample_event(event_t *event, (void *)(long)data.ip, (long long)data.period); - thread = threads__findnew(data.pid); + thread = perf_session__findnew(session, data.pid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", event->header.type); @@ -1627,7 +1641,7 @@ static int process_sample_event(event_t *event, if (profile_cpu != -1 && profile_cpu != (int)data.cpu) return 0; - process_raw_event(event, data.raw_data, data.cpu, data.time, thread); + process_raw_event(event, session, data.raw_data, data.cpu, data.time, thread); return 0; } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index b13f426..0f7a4da 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -20,8 +20,9 @@ #include "perf.h" -#include "util/symbol.h" #include "util/color.h" +#include "util/session.h" +#include "util/symbol.h" #include "util/thread.h" #include "util/util.h" #include @@ -926,7 +927,8 @@ static int symbol_filter(struct map *map, struct symbol *sym) return 0; } -static void event__process_sample(const event_t *self, int counter) +static void event__process_sample(const event_t *self, + struct perf_session *session, int counter) { u64 ip = self->ip.ip; struct sym_entry *syme; @@ -946,7 +948,7 @@ static void event__process_sample(const event_t *self, int counter) return; } - if (event__preprocess_sample(self, &al, symbol_filter) < 0 || + if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 || al.sym == NULL) return; @@ -1053,7 +1055,7 @@ static void perf_session__mmap_read_counter(struct perf_session *self, } if (event->header.type == PERF_RECORD_SAMPLE) - event__process_sample(event, md->counter); + event__process_sample(event, self, md->counter); else event__process(event, self); old += size; @@ -1157,10 +1159,13 @@ static int __cmd_top(void) int i, counter; int ret; /* - * XXX perf_session__new should allow passing a O_MMAP, so that all this - * mmap reading, etc is encapsulated in it. + * FIXME: perf_session__new should allow passing a O_MMAP, so that all this + * mmap reading, etc is encapsulated in it. Use O_WRONLY for now. */ - struct perf_session *session = NULL; + struct perf_session *session = perf_session__new(NULL, O_WRONLY, false); + + if (session == NULL) + return -ENOMEM; if (target_pid != -1) event__synthesize_thread(target_pid, event__process, session); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index b7eb3fc..d765323 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -63,7 +63,7 @@ static char const *input_name = "perf.data"; static u64 sample_type; -static int process_sample_event(event_t *event, struct perf_session *session __used) +static int process_sample_event(event_t *event, struct perf_session *session) { struct sample_data data; struct thread *thread; @@ -81,7 +81,7 @@ static int process_sample_event(event_t *event, struct perf_session *session __u (void *)(long)data.ip, (long long)data.period); - thread = threads__findnew(event->ip.pid); + thread = perf_session__findnew(session, event->ip.pid); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", event->header.type); diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index ba2eb2c..44dea21 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c @@ -125,9 +125,9 @@ out: return err; } -static struct thread *perf_session__register_idle_thread(struct perf_session *self __used) +static struct thread *perf_session__register_idle_thread(struct perf_session *self) { - struct thread *thread = threads__findnew(0); + struct thread *thread = perf_session__findnew(self, 0); if (!thread || thread__set_comm(thread, "swapper")) { pr_err("problem inserting idle task.\n"); diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 40d8d84..2d09c29 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -189,9 +189,9 @@ void event__synthesize_threads(int (*process)(event_t *event, struct events_stats event__stats; -int event__process_comm(event_t *self, struct perf_session *session __used) +int event__process_comm(event_t *self, struct perf_session *session) { - struct thread *thread = threads__findnew(self->comm.pid); + struct thread *thread = perf_session__findnew(session, self->comm.pid); dump_printf(": %s:%d\n", self->comm.comm, self->comm.pid); @@ -212,7 +212,7 @@ int event__process_lost(event_t *self, struct perf_session *session __used) int event__process_mmap(event_t *self, struct perf_session *session) { - struct thread *thread = threads__findnew(self->mmap.pid); + struct thread *thread = perf_session__findnew(session, self->mmap.pid); struct map *map = map__new(&self->mmap, MAP__FUNCTION, session->cwd, session->cwdlen); @@ -231,10 +231,10 @@ int event__process_mmap(event_t *self, struct perf_session *session) return 0; } -int event__process_task(event_t *self, struct perf_session *session __used) +int event__process_task(event_t *self, struct perf_session *session) { - struct thread *thread = threads__findnew(self->fork.pid); - struct thread *parent = threads__findnew(self->fork.ppid); + struct thread *thread = perf_session__findnew(session, self->fork.pid); + struct thread *parent = perf_session__findnew(session, self->fork.ppid); dump_printf("(%d:%d):(%d:%d)\n", self->fork.pid, self->fork.tid, self->fork.ppid, self->fork.ptid); @@ -300,11 +300,11 @@ try_again: } } -int event__preprocess_sample(const event_t *self, struct addr_location *al, - symbol_filter_t filter) +int event__preprocess_sample(const event_t *self, struct perf_session *session, + struct addr_location *al, symbol_filter_t filter) { u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - struct thread *thread = threads__findnew(self->ip.pid); + struct thread *thread = perf_session__findnew(session, self->ip.pid); if (thread == NULL) return -1; diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 6b6429b..bb09025 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -177,8 +177,8 @@ int event__process_mmap(event_t *self, struct perf_session *session); int event__process_task(event_t *self, struct perf_session *session); struct addr_location; -int event__preprocess_sample(const event_t *self, struct addr_location *al, - symbol_filter_t filter); +int event__preprocess_sample(const event_t *self, struct perf_session *session, + struct addr_location *al, symbol_filter_t filter); int event__parse_sample(event_t *event, u64 type, struct sample_data *data); #endif /* __PERF_RECORD_H */ diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 534a877..09836a5 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -51,7 +51,7 @@ out_close: struct perf_session *perf_session__new(const char *filename, int mode, bool force) { - size_t len = strlen(filename) + 1; + size_t len = filename ? strlen(filename) + 1 : 0; struct perf_session *self = zalloc(sizeof(*self) + len); if (self == NULL) @@ -61,6 +61,8 @@ struct perf_session *perf_session__new(const char *filename, int mode, goto out_delete; memcpy(self->filename, filename, len); + self->threads = RB_ROOT; + self->last_match = NULL; self->mmap_window = 32; self->cwd = NULL; self->cwdlen = 0; diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 1e0da9c..1dbef7c 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -3,11 +3,16 @@ #include "event.h" #include "header.h" +#include + +struct thread; struct perf_session { struct perf_header header; unsigned long size; unsigned long mmap_window; + struct rb_root threads; + struct thread *last_match; int fd; int cwdlen; char *cwd; diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 5c0ab14..634b7f7 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -2,13 +2,11 @@ #include #include #include +#include "session.h" #include "thread.h" #include "util.h" #include "debug.h" -static struct rb_root threads; -static struct thread *last_match; - void map_groups__init(struct map_groups *self) { int i; @@ -122,9 +120,9 @@ static size_t thread__fprintf(struct thread *self, FILE *fp) map_groups__fprintf(&self->mg, fp); } -struct thread *threads__findnew(pid_t pid) +struct thread *perf_session__findnew(struct perf_session *self, pid_t pid) { - struct rb_node **p = &threads.rb_node; + struct rb_node **p = &self->threads.rb_node; struct rb_node *parent = NULL; struct thread *th; @@ -133,15 +131,15 @@ struct thread *threads__findnew(pid_t pid) * so most of the time we dont have to look up * the full rbtree: */ - if (last_match && last_match->pid == pid) - return last_match; + if (self->last_match && self->last_match->pid == pid) + return self->last_match; while (*p != NULL) { parent = *p; th = rb_entry(parent, struct thread, rb_node); if (th->pid == pid) { - last_match = th; + self->last_match = th; return th; } @@ -154,8 +152,8 @@ struct thread *threads__findnew(pid_t pid) th = thread__new(pid); if (th != NULL) { rb_link_node(&th->rb_node, parent, p); - rb_insert_color(&th->rb_node, &threads); - last_match = th; + rb_insert_color(&th->rb_node, &self->threads); + self->last_match = th; } return th; @@ -269,12 +267,12 @@ int thread__fork(struct thread *self, struct thread *parent) return 0; } -size_t threads__fprintf(FILE *fp) +size_t perf_session__fprintf(struct perf_session *self, FILE *fp) { size_t ret = 0; struct rb_node *nd; - for (nd = rb_first(&threads); nd; nd = rb_next(nd)) { + for (nd = rb_first(&self->threads); nd; nd = rb_next(nd)) { struct thread *pos = rb_entry(nd, struct thread, rb_node); ret += thread__fprintf(pos, fp); diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 2e35e1f..e93abf2 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -23,11 +23,11 @@ struct thread { void map_groups__init(struct map_groups *self); int thread__set_comm(struct thread *self, const char *comm); int thread__comm_len(struct thread *self); -struct thread *threads__findnew(pid_t pid); +struct thread *perf_session__findnew(struct perf_session *self, pid_t pid); void thread__insert_map(struct thread *self, struct map *map); int thread__fork(struct thread *self, struct thread *parent); size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp); -size_t threads__fprintf(FILE *fp); +size_t perf_session__fprintf(struct perf_session *self, FILE *fp); void maps__insert(struct rb_root *maps, struct map *map); struct map *maps__find(struct rb_root *maps, u64 addr); -- cgit v0.10.2 From 4aa65636411ccb12f006a6ad593930655c445ff6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 13 Dec 2009 19:50:29 -0200 Subject: perf session: Move kmaps to perf_session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is still some more work to do to disentangle map creation from DSO loading, but this happens only for the kernel, and for the early adopters of perf diff, where this disentanglement matters most, we'll be testing different kernels, so no problem here. Further clarification: right now we create the kernel maps for the various modules and discontiguous kernel text maps when loading the DSO, we should do it as a two step process, first creating the maps, for multiple mappings with the same DSO store, then doing the dso load just once, for the first hit on one of the maps sharing this DSO backing store. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260741029-4430-6-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 795f865..e44c54c 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -463,7 +463,7 @@ static struct perf_event_ops event_ops = { static int __cmd_annotate(void) { struct perf_session *session = perf_session__new(input_name, O_RDONLY, - force); + force, &symbol_conf); int ret; if (session == NULL) diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index 2629f76..7c36e4b 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -54,8 +54,8 @@ static int perf_file_section__process_buildids(struct perf_file_section *self, static int __cmd_buildid_list(void) { int err = -1; - struct perf_session *session = perf_session__new(input_name, O_RDONLY, force); - + struct perf_session *session = perf_session__new(input_name, O_RDONLY, + force, NULL); if (session == NULL) return -1; diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index de19495..e79ecbc 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -364,19 +364,6 @@ static struct perf_event_ops event_ops = { .sample_type_check = sample_type_check, }; -static int read_events(void) -{ - int err; - struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0); - - if (session == NULL) - return -ENOMEM; - - err = perf_session__process_events(session, &event_ops); - perf_session__delete(session); - return err; -} - static double fragmentation(unsigned long n_req, unsigned long n_alloc) { if (n_alloc == 0) @@ -385,7 +372,8 @@ static double fragmentation(unsigned long n_req, unsigned long n_alloc) return 100.0 - (100.0 * n_req / n_alloc); } -static void __print_result(struct rb_root *root, int n_lines, int is_caller) +static void __print_result(struct rb_root *root, struct perf_session *session, + int n_lines, int is_caller) { struct rb_node *next; @@ -406,7 +394,7 @@ static void __print_result(struct rb_root *root, int n_lines, int is_caller) if (is_caller) { addr = data->call_site; if (!raw_ip) - sym = map_groups__find_function(kmaps, addr, NULL); + sym = map_groups__find_function(&session->kmaps, session, addr, NULL); } else addr = data->ptr; @@ -447,12 +435,12 @@ static void print_summary(void) printf("Cross CPU allocations: %lu/%lu\n", nr_cross_allocs, nr_allocs); } -static void print_result(void) +static void print_result(struct perf_session *session) { if (caller_flag) - __print_result(&root_caller_sorted, caller_lines, 1); + __print_result(&root_caller_sorted, session, caller_lines, 1); if (alloc_flag) - __print_result(&root_alloc_sorted, alloc_lines, 0); + __print_result(&root_alloc_sorted, session, alloc_lines, 0); print_summary(); } @@ -520,12 +508,21 @@ static void sort_result(void) static int __cmd_kmem(void) { + int err; + struct perf_session *session = perf_session__new(input_name, O_RDONLY, + 0, NULL); + if (session == NULL) + return -ENOMEM; + setup_pager(); - read_events(); + err = perf_session__process_events(session, &event_ops); + if (err != 0) + goto out_delete; sort_result(); - print_result(); - - return 0; + print_result(session); +out_delete: + perf_session__delete(session); + return err; } static const char * const kmem_usage[] = { diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index b7e15a1..a66a58d 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -442,7 +442,7 @@ static int __cmd_record(int argc, const char **argv) exit(-1); } - session = perf_session__new(output_name, O_WRONLY, force); + session = perf_session__new(output_name, O_WRONLY, force, NULL); if (session == NULL) { pr_err("Not enough memory for reading perf file header\n"); return -1; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index efa8147..3487224 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -414,6 +414,7 @@ static int call__match(struct symbol *sym) } static struct symbol **resolve_callchain(struct thread *thread, + struct perf_session *session, struct ip_callchain *chain, struct symbol **parent) { @@ -447,8 +448,8 @@ static struct symbol **resolve_callchain(struct thread *thread, continue; } - thread__find_addr_location(thread, cpumode, MAP__FUNCTION, - ip, &al, NULL); + thread__find_addr_location(thread, session, cpumode, + MAP__FUNCTION, ip, &al, NULL); if (al.sym != NULL) { if (sort__has_parent && !*parent && call__match(al.sym)) @@ -467,6 +468,7 @@ static struct symbol **resolve_callchain(struct thread *thread, */ static int hist_entry__add(struct addr_location *al, + struct perf_session *session, struct ip_callchain *chain, u64 count) { struct symbol **syms = NULL, *parent = NULL; @@ -474,7 +476,7 @@ static int hist_entry__add(struct addr_location *al, struct hist_entry *he; if ((sort__has_parent || callchain) && chain) - syms = resolve_callchain(al->thread, chain, &parent); + syms = resolve_callchain(al->thread, session, chain, &parent); he = __hist_entry__add(al, parent, count, &hit); if (he == NULL) @@ -650,7 +652,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - thread__find_addr_location(thread, cpumode, + thread__find_addr_location(thread, session, cpumode, MAP__FUNCTION, data.ip, &al, NULL); /* * We have to do this here as we may have a dso with no symbol hit that @@ -669,7 +671,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name)) return 0; - if (hist_entry__add(&al, data.callchain, data.period)) { + if (hist_entry__add(&al, session, data.callchain, data.period)) { pr_debug("problem incrementing symbol count, skipping event\n"); return -1; } @@ -763,7 +765,7 @@ static int __cmd_report(void) int ret; struct perf_session *session; - session = perf_session__new(input_name, O_RDONLY, force); + session = perf_session__new(input_name, O_RDONLY, force, &symbol_conf); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 8d58d9e..bce05df 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1679,8 +1679,8 @@ static struct perf_event_ops event_ops = { static int read_events(void) { int err; - struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0); - + struct perf_session *session = perf_session__new(input_name, O_RDONLY, + 0, NULL); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index b5211fa..2701853 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1056,7 +1056,8 @@ static struct perf_event_ops event_ops = { static int __cmd_timechart(void) { - struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0); + struct perf_session *session = perf_session__new(input_name, O_RDONLY, + 0, NULL); int ret; if (session == NULL) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0f7a4da..3b212bb 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1162,8 +1162,8 @@ static int __cmd_top(void) * FIXME: perf_session__new should allow passing a O_MMAP, so that all this * mmap reading, etc is encapsulated in it. Use O_WRONLY for now. */ - struct perf_session *session = perf_session__new(NULL, O_WRONLY, false); - + struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, + &symbol_conf); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index d765323..9d89ae42 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -318,7 +318,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) setup_pager(); - session = perf_session__new(input_name, O_RDONLY, 0); + session = perf_session__new(input_name, O_RDONLY, 0, NULL); if (session == NULL) return -ENOMEM; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 2d09c29..222efb1 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -256,7 +256,8 @@ int event__process_task(event_t *self, struct perf_session *session) return 0; } -void thread__find_addr_location(struct thread *self, u8 cpumode, +void thread__find_addr_location(struct thread *self, + struct perf_session *session, u8 cpumode, enum map_type type, u64 addr, struct addr_location *al, symbol_filter_t filter) @@ -268,7 +269,7 @@ void thread__find_addr_location(struct thread *self, u8 cpumode, if (cpumode & PERF_RECORD_MISC_KERNEL) { al->level = 'k'; - mg = kmaps; + mg = &session->kmaps; } else if (cpumode & PERF_RECORD_MISC_USER) al->level = '.'; else { @@ -289,14 +290,14 @@ try_again: * "[vdso]" dso, but for now lets use the old trick of looking * in the whole kernel symbol list. */ - if ((long long)al->addr < 0 && mg != kmaps) { - mg = kmaps; + if ((long long)al->addr < 0 && mg != &session->kmaps) { + mg = &session->kmaps; goto try_again; } al->sym = NULL; } else { al->addr = al->map->map_ip(al->map, al->addr); - al->sym = map__find_symbol(al->map, al->addr, filter); + al->sym = map__find_symbol(al->map, session, al->addr, filter); } } @@ -311,7 +312,7 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session, dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); - thread__find_addr_location(thread, cpumode, MAP__FUNCTION, + thread__find_addr_location(thread, session, cpumode, MAP__FUNCTION, self->ip.ip, al, filter); dump_printf(" ...... dso: %s\n", al->map ? al->map->dso->long_name : diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index bb09025..035ecf3 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -149,15 +149,17 @@ void map__delete(struct map *self); struct map *map__clone(struct map *self); int map__overlap(struct map *l, struct map *r); size_t map__fprintf(struct map *self, FILE *fp); -struct symbol *map__find_symbol(struct map *self, u64 addr, - symbol_filter_t filter); + +struct perf_session; + +struct symbol *map__find_symbol(struct map *self, struct perf_session *session, + u64 addr, symbol_filter_t filter); struct symbol *map__find_symbol_by_name(struct map *self, const char *name, + struct perf_session *session, symbol_filter_t filter); void map__fixup_start(struct map *self); void map__fixup_end(struct map *self); -struct perf_session; - int event__synthesize_thread(pid_t pid, int (*process)(event_t *event, struct perf_session *session), diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 76bdca6..8b3dd46 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -104,10 +104,11 @@ void map__fixup_end(struct map *self) #define DSO__DELETED "(deleted)" -static int map__load(struct map *self, symbol_filter_t filter) +static int map__load(struct map *self, struct perf_session *session, + symbol_filter_t filter) { const char *name = self->dso->long_name; - int nr = dso__load(self->dso, self, filter); + int nr = dso__load(self->dso, self, session, filter); if (nr < 0) { if (self->dso->has_build_id) { @@ -143,19 +144,20 @@ static int map__load(struct map *self, symbol_filter_t filter) return 0; } -struct symbol *map__find_symbol(struct map *self, u64 addr, - symbol_filter_t filter) +struct symbol *map__find_symbol(struct map *self, struct perf_session *session, + u64 addr, symbol_filter_t filter) { - if (!dso__loaded(self->dso, self->type) && map__load(self, filter) < 0) + if (!dso__loaded(self->dso, self->type) && map__load(self, session, filter) < 0) return NULL; return dso__find_symbol(self->dso, self->type, addr); } struct symbol *map__find_symbol_by_name(struct map *self, const char *name, + struct perf_session *session, symbol_filter_t filter) { - if (!dso__loaded(self->dso, self->type) && map__load(self, filter) < 0) + if (!dso__loaded(self->dso, self->type) && map__load(self, session, filter) < 0) return NULL; if (!dso__sorted_by_name(self->dso, self->type)) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 09836a5..fe87a2f 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -49,7 +49,7 @@ out_close: } struct perf_session *perf_session__new(const char *filename, int mode, - bool force) + bool force, struct symbol_conf *conf) { size_t len = filename ? strlen(filename) + 1 : 0; struct perf_session *self = zalloc(sizeof(*self) + len); @@ -58,7 +58,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, goto out; if (perf_header__init(&self->header) < 0) - goto out_delete; + goto out_free; memcpy(self->filename, filename, len); self->threads = RB_ROOT; @@ -66,16 +66,21 @@ struct perf_session *perf_session__new(const char *filename, int mode, self->mmap_window = 32; self->cwd = NULL; self->cwdlen = 0; + map_groups__init(&self->kmaps); - if (mode == O_RDONLY && perf_session__open(self, force) < 0) { - perf_session__delete(self); - self = NULL; - } + if (perf_session__create_kernel_maps(self, conf) < 0) + goto out_delete; + + if (mode == O_RDONLY && perf_session__open(self, force) < 0) + goto out_delete; out: return self; -out_delete: +out_free: free(self); return NULL; +out_delete: + perf_session__delete(self); + return NULL; } void perf_session__delete(struct perf_session *self) diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 1dbef7c..20b2c9c 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -3,19 +3,23 @@ #include "event.h" #include "header.h" +#include "thread.h" #include struct thread; +struct symbol_conf; struct perf_session { struct perf_header header; unsigned long size; unsigned long mmap_window; + struct map_groups kmaps; struct rb_root threads; struct thread *last_match; int fd; int cwdlen; char *cwd; + bool use_modules; char filename[0]; }; @@ -37,7 +41,7 @@ struct perf_event_ops { }; struct perf_session *perf_session__new(const char *filename, int mode, - bool force); + bool force, struct symbol_conf *conf); void perf_session__delete(struct perf_session *self); int perf_session__process_events(struct perf_session *self, diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index d3d9fed..185b9ee 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1,5 +1,6 @@ #include "util.h" #include "../perf.h" +#include "session.h" #include "string.h" #include "symbol.h" #include "thread.h" @@ -31,7 +32,7 @@ enum dso_origin { static void dsos__add(struct list_head *head, struct dso *dso); static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); static int dso__load_kernel_sym(struct dso *self, struct map *map, - struct map_groups *mg, symbol_filter_t filter); + struct perf_session *session, symbol_filter_t filter); unsigned int symbol__priv_size; static int vmlinux_path__nr_entries; static char **vmlinux_path; @@ -41,9 +42,6 @@ static struct symbol_conf symbol_conf__defaults = { .try_vmlinux_path = true, }; -static struct map_groups kmaps_mem; -struct map_groups *kmaps = &kmaps_mem; - bool dso__loaded(const struct dso *self, enum map_type type) { return self->loaded & (1 << type); @@ -456,7 +454,7 @@ out_failure: * the original ELF section names vmlinux have. */ static int dso__split_kallsyms(struct dso *self, struct map *map, - struct map_groups *mg, symbol_filter_t filter) + struct perf_session *session, symbol_filter_t filter) { struct map *curr_map = map; struct symbol *pos; @@ -473,13 +471,13 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, module = strchr(pos->name, '\t'); if (module) { - if (!mg->use_modules) + if (!session->use_modules) goto discard_symbol; *module++ = '\0'; if (strcmp(self->name, module)) { - curr_map = map_groups__find_by_name(mg, map->type, module); + curr_map = map_groups__find_by_name(&session->kmaps, map->type, module); if (curr_map == NULL) { pr_debug("/proc/{kallsyms,modules} " "inconsistency!\n"); @@ -510,7 +508,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, } curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; - map_groups__insert(mg, curr_map); + map_groups__insert(&session->kmaps, curr_map); ++kernel_range; } @@ -531,7 +529,7 @@ discard_symbol: rb_erase(&pos->rb_node, root); static int dso__load_kallsyms(struct dso *self, struct map *map, - struct map_groups *mg, symbol_filter_t filter) + struct perf_session *session, symbol_filter_t filter) { if (dso__load_all_kallsyms(self, map) < 0) return -1; @@ -539,14 +537,7 @@ static int dso__load_kallsyms(struct dso *self, struct map *map, symbols__fixup_end(&self->symbols[map->type]); self->origin = DSO__ORIG_KERNEL; - return dso__split_kallsyms(self, map, mg, filter); -} - -size_t kernel_maps__fprintf(FILE *fp) -{ - size_t printed = fprintf(fp, "Kernel maps:\n"); - printed += map_groups__fprintf_maps(kmaps, fp); - return printed + fprintf(fp, "END kernel maps\n"); + return dso__split_kallsyms(self, map, session, filter); } static int dso__load_perf_map(struct dso *self, struct map *map, @@ -873,7 +864,7 @@ static bool elf_sec__is_a(GElf_Shdr *self, Elf_Data *secstrs, enum map_type type } static int dso__load_sym(struct dso *self, struct map *map, - struct map_groups *mg, const char *name, int fd, + struct perf_session *session, const char *name, int fd, symbol_filter_t filter, int kernel, int kmodule) { struct map *curr_map = map; @@ -977,7 +968,7 @@ static int dso__load_sym(struct dso *self, struct map *map, snprintf(dso_name, sizeof(dso_name), "%s%s", self->short_name, section_name); - curr_map = map_groups__find_by_name(mg, map->type, dso_name); + curr_map = map_groups__find_by_name(&session->kmaps, map->type, dso_name); if (curr_map == NULL) { u64 start = sym.st_value; @@ -996,7 +987,7 @@ static int dso__load_sym(struct dso *self, struct map *map, curr_map->map_ip = identity__map_ip; curr_map->unmap_ip = identity__map_ip; curr_dso->origin = DSO__ORIG_KERNEL; - map_groups__insert(kmaps, curr_map); + map_groups__insert(&session->kmaps, curr_map); dsos__add(&dsos__kernel, curr_dso); } else curr_dso = curr_map->dso; @@ -1211,7 +1202,8 @@ char dso__symtab_origin(const struct dso *self) return origin[self->origin]; } -int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) +int dso__load(struct dso *self, struct map *map, struct perf_session *session, + symbol_filter_t filter) { int size = PATH_MAX; char *name; @@ -1222,7 +1214,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) dso__set_loaded(self, map->type); if (self->kernel) - return dso__load_kernel_sym(self, map, kmaps, filter); + return dso__load_kernel_sym(self, map, session, filter); name = malloc(size); if (!name) @@ -1323,7 +1315,7 @@ struct map *map_groups__find_by_name(struct map_groups *self, return NULL; } -static int dsos__set_modules_path_dir(char *dirname) +static int perf_session__set_modules_path_dir(struct perf_session *self, char *dirname) { struct dirent *dent; DIR *dir = opendir(dirname); @@ -1343,7 +1335,7 @@ static int dsos__set_modules_path_dir(char *dirname) snprintf(path, sizeof(path), "%s/%s", dirname, dent->d_name); - if (dsos__set_modules_path_dir(path) < 0) + if (perf_session__set_modules_path_dir(self, path) < 0) goto failure; } else { char *dot = strrchr(dent->d_name, '.'), @@ -1357,7 +1349,7 @@ static int dsos__set_modules_path_dir(char *dirname) (int)(dot - dent->d_name), dent->d_name); strxfrchar(dso_name, '-', '_'); - map = map_groups__find_by_name(kmaps, MAP__FUNCTION, dso_name); + map = map_groups__find_by_name(&self->kmaps, MAP__FUNCTION, dso_name); if (map == NULL) continue; @@ -1377,7 +1369,7 @@ failure: return -1; } -static int dsos__set_modules_path(void) +static int perf_session__set_modules_path(struct perf_session *self) { struct utsname uts; char modules_path[PATH_MAX]; @@ -1388,7 +1380,7 @@ static int dsos__set_modules_path(void) snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel", uts.release); - return dsos__set_modules_path_dir(modules_path); + return perf_session__set_modules_path_dir(self, modules_path); } /* @@ -1410,7 +1402,7 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type) return self; } -static int map_groups__create_module_maps(struct map_groups *self) +static int perf_session__create_module_maps(struct perf_session *self) { char *line = NULL; size_t n; @@ -1467,14 +1459,14 @@ static int map_groups__create_module_maps(struct map_groups *self) dso->has_build_id = true; dso->origin = DSO__ORIG_KMODULE; - map_groups__insert(self, map); + map_groups__insert(&self->kmaps, map); dsos__add(&dsos__kernel, dso); } free(line); fclose(file); - return dsos__set_modules_path(); + return perf_session__set_modules_path(self); out_delete_line: free(line); @@ -1483,7 +1475,7 @@ out_failure: } static int dso__load_vmlinux(struct dso *self, struct map *map, - struct map_groups *mg, + struct perf_session *session, const char *vmlinux, symbol_filter_t filter) { int err = -1, fd; @@ -1517,14 +1509,14 @@ static int dso__load_vmlinux(struct dso *self, struct map *map, return -1; dso__set_loaded(self, map->type); - err = dso__load_sym(self, map, mg, self->long_name, fd, filter, 1, 0); + err = dso__load_sym(self, map, session, self->long_name, fd, filter, 1, 0); close(fd); return err; } static int dso__load_kernel_sym(struct dso *self, struct map *map, - struct map_groups *mg, symbol_filter_t filter) + struct perf_session *session, symbol_filter_t filter) { int err; bool is_kallsyms; @@ -1534,7 +1526,7 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, pr_debug("Looking at the vmlinux_path (%d entries long)\n", vmlinux_path__nr_entries); for (i = 0; i < vmlinux_path__nr_entries; ++i) { - err = dso__load_vmlinux(self, map, mg, + err = dso__load_vmlinux(self, map, session, vmlinux_path[i], filter); if (err > 0) { pr_debug("Using %s for symbols\n", @@ -1550,12 +1542,12 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, if (is_kallsyms) goto do_kallsyms; - err = dso__load_vmlinux(self, map, mg, self->long_name, filter); + err = dso__load_vmlinux(self, map, session, self->long_name, filter); if (err <= 0) { pr_info("The file %s cannot be used, " "trying to use /proc/kallsyms...", self->long_name); do_kallsyms: - err = dso__load_kallsyms(self, map, mg, filter); + err = dso__load_kallsyms(self, map, session, filter); if (err > 0 && !is_kallsyms) dso__set_long_name(self, strdup("[kernel.kallsyms]")); } @@ -1757,23 +1749,30 @@ int symbol__init(struct symbol_conf *conf) if (pconf->sort_by_name) symbol__priv_size += (sizeof(struct symbol_name_rb_node) - sizeof(struct symbol)); - map_groups__init(kmaps); if (pconf->try_vmlinux_path && vmlinux_path__init() < 0) return -1; - if (map_groups__create_kernel_maps(kmaps, pconf->vmlinux_name) < 0) { - vmlinux_path__exit(); + return 0; +} + +int perf_session__create_kernel_maps(struct perf_session *self, + struct symbol_conf *conf) +{ + const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults; + + if (map_groups__create_kernel_maps(&self->kmaps, + pconf->vmlinux_name) < 0) return -1; - } - kmaps->use_modules = pconf->use_modules; - if (pconf->use_modules && map_groups__create_module_maps(kmaps) < 0) - pr_debug("Failed to load list of modules in use, " - "continuing...\n"); + self->use_modules = pconf->use_modules; + + if (pconf->use_modules && perf_session__create_module_maps(self) < 0) + pr_debug("Failed to load list of modules for session %s, " + "continuing...\n", self->filename); /* * Now that we have all the maps created, just set the ->end of them: */ - map_groups__fixup_end(kmaps); + map_groups__fixup_end(&self->kmaps); return 0; } diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index cf99f88..941ef33 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -98,8 +98,11 @@ bool dso__sorted_by_name(const struct dso *self, enum map_type type); void dso__sort_by_name(struct dso *self, enum map_type type); +struct perf_session; + struct dso *dsos__findnew(const char *name); -int dso__load(struct dso *self, struct map *map, symbol_filter_t filter); +int dso__load(struct dso *self, struct map *map, struct perf_session *session, + symbol_filter_t filter); void dsos__fprintf(FILE *fp); size_t dsos__fprintf_buildid(FILE *fp); @@ -116,12 +119,10 @@ int sysfs__read_build_id(const char *filename, void *bf, size_t size); bool dsos__read_build_ids(void); int build_id__sprintf(u8 *self, int len, char *bf); -size_t kernel_maps__fprintf(FILE *fp); - int symbol__init(struct symbol_conf *conf); +int perf_session__create_kernel_maps(struct perf_session *self, + struct symbol_conf *conf); -struct map_groups; -struct map_groups *kmaps; extern struct list_head dsos__user, dsos__kernel; extern struct dso *vdso; #endif /* __PERF_SYMBOL */ diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 634b7f7..4a08dcf 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -282,13 +282,14 @@ size_t perf_session__fprintf(struct perf_session *self, FILE *fp) } struct symbol *map_groups__find_symbol(struct map_groups *self, + struct perf_session *session, enum map_type type, u64 addr, symbol_filter_t filter) { struct map *map = map_groups__find(self, type, addr); if (map != NULL) - return map__find_symbol(map, map->map_ip(map, addr), filter); + return map__find_symbol(map, session, map->map_ip(map, addr), filter); return NULL; } diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index e93abf2..c206f72 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -8,7 +8,6 @@ struct map_groups { struct rb_root maps[MAP__NR_TYPES]; struct list_head removed_maps[MAP__NR_TYPES]; - bool use_modules; }; struct thread { @@ -49,19 +48,21 @@ static inline struct map *thread__find_map(struct thread *self, return self ? map_groups__find(&self->mg, type, addr) : NULL; } -void thread__find_addr_location(struct thread *self, u8 cpumode, +void thread__find_addr_location(struct thread *self, + struct perf_session *session, u8 cpumode, enum map_type type, u64 addr, struct addr_location *al, symbol_filter_t filter); struct symbol *map_groups__find_symbol(struct map_groups *self, + struct perf_session *session, enum map_type type, u64 addr, symbol_filter_t filter); static inline struct symbol * -map_groups__find_function(struct map_groups *self, u64 addr, - symbol_filter_t filter) +map_groups__find_function(struct map_groups *self, struct perf_session *session, + u64 addr, symbol_filter_t filter) { - return map_groups__find_symbol(self, MAP__FUNCTION, addr, filter); + return map_groups__find_symbol(self, session, MAP__FUNCTION, addr, filter); } struct map *map_groups__find_by_name(struct map_groups *self, -- cgit v0.10.2 From b9bf089212d95746ce66482bcdbc7e77a0651088 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 14 Dec 2009 11:37:11 -0200 Subject: perf tools: No need for three rb_trees for sorting hist entries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All hist entries are in only one of them, so use just one and a temporary rb_root while sorting/collapsing. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260797831-11220-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index e44c54c..f25e89e 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -432,7 +432,7 @@ static void find_annotations(void) { struct rb_node *nd; - for (nd = rb_first(&output_hists); nd; nd = rb_next(nd)) { + for (nd = rb_first(&hist); nd; nd = rb_next(nd)) { struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); struct sym_priv *priv; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 3487224..9cbdcbc 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -567,7 +567,7 @@ static size_t output__fprintf(FILE *fp, u64 total_samples) fprintf(fp, "#\n"); print_entries: - for (nd = rb_first(&output_hists); nd; nd = rb_next(nd)) { + for (nd = rb_first(&hist); nd; nd = rb_next(nd)) { pos = rb_entry(nd, struct hist_entry, rb_node); ret += hist_entry__fprintf(fp, pos, total_samples); } diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 0ebf6ee..b40e37d 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1,8 +1,6 @@ #include "hist.h" struct rb_root hist; -struct rb_root collapse_hists; -struct rb_root output_hists; int callchain; struct callchain_param callchain_param = { @@ -102,9 +100,9 @@ void hist_entry__free(struct hist_entry *he) * collapse the histogram */ -void collapse__insert_entry(struct hist_entry *he) +static void collapse__insert_entry(struct rb_root *root, struct hist_entry *he) { - struct rb_node **p = &collapse_hists.rb_node; + struct rb_node **p = &root->rb_node; struct rb_node *parent = NULL; struct hist_entry *iter; int64_t cmp; @@ -128,34 +126,40 @@ void collapse__insert_entry(struct hist_entry *he) } rb_link_node(&he->rb_node, parent, p); - rb_insert_color(&he->rb_node, &collapse_hists); + rb_insert_color(&he->rb_node, root); } void collapse__resort(void) { + struct rb_root tmp; struct rb_node *next; struct hist_entry *n; if (!sort__need_collapse) return; + tmp = RB_ROOT; next = rb_first(&hist); + while (next) { n = rb_entry(next, struct hist_entry, rb_node); next = rb_next(&n->rb_node); rb_erase(&n->rb_node, &hist); - collapse__insert_entry(n); + collapse__insert_entry(&tmp, n); } + + hist = tmp; } /* * reverse the map, sort on count. */ -void output__insert_entry(struct hist_entry *he, u64 min_callchain_hits) +static void output__insert_entry(struct rb_root *root, struct hist_entry *he, + u64 min_callchain_hits) { - struct rb_node **p = &output_hists.rb_node; + struct rb_node **p = &root->rb_node; struct rb_node *parent = NULL; struct hist_entry *iter; @@ -174,29 +178,29 @@ void output__insert_entry(struct hist_entry *he, u64 min_callchain_hits) } rb_link_node(&he->rb_node, parent, p); - rb_insert_color(&he->rb_node, &output_hists); + rb_insert_color(&he->rb_node, root); } void output__resort(u64 total_samples) { + struct rb_root tmp; struct rb_node *next; struct hist_entry *n; - struct rb_root *tree = &hist; u64 min_callchain_hits; min_callchain_hits = total_samples * (callchain_param.min_percent / 100); - if (sort__need_collapse) - tree = &collapse_hists; - - next = rb_first(tree); + tmp = RB_ROOT; + next = rb_first(&hist); while (next) { n = rb_entry(next, struct hist_entry, rb_node); next = rb_next(&n->rb_node); - rb_erase(&n->rb_node, tree); - output__insert_entry(n, min_callchain_hits); + rb_erase(&n->rb_node, &hist); + output__insert_entry(&tmp, n, min_callchain_hits); } + + hist = tmp; } diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 3020db0..a6cb148 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -25,16 +25,8 @@ #include "sort.h" extern struct rb_root hist; -extern struct rb_root collapse_hists; -extern struct rb_root output_hists; extern int callchain; extern struct callchain_param callchain_param; -extern unsigned long total; -extern unsigned long total_mmap; -extern unsigned long total_comm; -extern unsigned long total_fork; -extern unsigned long total_unknown; -extern unsigned long total_lost; struct hist_entry *__hist_entry__add(struct addr_location *al, struct symbol *parent, @@ -42,9 +34,7 @@ struct hist_entry *__hist_entry__add(struct addr_location *al, extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); extern void hist_entry__free(struct hist_entry *); -extern void collapse__insert_entry(struct hist_entry *); extern void collapse__resort(void); -extern void output__insert_entry(struct hist_entry *, u64); extern void output__resort(u64); #endif /* __PERF_HIST_H */ -- cgit v0.10.2 From 4e4f06e4c8f17ea96f7dd76251cab99511026401 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 14 Dec 2009 13:10:39 -0200 Subject: perf session: Move the hist_entries rb tree to perf_session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As we'll need to sort multiple times for multiple perf sessions, so that we can then do a diff. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260803439-16783-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index f25e89e..1f1341f 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -121,10 +121,12 @@ static void hist_hit(struct hist_entry *he, u64 ip) h->ip[offset]); } -static int hist_entry__add(struct addr_location *al, u64 count) +static int perf_session__add_hist_entry(struct perf_session *self, + struct addr_location *al, u64 count) { bool hit; - struct hist_entry *he = __hist_entry__add(al, NULL, count, &hit); + struct hist_entry *he = __perf_session__add_hist_entry(self, al, NULL, + count, &hit); if (he == NULL) return -ENOMEM; hist_hit(he, al->addr); @@ -144,7 +146,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) return -1; } - if (hist_entry__add(&al, 1)) { + if (perf_session__add_hist_entry(session, &al, 1)) { fprintf(stderr, "problem incrementing symbol count, " "skipping event\n"); return -1; @@ -428,11 +430,11 @@ static void annotate_sym(struct hist_entry *he) free_source_line(he, len); } -static void find_annotations(void) +static void perf_session__find_annotations(struct perf_session *self) { struct rb_node *nd; - for (nd = rb_first(&hist); nd; nd = rb_next(nd)) { + for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) { struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); struct sym_priv *priv; @@ -484,10 +486,9 @@ static int __cmd_annotate(void) if (verbose > 2) dsos__fprintf(stdout); - collapse__resort(); - output__resort(event__total[0]); - - find_annotations(); + perf_session__collapse_resort(session); + perf_session__output_resort(session, event__total[0]); + perf_session__find_annotations(session); out_delete: perf_session__delete(session); diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index e79ecbc..3b329c6 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -344,7 +344,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) return 0; } -static int sample_type_check(u64 type) +static int sample_type_check(u64 type, struct perf_session *session __used) { sample_type = type; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 9cbdcbc..854427f 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -38,6 +38,7 @@ static char *dso_list_str, *comm_list_str, *sym_list_str, static struct strlist *dso_list, *comm_list, *sym_list; static int force; +static bool use_callchain; static int show_nr_samples; @@ -312,8 +313,9 @@ hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, return ret; } -static size_t -hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples) +static size_t hist_entry__fprintf(FILE *fp, struct hist_entry *self, + struct perf_session *session, + u64 total_samples) { struct sort_entry *se; size_t ret; @@ -345,7 +347,7 @@ hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples) ret += fprintf(fp, "\n"); - if (callchain) { + if (session->use_callchain) { int left_margin = 0; if (sort__first_dimension == SORT_COMM) { @@ -422,7 +424,7 @@ static struct symbol **resolve_callchain(struct thread *thread, struct symbol **syms = NULL; unsigned int i; - if (callchain) { + if (session->use_callchain) { syms = calloc(chain->nr, sizeof(*syms)); if (!syms) { fprintf(stderr, "Can't allocate memory for symbols\n"); @@ -454,7 +456,7 @@ static struct symbol **resolve_callchain(struct thread *thread, if (sort__has_parent && !*parent && call__match(al.sym)) *parent = al.sym; - if (!callchain) + if (!session->use_callchain) break; syms[i] = al.sym; } @@ -467,25 +469,25 @@ static struct symbol **resolve_callchain(struct thread *thread, * collect histogram counts */ -static int hist_entry__add(struct addr_location *al, - struct perf_session *session, - struct ip_callchain *chain, u64 count) +static int perf_session__add_hist_entry(struct perf_session *self, + struct addr_location *al, + struct ip_callchain *chain, u64 count) { struct symbol **syms = NULL, *parent = NULL; bool hit; struct hist_entry *he; - if ((sort__has_parent || callchain) && chain) - syms = resolve_callchain(al->thread, session, chain, &parent); + if ((sort__has_parent || self->use_callchain) && chain) + syms = resolve_callchain(al->thread, self, chain, &parent); - he = __hist_entry__add(al, parent, count, &hit); + he = __perf_session__add_hist_entry(self, al, parent, count, &hit); if (he == NULL) return -ENOMEM; if (hit) he->count += count; - if (callchain) { + if (self->use_callchain) { if (!hit) callchain_init(&he->callchain); append_chain(&he->callchain, chain, syms); @@ -495,7 +497,8 @@ static int hist_entry__add(struct addr_location *al, return 0; } -static size_t output__fprintf(FILE *fp, u64 total_samples) +static size_t perf_session__fprintf_hist_entries(struct perf_session *self, + u64 total_samples, FILE *fp) { struct hist_entry *pos; struct sort_entry *se; @@ -567,9 +570,9 @@ static size_t output__fprintf(FILE *fp, u64 total_samples) fprintf(fp, "#\n"); print_entries: - for (nd = rb_first(&hist); nd; nd = rb_next(nd)) { + for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) { pos = rb_entry(nd, struct hist_entry, rb_node); - ret += hist_entry__fprintf(fp, pos, total_samples); + ret += hist_entry__fprintf(fp, pos, self, total_samples); } if (sort_order == default_sort_order && @@ -671,7 +674,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name)) return 0; - if (hist_entry__add(&al, session, data.callchain, data.period)) { + if (perf_session__add_hist_entry(session, &al, data.callchain, data.period)) { pr_debug("problem incrementing symbol count, skipping event\n"); return -1; } @@ -719,7 +722,7 @@ static int process_read_event(event_t *event, struct perf_session *session __use return 0; } -static int sample_type_check(u64 type) +static int sample_type_check(u64 type, struct perf_session *session) { sample_type = type; @@ -730,14 +733,14 @@ static int sample_type_check(u64 type) " perf record without -g?\n"); return -1; } - if (callchain) { + if (session->use_callchain) { fprintf(stderr, "selected -g but no callchain data." " Did you call perf record without" " -g?\n"); return -1; } - } else if (callchain_param.mode != CHAIN_NONE && !callchain) { - callchain = 1; + } else if (callchain_param.mode != CHAIN_NONE && !session->use_callchain) { + session->use_callchain = true; if (register_callchain_param(&callchain_param) < 0) { fprintf(stderr, "Can't register callchain" " params\n"); @@ -769,6 +772,8 @@ static int __cmd_report(void) if (session == NULL) return -ENOMEM; + session->use_callchain = use_callchain; + if (show_threads) perf_read_values_init(&show_threads_values); @@ -787,9 +792,9 @@ static int __cmd_report(void) if (verbose > 2) dsos__fprintf(stdout); - collapse__resort(); - output__resort(event__stats.total); - output__fprintf(stdout, event__stats.total); + perf_session__collapse_resort(session); + perf_session__output_resort(session, event__stats.total); + perf_session__fprintf_hist_entries(session, event__stats.total, stdout); if (show_threads) perf_read_values_destroy(&show_threads_values); @@ -805,7 +810,7 @@ parse_callchain_opt(const struct option *opt __used, const char *arg, char *tok; char *endptr; - callchain = 1; + use_callchain = true; if (!arg) return 0; @@ -826,7 +831,7 @@ parse_callchain_opt(const struct option *opt __used, const char *arg, else if (!strncmp(tok, "none", strlen(arg))) { callchain_param.mode = CHAIN_NONE; - callchain = 0; + use_callchain = true; return 0; } diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index bce05df..412ae92 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1655,7 +1655,7 @@ static int process_lost_event(event_t *event __used, return 0; } -static int sample_type_check(u64 type) +static int sample_type_check(u64 type, struct perf_session *session __used) { sample_type = type; diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 2701853..3a0a89e 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1033,7 +1033,7 @@ static void process_samples(void) } } -static int sample_type_check(u64 type) +static int sample_type_check(u64 type, struct perf_session *session __used) { sample_type = type; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 9d89ae42..adce442 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -103,7 +103,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) return 0; } -static int sample_type_check(u64 type) +static int sample_type_check(u64 type, struct perf_session *session __used) { sample_type = type; diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index 44dea21..08c4cf5 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c @@ -161,7 +161,7 @@ int perf_session__process_events(struct perf_session *self, err = -EINVAL; if (ops->sample_type_check && - ops->sample_type_check(sample_type) < 0) + ops->sample_type_check(sample_type, self) < 0) goto out_err; if (!ops->full_paths) { diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index b40e37d..b9828fc 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1,7 +1,6 @@ #include "hist.h" - -struct rb_root hist; -int callchain; +#include "session.h" +#include "sort.h" struct callchain_param callchain_param = { .mode = CHAIN_GRAPH_REL, @@ -12,11 +11,12 @@ struct callchain_param callchain_param = { * histogram, sorted on item, collects counts */ -struct hist_entry *__hist_entry__add(struct addr_location *al, - struct symbol *sym_parent, - u64 count, bool *hit) +struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self, + struct addr_location *al, + struct symbol *sym_parent, + u64 count, bool *hit) { - struct rb_node **p = &hist.rb_node; + struct rb_node **p = &self->hists.rb_node; struct rb_node *parent = NULL; struct hist_entry *he; struct hist_entry entry = { @@ -52,7 +52,7 @@ struct hist_entry *__hist_entry__add(struct addr_location *al, return NULL; *he = entry; rb_link_node(&he->rb_node, parent, p); - rb_insert_color(&he->rb_node, &hist); + rb_insert_color(&he->rb_node, &self->hists); *hit = false; return he; } @@ -129,7 +129,7 @@ static void collapse__insert_entry(struct rb_root *root, struct hist_entry *he) rb_insert_color(&he->rb_node, root); } -void collapse__resort(void) +void perf_session__collapse_resort(struct perf_session *self) { struct rb_root tmp; struct rb_node *next; @@ -139,31 +139,33 @@ void collapse__resort(void) return; tmp = RB_ROOT; - next = rb_first(&hist); + next = rb_first(&self->hists); while (next) { n = rb_entry(next, struct hist_entry, rb_node); next = rb_next(&n->rb_node); - rb_erase(&n->rb_node, &hist); + rb_erase(&n->rb_node, &self->hists); collapse__insert_entry(&tmp, n); } - hist = tmp; + self->hists = tmp; } /* * reverse the map, sort on count. */ -static void output__insert_entry(struct rb_root *root, struct hist_entry *he, - u64 min_callchain_hits) +static void perf_session__insert_output_hist_entry(struct perf_session *self, + struct rb_root *root, + struct hist_entry *he, + u64 min_callchain_hits) { struct rb_node **p = &root->rb_node; struct rb_node *parent = NULL; struct hist_entry *iter; - if (callchain) + if (self->use_callchain) callchain_param.sort(&he->sorted_chain, &he->callchain, min_callchain_hits, &callchain_param); @@ -181,7 +183,7 @@ static void output__insert_entry(struct rb_root *root, struct hist_entry *he, rb_insert_color(&he->rb_node, root); } -void output__resort(u64 total_samples) +void perf_session__output_resort(struct perf_session *self, u64 total_samples) { struct rb_root tmp; struct rb_node *next; @@ -192,15 +194,16 @@ void output__resort(u64 total_samples) total_samples * (callchain_param.min_percent / 100); tmp = RB_ROOT; - next = rb_first(&hist); + next = rb_first(&self->hists); while (next) { n = rb_entry(next, struct hist_entry, rb_node); next = rb_next(&n->rb_node); - rb_erase(&n->rb_node, &hist); - output__insert_entry(&tmp, n, min_callchain_hits); + rb_erase(&n->rb_node, &self->hists); + perf_session__insert_output_hist_entry(self, &tmp, n, + min_callchain_hits); } - hist = tmp; + self->hists = tmp; } diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index a6cb148..7efdb1b 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -1,40 +1,25 @@ #ifndef __PERF_HIST_H #define __PERF_HIST_H -#include "../builtin.h" -#include "util.h" - -#include "color.h" -#include -#include "cache.h" -#include -#include "symbol.h" -#include "string.h" +#include #include "callchain.h" -#include "strlist.h" -#include "values.h" - -#include "../perf.h" -#include "debug.h" -#include "header.h" - -#include "parse-options.h" -#include "parse-events.h" -#include "thread.h" -#include "sort.h" - -extern struct rb_root hist; -extern int callchain; extern struct callchain_param callchain_param; -struct hist_entry *__hist_entry__add(struct addr_location *al, - struct symbol *parent, - u64 count, bool *hit); +struct perf_session; +struct hist_entry; +struct addr_location; +struct symbol; + +struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self, + struct addr_location *al, + struct symbol *parent, + u64 count, bool *hit); extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); -extern void hist_entry__free(struct hist_entry *); -extern void collapse__resort(void); -extern void output__resort(u64); +void hist_entry__free(struct hist_entry *); + +void perf_session__output_resort(struct perf_session *self, u64 total_samples); +void perf_session__collapse_resort(struct perf_session *self); #endif /* __PERF_HIST_H */ diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 20b2c9c..759d960 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -16,10 +16,12 @@ struct perf_session { struct map_groups kmaps; struct rb_root threads; struct thread *last_match; + struct rb_root hists; int fd; int cwdlen; char *cwd; bool use_modules; + bool use_callchain; char filename[0]; }; @@ -35,7 +37,8 @@ struct perf_event_ops { event_op process_read_event; event_op process_throttle_event; event_op process_unthrottle_event; - int (*sample_type_check)(u64 sample_type); + int (*sample_type_check)(u64 sample_type, + struct perf_session *session); unsigned long total_unknown; bool full_paths; }; -- cgit v0.10.2 From ae4cec4736969ec2196a6bbce4ab263ff7cb7eef Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 14 Dec 2009 09:04:24 -0700 Subject: powerpc: fix up for mmu_mapin_ram api change Today's linux-next build (powerpc ppc44x_defconfig) failed like this: arch/powerpc/mm/pgtable_32.c: In function 'mapin_ram': arch/powerpc/mm/pgtable_32.c:318: error: too many arguments to function 'mmu_mapin_ram' Casued by commit de32400dd26e743c5d500aa42d8d6818b79edb73 ("wii: use both mem1 and mem2 as ram"). Signed-off-by: Stephen Rothwell Signed-off-by: Grant Likely diff --git a/arch/powerpc/mm/40x_mmu.c b/arch/powerpc/mm/40x_mmu.c index f5e7b9c..08dfa8e 100644 --- a/arch/powerpc/mm/40x_mmu.c +++ b/arch/powerpc/mm/40x_mmu.c @@ -91,7 +91,7 @@ void __init MMU_init_hw(void) #define LARGE_PAGE_SIZE_16M (1<<24) #define LARGE_PAGE_SIZE_4M (1<<22) -unsigned long __init mmu_mapin_ram(void) +unsigned long __init mmu_mapin_ram(unsigned long top) { unsigned long v, s, mapped; phys_addr_t p; diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c index 98052ac..3986264 100644 --- a/arch/powerpc/mm/44x_mmu.c +++ b/arch/powerpc/mm/44x_mmu.c @@ -88,7 +88,7 @@ void __init MMU_init_hw(void) flush_instruction_cache(); } -unsigned long __init mmu_mapin_ram(void) +unsigned long __init mmu_mapin_ram(unsigned long top) { unsigned long addr; diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index dc93e95..6da4b90 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -156,7 +156,7 @@ void invalidate_tlbcam_entry(int index) loadcam_entry(index); } -unsigned long __init mmu_mapin_ram(void) +unsigned long __init mmu_mapin_ram(unsigned long top) { unsigned long virt = PAGE_OFFSET; phys_addr_t phys = memstart_addr; diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 34dacc3..06f708c 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -150,15 +150,15 @@ extern void wii_memory_fixups(void); */ #if defined(CONFIG_8xx) #define MMU_init_hw() do { } while(0) -#define mmu_mapin_ram() (0UL) +#define mmu_mapin_ram(top) (0UL) #elif defined(CONFIG_4xx) extern void MMU_init_hw(void); -extern unsigned long mmu_mapin_ram(void); +extern unsigned long mmu_mapin_ram(unsigned long top); #elif defined(CONFIG_FSL_BOOKE) extern void MMU_init_hw(void); -extern unsigned long mmu_mapin_ram(void); +extern unsigned long mmu_mapin_ram(unsigned long top); extern void adjust_total_lowmem(void); #elif defined(CONFIG_PPC32) -- cgit v0.10.2 From 5fe85be081edf0ac92d83f9c39e0ab5c1371eb82 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 9 Dec 2009 10:14:58 +0000 Subject: sched: Use rcu in sys_sched_getscheduler/sys_sched_getparam() read_lock(&tasklist_lock) does not protect sys_sched_getscheduler and sys_sched_getparam() against a concurrent update of the policy or scheduler parameters as do_sched_setscheduler() does not take the tasklist_lock. The accessed integers can be retrieved w/o locking and are snapshots anyway. Using rcu_read_lock() to protect find_task_by_vpid() and prevent the task struct from going away is not changing the above situation. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra LKML-Reference: <20091209100706.753790977@linutronix.de> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 258c73c..1782bee 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6458,7 +6458,7 @@ SYSCALL_DEFINE1(sched_getscheduler, pid_t, pid) return -EINVAL; retval = -ESRCH; - read_lock(&tasklist_lock); + rcu_read_lock(); p = find_process_by_pid(pid); if (p) { retval = security_task_getscheduler(p); @@ -6466,7 +6466,7 @@ SYSCALL_DEFINE1(sched_getscheduler, pid_t, pid) retval = p->policy | (p->sched_reset_on_fork ? SCHED_RESET_ON_FORK : 0); } - read_unlock(&tasklist_lock); + rcu_read_unlock(); return retval; } @@ -6484,7 +6484,7 @@ SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param) if (!param || pid < 0) return -EINVAL; - read_lock(&tasklist_lock); + rcu_read_lock(); p = find_process_by_pid(pid); retval = -ESRCH; if (!p) @@ -6495,7 +6495,7 @@ SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param) goto out_unlock; lp.sched_priority = p->rt_priority; - read_unlock(&tasklist_lock); + rcu_read_unlock(); /* * This one might sleep, we cannot do it with a spinlock held ... @@ -6505,7 +6505,7 @@ SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param) return retval; out_unlock: - read_unlock(&tasklist_lock); + rcu_read_unlock(); return retval; } -- cgit v0.10.2 From 23f5d142519621b16cf2b378cf8adf4dcf01a616 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 9 Dec 2009 10:15:01 +0000 Subject: sched: Use rcu in sched_get/set_affinity() tasklist_lock is held read locked to protect the find_task_by_vpid() call and to prevent the task going away. sched_setaffinity acquires a task struct ref and drops tasklist lock right away. The access to the cpus_allowed mask is protected by rq->lock. rcu_read_lock() provides the same protection here. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra LKML-Reference: <20091209100706.789059966@linutronix.de> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 1782bee..7989312 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6516,22 +6516,18 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask) int retval; get_online_cpus(); - read_lock(&tasklist_lock); + rcu_read_lock(); p = find_process_by_pid(pid); if (!p) { - read_unlock(&tasklist_lock); + rcu_read_unlock(); put_online_cpus(); return -ESRCH; } - /* - * It is not safe to call set_cpus_allowed with the - * tasklist_lock held. We will bump the task_struct's - * usage count and then drop tasklist_lock. - */ + /* Prevent p going away */ get_task_struct(p); - read_unlock(&tasklist_lock); + rcu_read_unlock(); if (!alloc_cpumask_var(&cpus_allowed, GFP_KERNEL)) { retval = -ENOMEM; @@ -6617,7 +6613,7 @@ long sched_getaffinity(pid_t pid, struct cpumask *mask) int retval; get_online_cpus(); - read_lock(&tasklist_lock); + rcu_read_lock(); retval = -ESRCH; p = find_process_by_pid(pid); @@ -6633,7 +6629,7 @@ long sched_getaffinity(pid_t pid, struct cpumask *mask) task_rq_unlock(rq, &flags); out_unlock: - read_unlock(&tasklist_lock); + rcu_read_unlock(); put_online_cpus(); return retval; -- cgit v0.10.2 From 1a551ae715825bb2a2107a2dd68de024a1fa4e32 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 9 Dec 2009 10:15:11 +0000 Subject: sched: Use rcu in sched_get_rr_param() read_lock(&tasklist_lock) does not protect sys_sched_get_rr_param() against a concurrent update of the policy or scheduler parameters as do_sched_scheduler() does not take the tasklist_lock. The access to task->sched_class->get_rr_interval is protected by task_rq_lock(task). Use rcu_read_lock() to protect find_task_by_vpid() and prevent the task struct from going away. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra LKML-Reference: <20091209100706.862897167@linutronix.de> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 7989312..db5c266 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6873,7 +6873,7 @@ SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid, return -EINVAL; retval = -ESRCH; - read_lock(&tasklist_lock); + rcu_read_lock(); p = find_process_by_pid(pid); if (!p) goto out_unlock; @@ -6886,13 +6886,13 @@ SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid, time_slice = p->sched_class->get_rr_interval(rq, p); task_rq_unlock(rq, &flags); - read_unlock(&tasklist_lock); + rcu_read_unlock(); jiffies_to_timespec(time_slice, &t); retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0; return retval; out_unlock: - read_unlock(&tasklist_lock); + rcu_read_unlock(); return retval; } -- cgit v0.10.2 From a328626b61aeda1a7d00a80c475c76ca1b815e0d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 14 Dec 2009 14:22:59 -0200 Subject: perf session: Adopt resolve_callchain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is really a generic library routine, so declutter builtin-report.c a bit by moving it to the library. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260807780-19377-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 854427f..5141cdc 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -407,64 +407,6 @@ static int thread__set_comm_adjust(struct thread *self, const char *comm) return 0; } -static int call__match(struct symbol *sym) -{ - if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0)) - return 1; - - return 0; -} - -static struct symbol **resolve_callchain(struct thread *thread, - struct perf_session *session, - struct ip_callchain *chain, - struct symbol **parent) -{ - u8 cpumode = PERF_RECORD_MISC_USER; - struct symbol **syms = NULL; - unsigned int i; - - if (session->use_callchain) { - syms = calloc(chain->nr, sizeof(*syms)); - if (!syms) { - fprintf(stderr, "Can't allocate memory for symbols\n"); - exit(-1); - } - } - - for (i = 0; i < chain->nr; i++) { - u64 ip = chain->ips[i]; - struct addr_location al; - - if (ip >= PERF_CONTEXT_MAX) { - switch (ip) { - case PERF_CONTEXT_HV: - cpumode = PERF_RECORD_MISC_HYPERVISOR; break; - case PERF_CONTEXT_KERNEL: - cpumode = PERF_RECORD_MISC_KERNEL; break; - case PERF_CONTEXT_USER: - cpumode = PERF_RECORD_MISC_USER; break; - default: - break; - } - continue; - } - - thread__find_addr_location(thread, session, cpumode, - MAP__FUNCTION, ip, &al, NULL); - if (al.sym != NULL) { - if (sort__has_parent && !*parent && - call__match(al.sym)) - *parent = al.sym; - if (!session->use_callchain) - break; - syms[i] = al.sym; - } - } - - return syms; -} - /* * collect histogram counts */ @@ -478,8 +420,8 @@ static int perf_session__add_hist_entry(struct perf_session *self, struct hist_entry *he; if ((sort__has_parent || self->use_callchain) && chain) - syms = resolve_callchain(al->thread, self, chain, &parent); - + syms = perf_session__resolve_callchain(self, al->thread, + chain, &parent); he = __perf_session__add_hist_entry(self, al, parent, count, &hit); if (he == NULL) return -ENOMEM; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index fe87a2f..ecd54be 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -4,6 +4,7 @@ #include #include "session.h" +#include "sort.h" #include "util.h" static int perf_session__open(struct perf_session *self, bool force) @@ -90,3 +91,61 @@ void perf_session__delete(struct perf_session *self) free(self->cwd); free(self); } + +static bool symbol__match_parent_regex(struct symbol *sym) +{ + if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0)) + return 1; + + return 0; +} + +struct symbol **perf_session__resolve_callchain(struct perf_session *self, + struct thread *thread, + struct ip_callchain *chain, + struct symbol **parent) +{ + u8 cpumode = PERF_RECORD_MISC_USER; + struct symbol **syms = NULL; + unsigned int i; + + if (self->use_callchain) { + syms = calloc(chain->nr, sizeof(*syms)); + if (!syms) { + fprintf(stderr, "Can't allocate memory for symbols\n"); + exit(-1); + } + } + + for (i = 0; i < chain->nr; i++) { + u64 ip = chain->ips[i]; + struct addr_location al; + + if (ip >= PERF_CONTEXT_MAX) { + switch (ip) { + case PERF_CONTEXT_HV: + cpumode = PERF_RECORD_MISC_HYPERVISOR; break; + case PERF_CONTEXT_KERNEL: + cpumode = PERF_RECORD_MISC_KERNEL; break; + case PERF_CONTEXT_USER: + cpumode = PERF_RECORD_MISC_USER; break; + default: + break; + } + continue; + } + + thread__find_addr_location(thread, self, cpumode, + MAP__FUNCTION, ip, &al, NULL); + if (al.sym != NULL) { + if (sort__has_parent && !*parent && + symbol__match_parent_regex(al.sym)) + *parent = al.sym; + if (!self->use_callchain) + break; + syms[i] = al.sym; + } + } + + return syms; +} diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 759d960..a8f3a49 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -6,7 +6,9 @@ #include "thread.h" #include +struct ip_callchain; struct thread; +struct symbol; struct symbol_conf; struct perf_session { @@ -50,6 +52,11 @@ void perf_session__delete(struct perf_session *self); int perf_session__process_events(struct perf_session *self, struct perf_event_ops *event_ops); +struct symbol **perf_session__resolve_callchain(struct perf_session *self, + struct thread *thread, + struct ip_callchain *chain, + struct symbol **parent); + int perf_header__read_build_ids(int input, u64 offset, u64 file_size); #endif /* __PERF_SESSION_H */ -- cgit v0.10.2 From c019879bcc5692ec9267c1cedad91f1794d0b693 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 14 Dec 2009 14:23:00 -0200 Subject: perf session: Adopt the sample_type variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All tools had copies, and perf diff would have to specify a sample_type_check method just for copying it. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260807780-19377-2-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 3b329c6..dda6086 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -20,8 +20,6 @@ typedef int (*sort_fn_t)(struct alloc_stat *, struct alloc_stat *); static char const *input_name = "perf.data"; -static u64 sample_type; - static int alloc_flag; static int caller_flag; @@ -321,7 +319,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) data.cpu = -1; data.period = 1; - event__parse_sample(event, sample_type, &data); + event__parse_sample(event, session->sample_type, &data); dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", event->header.misc, @@ -344,11 +342,9 @@ static int process_sample_event(event_t *event, struct perf_session *session) return 0; } -static int sample_type_check(u64 type, struct perf_session *session __used) +static int sample_type_check(struct perf_session *session) { - sample_type = type; - - if (!(sample_type & PERF_SAMPLE_RAW)) { + if (!(session->sample_type & PERF_SAMPLE_RAW)) { fprintf(stderr, "No trace sample to read. Did you call perf record " "without -R?"); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 5141cdc..142c475 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -52,8 +52,6 @@ static int exclude_other = 1; static char callchain_default_opt[] = "fractal,0.5"; -static u64 sample_type; - struct symbol_conf symbol_conf; @@ -557,7 +555,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) memset(&data, 0, sizeof(data)); data.period = 1; - event__parse_sample(event, sample_type, &data); + event__parse_sample(event, session->sample_type, &data); dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", event->header.misc, @@ -565,7 +563,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) (void *)(long)data.ip, (long long)data.period); - if (sample_type & PERF_SAMPLE_CALLCHAIN) { + if (session->sample_type & PERF_SAMPLE_CALLCHAIN) { unsigned int i; dump_printf("... chain: nr:%Lu\n", data.callchain->nr); @@ -664,11 +662,9 @@ static int process_read_event(event_t *event, struct perf_session *session __use return 0; } -static int sample_type_check(u64 type, struct perf_session *session) +static int sample_type_check(struct perf_session *session) { - sample_type = type; - - if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) { + if (!(session->sample_type & PERF_SAMPLE_CALLCHAIN)) { if (sort__has_parent) { fprintf(stderr, "selected --sort parent, but no" " callchain data. Did you call" diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 412ae92..d67f274 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -21,8 +21,6 @@ static char const *input_name = "perf.data"; -static u64 sample_type; - static char default_sort_order[] = "avg, max, switch, runtime"; static char *sort_order = default_sort_order; @@ -1613,7 +1611,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) struct sample_data data; struct thread *thread; - if (!(sample_type & PERF_SAMPLE_RAW)) + if (!(session->sample_type & PERF_SAMPLE_RAW)) return 0; memset(&data, 0, sizeof(data)); @@ -1621,7 +1619,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) data.cpu = -1; data.period = -1; - event__parse_sample(event, sample_type, &data); + event__parse_sample(event, session->sample_type, &data); dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", event->header.misc, @@ -1655,11 +1653,9 @@ static int process_lost_event(event_t *event __used, return 0; } -static int sample_type_check(u64 type, struct perf_session *session __used) +static int sample_type_check(struct perf_session *session __used) { - sample_type = type; - - if (!(sample_type & PERF_SAMPLE_RAW)) { + if (!(session->sample_type & PERF_SAMPLE_RAW)) { fprintf(stderr, "No trace sample to read. Did you call perf record " "without -R?"); diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 3a0a89e..ffd81e8 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -36,9 +36,6 @@ static char const *input_name = "perf.data"; static char const *output_name = "output.svg"; - -static u64 sample_type; - static unsigned int numcpus; static u64 min_freq; /* Lowest CPU frequency seen */ static u64 max_freq; /* Highest CPU frequency seen */ @@ -478,17 +475,16 @@ static void sched_switch(int cpu, u64 timestamp, struct trace_entry *te) } -static int -process_sample_event(event_t *event) +static int process_sample_event(event_t *event, struct perf_session *session) { struct sample_data data; struct trace_entry *te; memset(&data, 0, sizeof(data)); - event__parse_sample(event, sample_type, &data); + event__parse_sample(event, session->sample_type, &data); - if (sample_type & PERF_SAMPLE_TIME) { + if (session->sample_type & PERF_SAMPLE_TIME) { if (!first_time || first_time > data.time) first_time = data.time; if (last_time < data.time) @@ -496,7 +492,7 @@ process_sample_event(event_t *event) } te = (void *)data.raw_data; - if (sample_type & PERF_SAMPLE_RAW && data.raw_size > 0) { + if (session->sample_type & PERF_SAMPLE_RAW && data.raw_size > 0) { char *event_str; struct power_entry *pe; @@ -573,16 +569,16 @@ static void end_sample_processing(void) } } -static u64 sample_time(event_t *event) +static u64 sample_time(event_t *event, const struct perf_session *session) { int cursor; cursor = 0; - if (sample_type & PERF_SAMPLE_IP) + if (session->sample_type & PERF_SAMPLE_IP) cursor++; - if (sample_type & PERF_SAMPLE_TID) + if (session->sample_type & PERF_SAMPLE_TID) cursor++; - if (sample_type & PERF_SAMPLE_TIME) + if (session->sample_type & PERF_SAMPLE_TIME) return event->sample.array[cursor]; return 0; } @@ -592,7 +588,7 @@ static u64 sample_time(event_t *event) * We first queue all events, sorted backwards by insertion. * The order will get flipped later. */ -static int queue_sample_event(event_t *event, struct perf_session *session __used) +static int queue_sample_event(event_t *event, struct perf_session *session) { struct sample_wrapper *copy, *prev; int size; @@ -606,7 +602,7 @@ static int queue_sample_event(event_t *event, struct perf_session *session __use memset(copy, 0, size); copy->next = NULL; - copy->timestamp = sample_time(event); + copy->timestamp = sample_time(event, session); memcpy(©->data, event, event->sample.header.size); @@ -1018,7 +1014,7 @@ static void write_svg_file(const char *filename) svg_close(); } -static void process_samples(void) +static void process_samples(struct perf_session *session) { struct sample_wrapper *cursor; event_t *event; @@ -1029,15 +1025,13 @@ static void process_samples(void) while (cursor) { event = (void *)&cursor->data; cursor = cursor->next; - process_sample_event(event); + process_sample_event(event, session); } } -static int sample_type_check(u64 type, struct perf_session *session __used) +static int sample_type_check(struct perf_session *session) { - sample_type = type; - - if (!(sample_type & PERF_SAMPLE_RAW)) { + if (!(session->sample_type & PERF_SAMPLE_RAW)) { fprintf(stderr, "No trace samples found in the file.\n" "Have you used 'perf timechart record' to record it?\n"); return -1; @@ -1067,7 +1061,7 @@ static int __cmd_timechart(void) if (ret) goto out_delete; - process_samples(); + process_samples(session); end_sample_processing(); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index adce442..9ee976d 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -61,8 +61,6 @@ static int cleanup_scripting(void) static char const *input_name = "perf.data"; -static u64 sample_type; - static int process_sample_event(event_t *event, struct perf_session *session) { struct sample_data data; @@ -73,7 +71,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) data.cpu = -1; data.period = 1; - event__parse_sample(event, sample_type, &data); + event__parse_sample(event, session->sample_type, &data); dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", event->header.misc, @@ -88,7 +86,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) return -1; } - if (sample_type & PERF_SAMPLE_RAW) { + if (session->sample_type & PERF_SAMPLE_RAW) { /* * FIXME: better resolve from pid from the struct trace_entry * field, although it should be the same than this perf @@ -103,11 +101,9 @@ static int process_sample_event(event_t *event, struct perf_session *session) return 0; } -static int sample_type_check(u64 type, struct perf_session *session __used) +static int sample_type_check(struct perf_session *session) { - sample_type = type; - - if (!(sample_type & PERF_SAMPLE_RAW)) { + if (!(session->sample_type & PERF_SAMPLE_RAW)) { fprintf(stderr, "No trace sample to read. Did you call perf record " "without -R?"); diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index 08c4cf5..b557b83 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c @@ -144,7 +144,6 @@ int perf_session__process_events(struct perf_session *self, unsigned long head, shift; unsigned long offset = 0; size_t page_size; - u64 sample_type; event_t *event; uint32_t size; char *buf; @@ -157,11 +156,10 @@ int perf_session__process_events(struct perf_session *self, page_size = getpagesize(); head = self->header.data_offset; - sample_type = perf_header__sample_type(&self->header); + self->sample_type = perf_header__sample_type(&self->header); err = -EINVAL; - if (ops->sample_type_check && - ops->sample_type_check(sample_type, self) < 0) + if (ops->sample_type_check && ops->sample_type_check(self) < 0) goto out_err; if (!ops->full_paths) { diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index a8f3a49..4e8a21c 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -19,6 +19,7 @@ struct perf_session { struct rb_root threads; struct thread *last_match; struct rb_root hists; + u64 sample_type; int fd; int cwdlen; char *cwd; @@ -39,8 +40,7 @@ struct perf_event_ops { event_op process_read_event; event_op process_throttle_event; event_op process_unthrottle_event; - int (*sample_type_check)(u64 sample_type, - struct perf_session *session); + int (*sample_type_check)(struct perf_session *session); unsigned long total_unknown; bool full_paths; }; -- cgit v0.10.2 From 494c2ebfb287eb10b229415063099e3700639028 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 14 Dec 2009 10:02:18 -0800 Subject: x86, msr: Remove incorrect, duplicated code in the MSR driver The MSR driver would compute the values for cpu and c at declaration, and then again in the body of the function. This isn't merely redundant, but unsafe, since cpu might not refer to a valid CPU at that point. Remove the unnecessary and dangerous references in the declarations. This code now matches the equivalent code in the CPUID driver. Signed-off-by: H. Peter Anvin diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 5534499..572b07e 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c @@ -172,11 +172,10 @@ static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg) static int msr_open(struct inode *inode, struct file *file) { - unsigned int cpu = iminor(file->f_path.dentry->d_inode); - struct cpuinfo_x86 *c = &cpu_data(cpu); + unsigned int cpu; + struct cpuinfo_x86 *c; cpu = iminor(file->f_path.dentry->d_inode); - if (cpu >= nr_cpu_ids || !cpu_online(cpu)) return -ENXIO; /* No such CPU */ -- cgit v0.10.2 From ce378f7da8dd2fb6c5bb126505ea1d0c6cdc8eb5 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 17 Nov 2009 14:39:31 -0800 Subject: avr32: convert to asm-generic/hardirq.h Signed-off-by: Christoph Hellwig Cc: Haavard Skinnemoen Signed-off-by: Andrew Morton Signed-off-by: Haavard Skinnemoen diff --git a/arch/avr32/include/asm/hardirq.h b/arch/avr32/include/asm/hardirq.h index 015bc75..9e36e3f 100644 --- a/arch/avr32/include/asm/hardirq.h +++ b/arch/avr32/include/asm/hardirq.h @@ -1,23 +1,6 @@ #ifndef __ASM_AVR32_HARDIRQ_H #define __ASM_AVR32_HARDIRQ_H - -#include -#include - #ifndef __ASSEMBLY__ - -#include - -/* entry.S is sensitive to the offsets of these fields */ -typedef struct { - unsigned int __softirq_pending; -} ____cacheline_aligned irq_cpustat_t; - -void ack_bad_irq(unsigned int irq); - -/* Standard mappings for irq_cpustat_t above */ -#include - +#include #endif /* __ASSEMBLY__ */ - #endif /* __ASM_AVR32_HARDIRQ_H */ diff --git a/arch/avr32/kernel/irq.c b/arch/avr32/kernel/irq.c index 9f57222..09904d2 100644 --- a/arch/avr32/kernel/irq.c +++ b/arch/avr32/kernel/irq.c @@ -16,15 +16,6 @@ #include #include -/* - * 'what should we do if we get a hw irq event on an illegal vector'. - * each architecture has to answer this themselves. - */ -void ack_bad_irq(unsigned int irq) -{ - printk("unexpected IRQ %u\n", irq); -} - /* May be overridden by platform code */ int __weak nmi_enable(void) { -- cgit v0.10.2 From 3550b9313b88d9ae74812eaba22e0ddf9ac9f2ae Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Thu, 3 Dec 2009 14:58:20 +0100 Subject: avr32: add support for ATNGW100 mkII board This patch adds board support for ATNGW100 mkII. This board is an upgrade of the ATNGW100 where the difference is an additional 256 MB NAND flash device and 128 MB 32-bit SDRAM instead of the 32 MB 16-bit SDRAM on ATNGW100. Tested on ATNGW100 mkII, duh (-: Signed-off-by: Hans-Christian Egtvedt Signed-off-by: Haavard Skinnemoen diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index 35e3bd9..9b339bf 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig @@ -111,6 +111,11 @@ config CPU_AT32AP7002 bool select CPU_AT32AP700X +# AP700X boards +config BOARD_ATNGW100_COMMON + bool + select CPU_AT32AP7000 + choice prompt "AVR32 board type" default BOARD_ATSTK1000 @@ -118,9 +123,13 @@ choice config BOARD_ATSTK1000 bool "ATSTK1000 evaluation board" -config BOARD_ATNGW100 +config BOARD_ATNGW100_MKI bool "ATNGW100 Network Gateway" - select CPU_AT32AP7000 + select BOARD_ATNGW100_COMMON + +config BOARD_ATNGW100_MKII + bool "ATNGW100 mkII Network Gateway" + select BOARD_ATNGW100_COMMON config BOARD_HAMMERHEAD bool "Hammerhead board" diff --git a/arch/avr32/Makefile b/arch/avr32/Makefile index c21a329..ead8a75 100644 --- a/arch/avr32/Makefile +++ b/arch/avr32/Makefile @@ -32,7 +32,7 @@ head-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/head.o head-y += arch/avr32/kernel/head.o core-y += $(machdirs) core-$(CONFIG_BOARD_ATSTK1000) += arch/avr32/boards/atstk1000/ -core-$(CONFIG_BOARD_ATNGW100) += arch/avr32/boards/atngw100/ +core-$(CONFIG_BOARD_ATNGW100_COMMON) += arch/avr32/boards/atngw100/ core-$(CONFIG_BOARD_HAMMERHEAD) += arch/avr32/boards/hammerhead/ core-$(CONFIG_BOARD_FAVR_32) += arch/avr32/boards/favr-32/ core-$(CONFIG_BOARD_MERISC) += arch/avr32/boards/merisc/ diff --git a/arch/avr32/boards/atngw100/Kconfig b/arch/avr32/boards/atngw100/Kconfig index be27a02..4e55617 100644 --- a/arch/avr32/boards/atngw100/Kconfig +++ b/arch/avr32/boards/atngw100/Kconfig @@ -1,6 +1,17 @@ # NGW100 customization -if BOARD_ATNGW100 +if BOARD_ATNGW100_COMMON + +config BOARD_ATNGW100_MKII_LCD + bool "Enable ATNGW100 mkII LCD interface" + depends on BOARD_ATNGW100_MKII + help + This enables the LCD controller (LCDC) in the AT32AP7000. Since the + LCDC is multiplexed with MACB1 (LAN) Ethernet port, only one can be + enabled at a time. + + This choice enables the LCDC and disables the MACB1 interface marked + LAN on the PCB. choice prompt "Select an NGW100 add-on board to support" @@ -11,15 +22,11 @@ config BOARD_ATNGW100_ADDON_NONE config BOARD_ATNGW100_EVKLCD10X bool "EVKLCD10X addon board" + depends on BOARD_ATNGW100_MKI || BOARD_ATNGW100_MKII_LCD help This enables support for the EVKLCD100 (QVGA) or EVKLCD101 (VGA) - addon board for the NGW100. By enabling this the LCD controller and - AC97 controller is added as platform devices. - - This choice disables the detect pin and the write-protect pin for the - MCI platform device, since it conflicts with the LCD platform device. - The MCI pins can be reenabled by editing the "add device function" but - this may break the setup for other displays that use these pins. + addon board for the NGW100 and NGW100 mkII. By enabling this the LCD + controller and AC97 controller is added as platform devices. config BOARD_ATNGW100_MRMT bool "Mediama RMT1/2 add-on board" @@ -55,4 +62,4 @@ if BOARD_ATNGW100_MRMT source "arch/avr32/boards/atngw100/Kconfig_mrmt" endif -endif # BOARD_ATNGW100 +endif # BOARD_ATNGW100_COMMON diff --git a/arch/avr32/boards/atngw100/evklcd10x.c b/arch/avr32/boards/atngw100/evklcd10x.c index 0033711..2038875 100644 --- a/arch/avr32/boards/atngw100/evklcd10x.c +++ b/arch/avr32/boards/atngw100/evklcd10x.c @@ -164,7 +164,12 @@ static int __init atevklcd10x_init(void) at32_add_device_lcdc(0, &atevklcd10x_lcdc_data, fbmem_start, fbmem_size, - ATMEL_LCDC_ALT_18BIT | ATMEL_LCDC_PE_DVAL); +#ifdef CONFIG_BOARD_ATNGW100_MKII + ATMEL_LCDC_PRI_18BIT | ATMEL_LCDC_PC_DVAL +#else + ATMEL_LCDC_ALT_18BIT | ATMEL_LCDC_PE_DVAL +#endif + ); at32_add_device_ac97c(0, &ac97c0_data, AC97C_BOTH); diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c index 5b022aa..8c6a244 100644 --- a/arch/avr32/boards/atngw100/setup.c +++ b/arch/avr32/boards/atngw100/setup.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,75 @@ unsigned long at32_board_osc_rates[3] = { [2] = 12000000, /* 12 MHz on osc1 */ }; +/* + * The ATNGW100 mkII is very similar to the ATNGW100. Both have the AT32AP7000 + * chip on board; the difference is that the ATNGW100 mkII has 128 MB 32-bit + * SDRAM (the ATNGW100 has 32 MB 16-bit SDRAM) and 256 MB 16-bit NAND flash + * (the ATNGW100 has none.) + * + * The RAM difference is handled by the boot loader, so the only difference we + * end up handling here is the NAND flash, EBI pin reservation and if LCDC or + * MACB1 should be enabled. + */ +#ifdef CONFIG_BOARD_ATNGW100_MKII +#include +#include + +static struct smc_timing nand_timing __initdata = { + .ncs_read_setup = 0, + .nrd_setup = 10, + .ncs_write_setup = 0, + .nwe_setup = 10, + + .ncs_read_pulse = 30, + .nrd_pulse = 15, + .ncs_write_pulse = 30, + .nwe_pulse = 15, + + .read_cycle = 30, + .write_cycle = 30, + + .ncs_read_recover = 0, + .nrd_recover = 15, + .ncs_write_recover = 0, + /* WE# high -> RE# low min 60 ns */ + .nwe_recover = 50, +}; + +static struct smc_config nand_config __initdata = { + .bus_width = 2, + .nrd_controlled = 1, + .nwe_controlled = 1, + .nwait_mode = 0, + .byte_write = 0, + .tdf_cycles = 2, + .tdf_mode = 0, +}; + +static struct mtd_partition nand_partitions[] = { + { + .name = "main", + .offset = 0x00000000, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition *nand_part_info(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(nand_partitions); + return nand_partitions; +} + +static struct atmel_nand_data atngw100mkii_nand_data __initdata = { + .cle = 21, + .ale = 22, + .rdy_pin = GPIO_PIN_PB(28), + .enable_pin = GPIO_PIN_PE(23), + .bus_width_16 = true, + .partition_info = nand_part_info, +}; +#endif + /* Initialized by bootloader-specific startup code. */ struct tag *bootloader_tags __initdata; @@ -56,11 +126,24 @@ static struct spi_board_info spi0_board_info[] __initdata = { static struct mci_platform_data __initdata mci0_data = { .slot[0] = { .bus_width = 4, +#if defined(CONFIG_BOARD_ATNGW100_MKII) + .detect_pin = GPIO_PIN_PC(25), + .wp_pin = GPIO_PIN_PE(22), +#else .detect_pin = GPIO_PIN_PC(25), .wp_pin = GPIO_PIN_PE(0), +#endif }, }; +static struct usba_platform_data atngw100_usba_data __initdata = { +#if defined(CONFIG_BOARD_ATNGW100_MKII) + .vbus_pin = GPIO_PIN_PE(26), +#else + .vbus_pin = -ENODEV, +#endif +}; + /* * The next two functions should go away as the boot loader is * supposed to initialize the macb address registers with a valid @@ -168,18 +251,27 @@ static int __init atngw100_init(void) unsigned i; /* - * ATNGW100 uses 16-bit SDRAM interface, so we don't need to - * reserve any pins for it. + * ATNGW100 mkII uses 32-bit SDRAM interface. Reserve the + * SDRAM-specific pins so that nobody messes with them. */ +#ifdef CONFIG_BOARD_ATNGW100_MKII + at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL); + + smc_set_timing(&nand_config, &nand_timing); + smc_set_configuration(3, &nand_config); + at32_add_device_nand(0, &atngw100mkii_nand_data); +#endif at32_add_device_usart(0); set_hw_addr(at32_add_device_eth(0, ð_data[0])); +#ifndef CONFIG_BOARD_ATNGW100_MKII_LCD set_hw_addr(at32_add_device_eth(1, ð_data[1])); +#endif at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); at32_add_device_mci(0, &mci0_data); - at32_add_device_usba(0, NULL); + at32_add_device_usba(0, &atngw100_usba_data); for (i = 0; i < ARRAY_SIZE(ngw_leds); i++) { at32_select_gpio(ngw_leds[i].gpio, @@ -189,10 +281,14 @@ static int __init atngw100_init(void) /* all these i2c/smbus pins should have external pullups for * open-drain sharing among all I2C devices. SDA and SCL do; - * PB28/EXTINT3 doesn't; it should be SMBALERT# (for PMBus), - * but it's not available off-board. + * PB28/EXTINT3 (ATNGW100) and PE21 (ATNGW100 mkII) doesn't; it should + * be SMBALERT# (for PMBus), but it's not available off-board. */ +#ifdef CONFIG_BOARD_ATNGW100_MKII + at32_select_periph(GPIO_PIOE_BASE, 1 << 21, 0, AT32_GPIOF_PULLUP); +#else at32_select_periph(GPIO_PIOB_BASE, 1 << 28, 0, AT32_GPIOF_PULLUP); +#endif at32_select_gpio(i2c_gpio_data.sda_pin, AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); at32_select_gpio(i2c_gpio_data.scl_pin, @@ -206,14 +302,22 @@ postcore_initcall(atngw100_init); static int __init atngw100_arch_init(void) { - /* PB30 is the otherwise unused jumper on the mainboard, with an - * external pullup; the jumper grounds it. Use it however you - * like, including letting U-Boot or Linux tweak boot sequences. + /* PB30 (ATNGW100) and PE30 (ATNGW100 mkII) is the otherwise unused + * jumper on the mainboard, with an external pullup; the jumper grounds + * it. Use it however you like, including letting U-Boot or Linux tweak + * boot sequences. */ +#ifdef CONFIG_BOARD_ATNGW100_MKII + at32_select_gpio(GPIO_PIN_PE(30), 0); + gpio_request(GPIO_PIN_PE(30), "j15"); + gpio_direction_input(GPIO_PIN_PE(30)); + gpio_export(GPIO_PIN_PE(30), false); +#else at32_select_gpio(GPIO_PIN_PB(30), 0); gpio_request(GPIO_PIN_PB(30), "j15"); gpio_direction_input(GPIO_PIN_PB(30)); gpio_export(GPIO_PIN_PB(30), false); +#endif /* set_irq_type() after the arch_initcall for EIC has run, and * before the I2C subsystem could try using this IRQ. -- cgit v0.10.2 From 2c651c139a4f4bfd511e5e4662cbe4f8ed3af8a3 Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Thu, 3 Dec 2009 14:58:21 +0100 Subject: avr32: add default configurations for ATNGW100 mkII and EVKLCD10X This patch adds three default configurations for ATNGW100 mkII and ATNGW100 mkII with either EVKLCD100 or EVKLCD101 addon board. Signed-off-by: Hans-Christian Egtvedt Signed-off-by: Haavard Skinnemoen diff --git a/arch/avr32/configs/atngw100mkii_defconfig b/arch/avr32/configs/atngw100mkii_defconfig new file mode 100644 index 0000000..9b8b5b3 --- /dev/null +++ b/arch/avr32/configs/atngw100mkii_defconfig @@ -0,0 +1,1414 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.32-rc5 +# Thu Nov 5 15:32:26 2009 +# +CONFIG_AVR32=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_BUG=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +# CONFIG_BASE_FULL is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_COMPAT_BRK is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_OPROFILE=m +CONFIG_HAVE_OPROFILE=y +CONFIG_KPROBES=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=1 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_FREEZER=y + +# +# System Type and features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_SUBARCH_AVR32B=y +CONFIG_MMU=y +CONFIG_PERFORMANCE_COUNTERS=y +CONFIG_PLATFORM_AT32AP=y +CONFIG_CPU_AT32AP700X=y +CONFIG_CPU_AT32AP7000=y +CONFIG_BOARD_ATNGW100_COMMON=y +# CONFIG_BOARD_ATSTK1000 is not set +# CONFIG_BOARD_ATNGW100_MKI is not set +CONFIG_BOARD_ATNGW100_MKII=y +# CONFIG_BOARD_HAMMERHEAD is not set +# CONFIG_BOARD_FAVR_32 is not set +# CONFIG_BOARD_MERISC is not set +# CONFIG_BOARD_MIMC200 is not set +# CONFIG_BOARD_ATNGW100_MKII_LCD is not set +CONFIG_BOARD_ATNGW100_ADDON_NONE=y +# CONFIG_BOARD_ATNGW100_EVKLCD10X is not set +# CONFIG_BOARD_ATNGW100_MRMT is not set +CONFIG_LOADER_U_BOOT=y + +# +# Atmel AVR32 AP options +# +# CONFIG_AP700X_32_BIT_SMC is not set +CONFIG_AP700X_16_BIT_SMC=y +# CONFIG_AP700X_8_BIT_SMC is not set +CONFIG_LOAD_ADDRESS=0x10000000 +CONFIG_ENTRY_ADDRESS=0x90000000 +CONFIG_PHYS_OFFSET=0x10000000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_QUICKLIST=y +# CONFIG_HAVE_ARCH_BOOTMEM is not set +# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set +# CONFIG_NEED_NODE_MEMMAP_SIZE is not set +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +# CONFIG_ARCH_SPARSEMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=2 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_OWNERSHIP_TRACE is not set +CONFIG_NMI_DEBUGGING=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +CONFIG_CMDLINE="" + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_PM_RUNTIME is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_STAT is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_AT32AP=y + +# +# Bus options +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=y +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MULTIPLE_TABLES is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +# CONFIG_IP_PIMSM_V2 is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +CONFIG_INET_XFRM_TUNNEL=y +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +# CONFIG_IPV6_MIP6 is not set +CONFIG_INET6_XFRM_TUNNEL=y +CONFIG_INET6_TUNNEL=y +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_NETFILTER_ADVANCED is not set + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NETFILTER_XTABLES=y +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +# CONFIG_NF_NAT_TFTP is not set +# CONFIG_NF_NAT_AMANDA is not set +# CONFIG_NF_NAT_PPTP is not set +# CONFIG_NF_NAT_H323 is not set +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_TCPPROBE is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +CONFIG_CFG80211_DEFAULT_PS_VALUE=0 +# CONFIG_WIRELESS_OLD_REGULATORY is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_DATAFLASH=y +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DATAFLASH_OTP is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +CONFIG_MTD_NAND_ATMEL=y +CONFIG_MTD_NAND_ATMEL_ECC_HW=y +# CONFIG_MTD_NAND_ATMEL_ECC_SOFT is not set +# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ATMEL_PWM is not set +CONFIG_ATMEL_TCLIB=y +CONFIG_ATMEL_TCB_CLKSRC=y +CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0 +# CONFIG_ICS932S401 is not set +# CONFIG_ATMEL_SSC is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +CONFIG_MACB=y +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +# CONFIG_PPPOL2TP is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=m +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_DEVKMEM is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_ATMEL=y +CONFIG_SERIAL_ATMEL_CONSOLE=y +CONFIG_SERIAL_ATMEL_PDC=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +CONFIG_I2C_GPIO=m +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_ATMEL=y +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=m +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_AT32AP700X_WDT=y +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_SOUND is not set +CONFIG_USB_SUPPORT=y +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +CONFIG_USB_GADGET_ATMEL_USBA=y +CONFIG_USB_ATMEL_USBA=y +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_ETH_EEM is not set +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +CONFIG_USB_CDC_COMPOSITE=m + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +CONFIG_MMC_TEST=m + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_AT91 is not set +CONFIG_MMC_ATMELMCI=y +# CONFIG_MMC_ATMELMCI_DMA is not set +CONFIG_MMC_SPI=m +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_AT32AP700X=y +CONFIG_DMADEVICES=y + +# +# DMA Devices +# +CONFIG_DW_DMAC=y +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=850 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_UBIFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +CONFIG_UFS_FS=y +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_KPROBES_SANITY_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_LKDTM is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_NOP_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_HW=y +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +CONFIG_CRC7=m +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/avr32/configs/atngw100mkii_evklcd100_defconfig b/arch/avr32/configs/atngw100mkii_evklcd100_defconfig new file mode 100644 index 0000000..01e913d --- /dev/null +++ b/arch/avr32/configs/atngw100mkii_evklcd100_defconfig @@ -0,0 +1,1549 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.32-rc5 +# Thu Nov 5 15:33:09 2009 +# +CONFIG_AVR32=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_BUG=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +# CONFIG_BASE_FULL is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_COMPAT_BRK is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_OPROFILE=m +CONFIG_HAVE_OPROFILE=y +CONFIG_KPROBES=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=1 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_FREEZER=y + +# +# System Type and features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_SUBARCH_AVR32B=y +CONFIG_MMU=y +CONFIG_PERFORMANCE_COUNTERS=y +CONFIG_PLATFORM_AT32AP=y +CONFIG_CPU_AT32AP700X=y +CONFIG_CPU_AT32AP7000=y +CONFIG_BOARD_ATNGW100_COMMON=y +# CONFIG_BOARD_ATSTK1000 is not set +# CONFIG_BOARD_ATNGW100_MKI is not set +CONFIG_BOARD_ATNGW100_MKII=y +# CONFIG_BOARD_HAMMERHEAD is not set +# CONFIG_BOARD_FAVR_32 is not set +# CONFIG_BOARD_MERISC is not set +# CONFIG_BOARD_MIMC200 is not set +CONFIG_BOARD_ATNGW100_MKII_LCD=y +# CONFIG_BOARD_ATNGW100_ADDON_NONE is not set +CONFIG_BOARD_ATNGW100_EVKLCD10X=y +# CONFIG_BOARD_ATNGW100_MRMT is not set +CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA=y +# CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA is not set +# CONFIG_BOARD_ATNGW100_EVKLCD10X_POW_QVGA is not set +CONFIG_LOADER_U_BOOT=y + +# +# Atmel AVR32 AP options +# +# CONFIG_AP700X_32_BIT_SMC is not set +CONFIG_AP700X_16_BIT_SMC=y +# CONFIG_AP700X_8_BIT_SMC is not set +CONFIG_LOAD_ADDRESS=0x10000000 +CONFIG_ENTRY_ADDRESS=0x90000000 +CONFIG_PHYS_OFFSET=0x10000000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_QUICKLIST=y +# CONFIG_HAVE_ARCH_BOOTMEM is not set +# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set +# CONFIG_NEED_NODE_MEMMAP_SIZE is not set +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +# CONFIG_ARCH_SPARSEMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=2 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_OWNERSHIP_TRACE is not set +CONFIG_NMI_DEBUGGING=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +CONFIG_CMDLINE="" + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_PM_RUNTIME is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_STAT is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_AT32AP=y + +# +# Bus options +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=y +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MULTIPLE_TABLES is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +# CONFIG_IP_PIMSM_V2 is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +CONFIG_INET_XFRM_TUNNEL=y +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +# CONFIG_IPV6_MIP6 is not set +CONFIG_INET6_XFRM_TUNNEL=y +CONFIG_INET6_TUNNEL=y +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_NETFILTER_ADVANCED is not set + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NETFILTER_XTABLES=y +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +# CONFIG_NF_NAT_TFTP is not set +# CONFIG_NF_NAT_AMANDA is not set +# CONFIG_NF_NAT_PPTP is not set +# CONFIG_NF_NAT_H323 is not set +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_TCPPROBE is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +CONFIG_CFG80211_DEFAULT_PS_VALUE=0 +# CONFIG_WIRELESS_OLD_REGULATORY is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_DATAFLASH=y +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DATAFLASH_OTP is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +CONFIG_MTD_NAND_ATMEL=y +CONFIG_MTD_NAND_ATMEL_ECC_HW=y +# CONFIG_MTD_NAND_ATMEL_ECC_SOFT is not set +# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ATMEL_PWM is not set +CONFIG_ATMEL_TCLIB=y +CONFIG_ATMEL_TCB_CLKSRC=y +CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0 +# CONFIG_ICS932S401 is not set +# CONFIG_ATMEL_SSC is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +CONFIG_MACB=y +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +# CONFIG_PPPOL2TP is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=m +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y +# CONFIG_TOUCHSCREEN_WM97XX_ATMEL is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_ATMEL=y +CONFIG_SERIAL_ATMEL_CONSOLE=y +CONFIG_SERIAL_ATMEL_PDC=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +CONFIG_I2C_GPIO=m +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_ATMEL=y +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=m +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_AT32AP700X_WDT=y +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_UCB1400_CORE is not set +# CONFIG_TPS65010 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_ATMEL=y +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set +# CONFIG_LOGO is not set +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=m +# CONFIG_SND_SEQUENCER is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_HRTIMER=y +# CONFIG_SND_DYNAMIC_MINORS is not set +# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_DRIVERS is not set + +# +# Atmel devices (AVR32 and AT91) +# +# CONFIG_SND_ATMEL_ABDAC is not set +CONFIG_SND_ATMEL_AC97C=m +# CONFIG_SND_SPI is not set +# CONFIG_SND_SOC is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set +# CONFIG_HID_PID is not set + +# +# Special HID drivers +# +CONFIG_USB_SUPPORT=y +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=350 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +CONFIG_USB_GADGET_ATMEL_USBA=y +CONFIG_USB_ATMEL_USBA=y +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_ETH_EEM is not set +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +CONFIG_USB_CDC_COMPOSITE=m + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_AT91 is not set +CONFIG_MMC_ATMELMCI=y +# CONFIG_MMC_ATMELMCI_DMA is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_AT32AP700X=y +CONFIG_DMADEVICES=y + +# +# DMA Devices +# +CONFIG_DW_DMAC=y +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=850 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=y +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_UBIFS_FS=y +# CONFIG_UBIFS_FS_XATTR is not set +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_UBIFS_FS_DEBUG is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_KPROBES_SANITY_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_LKDTM is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_NOP_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +CONFIG_CRYPTO_LZO=y + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_HW=y +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/avr32/configs/atngw100mkii_evklcd101_defconfig b/arch/avr32/configs/atngw100mkii_evklcd101_defconfig new file mode 100644 index 0000000..bbf6bc3 --- /dev/null +++ b/arch/avr32/configs/atngw100mkii_evklcd101_defconfig @@ -0,0 +1,1549 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.32-rc5 +# Thu Nov 5 15:33:32 2009 +# +CONFIG_AVR32=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_BUG=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +# CONFIG_BASE_FULL is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_COMPAT_BRK is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_OPROFILE=m +CONFIG_HAVE_OPROFILE=y +CONFIG_KPROBES=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=1 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_FREEZER=y + +# +# System Type and features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_SUBARCH_AVR32B=y +CONFIG_MMU=y +CONFIG_PERFORMANCE_COUNTERS=y +CONFIG_PLATFORM_AT32AP=y +CONFIG_CPU_AT32AP700X=y +CONFIG_CPU_AT32AP7000=y +CONFIG_BOARD_ATNGW100_COMMON=y +# CONFIG_BOARD_ATSTK1000 is not set +# CONFIG_BOARD_ATNGW100_MKI is not set +CONFIG_BOARD_ATNGW100_MKII=y +# CONFIG_BOARD_HAMMERHEAD is not set +# CONFIG_BOARD_FAVR_32 is not set +# CONFIG_BOARD_MERISC is not set +# CONFIG_BOARD_MIMC200 is not set +CONFIG_BOARD_ATNGW100_MKII_LCD=y +# CONFIG_BOARD_ATNGW100_ADDON_NONE is not set +CONFIG_BOARD_ATNGW100_EVKLCD10X=y +# CONFIG_BOARD_ATNGW100_MRMT is not set +# CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA is not set +CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA=y +# CONFIG_BOARD_ATNGW100_EVKLCD10X_POW_QVGA is not set +CONFIG_LOADER_U_BOOT=y + +# +# Atmel AVR32 AP options +# +# CONFIG_AP700X_32_BIT_SMC is not set +CONFIG_AP700X_16_BIT_SMC=y +# CONFIG_AP700X_8_BIT_SMC is not set +CONFIG_LOAD_ADDRESS=0x10000000 +CONFIG_ENTRY_ADDRESS=0x90000000 +CONFIG_PHYS_OFFSET=0x10000000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_QUICKLIST=y +# CONFIG_HAVE_ARCH_BOOTMEM is not set +# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set +# CONFIG_NEED_NODE_MEMMAP_SIZE is not set +CONFIG_ARCH_FLATMEM_ENABLE=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +# CONFIG_ARCH_SPARSEMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=2 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_OWNERSHIP_TRACE is not set +CONFIG_NMI_DEBUGGING=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +CONFIG_CMDLINE="" + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_PM_RUNTIME is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_STAT is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_AT32AP=y + +# +# Bus options +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=y +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MULTIPLE_TABLES is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +# CONFIG_IP_PIMSM_V2 is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +CONFIG_INET_XFRM_TUNNEL=y +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +# CONFIG_IPV6_MIP6 is not set +CONFIG_INET6_XFRM_TUNNEL=y +CONFIG_INET6_TUNNEL=y +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_NETFILTER_ADVANCED is not set + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NETFILTER_XTABLES=y +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +# CONFIG_NF_NAT_TFTP is not set +# CONFIG_NF_NAT_AMANDA is not set +# CONFIG_NF_NAT_PPTP is not set +# CONFIG_NF_NAT_H323 is not set +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_TCPPROBE is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +CONFIG_CFG80211_DEFAULT_PS_VALUE=0 +# CONFIG_WIRELESS_OLD_REGULATORY is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_DATAFLASH=y +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DATAFLASH_OTP is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +CONFIG_MTD_NAND_ATMEL=y +CONFIG_MTD_NAND_ATMEL_ECC_HW=y +# CONFIG_MTD_NAND_ATMEL_ECC_SOFT is not set +# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ATMEL_PWM is not set +CONFIG_ATMEL_TCLIB=y +CONFIG_ATMEL_TCB_CLKSRC=y +CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0 +# CONFIG_ICS932S401 is not set +# CONFIG_ATMEL_SSC is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +CONFIG_MACB=y +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +# CONFIG_PPPOL2TP is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=m +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y +# CONFIG_TOUCHSCREEN_WM97XX_ATMEL is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_ATMEL=y +CONFIG_SERIAL_ATMEL_CONSOLE=y +CONFIG_SERIAL_ATMEL_PDC=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +CONFIG_I2C_GPIO=m +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_ATMEL=y +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=m +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_AT32AP700X_WDT=y +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_UCB1400_CORE is not set +# CONFIG_TPS65010 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_ATMEL=y +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set +# CONFIG_LOGO is not set +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=m +# CONFIG_SND_SEQUENCER is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_HRTIMER=y +# CONFIG_SND_DYNAMIC_MINORS is not set +# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_DRIVERS is not set + +# +# Atmel devices (AVR32 and AT91) +# +# CONFIG_SND_ATMEL_ABDAC is not set +CONFIG_SND_ATMEL_AC97C=m +# CONFIG_SND_SPI is not set +# CONFIG_SND_SOC is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set +# CONFIG_HID_PID is not set + +# +# Special HID drivers +# +CONFIG_USB_SUPPORT=y +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=350 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +CONFIG_USB_GADGET_ATMEL_USBA=y +CONFIG_USB_ATMEL_USBA=y +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_ETH_EEM is not set +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +CONFIG_USB_CDC_COMPOSITE=m + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_AT91 is not set +CONFIG_MMC_ATMELMCI=y +# CONFIG_MMC_ATMELMCI_DMA is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_AT32AP700X=y +CONFIG_DMADEVICES=y + +# +# DMA Devices +# +CONFIG_DW_DMAC=y +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=850 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=y +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_UBIFS_FS=y +# CONFIG_UBIFS_FS_XATTR is not set +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_UBIFS_FS_DEBUG is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_KPROBES_SANITY_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_LKDTM is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_NOP_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +CONFIG_CRYPTO_LZO=y + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_HW=y +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y -- cgit v0.10.2 From 0386f9e68fc92a3650088b86d908b07de4fb1744 Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Thu, 3 Dec 2009 14:58:22 +0100 Subject: avr32: update default configurations for ATNGW100, ATSTK1002 and ATSTK1006 This patch updates the default configuration for ATNGW100 (also for the EVKLCD10X configs), ATSTK1002 and ATSTK1006. By default all kernels will now have support for EXT2/3/4 out of the box, this is handy if the user wants to boot from SD-Card. Signed-off-by: Hans-Christian Egtvedt Signed-off-by: Haavard Skinnemoen diff --git a/arch/avr32/configs/atngw100_defconfig b/arch/avr32/configs/atngw100_defconfig index 574aca9..32205c9 100644 --- a/arch/avr32/configs/atngw100_defconfig +++ b/arch/avr32/configs/atngw100_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.27-rc1 -# Tue Aug 5 16:00:47 2008 +# Linux kernel version: 2.6.32-rc5 +# Thu Oct 29 09:39:22 2009 # CONFIG_AVR32=y CONFIG_GENERIC_GPIO=y @@ -21,6 +21,7 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_BUG=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -34,22 +35,37 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y @@ -59,38 +75,40 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -# CONFIG_COMPAT_BRK is not set # CONFIG_BASE_FULL is not set CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB_DEBUG=y +# CONFIG_COMPAT_BRK is not set # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_PROFILING=y -# CONFIG_MARKERS is not set +CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=m CONFIG_HAVE_OPROFILE=y CONFIG_KPROBES=y -# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set -# CONFIG_HAVE_IOREMAP_PROT is not set CONFIG_HAVE_KPROBES=y -# CONFIG_HAVE_KRETPROBES is not set -# CONFIG_HAVE_ARCH_TRACEHOOK is not set -# CONFIG_HAVE_DMA_ATTRS is not set -# CONFIG_USE_GENERIC_SMP_HELPERS is not set CONFIG_HAVE_CLK=y -CONFIG_PROC_PAGE_MONITOR=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=1 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -98,11 +116,8 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -118,7 +133,7 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_CLASSIC_RCU=y +CONFIG_FREEZER=y # # System Type and features @@ -133,8 +148,23 @@ CONFIG_PERFORMANCE_COUNTERS=y CONFIG_PLATFORM_AT32AP=y CONFIG_CPU_AT32AP700X=y CONFIG_CPU_AT32AP7000=y +CONFIG_BOARD_ATNGW100_COMMON=y # CONFIG_BOARD_ATSTK1000 is not set -CONFIG_BOARD_ATNGW100=y +CONFIG_BOARD_ATNGW100_MKI=y +# CONFIG_BOARD_ATNGW100_MKII is not set +# CONFIG_BOARD_HAMMERHEAD is not set +# CONFIG_BOARD_FAVR_32 is not set +# CONFIG_BOARD_MERISC is not set +# CONFIG_BOARD_MIMC200 is not set +# CONFIG_BOARD_ATSTK1002 is not set +# CONFIG_BOARD_ATSTK1003 is not set +# CONFIG_BOARD_ATSTK1004 is not set +# CONFIG_BOARD_ATSTK1006 is not set +# CONFIG_BOARD_ATSTK1000_J2_LED8 is not set +# CONFIG_BOARD_ATSTK1000_J2_RGB is not set +CONFIG_BOARD_ATNGW100_ADDON_NONE=y +# CONFIG_BOARD_ATNGW100_EVKLCD10X is not set +# CONFIG_BOARD_ATNGW100_MRMT is not set CONFIG_LOADER_U_BOOT=y # @@ -150,7 +180,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_QUICKLIST=y -# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set +# CONFIG_HAVE_ARCH_BOOTMEM is not set # CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set # CONFIG_NEED_NODE_MEMMAP_SIZE is not set CONFIG_ARCH_FLATMEM_ENABLE=y @@ -162,14 +192,16 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 # CONFIG_OWNERSHIP_TRACE is not set CONFIG_NMI_DEBUGGING=y # CONFIG_HZ_100 is not set @@ -177,7 +209,7 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 -# CONFIG_SCHED_HRTICK is not set +CONFIG_SCHED_HRTICK=y CONFIG_CMDLINE="" # @@ -188,6 +220,7 @@ CONFIG_PM=y CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y +# CONFIG_PM_RUNTIME is not set CONFIG_ARCH_SUSPEND_POSSIBLE=y # @@ -219,6 +252,8 @@ CONFIG_CPU_FREQ_AT32AP=y # Executable file formats # CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set CONFIG_NET=y @@ -271,7 +306,6 @@ CONFIG_INET_TCP_DIAG=y CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set -# CONFIG_IP_VS is not set CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set @@ -314,10 +348,12 @@ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_STATE=m +# CONFIG_IP_VS is not set # # IP: Netfilter Configuration # +CONFIG_NF_DEFRAG_IPV4=m CONFIG_NF_CONNTRACK_IPV4=m CONFIG_NF_CONNTRACK_PROC_COMPAT=y CONFIG_IP_NF_IPTABLES=m @@ -343,16 +379,18 @@ CONFIG_IP_NF_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set CONFIG_STP=m CONFIG_BRIDGE=m +# CONFIG_NET_DSA is not set CONFIG_VLAN_8021Q=m # CONFIG_VLAN_8021Q_GVRP is not set # CONFIG_DECNET is not set @@ -364,26 +402,33 @@ CONFIG_LLC=m # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing # # CONFIG_NET_PKTGEN is not set # CONFIG_NET_TCPPROBE is not set +# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +CONFIG_CFG80211_DEFAULT_PS_VALUE=0 +# CONFIG_WIRELESS_OLD_REGULATORY is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_LIB80211 is not set # -# Wireless +# CFG80211 needs to be enabled for MAC80211 # -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -395,6 +440,7 @@ CONFIG_LLC=m # Generic Driver Options # CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set CONFIG_STANDALONE=y # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FW_LOADER is not set @@ -404,6 +450,7 @@ CONFIG_STANDALONE=y # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set @@ -453,16 +500,17 @@ CONFIG_MTD_CFI_UTIL=y # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x80000000 -CONFIG_MTD_PHYSMAP_LEN=0x0 -CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_PHYSMAP_COMPAT is not set # CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers # CONFIG_MTD_DATAFLASH=y +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DATAFLASH_OTP is not set # CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -478,9 +526,22 @@ CONFIG_MTD_DATAFLASH=y # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # -# CONFIG_MTD_UBI is not set +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set @@ -498,10 +559,20 @@ CONFIG_MISC_DEVICES=y CONFIG_ATMEL_TCLIB=y CONFIG_ATMEL_TCB_CLKSRC=y CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0 -# CONFIG_EEPROM_93CX6 is not set +# CONFIG_ICS932S401 is not set # CONFIG_ATMEL_SSC is not set # CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HAVE_IDE is not set +# CONFIG_ISL29003 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=m +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set # # SCSI device support @@ -534,26 +605,37 @@ CONFIG_PHYLIB=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y # CONFIG_MII is not set CONFIG_MACB=y # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_DNET is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # -# Wireless LAN +# Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set @@ -603,9 +685,11 @@ CONFIG_SERIAL_ATMEL=y CONFIG_SERIAL_ATMEL_CONSOLE=y CONFIG_SERIAL_ATMEL_PDC=y # CONFIG_SERIAL_ATMEL_TTYAT is not set +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set @@ -614,7 +698,9 @@ CONFIG_UNIX98_PTYS=y # CONFIG_TCG_TPM is not set CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=m +CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_ALGOBIT=m # @@ -624,6 +710,7 @@ CONFIG_I2C_ALGOBIT=m # # I2C system bus drivers (mostly embedded / system-on-chip) # +# CONFIG_I2C_DESIGNWARE is not set CONFIG_I2C_GPIO=m # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SIMTEC is not set @@ -644,14 +731,6 @@ CONFIG_I2C_GPIO=m # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -CONFIG_EEPROM_AT24=m -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_TPS65010 is not set -# CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -666,19 +745,28 @@ CONFIG_SPI_MASTER=y # CONFIG_SPI_ATMEL=y # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set CONFIG_SPI_SPIDEV=m # CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set CONFIG_ARCH_REQUIRE_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y # +# Memory mapped GPIO expanders: +# + +# # I2C GPIO expanders: # # CONFIG_GPIO_MAX732X is not set @@ -694,11 +782,15 @@ CONFIG_GPIO_SYSFS=y # # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -707,11 +799,11 @@ CONFIG_WATCHDOG=y # # CONFIG_SOFT_WATCHDOG is not set CONFIG_AT32AP700X_WDT=y +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # @@ -720,22 +812,17 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set +# CONFIG_TPS65010 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -756,32 +843,43 @@ CONFIG_USB_SUPPORT=y # CONFIG_USB_ARCH_HAS_EHCI is not set # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 CONFIG_USB_GADGET_SELECTED=y -# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_AT91 is not set CONFIG_USB_GADGET_ATMEL_USBA=y CONFIG_USB_ATMEL_USBA=y # CONFIG_USB_GADGET_FSL_USB2 is not set -# CONFIG_USB_GADGET_NET2280 is not set -# CONFIG_USB_GADGET_PXA25X is not set -# CONFIG_USB_GADGET_M66592 is not set -# CONFIG_USB_GADGET_PXA27X is not set -# CONFIG_USB_GADGET_GOKU is not set # CONFIG_USB_GADGET_LH7A40X is not set # CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set # CONFIG_USB_GADGET_S3C2410 is not set -# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set CONFIG_USB_GADGET_DUALSPEED=y CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set CONFIG_USB_ETH=m CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_ETH_EEM is not set CONFIG_USB_GADGETFS=m CONFIG_USB_FILE_STORAGE=m # CONFIG_USB_FILE_STORAGE_TEST is not set @@ -789,12 +887,18 @@ CONFIG_USB_G_SERIAL=m # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set CONFIG_USB_CDC_COMPOSITE=m + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set # CONFIG_MMC_UNSAFE_RESUME is not set # -# MMC/SD Card Drivers +# MMC/SD/SDIO Card Drivers # CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_BOUNCE=y @@ -802,10 +906,12 @@ CONFIG_MMC_BLOCK_BOUNCE=y CONFIG_MMC_TEST=m # -# MMC/SD Host Controller Drivers +# MMC/SD/SDIO Host Controller Drivers # # CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_AT91 is not set CONFIG_MMC_ATMELMCI=y +# CONFIG_MMC_ATMELMCI_DMA is not set CONFIG_MMC_SPI=m # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y @@ -815,7 +921,11 @@ CONFIG_LEDS_CLASS=y # LED drivers # CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set # CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set # # LED Triggers @@ -823,7 +933,13 @@ CONFIG_LEDS_GPIO=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# # CONFIG_ACCESSIBILITY is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y @@ -855,25 +971,33 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M41T80 is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers # # CONFIG_RTC_DRV_M41T94 is not set # CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set # CONFIG_RTC_DRV_MAX6902 is not set # CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set # # Platform RTC drivers # +# CONFIG_RTC_DRV_DS1286 is not set # CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -892,24 +1016,38 @@ CONFIG_DMA_ENGINE=y # DMA Clients # # CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set # CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set # +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# # File systems # -CONFIG_EXT2_FS=m +CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=m +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=m +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -917,6 +1055,12 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set # # CD-ROM/DVD Filesystems @@ -940,15 +1084,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y # CONFIG_PROC_KCORE is not set CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_CONFIGFS_FS=m - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -967,7 +1109,9 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_UBIFS_FS is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -975,7 +1119,9 @@ CONFIG_JFFS2_RTIME=y # CONFIG_QNX4FS_FS is not set # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set +CONFIG_UFS_FS=y +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -1060,14 +1206,18 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1083,6 +1233,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set @@ -1091,13 +1242,39 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set CONFIG_FRAME_POINTER=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_KPROBES_SANITY_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_NOP_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set # @@ -1105,19 +1282,30 @@ CONFIG_FRAME_POINTER=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set CONFIG_CRYPTO=y # # Crypto core or helper # +# CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_AUTHENC=y # CONFIG_CRYPTO_TEST is not set @@ -1145,11 +1333,13 @@ CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -1166,7 +1356,7 @@ CONFIG_CRYPTO_SHA1=y # # Ciphers # -# CONFIG_CRYPTO_AES is not set +CONFIG_CRYPTO_AES=m # CONFIG_CRYPTO_ANUBIS is not set CONFIG_CRYPTO_ARC4=m # CONFIG_CRYPTO_BLOWFISH is not set @@ -1186,15 +1376,21 @@ CONFIG_CRYPTO_DES=y # Compression # CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m CONFIG_CRYPTO_HW=y +CONFIG_BINARY_PRINTF=y # # Library routines # CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -# CONFIG_GENERIC_FIND_NEXT_BIT is not set +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -1204,8 +1400,9 @@ CONFIG_CRC7=m # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_GZIP=y CONFIG_GENERIC_ALLOCATOR=y -CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/avr32/configs/atngw100_evklcd100_defconfig b/arch/avr32/configs/atngw100_evklcd100_defconfig index 86a45b5..c732cc3 100644 --- a/arch/avr32/configs/atngw100_evklcd100_defconfig +++ b/arch/avr32/configs/atngw100_evklcd100_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25.6 -# Wed Jun 18 16:06:32 2008 +# Linux kernel version: 2.6.32-rc5 +# Thu Oct 29 09:36:39 2009 # CONFIG_AVR32=y CONFIG_GENERIC_GPIO=y @@ -21,6 +21,7 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_BUG=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -34,22 +35,37 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y @@ -59,43 +75,51 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -# CONFIG_COMPAT_BRK is not set # CONFIG_BASE_FULL is not set CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB_DEBUG=y +# CONFIG_COMPAT_BRK is not set # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_PROFILING=y -# CONFIG_MARKERS is not set +CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=m CONFIG_HAVE_OPROFILE=y CONFIG_KPROBES=y CONFIG_HAVE_KPROBES=y -# CONFIG_HAVE_KRETPROBES is not set -CONFIG_PROC_PAGE_MONITOR=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=1 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set # # IO Schedulers @@ -109,7 +133,7 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_CLASSIC_RCU=y +CONFIG_FREEZER=y # # System Type and features @@ -124,13 +148,26 @@ CONFIG_PERFORMANCE_COUNTERS=y CONFIG_PLATFORM_AT32AP=y CONFIG_CPU_AT32AP700X=y CONFIG_CPU_AT32AP7000=y +CONFIG_BOARD_ATNGW100_COMMON=y # CONFIG_BOARD_ATSTK1000 is not set -CONFIG_BOARD_ATNGW100=y +CONFIG_BOARD_ATNGW100_MKI=y +# CONFIG_BOARD_ATNGW100_MKII is not set +# CONFIG_BOARD_HAMMERHEAD is not set +# CONFIG_BOARD_FAVR_32 is not set +# CONFIG_BOARD_MERISC is not set +# CONFIG_BOARD_MIMC200 is not set +# CONFIG_BOARD_ATSTK1002 is not set +# CONFIG_BOARD_ATSTK1003 is not set +# CONFIG_BOARD_ATSTK1004 is not set +# CONFIG_BOARD_ATSTK1006 is not set +# CONFIG_BOARD_ATSTK1000_J2_LED8 is not set +# CONFIG_BOARD_ATSTK1000_J2_RGB is not set +# CONFIG_BOARD_ATNGW100_ADDON_NONE is not set CONFIG_BOARD_ATNGW100_EVKLCD10X=y +# CONFIG_BOARD_ATNGW100_MRMT is not set CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA=y # CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA is not set # CONFIG_BOARD_ATNGW100_EVKLCD10X_POW_QVGA is not set -CONFIG_BOARD_ATNGW100_I2C_GPIO=y CONFIG_LOADER_U_BOOT=y # @@ -139,14 +176,14 @@ CONFIG_LOADER_U_BOOT=y # CONFIG_AP700X_32_BIT_SMC is not set CONFIG_AP700X_16_BIT_SMC=y # CONFIG_AP700X_8_BIT_SMC is not set -CONFIG_GPIO_DEV=y CONFIG_LOAD_ADDRESS=0x10000000 CONFIG_ENTRY_ADDRESS=0x90000000 CONFIG_PHYS_OFFSET=0x10000000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set +CONFIG_QUICKLIST=y +# CONFIG_HAVE_ARCH_BOOTMEM is not set # CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set # CONFIG_NEED_NODE_MEMMAP_SIZE is not set CONFIG_ARCH_FLATMEM_ENABLE=y @@ -158,33 +195,36 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=2 CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 # CONFIG_OWNERSHIP_TRACE is not set CONFIG_NMI_DEBUGGING=y -CONFIG_DW_DMAC=y # CONFIG_HZ_100 is not set CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 -# CONFIG_SCHED_HRTICK is not set +CONFIG_SCHED_HRTICK=y CONFIG_CMDLINE="" # # Power management options # -CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_PM=y -# CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y +# CONFIG_PM_RUNTIME is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y # # CPU Frequency scaling @@ -194,6 +234,7 @@ CONFIG_CPU_FREQ_TABLE=y # CONFIG_CPU_FREQ_DEBUG is not set # CONFIG_CPU_FREQ_STAT is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set @@ -214,11 +255,9 @@ CONFIG_CPU_FREQ_AT32AP=y # Executable file formats # CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set - -# -# Networking -# CONFIG_NET=y # @@ -232,6 +271,7 @@ CONFIG_XFRM_USER=y # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set # CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=y CONFIG_NET_KEY=y # CONFIG_NET_KEY_MIGRATE is not set CONFIG_INET=y @@ -269,7 +309,6 @@ CONFIG_INET_TCP_DIAG=y CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set -# CONFIG_IP_VS is not set CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set @@ -285,8 +324,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y CONFIG_INET6_XFRM_MODE_BEET=y # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set CONFIG_IPV6_SIT=y +CONFIG_IPV6_NDISC_NODETYPE=y # CONFIG_IPV6_TUNNEL is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -310,10 +351,12 @@ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_STATE=m +# CONFIG_IP_VS is not set # # IP: Netfilter Configuration # +CONFIG_NF_DEFRAG_IPV4=m CONFIG_NF_CONNTRACK_IPV4=m CONFIG_NF_CONNTRACK_PROC_COMPAT=y CONFIG_IP_NF_IPTABLES=m @@ -339,16 +382,20 @@ CONFIG_IP_NF_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set +CONFIG_STP=m CONFIG_BRIDGE=m +# CONFIG_NET_DSA is not set CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set # CONFIG_DECNET is not set CONFIG_LLC=m # CONFIG_LLC2 is not set @@ -358,26 +405,33 @@ CONFIG_LLC=m # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing # # CONFIG_NET_PKTGEN is not set # CONFIG_NET_TCPPROBE is not set +# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +CONFIG_CFG80211_DEFAULT_PS_VALUE=0 +# CONFIG_WIRELESS_OLD_REGULATORY is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_LIB80211 is not set # -# Wireless +# CFG80211 needs to be enabled for MAC80211 # -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -389,6 +443,7 @@ CONFIG_LLC=m # Generic Driver Options # CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set CONFIG_STANDALONE=y # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FW_LOADER is not set @@ -398,10 +453,12 @@ CONFIG_STANDALONE=y # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set # # User Modules And Translation Layers @@ -446,16 +503,17 @@ CONFIG_MTD_CFI_UTIL=y # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x80000000 -CONFIG_MTD_PHYSMAP_LEN=0x0 -CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_PHYSMAP_COMPAT is not set # CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers # CONFIG_MTD_DATAFLASH=y +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DATAFLASH_OTP is not set # CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -471,6 +529,11 @@ CONFIG_MTD_DATAFLASH=y # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # CONFIG_MTD_UBI=y @@ -499,10 +562,20 @@ CONFIG_MISC_DEVICES=y CONFIG_ATMEL_TCLIB=y CONFIG_ATMEL_TCB_CLKSRC=y CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0 -# CONFIG_EEPROM_93CX6 is not set +# CONFIG_ICS932S401 is not set # CONFIG_ATMEL_SSC is not set # CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HAVE_IDE is not set +# CONFIG_ISL29003 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set # # SCSI device support @@ -514,7 +587,6 @@ CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0 # CONFIG_ATA is not set # CONFIG_MD is not set CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_MACVLAN is not set @@ -536,25 +608,37 @@ CONFIG_PHYLIB=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y # CONFIG_MII is not set CONFIG_MACB=y # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_DNET is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # -# Wireless LAN +# Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set @@ -598,15 +682,30 @@ CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y # CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_EETI is not set # CONFIG_TOUCHSCREEN_FUJITSU is not set # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set # CONFIG_TOUCHSCREEN_MK712 is not set # CONFIG_TOUCHSCREEN_PENMOUNT is not set # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set -# CONFIG_TOUCHSCREEN_UCB1400 is not set +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y +# CONFIG_TOUCHSCREEN_WM97XX_ATMEL is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set # CONFIG_INPUT_MISC is not set # @@ -619,9 +718,11 @@ CONFIG_INPUT_TOUCHSCREEN=y # Character devices # CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y # CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y # CONFIG_SERIAL_NONSTANDARD is not set # @@ -636,9 +737,11 @@ CONFIG_SERIAL_ATMEL=y CONFIG_SERIAL_ATMEL_CONSOLE=y CONFIG_SERIAL_ATMEL_PDC=y # CONFIG_SERIAL_ATMEL_TTYAT is not set +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set @@ -647,45 +750,44 @@ CONFIG_UNIX98_PTYS=y # CONFIG_TCG_TPM is not set CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=m +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m # -# I2C Algorithms +# I2C Hardware Bus support # -CONFIG_I2C_ALGOBIT=m -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set # -# I2C Hardware Bus support +# I2C system bus drivers (mostly embedded / system-on-chip) # -CONFIG_I2C_ATMELTWI=m +# CONFIG_I2C_DESIGNWARE is not set CONFIG_I2C_GPIO=m # CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set # # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_TPS65010 is not set -# CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set - -# -# SPI support -# CONFIG_SPI=y # CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y @@ -695,30 +797,48 @@ CONFIG_SPI_MASTER=y # CONFIG_SPI_ATMEL=y # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set CONFIG_SPI_SPIDEV=m # CONFIG_SPI_TLE62X0 is not set -CONFIG_HAVE_GPIO_LIB=y # -# GPIO Support +# PPS support # +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set # +# PCI GPIO expanders: +# + +# # SPI GPIO expanders: # +# CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -731,24 +851,31 @@ CONFIG_WATCHDOG=y # # CONFIG_SOFT_WATCHDOG is not set CONFIG_AT32AP700X_WDT=y +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # # Multifunction device drivers # +# CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_UCB1400_CORE is not set +# CONFIG_TPS65010 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -758,6 +885,7 @@ CONFIG_SSB_POSSIBLE=y CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y @@ -765,8 +893,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set # CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -779,6 +907,9 @@ CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_S1D13XXX is not set CONFIG_FB_ATMEL=y # CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -792,119 +923,124 @@ CONFIG_FB_ATMEL=y CONFIG_DUMMY_CONSOLE=y # CONFIG_FRAMEBUFFER_CONSOLE is not set # CONFIG_LOGO is not set - -# -# Sound -# CONFIG_SOUND=y - -# -# Advanced Linux Sound Architecture -# +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y CONFIG_SND=y -CONFIG_SND_TIMER=m +CONFIG_SND_TIMER=y CONFIG_SND_PCM=m # CONFIG_SND_SEQUENCER is not set CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_HRTIMER=y # CONFIG_SND_DYNAMIC_MINORS is not set # CONFIG_SND_SUPPORT_OLD_API is not set CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set - -# -# Generic devices -# +CONFIG_SND_VMASTER=y +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set CONFIG_SND_AC97_CODEC=m -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set +# CONFIG_SND_DRIVERS is not set # -# AVR32 devices -# -CONFIG_SND_ATMEL_AC97=m - -# -# SPI devices -# - -# -# System on Chip audio support +# Atmel devices (AVR32 and AT91) # +# CONFIG_SND_ATMEL_ABDAC is not set +CONFIG_SND_ATMEL_AC97C=m +# CONFIG_SND_SPI is not set # CONFIG_SND_SOC is not set - -# -# SoC Audio support for SuperH -# - -# -# ALSA SoC audio for Freescale SOCs -# - -# -# Open Sound System -# # CONFIG_SOUND_PRIME is not set CONFIG_AC97_BUS=m CONFIG_HID_SUPPORT=y CONFIG_HID=y -# CONFIG_HID_DEBUG is not set # CONFIG_HIDRAW is not set +# CONFIG_HID_PID is not set + +# +# Special HID drivers +# CONFIG_USB_SUPPORT=y # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set # CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=350 CONFIG_USB_GADGET_SELECTED=y -# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_AT91 is not set CONFIG_USB_GADGET_ATMEL_USBA=y CONFIG_USB_ATMEL_USBA=y # CONFIG_USB_GADGET_FSL_USB2 is not set -# CONFIG_USB_GADGET_NET2280 is not set -# CONFIG_USB_GADGET_PXA2XX is not set -# CONFIG_USB_GADGET_M66592 is not set -# CONFIG_USB_GADGET_GOKU is not set # CONFIG_USB_GADGET_LH7A40X is not set # CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set # CONFIG_USB_GADGET_S3C2410 is not set -# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set CONFIG_USB_GADGET_DUALSPEED=y CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set CONFIG_USB_ETH=m CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_ETH_EEM is not set CONFIG_USB_GADGETFS=m CONFIG_USB_FILE_STORAGE=m # CONFIG_USB_FILE_STORAGE_TEST is not set CONFIG_USB_G_SERIAL=m # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set +CONFIG_USB_CDC_COMPOSITE=m + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set # CONFIG_MMC_UNSAFE_RESUME is not set # -# MMC/SD Card Drivers +# MMC/SD/SDIO Card Drivers # CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_BOUNCE=y # CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set # -# MMC/SD Host Controller Drivers +# MMC/SD/SDIO Host Controller Drivers # +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_AT91 is not set CONFIG_MMC_ATMELMCI=y +# CONFIG_MMC_ATMELMCI_DMA is not set # CONFIG_MMC_SPI is not set # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y @@ -913,7 +1049,13 @@ CONFIG_LEDS_CLASS=y # # LED drivers # +# CONFIG_LEDS_PCA9532 is not set CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set # # LED Triggers @@ -921,6 +1063,14 @@ CONFIG_LEDS_GPIO=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y @@ -950,51 +1100,84 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set # CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers # +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set # CONFIG_RTC_DRV_MAX6902 is not set # CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set # # Platform RTC drivers # +# CONFIG_RTC_DRV_DS1286 is not set # CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_V3020 is not set # # on-CPU RTC drivers # CONFIG_RTC_DRV_AT32AP700X=y +CONFIG_DMADEVICES=y # -# Userspace I/O +# DMA Devices # +CONFIG_DW_DMAC=y +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set # +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set -# CONFIG_EXT4DEV_FS is not set +# CONFIG_EXT4_FS is not set CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -1002,6 +1185,12 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set # # CD-ROM/DVD Filesystems @@ -1025,15 +1214,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y # CONFIG_PROC_KCORE is not set CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_CONFIGFS_FS=y - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1059,8 +1246,10 @@ CONFIG_UBIFS_FS_LZO=y CONFIG_UBIFS_FS_ZLIB=y # CONFIG_UBIFS_FS_DEBUG is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set # CONFIG_ROMFS_FS is not set @@ -1071,19 +1260,16 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V3=y # CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y -CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y -# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1151,16 +1337,24 @@ CONFIG_NLS_UTF8=m # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set # CONFIG_SLUB_DEBUG_ON is not set # CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_RT_MUTEXES is not set @@ -1172,19 +1366,48 @@ CONFIG_SCHED_DEBUG=y # CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set CONFIG_FRAME_POINTER=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_KPROBES_SANITY_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_NOP_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set # @@ -1192,63 +1415,118 @@ CONFIG_FRAME_POINTER=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y -# CONFIG_CRYPTO_SEQIV is not set +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set CONFIG_CRYPTO_SHA1=y # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_GF128MUL is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_XTS is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=m # CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_CAST5 is not set # CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_SEED is not set # CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_TEST is not set -CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_ZLIB is not set CONFIG_CRYPTO_LZO=y + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m CONFIG_CRYPTO_HW=y +CONFIG_BINARY_PRINTF=y # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_CRC7 is not set @@ -1257,8 +1535,9 @@ CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y +CONFIG_DECOMPRESS_GZIP=y CONFIG_GENERIC_ALLOCATOR=y -CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/avr32/configs/atngw100_evklcd101_defconfig b/arch/avr32/configs/atngw100_evklcd101_defconfig index a96b68e..5ef67da 100644 --- a/arch/avr32/configs/atngw100_evklcd101_defconfig +++ b/arch/avr32/configs/atngw100_evklcd101_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25.6 -# Wed Jun 18 16:09:32 2008 +# Linux kernel version: 2.6.32-rc5 +# Thu Oct 29 09:37:19 2009 # CONFIG_AVR32=y CONFIG_GENERIC_GPIO=y @@ -21,6 +21,7 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_BUG=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -34,22 +35,37 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y @@ -59,43 +75,51 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -# CONFIG_COMPAT_BRK is not set # CONFIG_BASE_FULL is not set CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB_DEBUG=y +# CONFIG_COMPAT_BRK is not set # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_PROFILING=y -# CONFIG_MARKERS is not set +CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=m CONFIG_HAVE_OPROFILE=y CONFIG_KPROBES=y CONFIG_HAVE_KPROBES=y -# CONFIG_HAVE_KRETPROBES is not set -CONFIG_PROC_PAGE_MONITOR=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=1 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set # # IO Schedulers @@ -109,7 +133,7 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_CLASSIC_RCU=y +CONFIG_FREEZER=y # # System Type and features @@ -124,13 +148,20 @@ CONFIG_PERFORMANCE_COUNTERS=y CONFIG_PLATFORM_AT32AP=y CONFIG_CPU_AT32AP700X=y CONFIG_CPU_AT32AP7000=y +CONFIG_BOARD_ATNGW100_COMMON=y # CONFIG_BOARD_ATSTK1000 is not set -CONFIG_BOARD_ATNGW100=y +CONFIG_BOARD_ATNGW100_MKI=y +# CONFIG_BOARD_ATNGW100_MKII is not set +# CONFIG_BOARD_HAMMERHEAD is not set +# CONFIG_BOARD_FAVR_32 is not set +# CONFIG_BOARD_MERISC is not set +# CONFIG_BOARD_MIMC200 is not set +# CONFIG_BOARD_ATNGW100_ADDON_NONE is not set CONFIG_BOARD_ATNGW100_EVKLCD10X=y +# CONFIG_BOARD_ATNGW100_MRMT is not set # CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA is not set CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA=y # CONFIG_BOARD_ATNGW100_EVKLCD10X_POW_QVGA is not set -CONFIG_BOARD_ATNGW100_I2C_GPIO=y CONFIG_LOADER_U_BOOT=y # @@ -139,14 +170,14 @@ CONFIG_LOADER_U_BOOT=y # CONFIG_AP700X_32_BIT_SMC is not set CONFIG_AP700X_16_BIT_SMC=y # CONFIG_AP700X_8_BIT_SMC is not set -CONFIG_GPIO_DEV=y CONFIG_LOAD_ADDRESS=0x10000000 CONFIG_ENTRY_ADDRESS=0x90000000 CONFIG_PHYS_OFFSET=0x10000000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set +CONFIG_QUICKLIST=y +# CONFIG_HAVE_ARCH_BOOTMEM is not set # CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set # CONFIG_NEED_NODE_MEMMAP_SIZE is not set CONFIG_ARCH_FLATMEM_ENABLE=y @@ -158,33 +189,36 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=2 CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 # CONFIG_OWNERSHIP_TRACE is not set CONFIG_NMI_DEBUGGING=y -CONFIG_DW_DMAC=y # CONFIG_HZ_100 is not set CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 -# CONFIG_SCHED_HRTICK is not set +CONFIG_SCHED_HRTICK=y CONFIG_CMDLINE="" # # Power management options # -CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_PM=y -# CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y +# CONFIG_PM_RUNTIME is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y # # CPU Frequency scaling @@ -194,6 +228,7 @@ CONFIG_CPU_FREQ_TABLE=y # CONFIG_CPU_FREQ_DEBUG is not set # CONFIG_CPU_FREQ_STAT is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set @@ -214,11 +249,9 @@ CONFIG_CPU_FREQ_AT32AP=y # Executable file formats # CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set - -# -# Networking -# CONFIG_NET=y # @@ -232,6 +265,7 @@ CONFIG_XFRM_USER=y # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set # CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=y CONFIG_NET_KEY=y # CONFIG_NET_KEY_MIGRATE is not set CONFIG_INET=y @@ -269,7 +303,6 @@ CONFIG_INET_TCP_DIAG=y CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set -# CONFIG_IP_VS is not set CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set @@ -285,8 +318,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y CONFIG_INET6_XFRM_MODE_BEET=y # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set CONFIG_IPV6_SIT=y +CONFIG_IPV6_NDISC_NODETYPE=y # CONFIG_IPV6_TUNNEL is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -310,10 +345,12 @@ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_STATE=m +# CONFIG_IP_VS is not set # # IP: Netfilter Configuration # +CONFIG_NF_DEFRAG_IPV4=m CONFIG_NF_CONNTRACK_IPV4=m CONFIG_NF_CONNTRACK_PROC_COMPAT=y CONFIG_IP_NF_IPTABLES=m @@ -339,16 +376,20 @@ CONFIG_IP_NF_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set +CONFIG_STP=m CONFIG_BRIDGE=m +# CONFIG_NET_DSA is not set CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set # CONFIG_DECNET is not set CONFIG_LLC=m # CONFIG_LLC2 is not set @@ -358,26 +399,33 @@ CONFIG_LLC=m # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing # # CONFIG_NET_PKTGEN is not set # CONFIG_NET_TCPPROBE is not set +# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +CONFIG_CFG80211_DEFAULT_PS_VALUE=0 +# CONFIG_WIRELESS_OLD_REGULATORY is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_LIB80211 is not set # -# Wireless +# CFG80211 needs to be enabled for MAC80211 # -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -389,6 +437,7 @@ CONFIG_LLC=m # Generic Driver Options # CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set CONFIG_STANDALONE=y # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FW_LOADER is not set @@ -398,10 +447,12 @@ CONFIG_STANDALONE=y # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set # # User Modules And Translation Layers @@ -446,16 +497,17 @@ CONFIG_MTD_CFI_UTIL=y # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x80000000 -CONFIG_MTD_PHYSMAP_LEN=0x0 -CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_PHYSMAP_COMPAT is not set # CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers # CONFIG_MTD_DATAFLASH=y +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DATAFLASH_OTP is not set # CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -471,6 +523,11 @@ CONFIG_MTD_DATAFLASH=y # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # CONFIG_MTD_UBI=y @@ -499,10 +556,20 @@ CONFIG_MISC_DEVICES=y CONFIG_ATMEL_TCLIB=y CONFIG_ATMEL_TCB_CLKSRC=y CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0 -# CONFIG_EEPROM_93CX6 is not set +# CONFIG_ICS932S401 is not set # CONFIG_ATMEL_SSC is not set # CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HAVE_IDE is not set +# CONFIG_ISL29003 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set # # SCSI device support @@ -514,7 +581,6 @@ CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0 # CONFIG_ATA is not set # CONFIG_MD is not set CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_MACVLAN is not set @@ -536,25 +602,37 @@ CONFIG_PHYLIB=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y # CONFIG_MII is not set CONFIG_MACB=y # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_DNET is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # -# Wireless LAN +# Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set @@ -598,15 +676,30 @@ CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y # CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_EETI is not set # CONFIG_TOUCHSCREEN_FUJITSU is not set # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set # CONFIG_TOUCHSCREEN_MK712 is not set # CONFIG_TOUCHSCREEN_PENMOUNT is not set # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set -# CONFIG_TOUCHSCREEN_UCB1400 is not set +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y +# CONFIG_TOUCHSCREEN_WM97XX_ATMEL is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set # CONFIG_INPUT_MISC is not set # @@ -619,9 +712,11 @@ CONFIG_INPUT_TOUCHSCREEN=y # Character devices # CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y # CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y # CONFIG_SERIAL_NONSTANDARD is not set # @@ -636,9 +731,11 @@ CONFIG_SERIAL_ATMEL=y CONFIG_SERIAL_ATMEL_CONSOLE=y CONFIG_SERIAL_ATMEL_PDC=y # CONFIG_SERIAL_ATMEL_TTYAT is not set +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set @@ -647,45 +744,44 @@ CONFIG_UNIX98_PTYS=y # CONFIG_TCG_TPM is not set CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=m +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m # -# I2C Algorithms +# I2C Hardware Bus support # -CONFIG_I2C_ALGOBIT=m -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set # -# I2C Hardware Bus support +# I2C system bus drivers (mostly embedded / system-on-chip) # -CONFIG_I2C_ATMELTWI=m +# CONFIG_I2C_DESIGNWARE is not set CONFIG_I2C_GPIO=m # CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set # # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_TPS65010 is not set -# CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set - -# -# SPI support -# CONFIG_SPI=y # CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y @@ -695,30 +791,48 @@ CONFIG_SPI_MASTER=y # CONFIG_SPI_ATMEL=y # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set CONFIG_SPI_SPIDEV=m # CONFIG_SPI_TLE62X0 is not set -CONFIG_HAVE_GPIO_LIB=y # -# GPIO Support +# PPS support # +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set # +# PCI GPIO expanders: +# + +# # SPI GPIO expanders: # +# CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -731,24 +845,31 @@ CONFIG_WATCHDOG=y # # CONFIG_SOFT_WATCHDOG is not set CONFIG_AT32AP700X_WDT=y +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # # Multifunction device drivers # +# CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_UCB1400_CORE is not set +# CONFIG_TPS65010 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -758,6 +879,7 @@ CONFIG_SSB_POSSIBLE=y CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y @@ -765,8 +887,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set # CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -779,6 +901,9 @@ CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_S1D13XXX is not set CONFIG_FB_ATMEL=y # CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -792,119 +917,124 @@ CONFIG_FB_ATMEL=y CONFIG_DUMMY_CONSOLE=y # CONFIG_FRAMEBUFFER_CONSOLE is not set # CONFIG_LOGO is not set - -# -# Sound -# CONFIG_SOUND=y - -# -# Advanced Linux Sound Architecture -# +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y CONFIG_SND=y -CONFIG_SND_TIMER=m +CONFIG_SND_TIMER=y CONFIG_SND_PCM=m # CONFIG_SND_SEQUENCER is not set CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_HRTIMER=y # CONFIG_SND_DYNAMIC_MINORS is not set # CONFIG_SND_SUPPORT_OLD_API is not set CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set - -# -# Generic devices -# +CONFIG_SND_VMASTER=y +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set CONFIG_SND_AC97_CODEC=m -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set +# CONFIG_SND_DRIVERS is not set # -# AVR32 devices -# -CONFIG_SND_ATMEL_AC97=m - -# -# SPI devices -# - -# -# System on Chip audio support +# Atmel devices (AVR32 and AT91) # +# CONFIG_SND_ATMEL_ABDAC is not set +CONFIG_SND_ATMEL_AC97C=m +# CONFIG_SND_SPI is not set # CONFIG_SND_SOC is not set - -# -# SoC Audio support for SuperH -# - -# -# ALSA SoC audio for Freescale SOCs -# - -# -# Open Sound System -# # CONFIG_SOUND_PRIME is not set CONFIG_AC97_BUS=m CONFIG_HID_SUPPORT=y CONFIG_HID=y -# CONFIG_HID_DEBUG is not set # CONFIG_HIDRAW is not set +# CONFIG_HID_PID is not set + +# +# Special HID drivers +# CONFIG_USB_SUPPORT=y # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set # CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=350 CONFIG_USB_GADGET_SELECTED=y -# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_AT91 is not set CONFIG_USB_GADGET_ATMEL_USBA=y CONFIG_USB_ATMEL_USBA=y # CONFIG_USB_GADGET_FSL_USB2 is not set -# CONFIG_USB_GADGET_NET2280 is not set -# CONFIG_USB_GADGET_PXA2XX is not set -# CONFIG_USB_GADGET_M66592 is not set -# CONFIG_USB_GADGET_GOKU is not set # CONFIG_USB_GADGET_LH7A40X is not set # CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set # CONFIG_USB_GADGET_S3C2410 is not set -# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set CONFIG_USB_GADGET_DUALSPEED=y CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set CONFIG_USB_ETH=m CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_ETH_EEM is not set CONFIG_USB_GADGETFS=m CONFIG_USB_FILE_STORAGE=m # CONFIG_USB_FILE_STORAGE_TEST is not set CONFIG_USB_G_SERIAL=m # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set +CONFIG_USB_CDC_COMPOSITE=m + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set # CONFIG_MMC_UNSAFE_RESUME is not set # -# MMC/SD Card Drivers +# MMC/SD/SDIO Card Drivers # CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_BOUNCE=y # CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set # -# MMC/SD Host Controller Drivers +# MMC/SD/SDIO Host Controller Drivers # +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_AT91 is not set CONFIG_MMC_ATMELMCI=y +# CONFIG_MMC_ATMELMCI_DMA is not set # CONFIG_MMC_SPI is not set # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y @@ -913,7 +1043,13 @@ CONFIG_LEDS_CLASS=y # # LED drivers # +# CONFIG_LEDS_PCA9532 is not set CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set # # LED Triggers @@ -921,6 +1057,14 @@ CONFIG_LEDS_GPIO=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y @@ -950,51 +1094,84 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set # CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers # +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set # CONFIG_RTC_DRV_MAX6902 is not set # CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set # # Platform RTC drivers # +# CONFIG_RTC_DRV_DS1286 is not set # CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_V3020 is not set # # on-CPU RTC drivers # CONFIG_RTC_DRV_AT32AP700X=y +CONFIG_DMADEVICES=y # -# Userspace I/O +# DMA Devices # +CONFIG_DW_DMAC=y +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set # +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set -# CONFIG_EXT4DEV_FS is not set +# CONFIG_EXT4_FS is not set CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -1002,6 +1179,12 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set # # CD-ROM/DVD Filesystems @@ -1025,15 +1208,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y # CONFIG_PROC_KCORE is not set CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_CONFIGFS_FS=y - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1059,8 +1240,10 @@ CONFIG_UBIFS_FS_LZO=y CONFIG_UBIFS_FS_ZLIB=y # CONFIG_UBIFS_FS_DEBUG is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set # CONFIG_ROMFS_FS is not set @@ -1071,19 +1254,16 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V3=y # CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y -CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y -# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1151,16 +1331,24 @@ CONFIG_NLS_UTF8=m # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set # CONFIG_SLUB_DEBUG_ON is not set # CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_RT_MUTEXES is not set @@ -1172,19 +1360,48 @@ CONFIG_SCHED_DEBUG=y # CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set CONFIG_FRAME_POINTER=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_KPROBES_SANITY_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_NOP_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set # @@ -1192,63 +1409,118 @@ CONFIG_FRAME_POINTER=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y -# CONFIG_CRYPTO_SEQIV is not set +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set CONFIG_CRYPTO_SHA1=y # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_GF128MUL is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_XTS is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=m # CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_CAST5 is not set # CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_SEED is not set # CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# CONFIG_CRYPTO_DEFLATE=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_TEST is not set -CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_ZLIB is not set CONFIG_CRYPTO_LZO=y + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m CONFIG_CRYPTO_HW=y +CONFIG_BINARY_PRINTF=y # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_CRC7 is not set @@ -1257,8 +1529,9 @@ CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y +CONFIG_DECOMPRESS_GZIP=y CONFIG_GENERIC_ALLOCATOR=y -CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/avr32/configs/atstk1002_defconfig b/arch/avr32/configs/atstk1002_defconfig index 0abe90a..42dafce 100644 --- a/arch/avr32/configs/atstk1002_defconfig +++ b/arch/avr32/configs/atstk1002_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.27-rc1 -# Mon Aug 4 16:02:27 2008 +# Linux kernel version: 2.6.32-rc5 +# Thu Oct 29 13:00:55 2009 # CONFIG_AVR32=y CONFIG_GENERIC_GPIO=y @@ -21,6 +21,7 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_BUG=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -34,21 +35,36 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y CONFIG_RELAY=y # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y @@ -58,38 +74,40 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -# CONFIG_COMPAT_BRK is not set # CONFIG_BASE_FULL is not set CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB_DEBUG=y +# CONFIG_COMPAT_BRK is not set # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_PROFILING=y -# CONFIG_MARKERS is not set +CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=m CONFIG_HAVE_OPROFILE=y CONFIG_KPROBES=y -# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set -# CONFIG_HAVE_IOREMAP_PROT is not set CONFIG_HAVE_KPROBES=y -# CONFIG_HAVE_KRETPROBES is not set -# CONFIG_HAVE_ARCH_TRACEHOOK is not set -# CONFIG_HAVE_DMA_ATTRS is not set -# CONFIG_USE_GENERIC_SMP_HELPERS is not set CONFIG_HAVE_CLK=y -CONFIG_PROC_PAGE_MONITOR=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=1 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -97,11 +115,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -117,7 +132,7 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_CLASSIC_RCU=y +CONFIG_FREEZER=y # # System Type and features @@ -133,7 +148,12 @@ CONFIG_PLATFORM_AT32AP=y CONFIG_CPU_AT32AP700X=y CONFIG_CPU_AT32AP7000=y CONFIG_BOARD_ATSTK1000=y -# CONFIG_BOARD_ATNGW100 is not set +# CONFIG_BOARD_ATNGW100_MKI is not set +# CONFIG_BOARD_ATNGW100_MKII is not set +# CONFIG_BOARD_HAMMERHEAD is not set +# CONFIG_BOARD_FAVR_32 is not set +# CONFIG_BOARD_MERISC is not set +# CONFIG_BOARD_MIMC200 is not set CONFIG_BOARD_ATSTK1002=y # CONFIG_BOARD_ATSTK1003 is not set # CONFIG_BOARD_ATSTK1004 is not set @@ -159,7 +179,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_QUICKLIST=y -# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set +# CONFIG_HAVE_ARCH_BOOTMEM is not set # CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set # CONFIG_NEED_NODE_MEMMAP_SIZE is not set CONFIG_ARCH_FLATMEM_ENABLE=y @@ -171,14 +191,16 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 # CONFIG_OWNERSHIP_TRACE is not set CONFIG_NMI_DEBUGGING=y # CONFIG_HZ_100 is not set @@ -186,7 +208,7 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 -# CONFIG_SCHED_HRTICK is not set +CONFIG_SCHED_HRTICK=y CONFIG_CMDLINE="" # @@ -197,6 +219,7 @@ CONFIG_PM=y CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y +# CONFIG_PM_RUNTIME is not set CONFIG_ARCH_SUSPEND_POSSIBLE=y # @@ -228,6 +251,8 @@ CONFIG_CPU_FREQ_AT32AP=y # Executable file formats # CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set CONFIG_NET=y @@ -295,10 +320,12 @@ CONFIG_IPV6_TUNNEL=m # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set CONFIG_STP=m CONFIG_BRIDGE=m +# CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set CONFIG_LLC=m @@ -309,26 +336,33 @@ CONFIG_LLC=m # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing # # CONFIG_NET_PKTGEN is not set # CONFIG_NET_TCPPROBE is not set +# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +CONFIG_CFG80211_DEFAULT_PS_VALUE=0 +# CONFIG_WIRELESS_OLD_REGULATORY is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_LIB80211 is not set # -# Wireless +# CFG80211 needs to be enabled for MAC80211 # -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -340,6 +374,7 @@ CONFIG_LLC=m # Generic Driver Options # CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set CONFIG_STANDALONE=y # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FW_LOADER is not set @@ -349,6 +384,7 @@ CONFIG_STANDALONE=y # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set @@ -398,17 +434,18 @@ CONFIG_MTD_CFI_UTIL=y # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x8000000 -CONFIG_MTD_PHYSMAP_LEN=0x0 -CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_PHYSMAP_COMPAT is not set # CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers # CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DATAFLASH_OTP is not set CONFIG_MTD_M25P80=m CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -424,9 +461,22 @@ CONFIG_M25PXX_USE_FAST_READ=y # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # -# CONFIG_MTD_UBI is not set +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set @@ -444,10 +494,20 @@ CONFIG_ATMEL_PWM=m CONFIG_ATMEL_TCLIB=y CONFIG_ATMEL_TCB_CLKSRC=y CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0 -# CONFIG_EEPROM_93CX6 is not set +# CONFIG_ICS932S401 is not set CONFIG_ATMEL_SSC=m # CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HAVE_IDE is not set +# CONFIG_ISL29003 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=m +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set # # SCSI device support @@ -469,10 +529,6 @@ CONFIG_BLK_DEV_SR=m # CONFIG_BLK_DEV_SR_VENDOR is not set # CONFIG_CHR_DEV_SG is not set # CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# # CONFIG_SCSI_MULTI_LUN is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set @@ -489,8 +545,10 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SRP_ATTRS is not set # CONFIG_SCSI_LOWLEVEL is not set # CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set CONFIG_ATA=m # CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_VERBOSE_ERROR=y # CONFIG_SATA_PMP is not set CONFIG_ATA_SFF=y # CONFIG_SATA_MV is not set @@ -519,26 +577,37 @@ CONFIG_PHYLIB=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y # CONFIG_MII is not set CONFIG_MACB=y # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_DNET is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # -# Wireless LAN +# Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set @@ -580,18 +649,25 @@ CONFIG_INPUT_EVDEV=m # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set # CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_QT2160 is not set # CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_KEYBOARD_GPIO=m +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_MAX7359 is not set # CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set # CONFIG_KEYBOARD_STOWAWAY is not set -CONFIG_KEYBOARD_GPIO=m +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set CONFIG_INPUT_MOUSE=y # CONFIG_MOUSE_PS2 is not set # CONFIG_MOUSE_SERIAL is not set # CONFIG_MOUSE_VSXXXAA is not set CONFIG_MOUSE_GPIO=m +# CONFIG_MOUSE_SYNAPTICS_I2C is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set @@ -622,9 +698,11 @@ CONFIG_SERIAL_ATMEL=y CONFIG_SERIAL_ATMEL_CONSOLE=y CONFIG_SERIAL_ATMEL_PDC=y # CONFIG_SERIAL_ATMEL_TTYAT is not set +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set @@ -633,7 +711,9 @@ CONFIG_UNIX98_PTYS=y # CONFIG_TCG_TPM is not set CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=m +CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_ALGOBIT=m # @@ -643,6 +723,7 @@ CONFIG_I2C_ALGOBIT=m # # I2C system bus drivers (mostly embedded / system-on-chip) # +# CONFIG_I2C_DESIGNWARE is not set CONFIG_I2C_GPIO=m # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SIMTEC is not set @@ -663,14 +744,6 @@ CONFIG_I2C_GPIO=m # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -CONFIG_EEPROM_AT24=m -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_TPS65010 is not set -# CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -685,19 +758,28 @@ CONFIG_SPI_MASTER=y # CONFIG_SPI_ATMEL=y # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set CONFIG_SPI_SPIDEV=m # CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set CONFIG_ARCH_REQUIRE_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y # +# Memory mapped GPIO expanders: +# + +# # I2C GPIO expanders: # # CONFIG_GPIO_MAX732X is not set @@ -713,11 +795,15 @@ CONFIG_GPIO_SYSFS=y # # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -726,11 +812,11 @@ CONFIG_WATCHDOG=y # # CONFIG_SOFT_WATCHDOG is not set CONFIG_AT32AP700X_WDT=y +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # @@ -739,22 +825,17 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set +# CONFIG_TPS65010 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -764,6 +845,7 @@ CONFIG_SSB_POSSIBLE=y CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y @@ -785,10 +867,15 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_S1D13XXX is not set CONFIG_FB_ATMEL=y # CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y +# CONFIG_LCD_LMS283GF05 is not set CONFIG_LCD_LTV350QV=y # CONFIG_LCD_ILI9320 is not set +# CONFIG_LCD_TDO24M is not set # CONFIG_LCD_VGG2432A4 is not set # CONFIG_LCD_PLATFORM is not set # CONFIG_BACKLIGHT_CLASS_DEVICE is not set @@ -799,6 +886,8 @@ CONFIG_LCD_LTV350QV=y # CONFIG_DISPLAY_SUPPORT is not set # CONFIG_LOGO is not set CONFIG_SOUND=m +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y CONFIG_SND=m CONFIG_SND_TIMER=m CONFIG_SND_PCM=m @@ -807,12 +896,24 @@ CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_HRTIMER is not set # CONFIG_SND_DYNAMIC_MINORS is not set # CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_VERBOSE_PROCFS is not set # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set # CONFIG_SND_DRIVERS is not set + +# +# Atmel devices (AVR32 and AT91) +# +# CONFIG_SND_ATMEL_ABDAC is not set +# CONFIG_SND_ATMEL_AC97C is not set CONFIG_SND_SPI=y CONFIG_SND_AT73C213=m CONFIG_SND_AT73C213_TARGET_BITRATE=48000 @@ -825,33 +926,43 @@ CONFIG_USB_SUPPORT=y # CONFIG_USB_ARCH_HAS_EHCI is not set # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set # CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 CONFIG_USB_GADGET_SELECTED=y -# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_AT91 is not set CONFIG_USB_GADGET_ATMEL_USBA=y CONFIG_USB_ATMEL_USBA=y # CONFIG_USB_GADGET_FSL_USB2 is not set -# CONFIG_USB_GADGET_NET2280 is not set -# CONFIG_USB_GADGET_PXA25X is not set -# CONFIG_USB_GADGET_M66592 is not set -# CONFIG_USB_GADGET_PXA27X is not set -# CONFIG_USB_GADGET_GOKU is not set # CONFIG_USB_GADGET_LH7A40X is not set # CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set # CONFIG_USB_GADGET_S3C2410 is not set -# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set CONFIG_USB_GADGET_DUALSPEED=y CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set CONFIG_USB_ETH=m CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_ETH_EEM is not set CONFIG_USB_GADGETFS=m CONFIG_USB_FILE_STORAGE=m # CONFIG_USB_FILE_STORAGE_TEST is not set @@ -859,12 +970,18 @@ CONFIG_USB_G_SERIAL=m # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set CONFIG_USB_CDC_COMPOSITE=m + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set # CONFIG_MMC_UNSAFE_RESUME is not set # -# MMC/SD Card Drivers +# MMC/SD/SDIO Card Drivers # CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_BOUNCE=y @@ -872,10 +989,12 @@ CONFIG_MMC_BLOCK_BOUNCE=y # CONFIG_MMC_TEST is not set # -# MMC/SD Host Controller Drivers +# MMC/SD/SDIO Host Controller Drivers # # CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_AT91 is not set CONFIG_MMC_ATMELMCI=y +# CONFIG_MMC_ATMELMCI_DMA is not set CONFIG_MMC_SPI=m # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y @@ -887,7 +1006,11 @@ CONFIG_LEDS_CLASS=m CONFIG_LEDS_ATMEL_PWM=m # CONFIG_LEDS_PCA9532 is not set CONFIG_LEDS_GPIO=m +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set # CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set # # LED Triggers @@ -895,7 +1018,13 @@ CONFIG_LEDS_GPIO=m CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=m CONFIG_LEDS_TRIGGER_HEARTBEAT=m +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set CONFIG_LEDS_TRIGGER_DEFAULT_ON=m + +# +# iptables trigger is under Netfilter config (LED target) +# # CONFIG_ACCESSIBILITY is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y @@ -927,25 +1056,33 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M41T80 is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers # # CONFIG_RTC_DRV_M41T94 is not set # CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set # CONFIG_RTC_DRV_MAX6902 is not set # CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set # # Platform RTC drivers # +# CONFIG_RTC_DRV_DS1286 is not set # CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -964,25 +1101,45 @@ CONFIG_DMA_ENGINE=y # DMA Clients # # CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set # CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set # +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set -# CONFIG_EXT4DEV_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_DEBUG is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -990,6 +1147,12 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set # # CD-ROM/DVD Filesystems @@ -1013,15 +1176,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1039,7 +1200,14 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +CONFIG_UBIFS_FS=y +# CONFIG_UBIFS_FS_XATTR is not set +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_UBIFS_FS_DEBUG is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set CONFIG_MINIX_FS=m # CONFIG_OMFS_FS is not set @@ -1122,6 +1290,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set @@ -1130,6 +1299,9 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1145,6 +1317,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set @@ -1153,13 +1326,39 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set CONFIG_FRAME_POINTER=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_KPROBES_SANITY_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_NOP_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set # @@ -1167,19 +1366,30 @@ CONFIG_FRAME_POINTER=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set CONFIG_CRYPTO=y # # Crypto core or helper # -CONFIG_CRYPTO_ALGAPI=m +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=m +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_AUTHENC=m # CONFIG_CRYPTO_TEST is not set @@ -1207,11 +1417,13 @@ CONFIG_CRYPTO_CBC=m # CONFIG_CRYPTO_HMAC=m # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=m # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -1228,7 +1440,7 @@ CONFIG_CRYPTO_SHA1=m # # Ciphers # -# CONFIG_CRYPTO_AES is not set +CONFIG_CRYPTO_AES=m # CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_ARC4 is not set # CONFIG_CRYPTO_BLOWFISH is not set @@ -1247,18 +1459,24 @@ CONFIG_CRYPTO_DES=m # # Compression # -CONFIG_CRYPTO_DEFLATE=m -# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +CONFIG_CRYPTO_LZO=y + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m # CONFIG_CRYPTO_HW is not set +CONFIG_BINARY_PRINTF=y # # Library routines # CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -# CONFIG_GENERIC_FIND_NEXT_BIT is not set +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m -# CONFIG_CRC16 is not set +CONFIG_CRC16=y CONFIG_CRC_T10DIF=m CONFIG_CRC_ITU_T=m CONFIG_CRC32=y @@ -1266,8 +1484,11 @@ CONFIG_CRC7=m # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_DECOMPRESS_GZIP=y CONFIG_GENERIC_ALLOCATOR=y -CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/avr32/configs/atstk1006_defconfig b/arch/avr32/configs/atstk1006_defconfig index c1603c4..363e238 100644 --- a/arch/avr32/configs/atstk1006_defconfig +++ b/arch/avr32/configs/atstk1006_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28-rc8 -# Thu Dec 18 11:22:23 2008 +# Linux kernel version: 2.6.32-rc5 +# Thu Oct 29 13:00:25 2009 # CONFIG_AVR32=y CONFIG_GENERIC_GPIO=y @@ -21,6 +21,7 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_BUG=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -34,21 +35,36 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y CONFIG_RELAY=y # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y @@ -58,32 +74,40 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -# CONFIG_COMPAT_BRK is not set # CONFIG_BASE_FULL is not set CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB_DEBUG=y +# CONFIG_COMPAT_BRK is not set # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_PROFILING=y -# CONFIG_MARKERS is not set +CONFIG_TRACEPOINTS=y CONFIG_OPROFILE=m CONFIG_HAVE_OPROFILE=y CONFIG_KPROBES=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=1 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -91,11 +115,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -111,7 +132,6 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_CLASSIC_RCU=y CONFIG_FREEZER=y # @@ -128,8 +148,11 @@ CONFIG_PLATFORM_AT32AP=y CONFIG_CPU_AT32AP700X=y CONFIG_CPU_AT32AP7000=y CONFIG_BOARD_ATSTK1000=y -# CONFIG_BOARD_ATNGW100 is not set +# CONFIG_BOARD_ATNGW100_MKI is not set +# CONFIG_BOARD_ATNGW100_MKII is not set +# CONFIG_BOARD_HAMMERHEAD is not set # CONFIG_BOARD_FAVR_32 is not set +# CONFIG_BOARD_MERISC is not set # CONFIG_BOARD_MIMC200 is not set # CONFIG_BOARD_ATSTK1002 is not set # CONFIG_BOARD_ATSTK1003 is not set @@ -156,7 +179,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_QUICKLIST=y -# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set +# CONFIG_HAVE_ARCH_BOOTMEM is not set # CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set # CONFIG_NEED_NODE_MEMMAP_SIZE is not set CONFIG_ARCH_FLATMEM_ENABLE=y @@ -170,12 +193,14 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=2 CONFIG_VIRT_TO_BUS=y -CONFIG_UNEVICTABLE_LRU=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 # CONFIG_OWNERSHIP_TRACE is not set CONFIG_NMI_DEBUGGING=y # CONFIG_HZ_100 is not set @@ -194,6 +219,7 @@ CONFIG_PM=y CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y +# CONFIG_PM_RUNTIME is not set CONFIG_ARCH_SUSPEND_POSSIBLE=y # @@ -294,6 +320,7 @@ CONFIG_IPV6_TUNNEL=m # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set CONFIG_STP=m @@ -309,20 +336,24 @@ CONFIG_LLC=m # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing # # CONFIG_NET_PKTGEN is not set # CONFIG_NET_TCPPROBE is not set +# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set # CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -334,6 +365,7 @@ CONFIG_LLC=m # Generic Driver Options # CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set CONFIG_STANDALONE=y # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FW_LOADER is not set @@ -343,6 +375,7 @@ CONFIG_STANDALONE=y # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set @@ -393,9 +426,7 @@ CONFIG_MTD_CFI_UTIL=y # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x8000000 -CONFIG_MTD_PHYSMAP_LEN=0x0 -CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_PHYSMAP_COMPAT is not set # CONFIG_MTD_PLATRAM is not set # @@ -406,6 +437,7 @@ CONFIG_MTD_DATAFLASH=m CONFIG_MTD_DATAFLASH_OTP=y CONFIG_MTD_M25P80=m CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -432,6 +464,11 @@ CONFIG_MTD_NAND_ATMEL_ECC_HW=y # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # CONFIG_MTD_UBI=y @@ -460,13 +497,22 @@ CONFIG_ATMEL_PWM=m CONFIG_ATMEL_TCLIB=y CONFIG_ATMEL_TCB_CLKSRC=y CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0 -# CONFIG_EEPROM_93CX6 is not set # CONFIG_ICS932S401 is not set CONFIG_ATMEL_SSC=m # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set # CONFIG_C2PORT is not set # +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set + +# # SCSI device support # # CONFIG_RAID_ATTRS is not set @@ -486,10 +532,6 @@ CONFIG_BLK_DEV_SR=m # CONFIG_BLK_DEV_SR_VENDOR is not set # CONFIG_CHR_DEV_SG is not set # CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# # CONFIG_SCSI_MULTI_LUN is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set @@ -506,8 +548,10 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SRP_ATTRS is not set # CONFIG_SCSI_LOWLEVEL is not set # CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set CONFIG_ATA=m # CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_VERBOSE_ERROR=y # CONFIG_SATA_PMP is not set CONFIG_ATA_SFF=y # CONFIG_SATA_MV is not set @@ -536,12 +580,17 @@ CONFIG_PHYLIB=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y # CONFIG_MII is not set CONFIG_MACB=y # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_DNET is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -550,15 +599,18 @@ CONFIG_MACB=y # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # -# Wireless LAN +# Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set @@ -600,18 +652,25 @@ CONFIG_INPUT_EVDEV=m # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set # CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_QT2160 is not set # CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_KEYBOARD_GPIO=m +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_MAX7359 is not set # CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set # CONFIG_KEYBOARD_STOWAWAY is not set -CONFIG_KEYBOARD_GPIO=m +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set CONFIG_INPUT_MOUSE=y # CONFIG_MOUSE_PS2 is not set # CONFIG_MOUSE_SERIAL is not set # CONFIG_MOUSE_VSXXXAA is not set CONFIG_MOUSE_GPIO=m +# CONFIG_MOUSE_SYNAPTICS_I2C is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set @@ -642,9 +701,11 @@ CONFIG_SERIAL_ATMEL=y CONFIG_SERIAL_ATMEL_CONSOLE=y CONFIG_SERIAL_ATMEL_PDC=y # CONFIG_SERIAL_ATMEL_TTYAT is not set +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set @@ -653,6 +714,7 @@ CONFIG_UNIX98_PTYS=y # CONFIG_TCG_TPM is not set CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=m CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_ALGOBIT=m @@ -664,6 +726,7 @@ CONFIG_I2C_ALGOBIT=m # # I2C system bus drivers (mostly embedded / system-on-chip) # +# CONFIG_I2C_DESIGNWARE is not set CONFIG_I2C_GPIO=m # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SIMTEC is not set @@ -684,14 +747,6 @@ CONFIG_I2C_GPIO=m # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_TPS65010 is not set -# CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -706,13 +761,18 @@ CONFIG_SPI_MASTER=y # CONFIG_SPI_ATMEL=y # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set CONFIG_SPI_SPIDEV=m # CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set CONFIG_ARCH_REQUIRE_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set @@ -738,11 +798,15 @@ CONFIG_GPIO_SYSFS=y # # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -764,26 +828,17 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set # CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -817,8 +872,10 @@ CONFIG_FB_ATMEL=y # CONFIG_FB_VIRTUAL is not set # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y +# CONFIG_LCD_LMS283GF05 is not set CONFIG_LCD_LTV350QV=y # CONFIG_LCD_ILI9320 is not set # CONFIG_LCD_TDO24M is not set @@ -833,6 +890,7 @@ CONFIG_LCD_LTV350QV=y # CONFIG_LOGO is not set CONFIG_SOUND=m CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y CONFIG_SND=m CONFIG_SND_TIMER=m CONFIG_SND_PCM=m @@ -841,16 +899,28 @@ CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_HRTIMER is not set # CONFIG_SND_DYNAMIC_MINORS is not set # CONFIG_SND_SUPPORT_OLD_API is not set # CONFIG_SND_VERBOSE_PROCFS is not set # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set CONFIG_SND_DRIVERS=y # CONFIG_SND_DUMMY is not set # CONFIG_SND_MTPAV is not set # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set + +# +# Atmel devices (AVR32 and AT91) +# +# CONFIG_SND_ATMEL_ABDAC is not set +# CONFIG_SND_ATMEL_AC97C is not set CONFIG_SND_SPI=y CONFIG_SND_AT73C213=m CONFIG_SND_AT73C213_TARGET_BITRATE=48000 @@ -863,11 +933,10 @@ CONFIG_USB_SUPPORT=y # CONFIG_USB_ARCH_HAS_EHCI is not set # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set -# CONFIG_USB_MUSB_HDRC is not set # CONFIG_USB_GADGET_MUSB_HDRC is not set # -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG is not set @@ -882,18 +951,25 @@ CONFIG_USB_ATMEL_USBA=y # CONFIG_USB_GADGET_LH7A40X is not set # CONFIG_USB_GADGET_OMAP is not set # CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set # CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set # CONFIG_USB_GADGET_S3C2410 is not set # CONFIG_USB_GADGET_M66592 is not set # CONFIG_USB_GADGET_AMD5536UDC is not set # CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set # CONFIG_USB_GADGET_NET2280 is not set # CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set CONFIG_USB_GADGET_DUALSPEED=y CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set CONFIG_USB_ETH=m CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_ETH_EEM is not set CONFIG_USB_GADGETFS=m CONFIG_USB_FILE_STORAGE=m # CONFIG_USB_FILE_STORAGE_TEST is not set @@ -901,6 +977,12 @@ CONFIG_USB_G_SERIAL=m # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set # CONFIG_USB_CDC_COMPOSITE is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set # CONFIG_MMC_UNSAFE_RESUME is not set @@ -917,6 +999,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y # MMC/SD/SDIO Host Controller Drivers # # CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_AT91 is not set CONFIG_MMC_ATMELMCI=y # CONFIG_MMC_ATMELMCI_DMA is not set CONFIG_MMC_SPI=m @@ -930,7 +1013,11 @@ CONFIG_LEDS_CLASS=m CONFIG_LEDS_ATMEL_PWM=m # CONFIG_LEDS_PCA9532 is not set CONFIG_LEDS_GPIO=m +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set # CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set # # LED Triggers @@ -939,7 +1026,12 @@ CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=m CONFIG_LEDS_TRIGGER_HEARTBEAT=m # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set CONFIG_LEDS_TRIGGER_DEFAULT_ON=m + +# +# iptables trigger is under Netfilter config (LED target) +# # CONFIG_ACCESSIBILITY is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y @@ -972,6 +1064,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers @@ -983,6 +1076,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RS5C348 is not set # CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set # # Platform RTC drivers @@ -1014,32 +1108,42 @@ CONFIG_DMA_ENGINE=y # DMA Clients # # CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set # CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set + +# +# TI VLYNQ +# # CONFIG_STAGING is not set -CONFIG_STAGING_EXCLUDE_BUILD=y # # File systems # -CONFIG_EXT2_FS=m +CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=m +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=m -CONFIG_EXT4DEV_COMPAT=y +CONFIG_EXT4_FS=y # CONFIG_EXT4_FS_XATTR is not set -CONFIG_JBD=m +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set -CONFIG_JBD2=m +CONFIG_JBD2=y # CONFIG_JBD2_DEBUG is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -1047,6 +1151,12 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set # # CD-ROM/DVD Filesystems @@ -1076,10 +1186,7 @@ CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1099,12 +1206,13 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_UBIFS_FS=y -CONFIG_UBIFS_FS_XATTR=y +# CONFIG_UBIFS_FS_XATTR is not set # CONFIG_UBIFS_FS_ADVANCED_COMPR is not set CONFIG_UBIFS_FS_LZO=y CONFIG_UBIFS_FS_ZLIB=y # CONFIG_UBIFS_FS_DEBUG is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set CONFIG_MINIX_FS=m # CONFIG_OMFS_FS is not set @@ -1124,7 +1232,6 @@ CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y -# CONFIG_SUNRPC_REGISTER_V4 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -1188,6 +1295,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set @@ -1196,6 +1304,9 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1211,6 +1322,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set @@ -1219,6 +1331,8 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set CONFIG_FRAME_POINTER=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set @@ -1226,17 +1340,30 @@ CONFIG_FRAME_POINTER=y # CONFIG_KPROBES_SANITY_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set - -# -# Tracers -# +# CONFIG_PAGE_POISONING is not set +CONFIG_NOP_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y # CONFIG_IRQSOFF_TRACER is not set # CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set # CONFIG_BOOT_TRACER is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set # @@ -1262,10 +1389,12 @@ CONFIG_CRYPTO_HASH=m CONFIG_CRYPTO_HASH2=y CONFIG_CRYPTO_RNG=m CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y CONFIG_CRYPTO_MANAGER=m CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_AUTHENC=m # CONFIG_CRYPTO_TEST is not set @@ -1293,11 +1422,13 @@ CONFIG_CRYPTO_CBC=m # CONFIG_CRYPTO_HMAC=m # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=m # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -1334,6 +1465,7 @@ CONFIG_CRYPTO_DES=m # Compression # CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set CONFIG_CRYPTO_LZO=y # @@ -1341,11 +1473,13 @@ CONFIG_CRYPTO_LZO=y # CONFIG_CRYPTO_ANSI_CPRNG=m # CONFIG_CRYPTO_HW is not set +CONFIG_BINARY_PRINTF=y # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m CONFIG_CRC16=y CONFIG_CRC_T10DIF=m @@ -1357,8 +1491,9 @@ CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y +CONFIG_DECOMPRESS_GZIP=y CONFIG_GENERIC_ALLOCATOR=y -CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y -- cgit v0.10.2 From b2ec153a637409bd87952d44409905b7d98418b8 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 14 Dec 2009 14:09:49 -0500 Subject: rt2x00: Fix rt2800usb detection in rt2800lib. rt2800lib incorrectly detected whether RT2800USB was enabled because it didn't account for a modularized RT2800USB driver. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index eb1e1d0..6e13650 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -37,7 +37,7 @@ #include #include "rt2x00.h" -#ifdef CONFIG_RT2800USB +#if defined(CONFIG_RT2800USB) || defined(CONFIG_RT2800USB_MODULE) #include "rt2x00usb.h" #endif #include "rt2800lib.h" @@ -1121,7 +1121,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) if (rt2x00_intf_is_usb(rt2x00dev)) { rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); -#ifdef CONFIG_RT2800USB +#if defined(CONFIG_RT2800USB) || defined(CONFIG_RT2800USB_MODULE) rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, USB_MODE_RESET, REGISTER_TIMEOUT); #endif -- cgit v0.10.2 From d24deb2580823ab0b8425790c6f5d18e2ff749d8 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Fri, 4 Dec 2009 23:46:54 +0100 Subject: mac80211: Add define for TX headroom reserved by mac80211 itself. Add a definition of the amount of TX headroom reserved by mac80211 itself for its own purposes. Also add BUILD_BUG_ON to validate the value. This define can then be used by drivers to request additional TX headroom in the most efficient manner. Signed-off-by: Gertjan van Wingerde Acked-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 2aff490..538d6b7 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1737,6 +1737,12 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw, local_bh_enable(); } +/* + * The TX headroom reserved by mac80211 for its own tx_status functions. + * This is enough for the radiotap header. + */ +#define IEEE80211_TX_STATUS_HEADROOM 13 + /** * ieee80211_tx_status - transmit status callback * diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 8116d1a..0d2d948 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -515,6 +515,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) * and we need some headroom for passing the frame to monitor * interfaces, but never both at the same time. */ + BUILD_BUG_ON(IEEE80211_TX_STATUS_HEADROOM != + sizeof(struct ieee80211_tx_status_rtap_hdr)); local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom, sizeof(struct ieee80211_tx_status_rtap_hdr)); -- cgit v0.10.2 From 310ec79210d754afe51e2e4a983e846b60179abd Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Dec 2009 21:17:23 +0100 Subject: i2c: Drop the kind parameter from detect callbacks The "kind" parameter always has value -1, and nobody is using it any longer, so we can remove it. Signed-off-by: Jean Delvare Tested-by: Wolfram Sang diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index 33acf29..3ebcdd9 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c @@ -97,7 +97,7 @@ struct adm1021_data { static int adm1021_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int adm1021_detect(struct i2c_client *client, int kind, +static int adm1021_detect(struct i2c_client *client, struct i2c_board_info *info); static void adm1021_init_client(struct i2c_client *client); static int adm1021_remove(struct i2c_client *client); @@ -284,7 +284,7 @@ static const struct attribute_group adm1021_group = { }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int adm1021_detect(struct i2c_client *client, int kind, +static int adm1021_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index db6ac2b..357c9ff 100644 --- a/drivers/hwmon/adm1025.c +++ b/drivers/hwmon/adm1025.c @@ -111,7 +111,7 @@ static const int in_scale[6] = { 2500, 2250, 3300, 5000, 12000, 3300 }; static int adm1025_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int adm1025_detect(struct i2c_client *client, int kind, +static int adm1025_detect(struct i2c_client *client, struct i2c_board_info *info); static void adm1025_init_client(struct i2c_client *client); static int adm1025_remove(struct i2c_client *client); @@ -409,7 +409,7 @@ static const struct attribute_group adm1025_group_in4 = { }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int adm1025_detect(struct i2c_client *client, int kind, +static int adm1025_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index fb53639..8deb17a 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -293,7 +293,7 @@ struct adm1026_data { static int adm1026_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int adm1026_detect(struct i2c_client *client, int kind, +static int adm1026_detect(struct i2c_client *client, struct i2c_board_info *info); static int adm1026_remove(struct i2c_client *client); static int adm1026_read_value(struct i2c_client *client, u8 reg); @@ -1650,7 +1650,7 @@ static const struct attribute_group adm1026_group_in8_9 = { }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int adm1026_detect(struct i2c_client *client, int kind, +static int adm1026_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index ef91e2a4..9bc9dbc 100644 --- a/drivers/hwmon/adm1029.c +++ b/drivers/hwmon/adm1029.c @@ -117,7 +117,7 @@ static const u8 ADM1029_REG_FAN_DIV[] = { static int adm1029_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int adm1029_detect(struct i2c_client *client, int kind, +static int adm1029_detect(struct i2c_client *client, struct i2c_board_info *info); static int adm1029_remove(struct i2c_client *client); static struct adm1029_data *adm1029_update_device(struct device *dev); @@ -297,7 +297,7 @@ static const struct attribute_group adm1029_group = { */ /* Return 0 if detection is successful, -ENODEV otherwise */ -static int adm1029_detect(struct i2c_client *client, int kind, +static int adm1029_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 0e72217..cebfbf6 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c @@ -102,7 +102,7 @@ struct adm1031_data { static int adm1031_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int adm1031_detect(struct i2c_client *client, int kind, +static int adm1031_detect(struct i2c_client *client, struct i2c_board_info *info); static void adm1031_init_client(struct i2c_client *client); static int adm1031_remove(struct i2c_client *client); @@ -813,7 +813,7 @@ static const struct attribute_group adm1031_group_opt = { }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int adm1031_detect(struct i2c_client *client, int kind, +static int adm1031_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 20e0481..9316e07 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c @@ -132,7 +132,7 @@ static inline unsigned int AOUT_FROM_REG(u8 reg) static int adm9240_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int adm9240_detect(struct i2c_client *client, int kind, +static int adm9240_detect(struct i2c_client *client, struct i2c_board_info *info); static void adm9240_init_client(struct i2c_client *client); static int adm9240_remove(struct i2c_client *client); @@ -545,7 +545,7 @@ static const struct attribute_group adm9240_group = { /*** sensor chip detect and driver install ***/ /* Return 0 if detection is successful, -ENODEV otherwise */ -static int adm9240_detect(struct i2c_client *new_client, int kind, +static int adm9240_detect(struct i2c_client *new_client, struct i2c_board_info *info) { struct i2c_adapter *adapter = new_client->adapter; diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c index 451977b..b508931 100644 --- a/drivers/hwmon/ads7828.c +++ b/drivers/hwmon/ads7828.c @@ -72,7 +72,7 @@ struct ads7828_data { }; /* Function declaration - necessary due to function dependencies */ -static int ads7828_detect(struct i2c_client *client, int kind, +static int ads7828_detect(struct i2c_client *client, struct i2c_board_info *info); static int ads7828_probe(struct i2c_client *client, const struct i2c_device_id *id); @@ -187,7 +187,7 @@ static struct i2c_driver ads7828_driver = { }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int ads7828_detect(struct i2c_client *client, int kind, +static int ads7828_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c index f9c9562..30cf002 100644 --- a/drivers/hwmon/adt7462.c +++ b/drivers/hwmon/adt7462.c @@ -237,7 +237,7 @@ struct adt7462_data { static int adt7462_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int adt7462_detect(struct i2c_client *client, int kind, +static int adt7462_detect(struct i2c_client *client, struct i2c_board_info *info); static int adt7462_remove(struct i2c_client *client); @@ -1902,7 +1902,7 @@ static struct attribute *adt7462_attr[] = }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int adt7462_detect(struct i2c_client *client, int kind, +static int adt7462_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index 32b1750..9ffe5c6 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c @@ -177,7 +177,7 @@ struct adt7470_data { static int adt7470_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int adt7470_detect(struct i2c_client *client, int kind, +static int adt7470_detect(struct i2c_client *client, struct i2c_board_info *info); static int adt7470_remove(struct i2c_client *client); @@ -1225,7 +1225,7 @@ static struct attribute *adt7470_attr[] = }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int adt7470_detect(struct i2c_client *client, int kind, +static int adt7470_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c index aea244d..78fadaa 100644 --- a/drivers/hwmon/adt7473.c +++ b/drivers/hwmon/adt7473.c @@ -166,7 +166,7 @@ struct adt7473_data { static int adt7473_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int adt7473_detect(struct i2c_client *client, int kind, +static int adt7473_detect(struct i2c_client *client, struct i2c_board_info *info); static int adt7473_remove(struct i2c_client *client); @@ -1085,7 +1085,7 @@ static struct attribute *adt7473_attr[] = }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int adt7473_detect(struct i2c_client *client, int kind, +static int adt7473_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c index 99abfdd..3c05715 100644 --- a/drivers/hwmon/adt7475.c +++ b/drivers/hwmon/adt7475.c @@ -1172,7 +1172,7 @@ static struct attribute_group in4_attr_group = { .attrs = in4_attrs }; static struct attribute_group in5_attr_group = { .attrs = in5_attrs }; static struct attribute_group vid_attr_group = { .attrs = vid_attrs }; -static int adt7475_detect(struct i2c_client *client, int kind, +static int adt7475_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index 480f80e..507e116 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c @@ -209,7 +209,7 @@ static void asb100_write_value(struct i2c_client *client, u16 reg, u16 val); static int asb100_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int asb100_detect(struct i2c_client *client, int kind, +static int asb100_detect(struct i2c_client *client, struct i2c_board_info *info); static int asb100_remove(struct i2c_client *client); static struct asb100_data *asb100_update_device(struct device *dev); @@ -697,7 +697,7 @@ ERROR_SC_2: } /* Return 0 if detection is successful, -ENODEV otherwise */ -static int asb100_detect(struct i2c_client *client, int kind, +static int asb100_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index d6b490d..6b74597 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c @@ -50,8 +50,7 @@ static int atxp1_probe(struct i2c_client *client, const struct i2c_device_id *id); static int atxp1_remove(struct i2c_client *client); static struct atxp1_data * atxp1_update_device(struct device *dev); -static int atxp1_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info); +static int atxp1_detect(struct i2c_client *client, struct i2c_board_info *info); static const struct i2c_device_id atxp1_id[] = { { "atxp1", atxp1 }, @@ -275,7 +274,7 @@ static const struct attribute_group atxp1_group = { /* Return 0 if detection is successful, -ENODEV otherwise */ -static int atxp1_detect(struct i2c_client *new_client, int kind, +static int atxp1_detect(struct i2c_client *new_client, struct i2c_board_info *info) { struct i2c_adapter *adapter = new_client->adapter; diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index 4377bb0..7024617 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c @@ -2208,7 +2208,7 @@ exit: } /* Return 0 if detection is successful, -ENODEV otherwise */ -static int dme1737_i2c_detect(struct i2c_client *client, int kind, +static int dme1737_i2c_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index 2a4c6a0..5fde2f5 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -224,7 +224,7 @@ static const struct attribute_group ds1621_group = { /* Return 0 if detection is successful, -ENODEV otherwise */ -static int ds1621_detect(struct i2c_client *client, int kind, +static int ds1621_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index 40dfbcd..2ffcf56 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -113,7 +113,7 @@ struct f75375_data { s8 temp_max_hyst[2]; }; -static int f75375_detect(struct i2c_client *client, int kind, +static int f75375_detect(struct i2c_client *client, struct i2c_board_info *info); static int f75375_probe(struct i2c_client *client, const struct i2c_device_id *id); @@ -677,7 +677,7 @@ static int f75375_remove(struct i2c_client *client) } /* Return 0 if detection is successful, -ENODEV otherwise */ -static int f75375_detect(struct i2c_client *client, int kind, +static int f75375_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index 281829c..bce18e0 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c @@ -221,7 +221,7 @@ static const int FSCHMD_NO_TEMP_SENSORS[7] = { 3, 3, 4, 3, 5, 5, 11 }; static int fschmd_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int fschmd_detect(struct i2c_client *client, int kind, +static int fschmd_detect(struct i2c_client *client, struct i2c_board_info *info); static int fschmd_remove(struct i2c_client *client); static struct fschmd_data *fschmd_update_device(struct device *dev); @@ -1000,7 +1000,7 @@ static void fschmd_dmi_decode(const struct dmi_header *header, void *dummy) } } -static int fschmd_detect(struct i2c_client *client, int _kind, +static int fschmd_detect(struct i2c_client *client, struct i2c_board_info *info) { enum chips kind; diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index 1d69458a..34f83c6 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c @@ -139,8 +139,7 @@ struct gl518_data { static int gl518_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int gl518_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info); +static int gl518_detect(struct i2c_client *client, struct i2c_board_info *info); static void gl518_init_client(struct i2c_client *client); static int gl518_remove(struct i2c_client *client); static int gl518_read_value(struct i2c_client *client, u8 reg); @@ -484,8 +483,7 @@ static const struct attribute_group gl518_group_r80 = { */ /* Return 0 if detection is successful, -ENODEV otherwise */ -static int gl518_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info) +static int gl518_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; int rev; diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index 92b5720..d03ba69 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c @@ -81,8 +81,7 @@ static const u8 GL520_REG_TEMP_MAX_HYST[] = { 0x06, 0x18 }; static int gl520_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int gl520_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info); +static int gl520_detect(struct i2c_client *client, struct i2c_board_info *info); static void gl520_init_client(struct i2c_client *client); static int gl520_remove(struct i2c_client *client); static int gl520_read_value(struct i2c_client *client, u8 reg); @@ -681,8 +680,7 @@ static const struct attribute_group gl520_group_opt = { */ /* Return 0 if detection is successful, -ENODEV otherwise */ -static int gl520_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info) +static int gl520_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 5da66ab..26844fc 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c @@ -134,8 +134,7 @@ static int lm63_remove(struct i2c_client *client); static struct lm63_data *lm63_update_device(struct device *dev); -static int lm63_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info); +static int lm63_detect(struct i2c_client *client, struct i2c_board_info *info); static void lm63_init_client(struct i2c_client *client); /* @@ -423,7 +422,7 @@ static const struct attribute_group lm63_group_fan1 = { */ /* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm63_detect(struct i2c_client *new_client, int kind, +static int lm63_detect(struct i2c_client *new_client, struct i2c_board_info *info) { struct i2c_adapter *adapter = new_client->adapter; diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c index 0bf8b2a..e610da9 100644 --- a/drivers/hwmon/lm73.c +++ b/drivers/hwmon/lm73.c @@ -151,7 +151,7 @@ static const struct i2c_device_id lm73_ids[] = { MODULE_DEVICE_TABLE(i2c, lm73_ids); /* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm73_detect(struct i2c_client *new_client, int kind, +static int lm73_detect(struct i2c_client *new_client, struct i2c_board_info *info) { struct i2c_adapter *adapter = new_client->adapter; diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index e392548..8fd759d 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -234,7 +234,7 @@ static const struct i2c_device_id lm75_ids[] = { MODULE_DEVICE_TABLE(i2c, lm75_ids); /* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm75_detect(struct i2c_client *new_client, int kind, +static int lm75_detect(struct i2c_client *new_client, struct i2c_board_info *info) { struct i2c_adapter *adapter = new_client->adapter; diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index ac067fd..6373ab2 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c @@ -66,8 +66,7 @@ struct lm77_data { static int lm77_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int lm77_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info); +static int lm77_detect(struct i2c_client *client, struct i2c_board_info *info); static void lm77_init_client(struct i2c_client *client); static int lm77_remove(struct i2c_client *client); static u16 lm77_read_value(struct i2c_client *client, u8 reg); @@ -245,7 +244,7 @@ static const struct attribute_group lm77_group = { }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm77_detect(struct i2c_client *new_client, int kind, +static int lm77_detect(struct i2c_client *new_client, struct i2c_board_info *info) { struct i2c_adapter *adapter = new_client->adapter; diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index 5978291..f58850a 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c @@ -142,7 +142,7 @@ struct lm78_data { }; -static int lm78_i2c_detect(struct i2c_client *client, int kind, +static int lm78_i2c_detect(struct i2c_client *client, struct i2c_board_info *info); static int lm78_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id); @@ -558,7 +558,7 @@ static int lm78_alias_detect(struct i2c_client *client, u8 chipid) return 1; } -static int lm78_i2c_detect(struct i2c_client *client, int kind, +static int lm78_i2c_detect(struct i2c_client *client, struct i2c_board_info *info) { int i; diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index bcffc18..e3222f3 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c @@ -133,8 +133,7 @@ struct lm80_data { static int lm80_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int lm80_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info); +static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info); static void lm80_init_client(struct i2c_client *client); static int lm80_remove(struct i2c_client *client); static struct lm80_data *lm80_update_device(struct device *dev); @@ -447,8 +446,7 @@ static const struct attribute_group lm80_group = { }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm80_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info) +static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; int i, cur; diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index 08b03e6..bfb7477 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c @@ -118,7 +118,7 @@ static const u8 LM83_REG_W_HIGH[] = { * Functions declaration */ -static int lm83_detect(struct i2c_client *new_client, int kind, +static int lm83_detect(struct i2c_client *new_client, struct i2c_board_info *info); static int lm83_probe(struct i2c_client *client, const struct i2c_device_id *id); @@ -291,7 +291,7 @@ static const struct attribute_group lm83_group_opt = { */ /* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm83_detect(struct i2c_client *new_client, int kind, +static int lm83_detect(struct i2c_client *new_client, struct i2c_board_info *info) { struct i2c_adapter *adapter = new_client->adapter; diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index d56da2e..f5fc45a 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -323,8 +323,7 @@ struct lm85_data { struct lm85_zone zone[3]; }; -static int lm85_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info); +static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info); static int lm85_probe(struct i2c_client *client, const struct i2c_device_id *id); static int lm85_remove(struct i2c_client *client); @@ -1156,8 +1155,7 @@ static int lm85_is_fake(struct i2c_client *client) } /* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm85_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info) +static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; int address = client->addr; diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index 4929b18..d545b85 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c @@ -158,7 +158,7 @@ static u8 LM87_REG_TEMP_LOW[3] = { 0x3A, 0x38, 0x2C }; static int lm87_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int lm87_detect(struct i2c_client *new_client, int kind, +static int lm87_detect(struct i2c_client *new_client, struct i2c_board_info *info); static void lm87_init_client(struct i2c_client *client); static int lm87_remove(struct i2c_client *client); @@ -662,7 +662,7 @@ static const struct attribute_group lm87_group_opt = { }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm87_detect(struct i2c_client *new_client, int kind, +static int lm87_detect(struct i2c_client *new_client, struct i2c_board_info *info) { struct i2c_adapter *adapter = new_client->adapter; diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index b7c905f..3acbaca 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -152,8 +152,7 @@ I2C_CLIENT_INSMOD_8(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680, * Functions declaration */ -static int lm90_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info); +static int lm90_detect(struct i2c_client *client, struct i2c_board_info *info); static int lm90_probe(struct i2c_client *client, const struct i2c_device_id *id); static void lm90_init_client(struct i2c_client *client); @@ -656,7 +655,7 @@ static int lm90_read_reg(struct i2c_client* client, u8 reg, u8 *value) } /* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm90_detect(struct i2c_client *new_client, int kind, +static int lm90_detect(struct i2c_client *new_client, struct i2c_board_info *info) { struct i2c_adapter *adapter = new_client->adapter; diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index 47ac698..da35422 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c @@ -319,7 +319,7 @@ static const struct attribute_group lm92_group = { }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm92_detect(struct i2c_client *new_client, int kind, +static int lm92_detect(struct i2c_client *new_client, struct i2c_board_info *info) { struct i2c_adapter *adapter = new_client->adapter; diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index 124dd7c..7b9c97b 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c @@ -2501,8 +2501,7 @@ static void lm93_init_client(struct i2c_client *client) } /* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm93_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info) +static int lm93_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; int mfr, ver; diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c index 906b896..05ede41 100644 --- a/drivers/hwmon/lm95241.c +++ b/drivers/hwmon/lm95241.c @@ -310,7 +310,7 @@ static const struct attribute_group lm95241_group = { }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int lm95241_detect(struct i2c_client *new_client, int kind, +static int lm95241_detect(struct i2c_client *new_client, struct i2c_board_info *info) { struct i2c_adapter *adapter = new_client->adapter; diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 7fcf5ff..4baf94e 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c @@ -88,7 +88,7 @@ static int temp_to_reg(int val) static int max1619_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int max1619_detect(struct i2c_client *client, int kind, +static int max1619_detect(struct i2c_client *client, struct i2c_board_info *info); static void max1619_init_client(struct i2c_client *client); static int max1619_remove(struct i2c_client *client); @@ -226,7 +226,7 @@ static const struct attribute_group max1619_group = { */ /* Return 0 if detection is successful, -ENODEV otherwise */ -static int max1619_detect(struct i2c_client *client, int kind, +static int max1619_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 1da561e..fd5d1ac 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c @@ -116,7 +116,7 @@ I2C_CLIENT_INSMOD_1(max6650); static int max6650_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int max6650_detect(struct i2c_client *client, int kind, +static int max6650_detect(struct i2c_client *client, struct i2c_board_info *info); static int max6650_init_client(struct i2c_client *client); static int max6650_remove(struct i2c_client *client); @@ -528,7 +528,7 @@ static struct attribute_group max6650_attr_grp = { */ /* Return 0 if detection is successful, -ENODEV otherwise */ -static int max6650_detect(struct i2c_client *client, int kind, +static int max6650_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/pcf8591.c b/drivers/hwmon/pcf8591.c index 1d7ffeb..4355aad 100644 --- a/drivers/hwmon/pcf8591.c +++ b/drivers/hwmon/pcf8591.c @@ -169,7 +169,7 @@ static const struct attribute_group pcf8591_attr_group_opt = { */ /* Return 0 if detection is successful, -ENODEV otherwise */ -static int pcf8591_detect(struct i2c_client *client, int kind, +static int pcf8591_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c index 4d88c04..1683fc7 100644 --- a/drivers/hwmon/smsc47m192.c +++ b/drivers/hwmon/smsc47m192.c @@ -115,7 +115,7 @@ struct smsc47m192_data { static int smsc47m192_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int smsc47m192_detect(struct i2c_client *client, int kind, +static int smsc47m192_detect(struct i2c_client *client, struct i2c_board_info *info); static int smsc47m192_remove(struct i2c_client *client); static struct smsc47m192_data *smsc47m192_update_device(struct device *dev); @@ -481,7 +481,7 @@ static void smsc47m192_init_client(struct i2c_client *client) } /* Return 0 if detection is successful, -ENODEV otherwise */ -static int smsc47m192_detect(struct i2c_client *client, int kind, +static int smsc47m192_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index 4b79384..02ac0d4 100644 --- a/drivers/hwmon/thmc50.c +++ b/drivers/hwmon/thmc50.c @@ -84,7 +84,7 @@ struct thmc50_data { u8 alarms; }; -static int thmc50_detect(struct i2c_client *client, int kind, +static int thmc50_detect(struct i2c_client *client, struct i2c_board_info *info); static int thmc50_probe(struct i2c_client *client, const struct i2c_device_id *id); @@ -286,7 +286,7 @@ static const struct attribute_group temp3_group = { }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int thmc50_detect(struct i2c_client *client, int kind, +static int thmc50_detect(struct i2c_client *client, struct i2c_board_info *info) { unsigned company; diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index ee96734..7cf1d54 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c @@ -98,7 +98,7 @@ static const u8 TMP411_TEMP_HIGHEST_LSB[2] = { 0x33, 0x37 }; static int tmp401_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int tmp401_detect(struct i2c_client *client, int kind, +static int tmp401_detect(struct i2c_client *client, struct i2c_board_info *info); static int tmp401_remove(struct i2c_client *client); static struct tmp401_data *tmp401_update_device(struct device *dev); @@ -488,7 +488,7 @@ static void tmp401_init_client(struct i2c_client *client) i2c_smbus_write_byte_data(client, TMP401_CONFIG_WRITE, config); } -static int tmp401_detect(struct i2c_client *client, int _kind, +static int tmp401_detect(struct i2c_client *client, struct i2c_board_info *info) { enum chips kind; diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c index bb5464a..34eb34c 100644 --- a/drivers/hwmon/tmp421.c +++ b/drivers/hwmon/tmp421.c @@ -223,7 +223,7 @@ static int tmp421_init_client(struct i2c_client *client) return 0; } -static int tmp421_detect(struct i2c_client *client, int _kind, +static int tmp421_detect(struct i2c_client *client, struct i2c_board_info *info) { enum chips kind; diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 7ab7967..44704d2 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -1051,8 +1051,7 @@ w83781d_create_files(struct device *dev, int kind, int is_isa) /* Return 0 if detection is successful, -ENODEV otherwise */ static int -w83781d_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info) +w83781d_detect(struct i2c_client *client, struct i2c_board_info *info) { int val1, val2; struct w83781d_data *isa = w83781d_data_if_isa(); diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 0410bf1..b3e91b6 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c @@ -326,7 +326,7 @@ struct w83791d_data { static int w83791d_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int w83791d_detect(struct i2c_client *client, int kind, +static int w83791d_detect(struct i2c_client *client, struct i2c_board_info *info); static int w83791d_remove(struct i2c_client *client); @@ -1259,7 +1259,7 @@ error_sc_0: /* Return 0 if detection is successful, -ENODEV otherwise */ -static int w83791d_detect(struct i2c_client *client, int kind, +static int w83791d_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 3897885..03b836c 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -302,7 +302,7 @@ struct w83792d_data { static int w83792d_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int w83792d_detect(struct i2c_client *client, int kind, +static int w83792d_detect(struct i2c_client *client, struct i2c_board_info *info); static int w83792d_remove(struct i2c_client *client); static struct w83792d_data *w83792d_update_device(struct device *dev); @@ -1263,7 +1263,7 @@ static const struct attribute_group w83792d_group = { /* Return 0 if detection is successful, -ENODEV otherwise */ static int -w83792d_detect(struct i2c_client *client, int kind, struct i2c_board_info *info) +w83792d_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; int val1, val2; diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 80a2191..acf35e6 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -230,7 +230,7 @@ static u8 w83793_read_value(struct i2c_client *client, u16 reg); static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value); static int w83793_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int w83793_detect(struct i2c_client *client, int kind, +static int w83793_detect(struct i2c_client *client, struct i2c_board_info *info); static int w83793_remove(struct i2c_client *client); static void w83793_init_client(struct i2c_client *client); @@ -1161,7 +1161,7 @@ ERROR_SC_0: } /* Return 0 if detection is successful, -ENODEV otherwise */ -static int w83793_detect(struct i2c_client *client, int kind, +static int w83793_detect(struct i2c_client *client, struct i2c_board_info *info) { u8 tmp, bank, chip_id; diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index 9b6c4c1..ec6e4b7 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c @@ -83,7 +83,7 @@ I2C_CLIENT_INSMOD_1(w83l785ts); static int w83l785ts_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int w83l785ts_detect(struct i2c_client *client, int kind, +static int w83l785ts_detect(struct i2c_client *client, struct i2c_board_info *info); static int w83l785ts_remove(struct i2c_client *client); static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval); @@ -146,7 +146,7 @@ static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL, 1); */ /* Return 0 if detection is successful, -ENODEV otherwise */ -static int w83l785ts_detect(struct i2c_client *client, int kind, +static int w83l785ts_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c index 27da7d2..12a5fd6 100644 --- a/drivers/hwmon/w83l786ng.c +++ b/drivers/hwmon/w83l786ng.c @@ -147,7 +147,7 @@ struct w83l786ng_data { static int w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int w83l786ng_detect(struct i2c_client *client, int kind, +static int w83l786ng_detect(struct i2c_client *client, struct i2c_board_info *info); static int w83l786ng_remove(struct i2c_client *client); static void w83l786ng_init_client(struct i2c_client *client); @@ -586,8 +586,7 @@ static const struct attribute_group w83l786ng_group = { }; static int -w83l786ng_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info) +w83l786ng_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; u16 man_id; diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 4f34823..c1047d6 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1184,7 +1184,7 @@ static int i2c_detect_address(struct i2c_client *temp_client, /* Finally call the custom detection function */ memset(&info, 0, sizeof(struct i2c_board_info)); info.addr = addr; - err = driver->detect(temp_client, -1, &info); + err = driver->detect(temp_client, &info); if (err) { /* -ENODEV is returned if the detection fails. We catch it here as this isn't an error. */ diff --git a/drivers/misc/eeprom/eeprom.c b/drivers/misc/eeprom/eeprom.c index 2c27193..2c428f4 100644 --- a/drivers/misc/eeprom/eeprom.c +++ b/drivers/misc/eeprom/eeprom.c @@ -135,8 +135,7 @@ static struct bin_attribute eeprom_attr = { }; /* Return 0 if detection is successful, -ENODEV otherwise */ -static int eeprom_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info) +static int eeprom_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/drivers/misc/ics932s401.c b/drivers/misc/ics932s401.c index 4bb7a3a..75097ec 100644 --- a/drivers/misc/ics932s401.c +++ b/drivers/misc/ics932s401.c @@ -106,7 +106,7 @@ struct ics932s401_data { static int ics932s401_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int ics932s401_detect(struct i2c_client *client, int kind, +static int ics932s401_detect(struct i2c_client *client, struct i2c_board_info *info); static int ics932s401_remove(struct i2c_client *client); @@ -413,7 +413,7 @@ static ssize_t show_spread(struct device *dev, } /* Return 0 if detection is successful, -ENODEV otherwise */ -static int ics932s401_detect(struct i2c_client *client, int kind, +static int ics932s401_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 419ab54..f6f2c08 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -161,7 +161,7 @@ struct i2c_driver { const struct i2c_device_id *id_table; /* Device detection callback for automatic device creation */ - int (*detect)(struct i2c_client *, int kind, struct i2c_board_info *); + int (*detect)(struct i2c_client *, struct i2c_board_info *); const struct i2c_client_address_data *address_data; struct list_head clients; }; -- cgit v0.10.2 From c3813d6af177fab19e322f3114b1f64fbcf08d71 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Dec 2009 21:17:25 +0100 Subject: i2c: Get rid of struct i2c_client_address_data Struct i2c_client_address_data only contains one field at this point, which makes its usefulness questionable. Get rid of it and pass simple address lists around instead. Signed-off-by: Jean Delvare Tested-by: Wolfram Sang diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index 7860aaf..0a74603 100644 --- a/Documentation/i2c/writing-clients +++ b/Documentation/i2c/writing-clients @@ -44,7 +44,7 @@ static struct i2c_driver foo_driver = { /* if device autodetection is needed: */ .class = I2C_CLASS_SOMETHING, .detect = foo_detect, - .address_data = &addr_data, + .address_list = normal_i2c, .shutdown = foo_shutdown, /* optional */ .suspend = foo_suspend, /* optional */ diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index 3ebcdd9..d7af039 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c @@ -130,7 +130,7 @@ static struct i2c_driver adm1021_driver = { .remove = adm1021_remove, .id_table = adm1021_id, .detect = adm1021_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static ssize_t show_temp(struct device *dev, diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index 357c9ff..e176510 100644 --- a/drivers/hwmon/adm1025.c +++ b/drivers/hwmon/adm1025.c @@ -137,7 +137,7 @@ static struct i2c_driver adm1025_driver = { .remove = adm1025_remove, .id_table = adm1025_id, .detect = adm1025_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 8deb17a..85bf23a 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -319,7 +319,7 @@ static struct i2c_driver adm1026_driver = { .remove = adm1026_remove, .id_table = adm1026_id, .detect = adm1026_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static int adm1026_read_value(struct i2c_client *client, u8 reg) diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index 9bc9dbc..a006ae5 100644 --- a/drivers/hwmon/adm1029.c +++ b/drivers/hwmon/adm1029.c @@ -142,7 +142,7 @@ static struct i2c_driver adm1029_driver = { .remove = adm1029_remove, .id_table = adm1029_id, .detect = adm1029_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index cebfbf6..1e02799 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c @@ -125,7 +125,7 @@ static struct i2c_driver adm1031_driver = { .remove = adm1031_remove, .id_table = adm1031_id, .detect = adm1031_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg) diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 9316e07..d9942e7 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c @@ -156,7 +156,7 @@ static struct i2c_driver adm9240_driver = { .remove = adm9240_remove, .id_table = adm9240_id, .detect = adm9240_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* per client data */ diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c index b508931..3827ce4 100644 --- a/drivers/hwmon/ads7828.c +++ b/drivers/hwmon/ads7828.c @@ -183,7 +183,7 @@ static struct i2c_driver ads7828_driver = { .remove = ads7828_remove, .id_table = ads7828_id, .detect = ads7828_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* Return 0 if detection is successful, -ENODEV otherwise */ diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c index 30cf002..3257004 100644 --- a/drivers/hwmon/adt7462.c +++ b/drivers/hwmon/adt7462.c @@ -256,7 +256,7 @@ static struct i2c_driver adt7462_driver = { .remove = adt7462_remove, .id_table = adt7462_id, .detect = adt7462_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index 9ffe5c6..33aa0fa 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c @@ -196,7 +196,7 @@ static struct i2c_driver adt7470_driver = { .remove = adt7470_remove, .id_table = adt7470_id, .detect = adt7470_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c index 78fadaa..1535733 100644 --- a/drivers/hwmon/adt7473.c +++ b/drivers/hwmon/adt7473.c @@ -184,7 +184,7 @@ static struct i2c_driver adt7473_driver = { .remove = adt7473_remove, .id_table = adt7473_id, .detect = adt7473_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c index 3c05715..1fb8940 100644 --- a/drivers/hwmon/adt7475.c +++ b/drivers/hwmon/adt7475.c @@ -1412,7 +1412,7 @@ static struct i2c_driver adt7475_driver = { .remove = adt7475_remove, .id_table = adt7475_id, .detect = adt7475_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static void adt7475_read_hystersis(struct i2c_client *client) diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index 507e116..a92512a 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c @@ -230,7 +230,7 @@ static struct i2c_driver asb100_driver = { .remove = asb100_remove, .id_table = asb100_id, .detect = asb100_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* 7 Voltages */ diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 6b74597..b0c3051 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c @@ -67,7 +67,7 @@ static struct i2c_driver atxp1_driver = { .remove = atxp1_remove, .id_table = atxp1_id, .detect = atxp1_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; struct atxp1_data { diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index 7024617..a3af09f 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c @@ -2318,7 +2318,7 @@ static struct i2c_driver dme1737_i2c_driver = { .remove = dme1737_i2c_remove, .id_table = dme1737_id, .detect = dme1737_i2c_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* --------------------------------------------------------------------- diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index 5fde2f5..dfa4329 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -321,7 +321,7 @@ static struct i2c_driver ds1621_driver = { .remove = ds1621_remove, .id_table = ds1621_id, .detect = ds1621_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static int __init ds1621_init(void) diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index 2ffcf56..f8992c9 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -135,7 +135,7 @@ static struct i2c_driver f75375_driver = { .remove = f75375_remove, .id_table = f75375_id, .detect = f75375_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static inline int f75375_read8(struct i2c_client *client, u8 reg) diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index bce18e0..4eebbbe 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c @@ -251,7 +251,7 @@ static struct i2c_driver fschmd_driver = { .remove = fschmd_remove, .id_table = fschmd_id, .detect = fschmd_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index 34f83c6..e9407ac 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c @@ -162,7 +162,7 @@ static struct i2c_driver gl518_driver = { .remove = gl518_remove, .id_table = gl518_id, .detect = gl518_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index d03ba69..c0ec8c2 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c @@ -104,7 +104,7 @@ static struct i2c_driver gl520_driver = { .remove = gl520_remove, .id_table = gl520_id, .detect = gl520_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* Client data */ diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 26844fc..1426a45 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c @@ -156,7 +156,7 @@ static struct i2c_driver lm63_driver = { .remove = lm63_remove, .id_table = lm63_id, .detect = lm63_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c index e610da9..fb6ab9a 100644 --- a/drivers/hwmon/lm73.c +++ b/drivers/hwmon/lm73.c @@ -182,7 +182,7 @@ static struct i2c_driver lm73_driver = { .remove = lm73_remove, .id_table = lm73_ids, .detect = lm73_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* module glue */ diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index 8fd759d..ce2423c 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -295,7 +295,7 @@ static struct i2c_driver lm75_driver = { .remove = lm75_remove, .id_table = lm75_ids, .detect = lm75_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /*-----------------------------------------------------------------------*/ diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index 6373ab2..b6105e5 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c @@ -91,7 +91,7 @@ static struct i2c_driver lm77_driver = { .remove = lm77_remove, .id_table = lm77_id, .detect = lm77_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* straight from the datasheet */ diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index f58850a..cd6a9ea 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c @@ -173,7 +173,7 @@ static struct i2c_driver lm78_driver = { .remove = lm78_i2c_remove, .id_table = lm78_i2c_id, .detect = lm78_i2c_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static struct platform_driver lm78_isa_driver = { diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index e3222f3..1cf5ff5 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c @@ -159,7 +159,7 @@ static struct i2c_driver lm80_driver = { .remove = lm80_remove, .id_table = lm80_id, .detect = lm80_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index bfb7477..b80ae18 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c @@ -145,7 +145,7 @@ static struct i2c_driver lm83_driver = { .remove = lm83_remove, .id_table = lm83_id, .detect = lm83_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index f5fc45a..d29bd34 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -356,7 +356,7 @@ static struct i2c_driver lm85_driver = { .remove = lm85_remove, .id_table = lm85_id, .detect = lm85_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index d545b85..60d34bc 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c @@ -184,7 +184,7 @@ static struct i2c_driver lm87_driver = { .remove = lm87_remove, .id_table = lm87_id, .detect = lm87_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 3acbaca..3e916ac 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -191,7 +191,7 @@ static struct i2c_driver lm90_driver = { .remove = lm90_remove, .id_table = lm90_id, .detect = lm90_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index da35422..b582b3b 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c @@ -416,7 +416,7 @@ static struct i2c_driver lm92_driver = { .remove = lm92_remove, .id_table = lm92_id, .detect = lm92_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static int __init sensors_lm92_init(void) diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index 7b9c97b..d160dfd 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c @@ -2616,7 +2616,7 @@ static struct i2c_driver lm93_driver = { .remove = lm93_remove, .id_table = lm93_id, .detect = lm93_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static int __init lm93_init(void) diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c index 05ede41..55e3bfd 100644 --- a/drivers/hwmon/lm95241.c +++ b/drivers/hwmon/lm95241.c @@ -460,7 +460,7 @@ static struct i2c_driver lm95241_driver = { .remove = lm95241_remove, .id_table = lm95241_id, .detect = lm95241_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static int __init sensors_lm95241_init(void) diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 4baf94e..94cea29 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c @@ -113,7 +113,7 @@ static struct i2c_driver max1619_driver = { .remove = max1619_remove, .id_table = max1619_id, .detect = max1619_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index fd5d1ac..c7c126c 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c @@ -141,7 +141,7 @@ static struct i2c_driver max6650_driver = { .remove = max6650_remove, .id_table = max6650_id, .detect = max6650_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/pcf8591.c b/drivers/hwmon/pcf8591.c index 4355aad..c19e61b 100644 --- a/drivers/hwmon/pcf8591.c +++ b/drivers/hwmon/pcf8591.c @@ -299,7 +299,7 @@ static struct i2c_driver pcf8591_driver = { .class = I2C_CLASS_HWMON, /* Nearest choice */ .detect = pcf8591_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static int __init pcf8591_init(void) diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c index 1683fc7..34df2e2 100644 --- a/drivers/hwmon/smsc47m192.c +++ b/drivers/hwmon/smsc47m192.c @@ -135,7 +135,7 @@ static struct i2c_driver smsc47m192_driver = { .remove = smsc47m192_remove, .id_table = smsc47m192_id, .detect = smsc47m192_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* Voltages */ diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index 02ac0d4..866d665 100644 --- a/drivers/hwmon/thmc50.c +++ b/drivers/hwmon/thmc50.c @@ -108,7 +108,7 @@ static struct i2c_driver thmc50_driver = { .remove = thmc50_remove, .id_table = thmc50_id, .detect = thmc50_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static ssize_t show_analog_out(struct device *dev, diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index 7cf1d54..ed08649 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c @@ -123,7 +123,7 @@ static struct i2c_driver tmp401_driver = { .remove = tmp401_remove, .id_table = tmp401_id, .detect = tmp401_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c index 34eb34c..018ad02 100644 --- a/drivers/hwmon/tmp421.c +++ b/drivers/hwmon/tmp421.c @@ -322,7 +322,7 @@ static struct i2c_driver tmp421_driver = { .remove = tmp421_remove, .id_table = tmp421_id, .detect = tmp421_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static int __init tmp421_init(void) diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 44704d2..bfaa888 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -1536,7 +1536,7 @@ static struct i2c_driver w83781d_driver = { .remove = w83781d_remove, .id_table = w83781d_ids, .detect = w83781d_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index b3e91b6..e059cf0 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c @@ -355,7 +355,7 @@ static struct i2c_driver w83791d_driver = { .remove = w83791d_remove, .id_table = w83791d_id, .detect = w83791d_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* following are the sysfs callback functions */ diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 03b836c..c6f198a 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -328,7 +328,7 @@ static struct i2c_driver w83792d_driver = { .remove = w83792d_remove, .id_table = w83792d_id, .detect = w83792d_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static inline long in_count_from_reg(int nr, struct w83792d_data *data) diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index acf35e6..ed32b18 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -252,7 +252,7 @@ static struct i2c_driver w83793_driver = { .remove = w83793_remove, .id_table = w83793_id, .detect = w83793_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static ssize_t diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index ec6e4b7..81c5993 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c @@ -108,7 +108,7 @@ static struct i2c_driver w83l785ts_driver = { .remove = w83l785ts_remove, .id_table = w83l785ts_id, .detect = w83l785ts_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c index 12a5fd6..a427347 100644 --- a/drivers/hwmon/w83l786ng.c +++ b/drivers/hwmon/w83l786ng.c @@ -168,7 +168,7 @@ static struct i2c_driver w83l786ng_driver = { .remove = w83l786ng_remove, .id_table = w83l786ng_id, .detect = w83l786ng_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static u8 diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index c1047d6..9065c72 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1214,13 +1214,13 @@ static int i2c_detect_address(struct i2c_client *temp_client, static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver) { - const struct i2c_client_address_data *address_data; + const unsigned short *address_list; struct i2c_client *temp_client; int i, err = 0; int adap_id = i2c_adapter_id(adapter); - address_data = driver->address_data; - if (!driver->detect || !address_data) + address_list = driver->address_list; + if (!driver->detect || !address_list) return 0; /* Set up a temporary client to help detect callback */ @@ -1235,7 +1235,7 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver) /* Stop here if we can't use SMBUS_QUICK */ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) { - if (address_data->normal_i2c[0] == I2C_CLIENT_END) + if (address_list[0] == I2C_CLIENT_END) goto exit_free; dev_warn(&adapter->dev, "SMBus Quick command not supported, " @@ -1244,11 +1244,10 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver) goto exit_free; } - for (i = 0; address_data->normal_i2c[i] != I2C_CLIENT_END; i += 1) { + for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) { dev_dbg(&adapter->dev, "found normal entry for adapter %d, " - "addr 0x%02x\n", adap_id, - address_data->normal_i2c[i]); - temp_client->addr = address_data->normal_i2c[i]; + "addr 0x%02x\n", adap_id, address_list[i]); + temp_client->addr = address_list[i]; err = i2c_detect_address(temp_client, driver); if (err) goto exit_free; diff --git a/drivers/misc/eeprom/eeprom.c b/drivers/misc/eeprom/eeprom.c index 2c428f4..3dc5e3d 100644 --- a/drivers/misc/eeprom/eeprom.c +++ b/drivers/misc/eeprom/eeprom.c @@ -232,7 +232,7 @@ static struct i2c_driver eeprom_driver = { .class = I2C_CLASS_DDC | I2C_CLASS_SPD, .detect = eeprom_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static int __init eeprom_init(void) diff --git a/drivers/misc/ics932s401.c b/drivers/misc/ics932s401.c index 75097ec..d8a8471 100644 --- a/drivers/misc/ics932s401.c +++ b/drivers/misc/ics932s401.c @@ -125,7 +125,7 @@ static struct i2c_driver ics932s401_driver = { .remove = ics932s401_remove, .id_table = ics932s401_id, .detect = ics932s401_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; static struct ics932s401_data *ics932s401_update_device(struct device *dev) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index f6f2c08..fb9df14 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -110,7 +110,7 @@ extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, * @driver: Device driver model driver * @id_table: List of I2C devices supported by this driver * @detect: Callback for device detection - * @address_data: The I2C addresses to probe (for detect) + * @address_list: The I2C addresses to probe (for detect) * @clients: List of detected clients we created (for i2c-core use only) * * The driver.owner field should be set to the module owner of this driver. @@ -162,7 +162,7 @@ struct i2c_driver { /* Device detection callback for automatic device creation */ int (*detect)(struct i2c_client *, struct i2c_board_info *); - const struct i2c_client_address_data *address_data; + const unsigned short *address_list; struct list_head clients; }; #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) @@ -391,14 +391,6 @@ static inline void i2c_unlock_adapter(struct i2c_adapter *adapter) #define I2C_CLASS_DDC (1<<3) /* DDC bus on graphics adapters */ #define I2C_CLASS_SPD (1<<7) /* SPD EEPROMs and similar */ -/* i2c_client_address_data is the struct for holding default client - * addresses for a driver and for the parameters supplied on the - * command line - */ -struct i2c_client_address_data { - const unsigned short *normal_i2c; -}; - /* Internal numbers to terminate lists */ #define I2C_CLIENT_END 0xfffeU @@ -610,48 +602,34 @@ union i2c_smbus_data { module_param_array(var, short, &var##_num, 0); \ MODULE_PARM_DESC(var, desc) -#define I2C_CLIENT_INSMOD_COMMON \ -static const struct i2c_client_address_data addr_data = { \ - .normal_i2c = normal_i2c, \ -} - /* These are the ones you want to use in your own drivers. Pick the one which matches the number of devices the driver differenciates between. */ -#define I2C_CLIENT_INSMOD \ -I2C_CLIENT_INSMOD_COMMON +#define I2C_CLIENT_INSMOD #define I2C_CLIENT_INSMOD_1(chip1) \ -enum chips { any_chip, chip1 }; \ -I2C_CLIENT_INSMOD_COMMON +enum chips { any_chip, chip1 } #define I2C_CLIENT_INSMOD_2(chip1, chip2) \ -enum chips { any_chip, chip1, chip2 }; \ -I2C_CLIENT_INSMOD_COMMON +enum chips { any_chip, chip1, chip2 } #define I2C_CLIENT_INSMOD_3(chip1, chip2, chip3) \ -enum chips { any_chip, chip1, chip2, chip3 }; \ -I2C_CLIENT_INSMOD_COMMON +enum chips { any_chip, chip1, chip2, chip3 } #define I2C_CLIENT_INSMOD_4(chip1, chip2, chip3, chip4) \ -enum chips { any_chip, chip1, chip2, chip3, chip4 }; \ -I2C_CLIENT_INSMOD_COMMON +enum chips { any_chip, chip1, chip2, chip3, chip4 } #define I2C_CLIENT_INSMOD_5(chip1, chip2, chip3, chip4, chip5) \ -enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 }; \ -I2C_CLIENT_INSMOD_COMMON +enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 } #define I2C_CLIENT_INSMOD_6(chip1, chip2, chip3, chip4, chip5, chip6) \ -enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 }; \ -I2C_CLIENT_INSMOD_COMMON +enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 } #define I2C_CLIENT_INSMOD_7(chip1, chip2, chip3, chip4, chip5, chip6, chip7) \ enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ - chip7 }; \ -I2C_CLIENT_INSMOD_COMMON + chip7 } #define I2C_CLIENT_INSMOD_8(chip1, chip2, chip3, chip4, chip5, chip6, chip7, chip8) \ enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ - chip7, chip8 }; \ -I2C_CLIENT_INSMOD_COMMON + chip7, chip8 } #endif /* __KERNEL__ */ #endif /* _LINUX_I2C_H */ -- cgit v0.10.2 From 1f86df49ddfd0067cce941187d57b2fd2f749a9e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Dec 2009 21:17:26 +0100 Subject: i2c: Drop I2C_CLIENT_INSMOD_1 This macro simply declares an enum, so drivers might as well declare it themselves. Signed-off-by: Jean Delvare Tested-by: Wolfram Sang diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 85bf23a..65335b2 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -37,9 +37,6 @@ /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(adm1026); - static int gpio_input[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; static int gpio_output[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -305,7 +302,7 @@ static void adm1026_init_client(struct i2c_client *client); static const struct i2c_device_id adm1026_id[] = { - { "adm1026", adm1026 }, + { "adm1026", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, adm1026_id); diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index a006ae5..0b8a3b1 100644 --- a/drivers/hwmon/adm1029.c +++ b/drivers/hwmon/adm1029.c @@ -44,12 +44,6 @@ static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, }; /* - * Insmod parameters - */ - -I2C_CLIENT_INSMOD_1(adm1029); - -/* * The ADM1029 registers * Manufacturer ID is 0x41 for Analog Devices */ @@ -128,7 +122,7 @@ static int adm1029_init_client(struct i2c_client *client); */ static const struct i2c_device_id adm1029_id[] = { - { "adm1029", adm1029 }, + { "adm1029", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, adm1029_id); diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c index 3827ce4..aac85f3 100644 --- a/drivers/hwmon/ads7828.c +++ b/drivers/hwmon/ads7828.c @@ -47,10 +47,7 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(ads7828); - -/* Other module parameters */ +/* Module parameters */ static int se_input = 1; /* Default is SE, 0 == diff */ static int int_vref = 1; /* Default is internal ref ON */ static int vref_mv = ADS7828_INT_VREF_MV; /* set if vref != 2.5V */ @@ -168,7 +165,7 @@ static int ads7828_remove(struct i2c_client *client) } static const struct i2c_device_id ads7828_id[] = { - { "ads7828", ads7828 }, + { "ads7828", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, ads7828_id); diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c index 3257004..a1a7ef1 100644 --- a/drivers/hwmon/adt7462.c +++ b/drivers/hwmon/adt7462.c @@ -32,9 +32,6 @@ /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(adt7462); - /* ADT7462 registers */ #define ADT7462_REG_DEVICE 0x3D #define ADT7462_REG_VENDOR 0x3E @@ -242,7 +239,7 @@ static int adt7462_detect(struct i2c_client *client, static int adt7462_remove(struct i2c_client *client); static const struct i2c_device_id adt7462_id[] = { - { "adt7462", adt7462 }, + { "adt7462", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, adt7462_id); diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index 33aa0fa..3445ce1 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c @@ -33,9 +33,6 @@ /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(adt7470); - /* ADT7470 registers */ #define ADT7470_REG_BASE_ADDR 0x20 #define ADT7470_REG_TEMP_BASE_ADDR 0x20 @@ -182,7 +179,7 @@ static int adt7470_detect(struct i2c_client *client, static int adt7470_remove(struct i2c_client *client); static const struct i2c_device_id adt7470_id[] = { - { "adt7470", adt7470 }, + { "adt7470", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, adt7470_id); diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c index 1535733..434576f 100644 --- a/drivers/hwmon/adt7473.c +++ b/drivers/hwmon/adt7473.c @@ -32,9 +32,6 @@ /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(adt7473); - /* ADT7473 registers */ #define ADT7473_REG_BASE_ADDR 0x20 @@ -171,7 +168,7 @@ static int adt7473_detect(struct i2c_client *client, static int adt7473_remove(struct i2c_client *client); static const struct i2c_device_id adt7473_id[] = { - { "adt7473", adt7473 }, + { "adt7473", 0 }, { } }; diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index a92512a..7dada55 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c @@ -51,9 +51,6 @@ /* I2C addresses to scan */ static const unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(asb100); - static unsigned short force_subclients[4]; module_param_array(force_subclients, short, NULL, 0); MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " @@ -216,7 +213,7 @@ static struct asb100_data *asb100_update_device(struct device *dev); static void asb100_init_client(struct i2c_client *client); static const struct i2c_device_id asb100_id[] = { - { "asb100", asb100 }, + { "asb100", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, asb100_id); diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index b0c3051..94cadc1 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c @@ -44,8 +44,6 @@ MODULE_AUTHOR("Sebastian Witt "); static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END }; -I2C_CLIENT_INSMOD_1(atxp1); - static int atxp1_probe(struct i2c_client *client, const struct i2c_device_id *id); static int atxp1_remove(struct i2c_client *client); @@ -53,7 +51,7 @@ static struct atxp1_data * atxp1_update_device(struct device *dev); static int atxp1_detect(struct i2c_client *client, struct i2c_board_info *info); static const struct i2c_device_id atxp1_id[] = { - { "atxp1", atxp1 }, + { "atxp1", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, atxp1_id); diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index dfa4329..e113634 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -38,7 +38,6 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; /* Insmod parameters */ -I2C_CLIENT_INSMOD_1(ds1621); static int polarity = -1; module_param(polarity, int, 0); MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low"); @@ -305,8 +304,8 @@ static int ds1621_remove(struct i2c_client *client) } static const struct i2c_device_id ds1621_id[] = { - { "ds1621", ds1621 }, - { "ds1625", ds1621 }, + { "ds1621", 0 }, + { "ds1625", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, ds1621_id); diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index c0ec8c2..ec58802 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c @@ -41,9 +41,6 @@ MODULE_PARM_DESC(extra_sensor_type, "Type of extra sensor (0=autodetect, 1=tempe /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(gl520sm); - /* Many GL520 constants specified below One of the inputs can be configured as either temp or voltage. That's why _TEMP2 and _IN4 access the same register @@ -90,7 +87,7 @@ static struct gl520_data *gl520_update_device(struct device *dev); /* Driver data */ static const struct i2c_device_id gl520_id[] = { - { "gl520sm", gl520sm }, + { "gl520sm", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, gl520_id); diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 1426a45..bf81aff 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c @@ -56,12 +56,6 @@ static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END }; /* - * Insmod parameters - */ - -I2C_CLIENT_INSMOD_1(lm63); - -/* * The LM63 registers */ @@ -142,7 +136,7 @@ static void lm63_init_client(struct i2c_client *client); */ static const struct i2c_device_id lm63_id[] = { - { "lm63", lm63 }, + { "lm63", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, lm63_id); diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c index fb6ab9a..c5f39ba 100644 --- a/drivers/hwmon/lm73.c +++ b/drivers/hwmon/lm73.c @@ -27,9 +27,6 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(lm73); - /* LM73 registers */ #define LM73_REG_INPUT 0x00 #define LM73_REG_CONF 0x01 @@ -145,7 +142,7 @@ static int lm73_remove(struct i2c_client *client) } static const struct i2c_device_id lm73_ids[] = { - { "lm73", lm73 }, + { "lm73", 0 }, { /* LIST END */ } }; MODULE_DEVICE_TABLE(i2c, lm73_ids); diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index ce2423c..8ae2cfe 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -32,15 +32,12 @@ /* * This driver handles the LM75 and compatible digital temperature sensors. - * Only types which are _not_ listed in I2C_CLIENT_INSMOD_*() need to be - * listed here. We start at 9 since I2C_CLIENT_INSMOD_*() currently allow - * definition of up to 8 chip types (plus zero). */ enum lm75_type { /* keep sorted in alphabetical order */ - ds1775 = 9, + ds1775, ds75, - /* lm75 -- in I2C_CLIENT_INSMOD_1() */ + lm75, lm75a, max6625, max6626, @@ -58,9 +55,6 @@ enum lm75_type { /* keep sorted in alphabetical order */ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(lm75); - /* The LM75 registers */ #define LM75_REG_CONF 0x01 diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index b6105e5..b28a297 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c @@ -39,9 +39,6 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(lm77); - /* The LM77 registers */ #define LM77_REG_TEMP 0x00 #define LM77_REG_CONF 0x01 @@ -76,7 +73,7 @@ static struct lm77_data *lm77_update_device(struct device *dev); static const struct i2c_device_id lm77_id[] = { - { "lm77", lm77 }, + { "lm77", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, lm77_id); diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index 1cf5ff5..18a0e6c 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c @@ -35,9 +35,6 @@ static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(lm80); - /* Many LM80 constants specified below */ /* The LM80 registers */ @@ -145,7 +142,7 @@ static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value); */ static const struct i2c_device_id lm80_id[] = { - { "lm80", lm80 }, + { "lm80", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, lm80_id); diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index b582b3b..7c31e62 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c @@ -54,9 +54,6 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(lm92); - /* The LM92 registers */ #define LM92_REG_CONFIG 0x01 /* 8-bit, RW */ #define LM92_REG_TEMP 0x00 /* 16-bit, RO */ @@ -401,7 +398,7 @@ static int lm92_remove(struct i2c_client *client) */ static const struct i2c_device_id lm92_id[] = { - { "lm92", lm92 }, + { "lm92", 0 }, /* max6635 could be added here */ { } }; diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index d160dfd..6669255 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c @@ -145,7 +145,6 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ -I2C_CLIENT_INSMOD_1(lm93); static int disable_block; module_param(disable_block, bool, 0); @@ -2602,7 +2601,7 @@ static int lm93_remove(struct i2c_client *client) } static const struct i2c_device_id lm93_id[] = { - { "lm93", lm93 }, + { "lm93", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, lm93_id); diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c index 55e3bfd..8fc8eb8 100644 --- a/drivers/hwmon/lm95241.c +++ b/drivers/hwmon/lm95241.c @@ -39,9 +39,6 @@ static const unsigned short normal_i2c[] = { 0x19, 0x2a, 0x2b, I2C_CLIENT_END}; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(lm95241); - /* LM95241 registers */ #define LM95241_REG_R_MAN_ID 0xFE #define LM95241_REG_R_CHIP_ID 0xFF @@ -446,7 +443,7 @@ static struct lm95241_data *lm95241_update_device(struct device *dev) /* Driver data (common to all clients) */ static const struct i2c_device_id lm95241_id[] = { - { "lm95241", lm95241 }, + { "lm95241", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, lm95241_id); diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 94cea29..022ded0 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c @@ -41,12 +41,6 @@ static const unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; /* - * Insmod parameters - */ - -I2C_CLIENT_INSMOD_1(max1619); - -/* * The MAX1619 registers */ @@ -99,7 +93,7 @@ static struct max1619_data *max1619_update_device(struct device *dev); */ static const struct i2c_device_id max1619_id[] = { - { "max1619", max1619 }, + { "max1619", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, max1619_id); diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index c7c126c..a0160ee 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c @@ -62,8 +62,6 @@ module_param(fan_voltage, int, S_IRUGO); module_param(prescaler, int, S_IRUGO); module_param(clock, int, S_IRUGO); -I2C_CLIENT_INSMOD_1(max6650); - /* * MAX 6650/6651 registers */ @@ -127,7 +125,7 @@ static struct max6650_data *max6650_update_device(struct device *dev); */ static const struct i2c_device_id max6650_id[] = { - { "max6650", max6650 }, + { "max6650", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, max6650_id); diff --git a/drivers/hwmon/pcf8591.c b/drivers/hwmon/pcf8591.c index c19e61b..d4478794 100644 --- a/drivers/hwmon/pcf8591.c +++ b/drivers/hwmon/pcf8591.c @@ -29,7 +29,6 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; /* Insmod parameters */ -I2C_CLIENT_INSMOD_1(pcf8591); static int input_mode; module_param(input_mode, int, 0); diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c index 34df2e2..40b2667 100644 --- a/drivers/hwmon/smsc47m192.c +++ b/drivers/hwmon/smsc47m192.c @@ -36,9 +36,6 @@ /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(smsc47m192); - /* SMSC47M192 registers */ #define SMSC47M192_REG_IN(nr) ((nr)<6 ? (0x20 + (nr)) : \ (0x50 + (nr) - 6)) @@ -121,7 +118,7 @@ static int smsc47m192_remove(struct i2c_client *client); static struct smsc47m192_data *smsc47m192_update_device(struct device *dev); static const struct i2c_device_id smsc47m192_id[] = { - { "smsc47m192", smsc47m192 }, + { "smsc47m192", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, smsc47m192_id); diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index e059cf0..400a88b 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c @@ -52,7 +52,6 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; /* Insmod parameters */ -I2C_CLIENT_INSMOD_1(w83791d); static unsigned short force_subclients[4]; module_param_array(force_subclients, short, NULL, 0); @@ -341,7 +340,7 @@ static void w83791d_print_debug(struct w83791d_data *data, struct device *dev); static void w83791d_init_client(struct i2c_client *client); static const struct i2c_device_id w83791d_id[] = { - { "w83791d", w83791d }, + { "w83791d", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, w83791d_id); diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index c6f198a..679718e 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -50,7 +50,6 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; /* Insmod parameters */ -I2C_CLIENT_INSMOD_1(w83792d); static unsigned short force_subclients[4]; module_param_array(force_subclients, short, NULL, 0); @@ -314,7 +313,7 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev); static void w83792d_init_client(struct i2c_client *client); static const struct i2c_device_id w83792d_id[] = { - { "w83792d", w83792d }, + { "w83792d", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, w83792d_id); diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index ed32b18..9a2022b 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -41,7 +41,6 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; /* Insmod parameters */ -I2C_CLIENT_INSMOD_1(w83793); static unsigned short force_subclients[4]; module_param_array(force_subclients, short, NULL, 0); @@ -238,7 +237,7 @@ static void w83793_update_nonvolatile(struct device *dev); static struct w83793_data *w83793_update_device(struct device *dev); static const struct i2c_device_id w83793_id[] = { - { "w83793", w83793 }, + { "w83793", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, w83793_id); diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index 81c5993..20781de 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c @@ -52,12 +52,6 @@ static const unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END }; /* - * Insmod parameters - */ - -I2C_CLIENT_INSMOD_1(w83l785ts); - -/* * The W83L785TS-S registers * Manufacturer ID is 0x5CA3 for Winbond. */ @@ -94,7 +88,7 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev); */ static const struct i2c_device_id w83l785ts_id[] = { - { "w83l785ts", w83l785ts }, + { "w83l785ts", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, w83l785ts_id); diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c index a427347..0254e18 100644 --- a/drivers/hwmon/w83l786ng.c +++ b/drivers/hwmon/w83l786ng.c @@ -38,7 +38,6 @@ static const unsigned short normal_i2c[] = { 0x2e, 0x2f, I2C_CLIENT_END }; /* Insmod parameters */ -I2C_CLIENT_INSMOD_1(w83l786ng); static int reset; module_param(reset, bool, 0); @@ -154,7 +153,7 @@ static void w83l786ng_init_client(struct i2c_client *client); static struct w83l786ng_data *w83l786ng_update_device(struct device *dev); static const struct i2c_device_id w83l786ng_id[] = { - { "w83l786ng", w83l786ng }, + { "w83l786ng", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, w83l786ng_id); diff --git a/drivers/misc/eeprom/eeprom.c b/drivers/misc/eeprom/eeprom.c index 3dc5e3d..f939ebc 100644 --- a/drivers/misc/eeprom/eeprom.c +++ b/drivers/misc/eeprom/eeprom.c @@ -32,9 +32,6 @@ static const unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(eeprom); - /* Size of EEPROM in bytes */ #define EEPROM_SIZE 256 diff --git a/drivers/misc/ics932s401.c b/drivers/misc/ics932s401.c index d8a8471..395a4ea 100644 --- a/drivers/misc/ics932s401.c +++ b/drivers/misc/ics932s401.c @@ -30,9 +30,6 @@ /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x69, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(ics932s401); - /* ICS932S401 registers */ #define ICS932S401_REG_CFG2 0x01 #define ICS932S401_CFG1_SPREAD 0x01 @@ -111,7 +108,7 @@ static int ics932s401_detect(struct i2c_client *client, static int ics932s401_remove(struct i2c_client *client); static const struct i2c_device_id ics932s401_id[] = { - { "ics932s401", ics932s401 }, + { "ics932s401", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, ics932s401_id); diff --git a/include/linux/i2c.h b/include/linux/i2c.h index fb9df14..7178b27 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -604,11 +604,6 @@ union i2c_smbus_data { /* These are the ones you want to use in your own drivers. Pick the one which matches the number of devices the driver differenciates between. */ -#define I2C_CLIENT_INSMOD - -#define I2C_CLIENT_INSMOD_1(chip1) \ -enum chips { any_chip, chip1 } - #define I2C_CLIENT_INSMOD_2(chip1, chip2) \ enum chips { any_chip, chip1, chip2 } -- cgit v0.10.2 From e5e9f44c246fbafe723e579e9fe887677beb40e4 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Dec 2009 21:17:27 +0100 Subject: i2c: Drop I2C_CLIENT_INSMOD_2 to 8 These macros simply declare an enum, so drivers might as well declare it themselves. This puts an end to the arbitrary limit of 8 chip types per i2c driver. Signed-off-by: Jean Delvare Tested-by: Wolfram Sang diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index d7af039..1ad0a88 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c @@ -34,9 +34,8 @@ static const unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, - mc1066); +enum chips { + adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, mc1066 }; /* adm1021 constants specified below */ diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index e176510..251b631 100644 --- a/drivers/hwmon/adm1025.c +++ b/drivers/hwmon/adm1025.c @@ -64,11 +64,7 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; -/* - * Insmod parameters - */ - -I2C_CLIENT_INSMOD_2(adm1025, ne1619); +enum chips { adm1025, ne1619 }; /* * The ADM1025 registers diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 1e02799..1644b92 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c @@ -64,8 +64,7 @@ /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_2(adm1030, adm1031); +enum chips { adm1030, adm1031 }; typedef u8 auto_chan_table_t[8][2]; diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index d9942e7..0727ad2 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c @@ -55,8 +55,7 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_3(adm9240, ds1780, lm81); +enum chips { adm9240, ds1780, lm81 }; /* ADM9240 registers */ #define ADM9240_REG_MAN_ID 0x3e diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c index 1fb8940..a0c3851 100644 --- a/drivers/hwmon/adt7475.c +++ b/drivers/hwmon/adt7475.c @@ -148,7 +148,7 @@ static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; -I2C_CLIENT_INSMOD_4(adt7473, adt7475, adt7476, adt7490); +enum chips { adt7473, adt7475, adt7476, adt7490 }; static const struct i2c_device_id adt7475_id[] = { { "adt7473", adt7473 }, diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index a3af09f..823dd28 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c @@ -57,11 +57,7 @@ MODULE_PARM_DESC(probe_all_addr, "Include probing of non-standard LPC " /* Addresses to scan */ static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_2(dme1737, sch5027); - -/* ISA chip types */ -enum isa_chips { sch311x = sch5027 + 1 }; +enum chips { dme1737, sch5027, sch311x }; /* --------------------------------------------------------------------- * Registers diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index f8992c9..277398f 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -39,8 +39,7 @@ /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_2(f75373, f75375); +enum chips { f75373, f75375 }; /* Fintek F75375 registers */ #define F75375_REG_CONFIG0 0x0 diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index 4eebbbe..bd0fc67 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c @@ -56,7 +56,8 @@ static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -I2C_CLIENT_INSMOD_7(fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl); + +enum chips { fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl }; /* * The FSCHMD registers and other defines diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index e9407ac..e7ae574 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c @@ -46,8 +46,7 @@ /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_2(gl518sm_r00, gl518sm_r80); +enum chips { gl518sm_r00, gl518sm_r80 }; /* Many GL518 constants specified below */ diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index cd6a9ea..cadcbd9 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c @@ -41,8 +41,7 @@ static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; static unsigned short isa_address = 0x290; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_2(lm78, lm79); +enum chips { lm78, lm79 }; /* Many LM78 constants specified below */ diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index b80ae18..8290476 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c @@ -51,11 +51,7 @@ static const unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; -/* - * Insmod parameters - */ - -I2C_CLIENT_INSMOD_2(lm83, lm82); +enum chips { lm83, lm82 }; /* * The LM83 registers diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index d29bd34..b3841a6 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -38,9 +38,11 @@ /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_7(lm85b, lm85c, adm1027, adt7463, adt7468, emc6d100, - emc6d102); +enum chips { + any_chip, lm85b, lm85c, + adm1027, adt7463, adt7468, + emc6d100, emc6d102 +}; /* The LM85 registers */ diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index 60d34bc..f1e6e75 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c @@ -74,11 +74,7 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; -/* - * Insmod parameters - */ - -I2C_CLIENT_INSMOD_2(lm87, adm1024); +enum chips { lm87, adm1024 }; /* * The LM87 registers diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 3e916ac..7c9bdc1 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -93,12 +93,7 @@ static const unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; -/* - * Insmod parameters - */ - -I2C_CLIENT_INSMOD_8(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680, - max6646); +enum chips { lm90, adm1032, lm99, lm86, max6657, adt7461, max6680, max6646 }; /* * The LM90 registers diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index 866d665..7dfb4de 100644 --- a/drivers/hwmon/thmc50.c +++ b/drivers/hwmon/thmc50.c @@ -35,7 +35,7 @@ MODULE_LICENSE("GPL"); static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ -I2C_CLIENT_INSMOD_2(thmc50, adm1022); +enum chips { thmc50, adm1022 }; static unsigned short adm1022_temp3[16]; static unsigned int adm1022_temp3_num; diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index ed08649..a13b30e 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c @@ -42,8 +42,7 @@ /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_2(tmp401, tmp411); +enum chips { tmp401, tmp411 }; /* * The TMP401 registers, note some registers have different addresses for diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c index 018ad02..4f7c051 100644 --- a/drivers/hwmon/tmp421.c +++ b/drivers/hwmon/tmp421.c @@ -39,8 +39,7 @@ static unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_3(tmp421, tmp422, tmp423); +enum chips { tmp421, tmp422, tmp423 }; /* The TMP421 registers */ #define TMP421_CONFIG_REG_1 0x09 diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index bfaa888..05f9225 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -56,9 +56,10 @@ /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_4(w83781d, w83782d, w83783s, as99127f); +enum chips { w83781d, w83782d, w83783s, as99127f }; + +/* Insmod parameters */ static unsigned short force_subclients[4]; module_param_array(force_subclients, short, NULL, 0); MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 7178b27..cc6e150 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -602,29 +602,5 @@ union i2c_smbus_data { module_param_array(var, short, &var##_num, 0); \ MODULE_PARM_DESC(var, desc) -/* These are the ones you want to use in your own drivers. Pick the one - which matches the number of devices the driver differenciates between. */ -#define I2C_CLIENT_INSMOD_2(chip1, chip2) \ -enum chips { any_chip, chip1, chip2 } - -#define I2C_CLIENT_INSMOD_3(chip1, chip2, chip3) \ -enum chips { any_chip, chip1, chip2, chip3 } - -#define I2C_CLIENT_INSMOD_4(chip1, chip2, chip3, chip4) \ -enum chips { any_chip, chip1, chip2, chip3, chip4 } - -#define I2C_CLIENT_INSMOD_5(chip1, chip2, chip3, chip4, chip5) \ -enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 } - -#define I2C_CLIENT_INSMOD_6(chip1, chip2, chip3, chip4, chip5, chip6) \ -enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 } - -#define I2C_CLIENT_INSMOD_7(chip1, chip2, chip3, chip4, chip5, chip6, chip7) \ -enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ - chip7 } - -#define I2C_CLIENT_INSMOD_8(chip1, chip2, chip3, chip4, chip5, chip6, chip7, chip8) \ -enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ - chip7, chip8 } #endif /* __KERNEL__ */ #endif /* _LINUX_I2C_H */ -- cgit v0.10.2 From 7f508118b1c1f9856a1c899a2bd4867a962b0225 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Dec 2009 21:17:29 +0100 Subject: i2c: Get rid of I2C_CLIENT_MODULE_PARM There is no user left of I2C_CLIENT_MODULE_PARM, so we can finally get rid of this ugly macro. Signed-off-by: Jean Delvare Tested-by: Wolfram Sang diff --git a/include/linux/i2c.h b/include/linux/i2c.h index cc6e150..02fc617 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -568,39 +568,4 @@ union i2c_smbus_data { #define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ #define I2C_SMBUS_I2C_BLOCK_DATA 8 - -#ifdef __KERNEL__ - -/* These defines are used for probing i2c client addresses */ -/* The length of the option lists */ -#define I2C_CLIENT_MAX_OPTS 48 - -/* Default fill of many variables */ -#define I2C_CLIENT_DEFAULTS {I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END} - -/* I2C_CLIENT_MODULE_PARM creates a module parameter, and puts it in the - module header */ - -#define I2C_CLIENT_MODULE_PARM(var,desc) \ - static unsigned short var[I2C_CLIENT_MAX_OPTS] = I2C_CLIENT_DEFAULTS; \ - static unsigned int var##_num; \ - module_param_array(var, short, &var##_num, 0); \ - MODULE_PARM_DESC(var, desc) - -#endif /* __KERNEL__ */ #endif /* _LINUX_I2C_H */ -- cgit v0.10.2 From 54067ee20645a4ee12a9546aeb3b048b4c44cf60 Mon Sep 17 00:00:00 2001 From: sonic zhang Date: Mon, 14 Dec 2009 21:17:30 +0100 Subject: i2c-core: i2c bus should support PM entries in struct dev_pm_ops Struct dev_pm_ops is not configured in current i2c bus type. i2c drivers only depends on suspend/resume entries in struct dev_pm_ops are not informed of PM suspend and resume events by i2c framework. Signed-off-by: Sonic Zhang Signed-off-by: Jean Delvare diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 9065c72..0ac2f90 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -155,6 +155,35 @@ static void i2c_device_shutdown(struct device *dev) driver->shutdown(client); } +#ifdef CONFIG_SUSPEND +static int i2c_device_pm_suspend(struct device *dev) +{ + const struct dev_pm_ops *pm; + + if (!dev->driver) + return 0; + pm = dev->driver->pm; + if (!pm || !pm->suspend) + return 0; + return pm->suspend(dev); +} + +static int i2c_device_pm_resume(struct device *dev) +{ + const struct dev_pm_ops *pm; + + if (!dev->driver) + return 0; + pm = dev->driver->pm; + if (!pm || !pm->resume) + return 0; + return pm->resume(dev); +} +#else +#define i2c_device_pm_suspend NULL +#define i2c_device_pm_resume NULL +#endif + static int i2c_device_suspend(struct device *dev, pm_message_t mesg) { struct i2c_client *client = i2c_verify_client(dev); @@ -219,6 +248,11 @@ static const struct attribute_group *i2c_dev_attr_groups[] = { NULL }; +const static struct dev_pm_ops i2c_device_pm_ops = { + .suspend = i2c_device_pm_suspend, + .resume = i2c_device_pm_resume, +}; + struct bus_type i2c_bus_type = { .name = "i2c", .match = i2c_device_match, @@ -227,6 +261,7 @@ struct bus_type i2c_bus_type = { .shutdown = i2c_device_shutdown, .suspend = i2c_device_suspend, .resume = i2c_device_resume, + .pm = &i2c_device_pm_ops, }; EXPORT_SYMBOL_GPL(i2c_bus_type); -- cgit v0.10.2 From 873b5271f878a11729fb4602c6ce967d0ff81119 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 14 Dec 2009 13:55:20 -0800 Subject: x86: Regex support and known-movable symbols for relocs, fix _end This adds a new category of symbols to the relocs program: symbols which are known to be relative, even though the linker emits them as absolute; this is the case for symbols that live in the linker script, which currently applies to _end. Unfortunately the previous workaround of putting _end in its own empty section was defeated by newer binutils, which remove empty sections completely. This patch also changes the symbol matching to use regular expressions instead of hardcoded C for specific patterns. This is a decidedly non-minimal patch: a modified version of the relocs program is used as part of the Syslinux build, and this is basically a backport to Linux of some of those changes; they have thus been well tested. Signed-off-by: H. Peter Anvin LKML-Reference: <4AF86211.3070103@zytor.com> Acked-by: Michal Marek Tested-by: Sedat Dilek diff --git a/arch/x86/boot/compressed/relocs.c b/arch/x86/boot/compressed/relocs.c index bbeb0c3..89bbf4e 100644 --- a/arch/x86/boot/compressed/relocs.c +++ b/arch/x86/boot/compressed/relocs.c @@ -9,6 +9,9 @@ #include #define USE_BSD #include +#include + +static void die(char *fmt, ...); #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) static Elf32_Ehdr ehdr; @@ -30,25 +33,47 @@ static struct section *secs; * the address for which it has been compiled. Don't warn user about * absolute relocations present w.r.t these symbols. */ -static const char* safe_abs_relocs[] = { - "xen_irq_disable_direct_reloc", - "xen_save_fl_direct_reloc", -}; +static const char abs_sym_regex[] = + "^(xen_irq_disable_direct_reloc$|" + "xen_save_fl_direct_reloc$|" + "VDSO|" + "__crc_)"; +static regex_t abs_sym_regex_c; +static int is_abs_reloc(const char *sym_name) +{ + return !regexec(&abs_sym_regex_c, sym_name, 0, NULL, 0); +} -static int is_safe_abs_reloc(const char* sym_name) +/* + * These symbols are known to be relative, even if the linker marks them + * as absolute (typically defined outside any section in the linker script.) + */ +static const char rel_sym_regex[] = + "^_end$"; +static regex_t rel_sym_regex_c; +static int is_rel_reloc(const char *sym_name) { - int i; + return !regexec(&rel_sym_regex_c, sym_name, 0, NULL, 0); +} - for (i = 0; i < ARRAY_SIZE(safe_abs_relocs); i++) { - if (!strcmp(sym_name, safe_abs_relocs[i])) - /* Match found */ - return 1; - } - if (strncmp(sym_name, "VDSO", 4) == 0) - return 1; - if (strncmp(sym_name, "__crc_", 6) == 0) - return 1; - return 0; +static void regex_init(void) +{ + char errbuf[128]; + int err; + + err = regcomp(&abs_sym_regex_c, abs_sym_regex, + REG_EXTENDED|REG_NOSUB); + if (err) { + regerror(err, &abs_sym_regex_c, errbuf, sizeof errbuf); + die("%s", errbuf); + } + + err = regcomp(&rel_sym_regex_c, rel_sym_regex, + REG_EXTENDED|REG_NOSUB); + if (err) { + regerror(err, &rel_sym_regex_c, errbuf, sizeof errbuf); + die("%s", errbuf); + } } static void die(char *fmt, ...) @@ -131,7 +156,7 @@ static const char *rel_type(unsigned type) #undef REL_TYPE }; const char *name = "unknown type rel type name"; - if (type < ARRAY_SIZE(type_name)) { + if (type < ARRAY_SIZE(type_name) && type_name[type]) { name = type_name[type]; } return name; @@ -448,7 +473,7 @@ static void print_absolute_relocs(void) * Before warning check if this absolute symbol * relocation is harmless. */ - if (is_safe_abs_reloc(name)) + if (is_abs_reloc(name) || is_rel_reloc(name)) continue; if (!printed) { @@ -501,21 +526,26 @@ static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; r_type = ELF32_R_TYPE(rel->r_info); /* Don't visit relocations to absolute symbols */ - if (sym->st_shndx == SHN_ABS) { + if (sym->st_shndx == SHN_ABS && + !is_rel_reloc(sym_name(sym_strtab, sym))) { continue; } - if (r_type == R_386_NONE || r_type == R_386_PC32) { + switch (r_type) { + case R_386_NONE: + case R_386_PC32: /* * NONE can be ignored and and PC relative * relocations don't need to be adjusted. */ - } - else if (r_type == R_386_32) { + break; + case R_386_32: /* Visit relocations that need to be adjusted */ visit(rel, sym); - } - else { - die("Unsupported relocation type: %d\n", r_type); + break; + default: + die("Unsupported relocation type: %s (%d)\n", + rel_type(r_type), r_type); + break; } } } @@ -571,16 +601,15 @@ static void emit_relocs(int as_text) } else { unsigned char buf[4]; - buf[0] = buf[1] = buf[2] = buf[3] = 0; /* Print a stop */ - printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); + fwrite("\0\0\0\0", 4, 1, stdout); /* Now print each relocation */ for (i = 0; i < reloc_count; i++) { buf[0] = (relocs[i] >> 0) & 0xff; buf[1] = (relocs[i] >> 8) & 0xff; buf[2] = (relocs[i] >> 16) & 0xff; buf[3] = (relocs[i] >> 24) & 0xff; - printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); + fwrite(buf, 4, 1, stdout); } } } @@ -598,6 +627,8 @@ int main(int argc, char **argv) FILE *fp; int i; + regex_init(); + show_absolute_syms = 0; show_absolute_relocs = 0; as_text = 0; diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index f3f2104..f92a0da 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -319,9 +319,7 @@ SECTIONS __brk_limit = .; } - .end : AT(ADDR(.end) - LOAD_OFFSET) { - _end = .; - } + _end = .; STABS_DEBUG DWARF_DEBUG -- cgit v0.10.2 From be1cb8689c480228ffd2e4bfccc0dab7156cd9ea Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 14 Dec 2009 22:07:45 +0000 Subject: drm/ttm: Add more driver type enums Signed-off-by: Jakob Bornecrantz Signed-off-by: Dave Airlie diff --git a/include/drm/ttm/ttm_object.h b/include/drm/ttm/ttm_object.h index 703ca4d..0d9db09 100644 --- a/include/drm/ttm/ttm_object.h +++ b/include/drm/ttm/ttm_object.h @@ -77,7 +77,11 @@ enum ttm_object_type { ttm_buffer_type, ttm_lock_type, ttm_driver_type0 = 256, - ttm_driver_type1 + ttm_driver_type1, + ttm_driver_type2, + ttm_driver_type3, + ttm_driver_type4, + ttm_driver_type5 }; struct ttm_object_file; -- cgit v0.10.2 From 632f61178d0473861ba77e774bb654b37bc7eccc Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 10 Dec 2009 00:19:10 +0000 Subject: drm/vmwgfx: Add svga headers for vmwgfx driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These headers are shared between multiple place where different coding standards apply. They will be fixed up at a later time. Signed-off-by: Thomas Hellström Signed-off-by: Jakob Bornecrantz Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/vmwgfx/svga3d_reg.h b/drivers/gpu/drm/vmwgfx/svga3d_reg.h new file mode 100644 index 0000000..77cb453 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/svga3d_reg.h @@ -0,0 +1,1793 @@ +/********************************************************** + * Copyright 1998-2009 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + **********************************************************/ + +/* + * svga3d_reg.h -- + * + * SVGA 3D hardware definitions + */ + +#ifndef _SVGA3D_REG_H_ +#define _SVGA3D_REG_H_ + +#include "svga_reg.h" + + +/* + * 3D Hardware Version + * + * The hardware version is stored in the SVGA_FIFO_3D_HWVERSION fifo + * register. Is set by the host and read by the guest. This lets + * us make new guest drivers which are backwards-compatible with old + * SVGA hardware revisions. It does not let us support old guest + * drivers. Good enough for now. + * + */ + +#define SVGA3D_MAKE_HWVERSION(major, minor) (((major) << 16) | ((minor) & 0xFF)) +#define SVGA3D_MAJOR_HWVERSION(version) ((version) >> 16) +#define SVGA3D_MINOR_HWVERSION(version) ((version) & 0xFF) + +typedef enum { + SVGA3D_HWVERSION_WS5_RC1 = SVGA3D_MAKE_HWVERSION(0, 1), + SVGA3D_HWVERSION_WS5_RC2 = SVGA3D_MAKE_HWVERSION(0, 2), + SVGA3D_HWVERSION_WS51_RC1 = SVGA3D_MAKE_HWVERSION(0, 3), + SVGA3D_HWVERSION_WS6_B1 = SVGA3D_MAKE_HWVERSION(1, 1), + SVGA3D_HWVERSION_FUSION_11 = SVGA3D_MAKE_HWVERSION(1, 4), + SVGA3D_HWVERSION_WS65_B1 = SVGA3D_MAKE_HWVERSION(2, 0), + SVGA3D_HWVERSION_CURRENT = SVGA3D_HWVERSION_WS65_B1, +} SVGA3dHardwareVersion; + +/* + * Generic Types + */ + +typedef uint32 SVGA3dBool; /* 32-bit Bool definition */ +#define SVGA3D_NUM_CLIPPLANES 6 +#define SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS 8 + + +/* + * Surface formats. + * + * If you modify this list, be sure to keep GLUtil.c in sync. It + * includes the internal format definition of each surface in + * GLUtil_ConvertSurfaceFormat, and it contains a table of + * human-readable names in GLUtil_GetFormatName. + */ + +typedef enum SVGA3dSurfaceFormat { + SVGA3D_FORMAT_INVALID = 0, + + SVGA3D_X8R8G8B8 = 1, + SVGA3D_A8R8G8B8 = 2, + + SVGA3D_R5G6B5 = 3, + SVGA3D_X1R5G5B5 = 4, + SVGA3D_A1R5G5B5 = 5, + SVGA3D_A4R4G4B4 = 6, + + SVGA3D_Z_D32 = 7, + SVGA3D_Z_D16 = 8, + SVGA3D_Z_D24S8 = 9, + SVGA3D_Z_D15S1 = 10, + + SVGA3D_LUMINANCE8 = 11, + SVGA3D_LUMINANCE4_ALPHA4 = 12, + SVGA3D_LUMINANCE16 = 13, + SVGA3D_LUMINANCE8_ALPHA8 = 14, + + SVGA3D_DXT1 = 15, + SVGA3D_DXT2 = 16, + SVGA3D_DXT3 = 17, + SVGA3D_DXT4 = 18, + SVGA3D_DXT5 = 19, + + SVGA3D_BUMPU8V8 = 20, + SVGA3D_BUMPL6V5U5 = 21, + SVGA3D_BUMPX8L8V8U8 = 22, + SVGA3D_BUMPL8V8U8 = 23, + + SVGA3D_ARGB_S10E5 = 24, /* 16-bit floating-point ARGB */ + SVGA3D_ARGB_S23E8 = 25, /* 32-bit floating-point ARGB */ + + SVGA3D_A2R10G10B10 = 26, + + /* signed formats */ + SVGA3D_V8U8 = 27, + SVGA3D_Q8W8V8U8 = 28, + SVGA3D_CxV8U8 = 29, + + /* mixed formats */ + SVGA3D_X8L8V8U8 = 30, + SVGA3D_A2W10V10U10 = 31, + + SVGA3D_ALPHA8 = 32, + + /* Single- and dual-component floating point formats */ + SVGA3D_R_S10E5 = 33, + SVGA3D_R_S23E8 = 34, + SVGA3D_RG_S10E5 = 35, + SVGA3D_RG_S23E8 = 36, + + /* + * Any surface can be used as a buffer object, but SVGA3D_BUFFER is + * the most efficient format to use when creating new surfaces + * expressly for index or vertex data. + */ + SVGA3D_BUFFER = 37, + + SVGA3D_Z_D24X8 = 38, + + SVGA3D_V16U16 = 39, + + SVGA3D_G16R16 = 40, + SVGA3D_A16B16G16R16 = 41, + + /* Packed Video formats */ + SVGA3D_UYVY = 42, + SVGA3D_YUY2 = 43, + + SVGA3D_FORMAT_MAX +} SVGA3dSurfaceFormat; + +typedef uint32 SVGA3dColor; /* a, r, g, b */ + +/* + * These match the D3DFORMAT_OP definitions used by Direct3D. We need + * them so that we can query the host for what the supported surface + * operations are (when we're using the D3D backend, in particular), + * and so we can send those operations to the guest. + */ +typedef enum { + SVGA3DFORMAT_OP_TEXTURE = 0x00000001, + SVGA3DFORMAT_OP_VOLUMETEXTURE = 0x00000002, + SVGA3DFORMAT_OP_CUBETEXTURE = 0x00000004, + SVGA3DFORMAT_OP_OFFSCREEN_RENDERTARGET = 0x00000008, + SVGA3DFORMAT_OP_SAME_FORMAT_RENDERTARGET = 0x00000010, + SVGA3DFORMAT_OP_ZSTENCIL = 0x00000040, + SVGA3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH = 0x00000080, + +/* + * This format can be used as a render target if the current display mode + * is the same depth if the alpha channel is ignored. e.g. if the device + * can render to A8R8G8B8 when the display mode is X8R8G8B8, then the + * format op list entry for A8R8G8B8 should have this cap. + */ + SVGA3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET = 0x00000100, + +/* + * This format contains DirectDraw support (including Flip). This flag + * should not to be set on alpha formats. + */ + SVGA3DFORMAT_OP_DISPLAYMODE = 0x00000400, + +/* + * The rasterizer can support some level of Direct3D support in this format + * and implies that the driver can create a Context in this mode (for some + * render target format). When this flag is set, the SVGA3DFORMAT_OP_DISPLAYMODE + * flag must also be set. + */ + SVGA3DFORMAT_OP_3DACCELERATION = 0x00000800, + +/* + * This is set for a private format when the driver has put the bpp in + * the structure. + */ + SVGA3DFORMAT_OP_PIXELSIZE = 0x00001000, + +/* + * Indicates that this format can be converted to any RGB format for which + * SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB is specified + */ + SVGA3DFORMAT_OP_CONVERT_TO_ARGB = 0x00002000, + +/* + * Indicates that this format can be used to create offscreen plain surfaces. + */ + SVGA3DFORMAT_OP_OFFSCREENPLAIN = 0x00004000, + +/* + * Indicated that this format can be read as an SRGB texture (meaning that the + * sampler will linearize the looked up data) + */ + SVGA3DFORMAT_OP_SRGBREAD = 0x00008000, + +/* + * Indicates that this format can be used in the bumpmap instructions + */ + SVGA3DFORMAT_OP_BUMPMAP = 0x00010000, + +/* + * Indicates that this format can be sampled by the displacement map sampler + */ + SVGA3DFORMAT_OP_DMAP = 0x00020000, + +/* + * Indicates that this format cannot be used with texture filtering + */ + SVGA3DFORMAT_OP_NOFILTER = 0x00040000, + +/* + * Indicates that format conversions are supported to this RGB format if + * SVGA3DFORMAT_OP_CONVERT_TO_ARGB is specified in the source format. + */ + SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB = 0x00080000, + +/* + * Indicated that this format can be written as an SRGB target (meaning that the + * pixel pipe will DE-linearize data on output to format) + */ + SVGA3DFORMAT_OP_SRGBWRITE = 0x00100000, + +/* + * Indicates that this format cannot be used with alpha blending + */ + SVGA3DFORMAT_OP_NOALPHABLEND = 0x00200000, + +/* + * Indicates that the device can auto-generated sublevels for resources + * of this format + */ + SVGA3DFORMAT_OP_AUTOGENMIPMAP = 0x00400000, + +/* + * Indicates that this format can be used by vertex texture sampler + */ + SVGA3DFORMAT_OP_VERTEXTEXTURE = 0x00800000, + +/* + * Indicates that this format supports neither texture coordinate wrap + * modes, nor mipmapping + */ + SVGA3DFORMAT_OP_NOTEXCOORDWRAPNORMIP = 0x01000000 +} SVGA3dFormatOp; + +/* + * This structure is a conversion of SVGA3DFORMAT_OP_*. + * Entries must be located at the same position. + */ +typedef union { + uint32 value; + struct { + uint32 texture : 1; + uint32 volumeTexture : 1; + uint32 cubeTexture : 1; + uint32 offscreenRenderTarget : 1; + uint32 sameFormatRenderTarget : 1; + uint32 unknown1 : 1; + uint32 zStencil : 1; + uint32 zStencilArbitraryDepth : 1; + uint32 sameFormatUpToAlpha : 1; + uint32 unknown2 : 1; + uint32 displayMode : 1; + uint32 acceleration3d : 1; + uint32 pixelSize : 1; + uint32 convertToARGB : 1; + uint32 offscreenPlain : 1; + uint32 sRGBRead : 1; + uint32 bumpMap : 1; + uint32 dmap : 1; + uint32 noFilter : 1; + uint32 memberOfGroupARGB : 1; + uint32 sRGBWrite : 1; + uint32 noAlphaBlend : 1; + uint32 autoGenMipMap : 1; + uint32 vertexTexture : 1; + uint32 noTexCoordWrapNorMip : 1; + }; +} SVGA3dSurfaceFormatCaps; + +/* + * SVGA_3D_CMD_SETRENDERSTATE Types. All value types + * must fit in a uint32. + */ + +typedef enum { + SVGA3D_RS_INVALID = 0, + SVGA3D_RS_ZENABLE = 1, /* SVGA3dBool */ + SVGA3D_RS_ZWRITEENABLE = 2, /* SVGA3dBool */ + SVGA3D_RS_ALPHATESTENABLE = 3, /* SVGA3dBool */ + SVGA3D_RS_DITHERENABLE = 4, /* SVGA3dBool */ + SVGA3D_RS_BLENDENABLE = 5, /* SVGA3dBool */ + SVGA3D_RS_FOGENABLE = 6, /* SVGA3dBool */ + SVGA3D_RS_SPECULARENABLE = 7, /* SVGA3dBool */ + SVGA3D_RS_STENCILENABLE = 8, /* SVGA3dBool */ + SVGA3D_RS_LIGHTINGENABLE = 9, /* SVGA3dBool */ + SVGA3D_RS_NORMALIZENORMALS = 10, /* SVGA3dBool */ + SVGA3D_RS_POINTSPRITEENABLE = 11, /* SVGA3dBool */ + SVGA3D_RS_POINTSCALEENABLE = 12, /* SVGA3dBool */ + SVGA3D_RS_STENCILREF = 13, /* uint32 */ + SVGA3D_RS_STENCILMASK = 14, /* uint32 */ + SVGA3D_RS_STENCILWRITEMASK = 15, /* uint32 */ + SVGA3D_RS_FOGSTART = 16, /* float */ + SVGA3D_RS_FOGEND = 17, /* float */ + SVGA3D_RS_FOGDENSITY = 18, /* float */ + SVGA3D_RS_POINTSIZE = 19, /* float */ + SVGA3D_RS_POINTSIZEMIN = 20, /* float */ + SVGA3D_RS_POINTSIZEMAX = 21, /* float */ + SVGA3D_RS_POINTSCALE_A = 22, /* float */ + SVGA3D_RS_POINTSCALE_B = 23, /* float */ + SVGA3D_RS_POINTSCALE_C = 24, /* float */ + SVGA3D_RS_FOGCOLOR = 25, /* SVGA3dColor */ + SVGA3D_RS_AMBIENT = 26, /* SVGA3dColor */ + SVGA3D_RS_CLIPPLANEENABLE = 27, /* SVGA3dClipPlanes */ + SVGA3D_RS_FOGMODE = 28, /* SVGA3dFogMode */ + SVGA3D_RS_FILLMODE = 29, /* SVGA3dFillMode */ + SVGA3D_RS_SHADEMODE = 30, /* SVGA3dShadeMode */ + SVGA3D_RS_LINEPATTERN = 31, /* SVGA3dLinePattern */ + SVGA3D_RS_SRCBLEND = 32, /* SVGA3dBlendOp */ + SVGA3D_RS_DSTBLEND = 33, /* SVGA3dBlendOp */ + SVGA3D_RS_BLENDEQUATION = 34, /* SVGA3dBlendEquation */ + SVGA3D_RS_CULLMODE = 35, /* SVGA3dFace */ + SVGA3D_RS_ZFUNC = 36, /* SVGA3dCmpFunc */ + SVGA3D_RS_ALPHAFUNC = 37, /* SVGA3dCmpFunc */ + SVGA3D_RS_STENCILFUNC = 38, /* SVGA3dCmpFunc */ + SVGA3D_RS_STENCILFAIL = 39, /* SVGA3dStencilOp */ + SVGA3D_RS_STENCILZFAIL = 40, /* SVGA3dStencilOp */ + SVGA3D_RS_STENCILPASS = 41, /* SVGA3dStencilOp */ + SVGA3D_RS_ALPHAREF = 42, /* float (0.0 .. 1.0) */ + SVGA3D_RS_FRONTWINDING = 43, /* SVGA3dFrontWinding */ + SVGA3D_RS_COORDINATETYPE = 44, /* SVGA3dCoordinateType */ + SVGA3D_RS_ZBIAS = 45, /* float */ + SVGA3D_RS_RANGEFOGENABLE = 46, /* SVGA3dBool */ + SVGA3D_RS_COLORWRITEENABLE = 47, /* SVGA3dColorMask */ + SVGA3D_RS_VERTEXMATERIALENABLE = 48, /* SVGA3dBool */ + SVGA3D_RS_DIFFUSEMATERIALSOURCE = 49, /* SVGA3dVertexMaterial */ + SVGA3D_RS_SPECULARMATERIALSOURCE = 50, /* SVGA3dVertexMaterial */ + SVGA3D_RS_AMBIENTMATERIALSOURCE = 51, /* SVGA3dVertexMaterial */ + SVGA3D_RS_EMISSIVEMATERIALSOURCE = 52, /* SVGA3dVertexMaterial */ + SVGA3D_RS_TEXTUREFACTOR = 53, /* SVGA3dColor */ + SVGA3D_RS_LOCALVIEWER = 54, /* SVGA3dBool */ + SVGA3D_RS_SCISSORTESTENABLE = 55, /* SVGA3dBool */ + SVGA3D_RS_BLENDCOLOR = 56, /* SVGA3dColor */ + SVGA3D_RS_STENCILENABLE2SIDED = 57, /* SVGA3dBool */ + SVGA3D_RS_CCWSTENCILFUNC = 58, /* SVGA3dCmpFunc */ + SVGA3D_RS_CCWSTENCILFAIL = 59, /* SVGA3dStencilOp */ + SVGA3D_RS_CCWSTENCILZFAIL = 60, /* SVGA3dStencilOp */ + SVGA3D_RS_CCWSTENCILPASS = 61, /* SVGA3dStencilOp */ + SVGA3D_RS_VERTEXBLEND = 62, /* SVGA3dVertexBlendFlags */ + SVGA3D_RS_SLOPESCALEDEPTHBIAS = 63, /* float */ + SVGA3D_RS_DEPTHBIAS = 64, /* float */ + + + /* + * Output Gamma Level + * + * Output gamma effects the gamma curve of colors that are output from the + * rendering pipeline. A value of 1.0 specifies a linear color space. If the + * value is <= 0.0, gamma correction is ignored and linear color space is + * used. + */ + + SVGA3D_RS_OUTPUTGAMMA = 65, /* float */ + SVGA3D_RS_ZVISIBLE = 66, /* SVGA3dBool */ + SVGA3D_RS_LASTPIXEL = 67, /* SVGA3dBool */ + SVGA3D_RS_CLIPPING = 68, /* SVGA3dBool */ + SVGA3D_RS_WRAP0 = 69, /* SVGA3dWrapFlags */ + SVGA3D_RS_WRAP1 = 70, /* SVGA3dWrapFlags */ + SVGA3D_RS_WRAP2 = 71, /* SVGA3dWrapFlags */ + SVGA3D_RS_WRAP3 = 72, /* SVGA3dWrapFlags */ + SVGA3D_RS_WRAP4 = 73, /* SVGA3dWrapFlags */ + SVGA3D_RS_WRAP5 = 74, /* SVGA3dWrapFlags */ + SVGA3D_RS_WRAP6 = 75, /* SVGA3dWrapFlags */ + SVGA3D_RS_WRAP7 = 76, /* SVGA3dWrapFlags */ + SVGA3D_RS_WRAP8 = 77, /* SVGA3dWrapFlags */ + SVGA3D_RS_WRAP9 = 78, /* SVGA3dWrapFlags */ + SVGA3D_RS_WRAP10 = 79, /* SVGA3dWrapFlags */ + SVGA3D_RS_WRAP11 = 80, /* SVGA3dWrapFlags */ + SVGA3D_RS_WRAP12 = 81, /* SVGA3dWrapFlags */ + SVGA3D_RS_WRAP13 = 82, /* SVGA3dWrapFlags */ + SVGA3D_RS_WRAP14 = 83, /* SVGA3dWrapFlags */ + SVGA3D_RS_WRAP15 = 84, /* SVGA3dWrapFlags */ + SVGA3D_RS_MULTISAMPLEANTIALIAS = 85, /* SVGA3dBool */ + SVGA3D_RS_MULTISAMPLEMASK = 86, /* uint32 */ + SVGA3D_RS_INDEXEDVERTEXBLENDENABLE = 87, /* SVGA3dBool */ + SVGA3D_RS_TWEENFACTOR = 88, /* float */ + SVGA3D_RS_ANTIALIASEDLINEENABLE = 89, /* SVGA3dBool */ + SVGA3D_RS_COLORWRITEENABLE1 = 90, /* SVGA3dColorMask */ + SVGA3D_RS_COLORWRITEENABLE2 = 91, /* SVGA3dColorMask */ + SVGA3D_RS_COLORWRITEENABLE3 = 92, /* SVGA3dColorMask */ + SVGA3D_RS_SEPARATEALPHABLENDENABLE = 93, /* SVGA3dBool */ + SVGA3D_RS_SRCBLENDALPHA = 94, /* SVGA3dBlendOp */ + SVGA3D_RS_DSTBLENDALPHA = 95, /* SVGA3dBlendOp */ + SVGA3D_RS_BLENDEQUATIONALPHA = 96, /* SVGA3dBlendEquation */ + SVGA3D_RS_MAX +} SVGA3dRenderStateName; + +typedef enum { + SVGA3D_VERTEXMATERIAL_NONE = 0, /* Use the value in the current material */ + SVGA3D_VERTEXMATERIAL_DIFFUSE = 1, /* Use the value in the diffuse component */ + SVGA3D_VERTEXMATERIAL_SPECULAR = 2, /* Use the value in the specular component */ +} SVGA3dVertexMaterial; + +typedef enum { + SVGA3D_FILLMODE_INVALID = 0, + SVGA3D_FILLMODE_POINT = 1, + SVGA3D_FILLMODE_LINE = 2, + SVGA3D_FILLMODE_FILL = 3, + SVGA3D_FILLMODE_MAX +} SVGA3dFillModeType; + + +typedef +union { + struct { + uint16 mode; /* SVGA3dFillModeType */ + uint16 face; /* SVGA3dFace */ + }; + uint32 uintValue; +} SVGA3dFillMode; + +typedef enum { + SVGA3D_SHADEMODE_INVALID = 0, + SVGA3D_SHADEMODE_FLAT = 1, + SVGA3D_SHADEMODE_SMOOTH = 2, + SVGA3D_SHADEMODE_PHONG = 3, /* Not supported */ + SVGA3D_SHADEMODE_MAX +} SVGA3dShadeMode; + +typedef +union { + struct { + uint16 repeat; + uint16 pattern; + }; + uint32 uintValue; +} SVGA3dLinePattern; + +typedef enum { + SVGA3D_BLENDOP_INVALID = 0, + SVGA3D_BLENDOP_ZERO = 1, + SVGA3D_BLENDOP_ONE = 2, + SVGA3D_BLENDOP_SRCCOLOR = 3, + SVGA3D_BLENDOP_INVSRCCOLOR = 4, + SVGA3D_BLENDOP_SRCALPHA = 5, + SVGA3D_BLENDOP_INVSRCALPHA = 6, + SVGA3D_BLENDOP_DESTALPHA = 7, + SVGA3D_BLENDOP_INVDESTALPHA = 8, + SVGA3D_BLENDOP_DESTCOLOR = 9, + SVGA3D_BLENDOP_INVDESTCOLOR = 10, + SVGA3D_BLENDOP_SRCALPHASAT = 11, + SVGA3D_BLENDOP_BLENDFACTOR = 12, + SVGA3D_BLENDOP_INVBLENDFACTOR = 13, + SVGA3D_BLENDOP_MAX +} SVGA3dBlendOp; + +typedef enum { + SVGA3D_BLENDEQ_INVALID = 0, + SVGA3D_BLENDEQ_ADD = 1, + SVGA3D_BLENDEQ_SUBTRACT = 2, + SVGA3D_BLENDEQ_REVSUBTRACT = 3, + SVGA3D_BLENDEQ_MINIMUM = 4, + SVGA3D_BLENDEQ_MAXIMUM = 5, + SVGA3D_BLENDEQ_MAX +} SVGA3dBlendEquation; + +typedef enum { + SVGA3D_FRONTWINDING_INVALID = 0, + SVGA3D_FRONTWINDING_CW = 1, + SVGA3D_FRONTWINDING_CCW = 2, + SVGA3D_FRONTWINDING_MAX +} SVGA3dFrontWinding; + +typedef enum { + SVGA3D_FACE_INVALID = 0, + SVGA3D_FACE_NONE = 1, + SVGA3D_FACE_FRONT = 2, + SVGA3D_FACE_BACK = 3, + SVGA3D_FACE_FRONT_BACK = 4, + SVGA3D_FACE_MAX +} SVGA3dFace; + +/* + * The order and the values should not be changed + */ + +typedef enum { + SVGA3D_CMP_INVALID = 0, + SVGA3D_CMP_NEVER = 1, + SVGA3D_CMP_LESS = 2, + SVGA3D_CMP_EQUAL = 3, + SVGA3D_CMP_LESSEQUAL = 4, + SVGA3D_CMP_GREATER = 5, + SVGA3D_CMP_NOTEQUAL = 6, + SVGA3D_CMP_GREATEREQUAL = 7, + SVGA3D_CMP_ALWAYS = 8, + SVGA3D_CMP_MAX +} SVGA3dCmpFunc; + +/* + * SVGA3D_FOGFUNC_* specifies the fog equation, or PER_VERTEX which allows + * the fog factor to be specified in the alpha component of the specular + * (a.k.a. secondary) vertex color. + */ +typedef enum { + SVGA3D_FOGFUNC_INVALID = 0, + SVGA3D_FOGFUNC_EXP = 1, + SVGA3D_FOGFUNC_EXP2 = 2, + SVGA3D_FOGFUNC_LINEAR = 3, + SVGA3D_FOGFUNC_PER_VERTEX = 4 +} SVGA3dFogFunction; + +/* + * SVGA3D_FOGTYPE_* specifies if fog factors are computed on a per-vertex + * or per-pixel basis. + */ +typedef enum { + SVGA3D_FOGTYPE_INVALID = 0, + SVGA3D_FOGTYPE_VERTEX = 1, + SVGA3D_FOGTYPE_PIXEL = 2, + SVGA3D_FOGTYPE_MAX = 3 +} SVGA3dFogType; + +/* + * SVGA3D_FOGBASE_* selects depth or range-based fog. Depth-based fog is + * computed using the eye Z value of each pixel (or vertex), whereas range- + * based fog is computed using the actual distance (range) to the eye. + */ +typedef enum { + SVGA3D_FOGBASE_INVALID = 0, + SVGA3D_FOGBASE_DEPTHBASED = 1, + SVGA3D_FOGBASE_RANGEBASED = 2, + SVGA3D_FOGBASE_MAX = 3 +} SVGA3dFogBase; + +typedef enum { + SVGA3D_STENCILOP_INVALID = 0, + SVGA3D_STENCILOP_KEEP = 1, + SVGA3D_STENCILOP_ZERO = 2, + SVGA3D_STENCILOP_REPLACE = 3, + SVGA3D_STENCILOP_INCRSAT = 4, + SVGA3D_STENCILOP_DECRSAT = 5, + SVGA3D_STENCILOP_INVERT = 6, + SVGA3D_STENCILOP_INCR = 7, + SVGA3D_STENCILOP_DECR = 8, + SVGA3D_STENCILOP_MAX +} SVGA3dStencilOp; + +typedef enum { + SVGA3D_CLIPPLANE_0 = (1 << 0), + SVGA3D_CLIPPLANE_1 = (1 << 1), + SVGA3D_CLIPPLANE_2 = (1 << 2), + SVGA3D_CLIPPLANE_3 = (1 << 3), + SVGA3D_CLIPPLANE_4 = (1 << 4), + SVGA3D_CLIPPLANE_5 = (1 << 5), +} SVGA3dClipPlanes; + +typedef enum { + SVGA3D_CLEAR_COLOR = 0x1, + SVGA3D_CLEAR_DEPTH = 0x2, + SVGA3D_CLEAR_STENCIL = 0x4 +} SVGA3dClearFlag; + +typedef enum { + SVGA3D_RT_DEPTH = 0, + SVGA3D_RT_STENCIL = 1, + SVGA3D_RT_COLOR0 = 2, + SVGA3D_RT_COLOR1 = 3, + SVGA3D_RT_COLOR2 = 4, + SVGA3D_RT_COLOR3 = 5, + SVGA3D_RT_COLOR4 = 6, + SVGA3D_RT_COLOR5 = 7, + SVGA3D_RT_COLOR6 = 8, + SVGA3D_RT_COLOR7 = 9, + SVGA3D_RT_MAX, + SVGA3D_RT_INVALID = ((uint32)-1), +} SVGA3dRenderTargetType; + +#define SVGA3D_MAX_RT_COLOR (SVGA3D_RT_COLOR7 - SVGA3D_RT_COLOR0 + 1) + +typedef +union { + struct { + uint32 red : 1; + uint32 green : 1; + uint32 blue : 1; + uint32 alpha : 1; + }; + uint32 uintValue; +} SVGA3dColorMask; + +typedef enum { + SVGA3D_VBLEND_DISABLE = 0, + SVGA3D_VBLEND_1WEIGHT = 1, + SVGA3D_VBLEND_2WEIGHT = 2, + SVGA3D_VBLEND_3WEIGHT = 3, +} SVGA3dVertexBlendFlags; + +typedef enum { + SVGA3D_WRAPCOORD_0 = 1 << 0, + SVGA3D_WRAPCOORD_1 = 1 << 1, + SVGA3D_WRAPCOORD_2 = 1 << 2, + SVGA3D_WRAPCOORD_3 = 1 << 3, + SVGA3D_WRAPCOORD_ALL = 0xF, +} SVGA3dWrapFlags; + +/* + * SVGA_3D_CMD_TEXTURESTATE Types. All value types + * must fit in a uint32. + */ + +typedef enum { + SVGA3D_TS_INVALID = 0, + SVGA3D_TS_BIND_TEXTURE = 1, /* SVGA3dSurfaceId */ + SVGA3D_TS_COLOROP = 2, /* SVGA3dTextureCombiner */ + SVGA3D_TS_COLORARG1 = 3, /* SVGA3dTextureArgData */ + SVGA3D_TS_COLORARG2 = 4, /* SVGA3dTextureArgData */ + SVGA3D_TS_ALPHAOP = 5, /* SVGA3dTextureCombiner */ + SVGA3D_TS_ALPHAARG1 = 6, /* SVGA3dTextureArgData */ + SVGA3D_TS_ALPHAARG2 = 7, /* SVGA3dTextureArgData */ + SVGA3D_TS_ADDRESSU = 8, /* SVGA3dTextureAddress */ + SVGA3D_TS_ADDRESSV = 9, /* SVGA3dTextureAddress */ + SVGA3D_TS_MIPFILTER = 10, /* SVGA3dTextureFilter */ + SVGA3D_TS_MAGFILTER = 11, /* SVGA3dTextureFilter */ + SVGA3D_TS_MINFILTER = 12, /* SVGA3dTextureFilter */ + SVGA3D_TS_BORDERCOLOR = 13, /* SVGA3dColor */ + SVGA3D_TS_TEXCOORDINDEX = 14, /* uint32 */ + SVGA3D_TS_TEXTURETRANSFORMFLAGS = 15, /* SVGA3dTexTransformFlags */ + SVGA3D_TS_TEXCOORDGEN = 16, /* SVGA3dTextureCoordGen */ + SVGA3D_TS_BUMPENVMAT00 = 17, /* float */ + SVGA3D_TS_BUMPENVMAT01 = 18, /* float */ + SVGA3D_TS_BUMPENVMAT10 = 19, /* float */ + SVGA3D_TS_BUMPENVMAT11 = 20, /* float */ + SVGA3D_TS_TEXTURE_MIPMAP_LEVEL = 21, /* uint32 */ + SVGA3D_TS_TEXTURE_LOD_BIAS = 22, /* float */ + SVGA3D_TS_TEXTURE_ANISOTROPIC_LEVEL = 23, /* uint32 */ + SVGA3D_TS_ADDRESSW = 24, /* SVGA3dTextureAddress */ + + + /* + * Sampler Gamma Level + * + * Sampler gamma effects the color of samples taken from the sampler. A + * value of 1.0 will produce linear samples. If the value is <= 0.0 the + * gamma value is ignored and a linear space is used. + */ + + SVGA3D_TS_GAMMA = 25, /* float */ + SVGA3D_TS_BUMPENVLSCALE = 26, /* float */ + SVGA3D_TS_BUMPENVLOFFSET = 27, /* float */ + SVGA3D_TS_COLORARG0 = 28, /* SVGA3dTextureArgData */ + SVGA3D_TS_ALPHAARG0 = 29, /* SVGA3dTextureArgData */ + SVGA3D_TS_MAX +} SVGA3dTextureStateName; + +typedef enum { + SVGA3D_TC_INVALID = 0, + SVGA3D_TC_DISABLE = 1, + SVGA3D_TC_SELECTARG1 = 2, + SVGA3D_TC_SELECTARG2 = 3, + SVGA3D_TC_MODULATE = 4, + SVGA3D_TC_ADD = 5, + SVGA3D_TC_ADDSIGNED = 6, + SVGA3D_TC_SUBTRACT = 7, + SVGA3D_TC_BLENDTEXTUREALPHA = 8, + SVGA3D_TC_BLENDDIFFUSEALPHA = 9, + SVGA3D_TC_BLENDCURRENTALPHA = 10, + SVGA3D_TC_BLENDFACTORALPHA = 11, + SVGA3D_TC_MODULATE2X = 12, + SVGA3D_TC_MODULATE4X = 13, + SVGA3D_TC_DSDT = 14, + SVGA3D_TC_DOTPRODUCT3 = 15, + SVGA3D_TC_BLENDTEXTUREALPHAPM = 16, + SVGA3D_TC_ADDSIGNED2X = 17, + SVGA3D_TC_ADDSMOOTH = 18, + SVGA3D_TC_PREMODULATE = 19, + SVGA3D_TC_MODULATEALPHA_ADDCOLOR = 20, + SVGA3D_TC_MODULATECOLOR_ADDALPHA = 21, + SVGA3D_TC_MODULATEINVALPHA_ADDCOLOR = 22, + SVGA3D_TC_MODULATEINVCOLOR_ADDALPHA = 23, + SVGA3D_TC_BUMPENVMAPLUMINANCE = 24, + SVGA3D_TC_MULTIPLYADD = 25, + SVGA3D_TC_LERP = 26, + SVGA3D_TC_MAX +} SVGA3dTextureCombiner; + +#define SVGA3D_TC_CAP_BIT(svga3d_tc_op) (svga3d_tc_op ? (1 << (svga3d_tc_op - 1)) : 0) + +typedef enum { + SVGA3D_TEX_ADDRESS_INVALID = 0, + SVGA3D_TEX_ADDRESS_WRAP = 1, + SVGA3D_TEX_ADDRESS_MIRROR = 2, + SVGA3D_TEX_ADDRESS_CLAMP = 3, + SVGA3D_TEX_ADDRESS_BORDER = 4, + SVGA3D_TEX_ADDRESS_MIRRORONCE = 5, + SVGA3D_TEX_ADDRESS_EDGE = 6, + SVGA3D_TEX_ADDRESS_MAX +} SVGA3dTextureAddress; + +/* + * SVGA3D_TEX_FILTER_NONE as the minification filter means mipmapping is + * disabled, and the rasterizer should use the magnification filter instead. + */ +typedef enum { + SVGA3D_TEX_FILTER_NONE = 0, + SVGA3D_TEX_FILTER_NEAREST = 1, + SVGA3D_TEX_FILTER_LINEAR = 2, + SVGA3D_TEX_FILTER_ANISOTROPIC = 3, + SVGA3D_TEX_FILTER_FLATCUBIC = 4, // Deprecated, not implemented + SVGA3D_TEX_FILTER_GAUSSIANCUBIC = 5, // Deprecated, not implemented + SVGA3D_TEX_FILTER_PYRAMIDALQUAD = 6, // Not currently implemented + SVGA3D_TEX_FILTER_GAUSSIANQUAD = 7, // Not currently implemented + SVGA3D_TEX_FILTER_MAX +} SVGA3dTextureFilter; + +typedef enum { + SVGA3D_TEX_TRANSFORM_OFF = 0, + SVGA3D_TEX_TRANSFORM_S = (1 << 0), + SVGA3D_TEX_TRANSFORM_T = (1 << 1), + SVGA3D_TEX_TRANSFORM_R = (1 << 2), + SVGA3D_TEX_TRANSFORM_Q = (1 << 3), + SVGA3D_TEX_PROJECTED = (1 << 15), +} SVGA3dTexTransformFlags; + +typedef enum { + SVGA3D_TEXCOORD_GEN_OFF = 0, + SVGA3D_TEXCOORD_GEN_EYE_POSITION = 1, + SVGA3D_TEXCOORD_GEN_EYE_NORMAL = 2, + SVGA3D_TEXCOORD_GEN_REFLECTIONVECTOR = 3, + SVGA3D_TEXCOORD_GEN_SPHERE = 4, + SVGA3D_TEXCOORD_GEN_MAX +} SVGA3dTextureCoordGen; + +/* + * Texture argument constants for texture combiner + */ +typedef enum { + SVGA3D_TA_INVALID = 0, + SVGA3D_TA_CONSTANT = 1, + SVGA3D_TA_PREVIOUS = 2, + SVGA3D_TA_DIFFUSE = 3, + SVGA3D_TA_TEXTURE = 4, + SVGA3D_TA_SPECULAR = 5, + SVGA3D_TA_MAX +} SVGA3dTextureArgData; + +#define SVGA3D_TM_MASK_LEN 4 + +/* Modifiers for texture argument constants defined above. */ +typedef enum { + SVGA3D_TM_NONE = 0, + SVGA3D_TM_ALPHA = (1 << SVGA3D_TM_MASK_LEN), + SVGA3D_TM_ONE_MINUS = (2 << SVGA3D_TM_MASK_LEN), +} SVGA3dTextureArgModifier; + +#define SVGA3D_INVALID_ID ((uint32)-1) +#define SVGA3D_MAX_CLIP_PLANES 6 + +/* + * This is the limit to the number of fixed-function texture + * transforms and texture coordinates we can support. It does *not* + * correspond to the number of texture image units (samplers) we + * support! + */ +#define SVGA3D_MAX_TEXTURE_COORDS 8 + +/* + * Vertex declarations + * + * Notes: + * + * SVGA3D_DECLUSAGE_POSITIONT is for pre-transformed vertices. If you + * draw with any POSITIONT vertex arrays, the programmable vertex + * pipeline will be implicitly disabled. Drawing will take place as if + * no vertex shader was bound. + */ + +typedef enum { + SVGA3D_DECLUSAGE_POSITION = 0, + SVGA3D_DECLUSAGE_BLENDWEIGHT, // 1 + SVGA3D_DECLUSAGE_BLENDINDICES, // 2 + SVGA3D_DECLUSAGE_NORMAL, // 3 + SVGA3D_DECLUSAGE_PSIZE, // 4 + SVGA3D_DECLUSAGE_TEXCOORD, // 5 + SVGA3D_DECLUSAGE_TANGENT, // 6 + SVGA3D_DECLUSAGE_BINORMAL, // 7 + SVGA3D_DECLUSAGE_TESSFACTOR, // 8 + SVGA3D_DECLUSAGE_POSITIONT, // 9 + SVGA3D_DECLUSAGE_COLOR, // 10 + SVGA3D_DECLUSAGE_FOG, // 11 + SVGA3D_DECLUSAGE_DEPTH, // 12 + SVGA3D_DECLUSAGE_SAMPLE, // 13 + SVGA3D_DECLUSAGE_MAX +} SVGA3dDeclUsage; + +typedef enum { + SVGA3D_DECLMETHOD_DEFAULT = 0, + SVGA3D_DECLMETHOD_PARTIALU, + SVGA3D_DECLMETHOD_PARTIALV, + SVGA3D_DECLMETHOD_CROSSUV, // Normal + SVGA3D_DECLMETHOD_UV, + SVGA3D_DECLMETHOD_LOOKUP, // Lookup a displacement map + SVGA3D_DECLMETHOD_LOOKUPPRESAMPLED, // Lookup a pre-sampled displacement map +} SVGA3dDeclMethod; + +typedef enum { + SVGA3D_DECLTYPE_FLOAT1 = 0, + SVGA3D_DECLTYPE_FLOAT2 = 1, + SVGA3D_DECLTYPE_FLOAT3 = 2, + SVGA3D_DECLTYPE_FLOAT4 = 3, + SVGA3D_DECLTYPE_D3DCOLOR = 4, + SVGA3D_DECLTYPE_UBYTE4 = 5, + SVGA3D_DECLTYPE_SHORT2 = 6, + SVGA3D_DECLTYPE_SHORT4 = 7, + SVGA3D_DECLTYPE_UBYTE4N = 8, + SVGA3D_DECLTYPE_SHORT2N = 9, + SVGA3D_DECLTYPE_SHORT4N = 10, + SVGA3D_DECLTYPE_USHORT2N = 11, + SVGA3D_DECLTYPE_USHORT4N = 12, + SVGA3D_DECLTYPE_UDEC3 = 13, + SVGA3D_DECLTYPE_DEC3N = 14, + SVGA3D_DECLTYPE_FLOAT16_2 = 15, + SVGA3D_DECLTYPE_FLOAT16_4 = 16, + SVGA3D_DECLTYPE_MAX, +} SVGA3dDeclType; + +/* + * This structure is used for the divisor for geometry instancing; + * it's a direct translation of the Direct3D equivalent. + */ +typedef union { + struct { + /* + * For index data, this number represents the number of instances to draw. + * For instance data, this number represents the number of + * instances/vertex in this stream + */ + uint32 count : 30; + + /* + * This is 1 if this is supposed to be the data that is repeated for + * every instance. + */ + uint32 indexedData : 1; + + /* + * This is 1 if this is supposed to be the per-instance data. + */ + uint32 instanceData : 1; + }; + + uint32 value; +} SVGA3dVertexDivisor; + +typedef enum { + SVGA3D_PRIMITIVE_INVALID = 0, + SVGA3D_PRIMITIVE_TRIANGLELIST = 1, + SVGA3D_PRIMITIVE_POINTLIST = 2, + SVGA3D_PRIMITIVE_LINELIST = 3, + SVGA3D_PRIMITIVE_LINESTRIP = 4, + SVGA3D_PRIMITIVE_TRIANGLESTRIP = 5, + SVGA3D_PRIMITIVE_TRIANGLEFAN = 6, + SVGA3D_PRIMITIVE_MAX +} SVGA3dPrimitiveType; + +typedef enum { + SVGA3D_COORDINATE_INVALID = 0, + SVGA3D_COORDINATE_LEFTHANDED = 1, + SVGA3D_COORDINATE_RIGHTHANDED = 2, + SVGA3D_COORDINATE_MAX +} SVGA3dCoordinateType; + +typedef enum { + SVGA3D_TRANSFORM_INVALID = 0, + SVGA3D_TRANSFORM_WORLD = 1, + SVGA3D_TRANSFORM_VIEW = 2, + SVGA3D_TRANSFORM_PROJECTION = 3, + SVGA3D_TRANSFORM_TEXTURE0 = 4, + SVGA3D_TRANSFORM_TEXTURE1 = 5, + SVGA3D_TRANSFORM_TEXTURE2 = 6, + SVGA3D_TRANSFORM_TEXTURE3 = 7, + SVGA3D_TRANSFORM_TEXTURE4 = 8, + SVGA3D_TRANSFORM_TEXTURE5 = 9, + SVGA3D_TRANSFORM_TEXTURE6 = 10, + SVGA3D_TRANSFORM_TEXTURE7 = 11, + SVGA3D_TRANSFORM_WORLD1 = 12, + SVGA3D_TRANSFORM_WORLD2 = 13, + SVGA3D_TRANSFORM_WORLD3 = 14, + SVGA3D_TRANSFORM_MAX +} SVGA3dTransformType; + +typedef enum { + SVGA3D_LIGHTTYPE_INVALID = 0, + SVGA3D_LIGHTTYPE_POINT = 1, + SVGA3D_LIGHTTYPE_SPOT1 = 2, /* 1-cone, in degrees */ + SVGA3D_LIGHTTYPE_SPOT2 = 3, /* 2-cone, in radians */ + SVGA3D_LIGHTTYPE_DIRECTIONAL = 4, + SVGA3D_LIGHTTYPE_MAX +} SVGA3dLightType; + +typedef enum { + SVGA3D_CUBEFACE_POSX = 0, + SVGA3D_CUBEFACE_NEGX = 1, + SVGA3D_CUBEFACE_POSY = 2, + SVGA3D_CUBEFACE_NEGY = 3, + SVGA3D_CUBEFACE_POSZ = 4, + SVGA3D_CUBEFACE_NEGZ = 5, +} SVGA3dCubeFace; + +typedef enum { + SVGA3D_SHADERTYPE_COMPILED_DX8 = 0, + SVGA3D_SHADERTYPE_VS = 1, + SVGA3D_SHADERTYPE_PS = 2, + SVGA3D_SHADERTYPE_MAX +} SVGA3dShaderType; + +typedef enum { + SVGA3D_CONST_TYPE_FLOAT = 0, + SVGA3D_CONST_TYPE_INT = 1, + SVGA3D_CONST_TYPE_BOOL = 2, +} SVGA3dShaderConstType; + +#define SVGA3D_MAX_SURFACE_FACES 6 + +typedef enum { + SVGA3D_STRETCH_BLT_POINT = 0, + SVGA3D_STRETCH_BLT_LINEAR = 1, + SVGA3D_STRETCH_BLT_MAX +} SVGA3dStretchBltMode; + +typedef enum { + SVGA3D_QUERYTYPE_OCCLUSION = 0, + SVGA3D_QUERYTYPE_MAX +} SVGA3dQueryType; + +typedef enum { + SVGA3D_QUERYSTATE_PENDING = 0, /* Waiting on the host (set by guest) */ + SVGA3D_QUERYSTATE_SUCCEEDED = 1, /* Completed successfully (set by host) */ + SVGA3D_QUERYSTATE_FAILED = 2, /* Completed unsuccessfully (set by host) */ + SVGA3D_QUERYSTATE_NEW = 3, /* Never submitted (For guest use only) */ +} SVGA3dQueryState; + +typedef enum { + SVGA3D_WRITE_HOST_VRAM = 1, + SVGA3D_READ_HOST_VRAM = 2, +} SVGA3dTransferType; + +/* + * The maximum number vertex arrays we're guaranteed to support in + * SVGA_3D_CMD_DRAWPRIMITIVES. + */ +#define SVGA3D_MAX_VERTEX_ARRAYS 32 + +/* + * Identifiers for commands in the command FIFO. + * + * IDs between 1000 and 1039 (inclusive) were used by obsolete versions of + * the SVGA3D protocol and remain reserved; they should not be used in the + * future. + * + * IDs between 1040 and 1999 (inclusive) are available for use by the + * current SVGA3D protocol. + * + * FIFO clients other than SVGA3D should stay below 1000, or at 2000 + * and up. + */ + +#define SVGA_3D_CMD_LEGACY_BASE 1000 +#define SVGA_3D_CMD_BASE 1040 + +#define SVGA_3D_CMD_SURFACE_DEFINE SVGA_3D_CMD_BASE + 0 +#define SVGA_3D_CMD_SURFACE_DESTROY SVGA_3D_CMD_BASE + 1 +#define SVGA_3D_CMD_SURFACE_COPY SVGA_3D_CMD_BASE + 2 +#define SVGA_3D_CMD_SURFACE_STRETCHBLT SVGA_3D_CMD_BASE + 3 +#define SVGA_3D_CMD_SURFACE_DMA SVGA_3D_CMD_BASE + 4 +#define SVGA_3D_CMD_CONTEXT_DEFINE SVGA_3D_CMD_BASE + 5 +#define SVGA_3D_CMD_CONTEXT_DESTROY SVGA_3D_CMD_BASE + 6 +#define SVGA_3D_CMD_SETTRANSFORM SVGA_3D_CMD_BASE + 7 +#define SVGA_3D_CMD_SETZRANGE SVGA_3D_CMD_BASE + 8 +#define SVGA_3D_CMD_SETRENDERSTATE SVGA_3D_CMD_BASE + 9 +#define SVGA_3D_CMD_SETRENDERTARGET SVGA_3D_CMD_BASE + 10 +#define SVGA_3D_CMD_SETTEXTURESTATE SVGA_3D_CMD_BASE + 11 +#define SVGA_3D_CMD_SETMATERIAL SVGA_3D_CMD_BASE + 12 +#define SVGA_3D_CMD_SETLIGHTDATA SVGA_3D_CMD_BASE + 13 +#define SVGA_3D_CMD_SETLIGHTENABLED SVGA_3D_CMD_BASE + 14 +#define SVGA_3D_CMD_SETVIEWPORT SVGA_3D_CMD_BASE + 15 +#define SVGA_3D_CMD_SETCLIPPLANE SVGA_3D_CMD_BASE + 16 +#define SVGA_3D_CMD_CLEAR SVGA_3D_CMD_BASE + 17 +#define SVGA_3D_CMD_PRESENT SVGA_3D_CMD_BASE + 18 // Deprecated +#define SVGA_3D_CMD_SHADER_DEFINE SVGA_3D_CMD_BASE + 19 +#define SVGA_3D_CMD_SHADER_DESTROY SVGA_3D_CMD_BASE + 20 +#define SVGA_3D_CMD_SET_SHADER SVGA_3D_CMD_BASE + 21 +#define SVGA_3D_CMD_SET_SHADER_CONST SVGA_3D_CMD_BASE + 22 +#define SVGA_3D_CMD_DRAW_PRIMITIVES SVGA_3D_CMD_BASE + 23 +#define SVGA_3D_CMD_SETSCISSORRECT SVGA_3D_CMD_BASE + 24 +#define SVGA_3D_CMD_BEGIN_QUERY SVGA_3D_CMD_BASE + 25 +#define SVGA_3D_CMD_END_QUERY SVGA_3D_CMD_BASE + 26 +#define SVGA_3D_CMD_WAIT_FOR_QUERY SVGA_3D_CMD_BASE + 27 +#define SVGA_3D_CMD_PRESENT_READBACK SVGA_3D_CMD_BASE + 28 // Deprecated +#define SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN SVGA_3D_CMD_BASE + 29 +#define SVGA_3D_CMD_MAX SVGA_3D_CMD_BASE + 30 + +#define SVGA_3D_CMD_FUTURE_MAX 2000 + +/* + * Common substructures used in multiple FIFO commands: + */ + +typedef struct { + union { + struct { + uint16 function; // SVGA3dFogFunction + uint8 type; // SVGA3dFogType + uint8 base; // SVGA3dFogBase + }; + uint32 uintValue; + }; +} SVGA3dFogMode; + +/* + * Uniquely identify one image (a 1D/2D/3D array) from a surface. This + * is a surface ID as well as face/mipmap indices. + */ + +typedef +struct SVGA3dSurfaceImageId { + uint32 sid; + uint32 face; + uint32 mipmap; +} SVGA3dSurfaceImageId; + +typedef +struct SVGA3dGuestImage { + SVGAGuestPtr ptr; + + /* + * A note on interpretation of pitch: This value of pitch is the + * number of bytes between vertically adjacent image + * blocks. Normally this is the number of bytes between the first + * pixel of two adjacent scanlines. With compressed textures, + * however, this may represent the number of bytes between + * compression blocks rather than between rows of pixels. + * + * XXX: Compressed textures currently must be tightly packed in guest memory. + * + * If the image is 1-dimensional, pitch is ignored. + * + * If 'pitch' is zero, the SVGA3D device calculates a pitch value + * assuming each row of blocks is tightly packed. + */ + uint32 pitch; +} SVGA3dGuestImage; + + +/* + * FIFO command format definitions: + */ + +/* + * The data size header following cmdNum for every 3d command + */ +typedef +struct { + uint32 id; + uint32 size; +} SVGA3dCmdHeader; + +/* + * A surface is a hierarchy of host VRAM surfaces: 1D, 2D, or 3D, with + * optional mipmaps and cube faces. + */ + +typedef +struct { + uint32 width; + uint32 height; + uint32 depth; +} SVGA3dSize; + +typedef enum { + SVGA3D_SURFACE_CUBEMAP = (1 << 0), + SVGA3D_SURFACE_HINT_STATIC = (1 << 1), + SVGA3D_SURFACE_HINT_DYNAMIC = (1 << 2), + SVGA3D_SURFACE_HINT_INDEXBUFFER = (1 << 3), + SVGA3D_SURFACE_HINT_VERTEXBUFFER = (1 << 4), + SVGA3D_SURFACE_HINT_TEXTURE = (1 << 5), + SVGA3D_SURFACE_HINT_RENDERTARGET = (1 << 6), + SVGA3D_SURFACE_HINT_DEPTHSTENCIL = (1 << 7), + SVGA3D_SURFACE_HINT_WRITEONLY = (1 << 8), +} SVGA3dSurfaceFlags; + +typedef +struct { + uint32 numMipLevels; +} SVGA3dSurfaceFace; + +typedef +struct { + uint32 sid; + SVGA3dSurfaceFlags surfaceFlags; + SVGA3dSurfaceFormat format; + SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES]; + /* + * Followed by an SVGA3dSize structure for each mip level in each face. + * + * A note on surface sizes: Sizes are always specified in pixels, + * even if the true surface size is not a multiple of the minimum + * block size of the surface's format. For example, a 3x3x1 DXT1 + * compressed texture would actually be stored as a 4x4x1 image in + * memory. + */ +} SVGA3dCmdDefineSurface; /* SVGA_3D_CMD_SURFACE_DEFINE */ + +typedef +struct { + uint32 sid; +} SVGA3dCmdDestroySurface; /* SVGA_3D_CMD_SURFACE_DESTROY */ + +typedef +struct { + uint32 cid; +} SVGA3dCmdDefineContext; /* SVGA_3D_CMD_CONTEXT_DEFINE */ + +typedef +struct { + uint32 cid; +} SVGA3dCmdDestroyContext; /* SVGA_3D_CMD_CONTEXT_DESTROY */ + +typedef +struct { + uint32 cid; + SVGA3dClearFlag clearFlag; + uint32 color; + float depth; + uint32 stencil; + /* Followed by variable number of SVGA3dRect structures */ +} SVGA3dCmdClear; /* SVGA_3D_CMD_CLEAR */ + +typedef +struct SVGA3dCopyRect { + uint32 x; + uint32 y; + uint32 w; + uint32 h; + uint32 srcx; + uint32 srcy; +} SVGA3dCopyRect; + +typedef +struct SVGA3dCopyBox { + uint32 x; + uint32 y; + uint32 z; + uint32 w; + uint32 h; + uint32 d; + uint32 srcx; + uint32 srcy; + uint32 srcz; +} SVGA3dCopyBox; + +typedef +struct { + uint32 x; + uint32 y; + uint32 w; + uint32 h; +} SVGA3dRect; + +typedef +struct { + uint32 x; + uint32 y; + uint32 z; + uint32 w; + uint32 h; + uint32 d; +} SVGA3dBox; + +typedef +struct { + uint32 x; + uint32 y; + uint32 z; +} SVGA3dPoint; + +typedef +struct { + SVGA3dLightType type; + SVGA3dBool inWorldSpace; + float diffuse[4]; + float specular[4]; + float ambient[4]; + float position[4]; + float direction[4]; + float range; + float falloff; + float attenuation0; + float attenuation1; + float attenuation2; + float theta; + float phi; +} SVGA3dLightData; + +typedef +struct { + uint32 sid; + /* Followed by variable number of SVGA3dCopyRect structures */ +} SVGA3dCmdPresent; /* SVGA_3D_CMD_PRESENT */ + +typedef +struct { + SVGA3dRenderStateName state; + union { + uint32 uintValue; + float floatValue; + }; +} SVGA3dRenderState; + +typedef +struct { + uint32 cid; + /* Followed by variable number of SVGA3dRenderState structures */ +} SVGA3dCmdSetRenderState; /* SVGA_3D_CMD_SETRENDERSTATE */ + +typedef +struct { + uint32 cid; + SVGA3dRenderTargetType type; + SVGA3dSurfaceImageId target; +} SVGA3dCmdSetRenderTarget; /* SVGA_3D_CMD_SETRENDERTARGET */ + +typedef +struct { + SVGA3dSurfaceImageId src; + SVGA3dSurfaceImageId dest; + /* Followed by variable number of SVGA3dCopyBox structures */ +} SVGA3dCmdSurfaceCopy; /* SVGA_3D_CMD_SURFACE_COPY */ + +typedef +struct { + SVGA3dSurfaceImageId src; + SVGA3dSurfaceImageId dest; + SVGA3dBox boxSrc; + SVGA3dBox boxDest; + SVGA3dStretchBltMode mode; +} SVGA3dCmdSurfaceStretchBlt; /* SVGA_3D_CMD_SURFACE_STRETCHBLT */ + +typedef +struct { + /* + * If the discard flag is present in a surface DMA operation, the host may + * discard the contents of the current mipmap level and face of the target + * surface before applying the surface DMA contents. + */ + uint32 discard : 1; + + /* + * If the unsynchronized flag is present, the host may perform this upload + * without syncing to pending reads on this surface. + */ + uint32 unsynchronized : 1; + + /* + * Guests *MUST* set the reserved bits to 0 before submitting the command + * suffix as future flags may occupy these bits. + */ + uint32 reserved : 30; +} SVGA3dSurfaceDMAFlags; + +typedef +struct { + SVGA3dGuestImage guest; + SVGA3dSurfaceImageId host; + SVGA3dTransferType transfer; + /* + * Followed by variable number of SVGA3dCopyBox structures. For consistency + * in all clipping logic and coordinate translation, we define the + * "source" in each copyBox as the guest image and the + * "destination" as the host image, regardless of transfer + * direction. + * + * For efficiency, the SVGA3D device is free to copy more data than + * specified. For example, it may round copy boxes outwards such + * that they lie on particular alignment boundaries. + */ +} SVGA3dCmdSurfaceDMA; /* SVGA_3D_CMD_SURFACE_DMA */ + +/* + * SVGA3dCmdSurfaceDMASuffix -- + * + * This is a command suffix that will appear after a SurfaceDMA command in + * the FIFO. It contains some extra information that hosts may use to + * optimize performance or protect the guest. This suffix exists to preserve + * backwards compatibility while also allowing for new functionality to be + * implemented. + */ + +typedef +struct { + uint32 suffixSize; + + /* + * The maximum offset is used to determine the maximum offset from the + * guestPtr base address that will be accessed or written to during this + * surfaceDMA. If the suffix is supported, the host will respect this + * boundary while performing surface DMAs. + * + * Defaults to MAX_UINT32 + */ + uint32 maximumOffset; + + /* + * A set of flags that describes optimizations that the host may perform + * while performing this surface DMA operation. The guest should never rely + * on behaviour that is different when these flags are set for correctness. + * + * Defaults to 0 + */ + SVGA3dSurfaceDMAFlags flags; +} SVGA3dCmdSurfaceDMASuffix; + +/* + * SVGA_3D_CMD_DRAW_PRIMITIVES -- + * + * This command is the SVGA3D device's generic drawing entry point. + * It can draw multiple ranges of primitives, optionally using an + * index buffer, using an arbitrary collection of vertex buffers. + * + * Each SVGA3dVertexDecl defines a distinct vertex array to bind + * during this draw call. The declarations specify which surface + * the vertex data lives in, what that vertex data is used for, + * and how to interpret it. + * + * Each SVGA3dPrimitiveRange defines a collection of primitives + * to render using the same vertex arrays. An index buffer is + * optional. + */ + +typedef +struct { + /* + * A range hint is an optional specification for the range of indices + * in an SVGA3dArray that will be used. If 'last' is zero, it is assumed + * that the entire array will be used. + * + * These are only hints. The SVGA3D device may use them for + * performance optimization if possible, but it's also allowed to + * ignore these values. + */ + uint32 first; + uint32 last; +} SVGA3dArrayRangeHint; + +typedef +struct { + /* + * Define the origin and shape of a vertex or index array. Both + * 'offset' and 'stride' are in bytes. The provided surface will be + * reinterpreted as a flat array of bytes in the same format used + * by surface DMA operations. To avoid unnecessary conversions, the + * surface should be created with the SVGA3D_BUFFER format. + * + * Index 0 in the array starts 'offset' bytes into the surface. + * Index 1 begins at byte 'offset + stride', etc. Array indices may + * not be negative. + */ + uint32 surfaceId; + uint32 offset; + uint32 stride; +} SVGA3dArray; + +typedef +struct { + /* + * Describe a vertex array's data type, and define how it is to be + * used by the fixed function pipeline or the vertex shader. It + * isn't useful to have two VertexDecls with the same + * VertexArrayIdentity in one draw call. + */ + SVGA3dDeclType type; + SVGA3dDeclMethod method; + SVGA3dDeclUsage usage; + uint32 usageIndex; +} SVGA3dVertexArrayIdentity; + +typedef +struct { + SVGA3dVertexArrayIdentity identity; + SVGA3dArray array; + SVGA3dArrayRangeHint rangeHint; +} SVGA3dVertexDecl; + +typedef +struct { + /* + * Define a group of primitives to render, from sequential indices. + * + * The value of 'primitiveType' and 'primitiveCount' imply the + * total number of vertices that will be rendered. + */ + SVGA3dPrimitiveType primType; + uint32 primitiveCount; + + /* + * Optional index buffer. If indexArray.surfaceId is + * SVGA3D_INVALID_ID, we render without an index buffer. Rendering + * without an index buffer is identical to rendering with an index + * buffer containing the sequence [0, 1, 2, 3, ...]. + * + * If an index buffer is in use, indexWidth specifies the width in + * bytes of each index value. It must be less than or equal to + * indexArray.stride. + * + * (Currently, the SVGA3D device requires index buffers to be tightly + * packed. In other words, indexWidth == indexArray.stride) + */ + SVGA3dArray indexArray; + uint32 indexWidth; + + /* + * Optional index bias. This number is added to all indices from + * indexArray before they are used as vertex array indices. This + * can be used in multiple ways: + * + * - When not using an indexArray, this bias can be used to + * specify where in the vertex arrays to begin rendering. + * + * - A positive number here is equivalent to increasing the + * offset in each vertex array. + * + * - A negative number can be used to render using a small + * vertex array and an index buffer that contains large + * values. This may be used by some applications that + * crop a vertex buffer without modifying their index + * buffer. + * + * Note that rendering with a negative bias value may be slower and + * use more memory than rendering with a positive or zero bias. + */ + int32 indexBias; +} SVGA3dPrimitiveRange; + +typedef +struct { + uint32 cid; + uint32 numVertexDecls; + uint32 numRanges; + + /* + * There are two variable size arrays after the + * SVGA3dCmdDrawPrimitives structure. In order, + * they are: + * + * 1. SVGA3dVertexDecl, quantity 'numVertexDecls' + * 2. SVGA3dPrimitiveRange, quantity 'numRanges' + * 3. Optionally, SVGA3dVertexDivisor, quantity 'numVertexDecls' (contains + * the frequency divisor for this the corresponding vertex decl) + */ +} SVGA3dCmdDrawPrimitives; /* SVGA_3D_CMD_DRAWPRIMITIVES */ + +typedef +struct { + uint32 stage; + SVGA3dTextureStateName name; + union { + uint32 value; + float floatValue; + }; +} SVGA3dTextureState; + +typedef +struct { + uint32 cid; + /* Followed by variable number of SVGA3dTextureState structures */ +} SVGA3dCmdSetTextureState; /* SVGA_3D_CMD_SETTEXTURESTATE */ + +typedef +struct { + uint32 cid; + SVGA3dTransformType type; + float matrix[16]; +} SVGA3dCmdSetTransform; /* SVGA_3D_CMD_SETTRANSFORM */ + +typedef +struct { + float min; + float max; +} SVGA3dZRange; + +typedef +struct { + uint32 cid; + SVGA3dZRange zRange; +} SVGA3dCmdSetZRange; /* SVGA_3D_CMD_SETZRANGE */ + +typedef +struct { + float diffuse[4]; + float ambient[4]; + float specular[4]; + float emissive[4]; + float shininess; +} SVGA3dMaterial; + +typedef +struct { + uint32 cid; + SVGA3dFace face; + SVGA3dMaterial material; +} SVGA3dCmdSetMaterial; /* SVGA_3D_CMD_SETMATERIAL */ + +typedef +struct { + uint32 cid; + uint32 index; + SVGA3dLightData data; +} SVGA3dCmdSetLightData; /* SVGA_3D_CMD_SETLIGHTDATA */ + +typedef +struct { + uint32 cid; + uint32 index; + uint32 enabled; +} SVGA3dCmdSetLightEnabled; /* SVGA_3D_CMD_SETLIGHTENABLED */ + +typedef +struct { + uint32 cid; + SVGA3dRect rect; +} SVGA3dCmdSetViewport; /* SVGA_3D_CMD_SETVIEWPORT */ + +typedef +struct { + uint32 cid; + SVGA3dRect rect; +} SVGA3dCmdSetScissorRect; /* SVGA_3D_CMD_SETSCISSORRECT */ + +typedef +struct { + uint32 cid; + uint32 index; + float plane[4]; +} SVGA3dCmdSetClipPlane; /* SVGA_3D_CMD_SETCLIPPLANE */ + +typedef +struct { + uint32 cid; + uint32 shid; + SVGA3dShaderType type; + /* Followed by variable number of DWORDs for shader bycode */ +} SVGA3dCmdDefineShader; /* SVGA_3D_CMD_SHADER_DEFINE */ + +typedef +struct { + uint32 cid; + uint32 shid; + SVGA3dShaderType type; +} SVGA3dCmdDestroyShader; /* SVGA_3D_CMD_SHADER_DESTROY */ + +typedef +struct { + uint32 cid; + uint32 reg; /* register number */ + SVGA3dShaderType type; + SVGA3dShaderConstType ctype; + uint32 values[4]; +} SVGA3dCmdSetShaderConst; /* SVGA_3D_CMD_SET_SHADER_CONST */ + +typedef +struct { + uint32 cid; + SVGA3dShaderType type; + uint32 shid; +} SVGA3dCmdSetShader; /* SVGA_3D_CMD_SET_SHADER */ + +typedef +struct { + uint32 cid; + SVGA3dQueryType type; +} SVGA3dCmdBeginQuery; /* SVGA_3D_CMD_BEGIN_QUERY */ + +typedef +struct { + uint32 cid; + SVGA3dQueryType type; + SVGAGuestPtr guestResult; /* Points to an SVGA3dQueryResult structure */ +} SVGA3dCmdEndQuery; /* SVGA_3D_CMD_END_QUERY */ + +typedef +struct { + uint32 cid; /* Same parameters passed to END_QUERY */ + SVGA3dQueryType type; + SVGAGuestPtr guestResult; +} SVGA3dCmdWaitForQuery; /* SVGA_3D_CMD_WAIT_FOR_QUERY */ + +typedef +struct { + uint32 totalSize; /* Set by guest before query is ended. */ + SVGA3dQueryState state; /* Set by host or guest. See SVGA3dQueryState. */ + union { /* Set by host on exit from PENDING state */ + uint32 result32; + }; +} SVGA3dQueryResult; + +/* + * SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN -- + * + * This is a blit from an SVGA3D surface to a Screen Object. Just + * like GMR-to-screen blits, this blit may be directed at a + * specific screen or to the virtual coordinate space. + * + * The blit copies from a rectangular region of an SVGA3D surface + * image to a rectangular region of a screen or screens. + * + * This command takes an optional variable-length list of clipping + * rectangles after the body of the command. If no rectangles are + * specified, there is no clipping region. The entire destRect is + * drawn to. If one or more rectangles are included, they describe + * a clipping region. The clip rectangle coordinates are measured + * relative to the top-left corner of destRect. + * + * This clipping region serves multiple purposes: + * + * - It can be used to perform an irregularly shaped blit more + * efficiently than by issuing many separate blit commands. + * + * - It is equivalent to allowing blits with non-integer + * source coordinates. You could blit just one half-pixel + * of a source, for example, by specifying a larger + * destination rectangle than you need, then removing + * part of it using a clip rectangle. + * + * Availability: + * SVGA_FIFO_CAP_SCREEN_OBJECT + * + * Limitations: + * + * - Currently, no backend supports blits from a mipmap or face + * other than the first one. + */ + +typedef +struct { + SVGA3dSurfaceImageId srcImage; + SVGASignedRect srcRect; + uint32 destScreenId; /* Screen ID or SVGA_ID_INVALID for virt. coords */ + SVGASignedRect destRect; /* Supports scaling if src/rest different size */ + /* Clipping: zero or more SVGASignedRects follow */ +} SVGA3dCmdBlitSurfaceToScreen; /* SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN */ + + +/* + * Capability query index. + * + * Notes: + * + * 1. SVGA3D_DEVCAP_MAX_TEXTURES reflects the maximum number of + * fixed-function texture units available. Each of these units + * work in both FFP and Shader modes, and they support texture + * transforms and texture coordinates. The host may have additional + * texture image units that are only usable with shaders. + * + * 2. The BUFFER_FORMAT capabilities are deprecated, and they always + * return TRUE. Even on physical hardware that does not support + * these formats natively, the SVGA3D device will provide an emulation + * which should be invisible to the guest OS. + * + * In general, the SVGA3D device should support any operation on + * any surface format, it just may perform some of these + * operations in software depending on the capabilities of the + * available physical hardware. + * + * XXX: In the future, we will add capabilities that describe in + * detail what formats are supported in hardware for what kinds + * of operations. + */ + +typedef enum { + SVGA3D_DEVCAP_3D = 0, + SVGA3D_DEVCAP_MAX_LIGHTS = 1, + SVGA3D_DEVCAP_MAX_TEXTURES = 2, /* See note (1) */ + SVGA3D_DEVCAP_MAX_CLIP_PLANES = 3, + SVGA3D_DEVCAP_VERTEX_SHADER_VERSION = 4, + SVGA3D_DEVCAP_VERTEX_SHADER = 5, + SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION = 6, + SVGA3D_DEVCAP_FRAGMENT_SHADER = 7, + SVGA3D_DEVCAP_MAX_RENDER_TARGETS = 8, + SVGA3D_DEVCAP_S23E8_TEXTURES = 9, + SVGA3D_DEVCAP_S10E5_TEXTURES = 10, + SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND = 11, + SVGA3D_DEVCAP_D16_BUFFER_FORMAT = 12, /* See note (2) */ + SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT = 13, /* See note (2) */ + SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT = 14, /* See note (2) */ + SVGA3D_DEVCAP_QUERY_TYPES = 15, + SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING = 16, + SVGA3D_DEVCAP_MAX_POINT_SIZE = 17, + SVGA3D_DEVCAP_MAX_SHADER_TEXTURES = 18, + SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH = 19, + SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT = 20, + SVGA3D_DEVCAP_MAX_VOLUME_EXTENT = 21, + SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT = 22, + SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO = 23, + SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY = 24, + SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT = 25, + SVGA3D_DEVCAP_MAX_VERTEX_INDEX = 26, + SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS = 27, + SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS = 28, + SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS = 29, + SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS = 30, + SVGA3D_DEVCAP_TEXTURE_OPS = 31, + SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8 = 32, + SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8 = 33, + SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10 = 34, + SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5 = 35, + SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5 = 36, + SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4 = 37, + SVGA3D_DEVCAP_SURFACEFMT_R5G6B5 = 38, + SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16 = 39, + SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8 = 40, + SVGA3D_DEVCAP_SURFACEFMT_ALPHA8 = 41, + SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8 = 42, + SVGA3D_DEVCAP_SURFACEFMT_Z_D16 = 43, + SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8 = 44, + SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8 = 45, + SVGA3D_DEVCAP_SURFACEFMT_DXT1 = 46, + SVGA3D_DEVCAP_SURFACEFMT_DXT2 = 47, + SVGA3D_DEVCAP_SURFACEFMT_DXT3 = 48, + SVGA3D_DEVCAP_SURFACEFMT_DXT4 = 49, + SVGA3D_DEVCAP_SURFACEFMT_DXT5 = 50, + SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8 = 51, + SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10 = 52, + SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8 = 53, + SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8 = 54, + SVGA3D_DEVCAP_SURFACEFMT_CxV8U8 = 55, + SVGA3D_DEVCAP_SURFACEFMT_R_S10E5 = 56, + SVGA3D_DEVCAP_SURFACEFMT_R_S23E8 = 57, + SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5 = 58, + SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8 = 59, + SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5 = 60, + SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8 = 61, + SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES = 63, + + /* + * Note that MAX_SIMULTANEOUS_RENDER_TARGETS is a maximum count of color + * render targets. This does no include the depth or stencil targets. + */ + SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS = 64, + + SVGA3D_DEVCAP_SURFACEFMT_V16U16 = 65, + SVGA3D_DEVCAP_SURFACEFMT_G16R16 = 66, + SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16 = 67, + SVGA3D_DEVCAP_SURFACEFMT_UYVY = 68, + SVGA3D_DEVCAP_SURFACEFMT_YUY2 = 69, + + /* + * Don't add new caps into the previous section; the values in this + * enumeration must not change. You can put new values right before + * SVGA3D_DEVCAP_MAX. + */ + SVGA3D_DEVCAP_MAX /* This must be the last index. */ +} SVGA3dDevCapIndex; + +typedef union { + Bool b; + uint32 u; + int32 i; + float f; +} SVGA3dDevCapResult; + +#endif /* _SVGA3D_REG_H_ */ diff --git a/drivers/gpu/drm/vmwgfx/svga_escape.h b/drivers/gpu/drm/vmwgfx/svga_escape.h new file mode 100644 index 0000000..7b85e9b --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/svga_escape.h @@ -0,0 +1,89 @@ +/********************************************************** + * Copyright 2007-2009 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + **********************************************************/ + +/* + * svga_escape.h -- + * + * Definitions for our own (vendor-specific) SVGA Escape commands. + */ + +#ifndef _SVGA_ESCAPE_H_ +#define _SVGA_ESCAPE_H_ + + +/* + * Namespace IDs for the escape command + */ + +#define SVGA_ESCAPE_NSID_VMWARE 0x00000000 +#define SVGA_ESCAPE_NSID_DEVEL 0xFFFFFFFF + + +/* + * Within SVGA_ESCAPE_NSID_VMWARE, we multiplex commands according to + * the first DWORD of escape data (after the nsID and size). As a + * guideline we're using the high word and low word as a major and + * minor command number, respectively. + * + * Major command number allocation: + * + * 0000: Reserved + * 0001: SVGA_ESCAPE_VMWARE_LOG (svga_binary_logger.h) + * 0002: SVGA_ESCAPE_VMWARE_VIDEO (svga_overlay.h) + * 0003: SVGA_ESCAPE_VMWARE_HINT (svga_escape.h) + */ + +#define SVGA_ESCAPE_VMWARE_MAJOR_MASK 0xFFFF0000 + + +/* + * SVGA Hint commands. + * + * These escapes let the SVGA driver provide optional information to + * he host about the state of the guest or guest applications. The + * host can use these hints to make user interface or performance + * decisions. + * + * Notes: + * + * - SVGA_ESCAPE_VMWARE_HINT_FULLSCREEN is deprecated for guests + * that use the SVGA Screen Object extension. Instead of sending + * this escape, use the SVGA_SCREEN_FULLSCREEN_HINT flag on your + * Screen Object. + */ + +#define SVGA_ESCAPE_VMWARE_HINT 0x00030000 +#define SVGA_ESCAPE_VMWARE_HINT_FULLSCREEN 0x00030001 // Deprecated + +typedef +struct { + uint32 command; + uint32 fullscreen; + struct { + int32 x, y; + } monitorPosition; +} SVGAEscapeHintFullscreen; + +#endif /* _SVGA_ESCAPE_H_ */ diff --git a/drivers/gpu/drm/vmwgfx/svga_overlay.h b/drivers/gpu/drm/vmwgfx/svga_overlay.h new file mode 100644 index 0000000..f753d73 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/svga_overlay.h @@ -0,0 +1,201 @@ +/********************************************************** + * Copyright 2007-2009 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + **********************************************************/ + +/* + * svga_overlay.h -- + * + * Definitions for video-overlay support. + */ + +#ifndef _SVGA_OVERLAY_H_ +#define _SVGA_OVERLAY_H_ + +#include "svga_reg.h" + +/* + * Video formats we support + */ + +#define VMWARE_FOURCC_YV12 0x32315659 // 'Y' 'V' '1' '2' +#define VMWARE_FOURCC_YUY2 0x32595559 // 'Y' 'U' 'Y' '2' +#define VMWARE_FOURCC_UYVY 0x59565955 // 'U' 'Y' 'V' 'Y' + +typedef enum { + SVGA_OVERLAY_FORMAT_INVALID = 0, + SVGA_OVERLAY_FORMAT_YV12 = VMWARE_FOURCC_YV12, + SVGA_OVERLAY_FORMAT_YUY2 = VMWARE_FOURCC_YUY2, + SVGA_OVERLAY_FORMAT_UYVY = VMWARE_FOURCC_UYVY, +} SVGAOverlayFormat; + +#define SVGA_VIDEO_COLORKEY_MASK 0x00ffffff + +#define SVGA_ESCAPE_VMWARE_VIDEO 0x00020000 + +#define SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS 0x00020001 + /* FIFO escape layout: + * Type, Stream Id, (Register Id, Value) pairs */ + +#define SVGA_ESCAPE_VMWARE_VIDEO_FLUSH 0x00020002 + /* FIFO escape layout: + * Type, Stream Id */ + +typedef +struct SVGAEscapeVideoSetRegs { + struct { + uint32 cmdType; + uint32 streamId; + } header; + + // May include zero or more items. + struct { + uint32 registerId; + uint32 value; + } items[1]; +} SVGAEscapeVideoSetRegs; + +typedef +struct SVGAEscapeVideoFlush { + uint32 cmdType; + uint32 streamId; +} SVGAEscapeVideoFlush; + + +/* + * Struct definitions for the video overlay commands built on + * SVGAFifoCmdEscape. + */ +typedef +struct { + uint32 command; + uint32 overlay; +} SVGAFifoEscapeCmdVideoBase; + +typedef +struct { + SVGAFifoEscapeCmdVideoBase videoCmd; +} SVGAFifoEscapeCmdVideoFlush; + +typedef +struct { + SVGAFifoEscapeCmdVideoBase videoCmd; + struct { + uint32 regId; + uint32 value; + } items[1]; +} SVGAFifoEscapeCmdVideoSetRegs; + +typedef +struct { + SVGAFifoEscapeCmdVideoBase videoCmd; + struct { + uint32 regId; + uint32 value; + } items[SVGA_VIDEO_NUM_REGS]; +} SVGAFifoEscapeCmdVideoSetAllRegs; + + +/* + *---------------------------------------------------------------------- + * + * VMwareVideoGetAttributes -- + * + * Computes the size, pitches and offsets for YUV frames. + * + * Results: + * TRUE on success; otherwise FALSE on failure. + * + * Side effects: + * Pitches and offsets for the given YUV frame are put in 'pitches' + * and 'offsets' respectively. They are both optional though. + * + *---------------------------------------------------------------------- + */ + +static inline bool +VMwareVideoGetAttributes(const SVGAOverlayFormat format, // IN + uint32 *width, // IN / OUT + uint32 *height, // IN / OUT + uint32 *size, // OUT + uint32 *pitches, // OUT (optional) + uint32 *offsets) // OUT (optional) +{ + int tmp; + + *width = (*width + 1) & ~1; + + if (offsets) { + offsets[0] = 0; + } + + switch (format) { + case VMWARE_FOURCC_YV12: + *height = (*height + 1) & ~1; + *size = (*width + 3) & ~3; + + if (pitches) { + pitches[0] = *size; + } + + *size *= *height; + + if (offsets) { + offsets[1] = *size; + } + + tmp = ((*width >> 1) + 3) & ~3; + + if (pitches) { + pitches[1] = pitches[2] = tmp; + } + + tmp *= (*height >> 1); + *size += tmp; + + if (offsets) { + offsets[2] = *size; + } + + *size += tmp; + break; + + case VMWARE_FOURCC_YUY2: + case VMWARE_FOURCC_UYVY: + *size = *width * 2; + + if (pitches) { + pitches[0] = *size; + } + + *size *= *height; + break; + + default: + return false; + } + + return true; +} + +#endif // _SVGA_OVERLAY_H_ diff --git a/drivers/gpu/drm/vmwgfx/svga_reg.h b/drivers/gpu/drm/vmwgfx/svga_reg.h new file mode 100644 index 0000000..1b96c2e --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/svga_reg.h @@ -0,0 +1,1346 @@ +/********************************************************** + * Copyright 1998-2009 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + **********************************************************/ + +/* + * svga_reg.h -- + * + * Virtual hardware definitions for the VMware SVGA II device. + */ + +#ifndef _SVGA_REG_H_ +#define _SVGA_REG_H_ + +/* + * PCI device IDs. + */ +#define PCI_VENDOR_ID_VMWARE 0x15AD +#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405 + +/* + * Legal values for the SVGA_REG_CURSOR_ON register in old-fashioned + * cursor bypass mode. This is still supported, but no new guest + * drivers should use it. + */ +#define SVGA_CURSOR_ON_HIDE 0x0 /* Must be 0 to maintain backward compatibility */ +#define SVGA_CURSOR_ON_SHOW 0x1 /* Must be 1 to maintain backward compatibility */ +#define SVGA_CURSOR_ON_REMOVE_FROM_FB 0x2 /* Remove the cursor from the framebuffer because we need to see what's under it */ +#define SVGA_CURSOR_ON_RESTORE_TO_FB 0x3 /* Put the cursor back in the framebuffer so the user can see it */ + +/* + * The maximum framebuffer size that can traced for e.g. guests in VESA mode. + * The changeMap in the monitor is proportional to this number. Therefore, we'd + * like to keep it as small as possible to reduce monitor overhead (using + * SVGA_VRAM_MAX_SIZE for this increases the size of the shared area by over + * 4k!). + * + * NB: For compatibility reasons, this value must be greater than 0xff0000. + * See bug 335072. + */ +#define SVGA_FB_MAX_TRACEABLE_SIZE 0x1000000 + +#define SVGA_MAX_PSEUDOCOLOR_DEPTH 8 +#define SVGA_MAX_PSEUDOCOLORS (1 << SVGA_MAX_PSEUDOCOLOR_DEPTH) +#define SVGA_NUM_PALETTE_REGS (3 * SVGA_MAX_PSEUDOCOLORS) + +#define SVGA_MAGIC 0x900000UL +#define SVGA_MAKE_ID(ver) (SVGA_MAGIC << 8 | (ver)) + +/* Version 2 let the address of the frame buffer be unsigned on Win32 */ +#define SVGA_VERSION_2 2 +#define SVGA_ID_2 SVGA_MAKE_ID(SVGA_VERSION_2) + +/* Version 1 has new registers starting with SVGA_REG_CAPABILITIES so + PALETTE_BASE has moved */ +#define SVGA_VERSION_1 1 +#define SVGA_ID_1 SVGA_MAKE_ID(SVGA_VERSION_1) + +/* Version 0 is the initial version */ +#define SVGA_VERSION_0 0 +#define SVGA_ID_0 SVGA_MAKE_ID(SVGA_VERSION_0) + +/* "Invalid" value for all SVGA IDs. (Version ID, screen object ID, surface ID...) */ +#define SVGA_ID_INVALID 0xFFFFFFFF + +/* Port offsets, relative to BAR0 */ +#define SVGA_INDEX_PORT 0x0 +#define SVGA_VALUE_PORT 0x1 +#define SVGA_BIOS_PORT 0x2 +#define SVGA_IRQSTATUS_PORT 0x8 + +/* + * Interrupt source flags for IRQSTATUS_PORT and IRQMASK. + * + * Interrupts are only supported when the + * SVGA_CAP_IRQMASK capability is present. + */ +#define SVGA_IRQFLAG_ANY_FENCE 0x1 /* Any fence was passed */ +#define SVGA_IRQFLAG_FIFO_PROGRESS 0x2 /* Made forward progress in the FIFO */ +#define SVGA_IRQFLAG_FENCE_GOAL 0x4 /* SVGA_FIFO_FENCE_GOAL reached */ + +/* + * Registers + */ + +enum { + SVGA_REG_ID = 0, + SVGA_REG_ENABLE = 1, + SVGA_REG_WIDTH = 2, + SVGA_REG_HEIGHT = 3, + SVGA_REG_MAX_WIDTH = 4, + SVGA_REG_MAX_HEIGHT = 5, + SVGA_REG_DEPTH = 6, + SVGA_REG_BITS_PER_PIXEL = 7, /* Current bpp in the guest */ + SVGA_REG_PSEUDOCOLOR = 8, + SVGA_REG_RED_MASK = 9, + SVGA_REG_GREEN_MASK = 10, + SVGA_REG_BLUE_MASK = 11, + SVGA_REG_BYTES_PER_LINE = 12, + SVGA_REG_FB_START = 13, /* (Deprecated) */ + SVGA_REG_FB_OFFSET = 14, + SVGA_REG_VRAM_SIZE = 15, + SVGA_REG_FB_SIZE = 16, + + /* ID 0 implementation only had the above registers, then the palette */ + + SVGA_REG_CAPABILITIES = 17, + SVGA_REG_MEM_START = 18, /* (Deprecated) */ + SVGA_REG_MEM_SIZE = 19, + SVGA_REG_CONFIG_DONE = 20, /* Set when memory area configured */ + SVGA_REG_SYNC = 21, /* See "FIFO Synchronization Registers" */ + SVGA_REG_BUSY = 22, /* See "FIFO Synchronization Registers" */ + SVGA_REG_GUEST_ID = 23, /* Set guest OS identifier */ + SVGA_REG_CURSOR_ID = 24, /* (Deprecated) */ + SVGA_REG_CURSOR_X = 25, /* (Deprecated) */ + SVGA_REG_CURSOR_Y = 26, /* (Deprecated) */ + SVGA_REG_CURSOR_ON = 27, /* (Deprecated) */ + SVGA_REG_HOST_BITS_PER_PIXEL = 28, /* (Deprecated) */ + SVGA_REG_SCRATCH_SIZE = 29, /* Number of scratch registers */ + SVGA_REG_MEM_REGS = 30, /* Number of FIFO registers */ + SVGA_REG_NUM_DISPLAYS = 31, /* (Deprecated) */ + SVGA_REG_PITCHLOCK = 32, /* Fixed pitch for all modes */ + SVGA_REG_IRQMASK = 33, /* Interrupt mask */ + + /* Legacy multi-monitor support */ + SVGA_REG_NUM_GUEST_DISPLAYS = 34,/* Number of guest displays in X/Y direction */ + SVGA_REG_DISPLAY_ID = 35, /* Display ID for the following display attributes */ + SVGA_REG_DISPLAY_IS_PRIMARY = 36,/* Whether this is a primary display */ + SVGA_REG_DISPLAY_POSITION_X = 37,/* The display position x */ + SVGA_REG_DISPLAY_POSITION_Y = 38,/* The display position y */ + SVGA_REG_DISPLAY_WIDTH = 39, /* The display's width */ + SVGA_REG_DISPLAY_HEIGHT = 40, /* The display's height */ + + /* See "Guest memory regions" below. */ + SVGA_REG_GMR_ID = 41, + SVGA_REG_GMR_DESCRIPTOR = 42, + SVGA_REG_GMR_MAX_IDS = 43, + SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH = 44, + + SVGA_REG_TRACES = 45, /* Enable trace-based updates even when FIFO is on */ + SVGA_REG_TOP = 46, /* Must be 1 more than the last register */ + + SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */ + /* Next 768 (== 256*3) registers exist for colormap */ + + SVGA_SCRATCH_BASE = SVGA_PALETTE_BASE + SVGA_NUM_PALETTE_REGS + /* Base of scratch registers */ + /* Next reg[SVGA_REG_SCRATCH_SIZE] registers exist for scratch usage: + First 4 are reserved for VESA BIOS Extension; any remaining are for + the use of the current SVGA driver. */ +}; + + +/* + * Guest memory regions (GMRs): + * + * This is a new memory mapping feature available in SVGA devices + * which have the SVGA_CAP_GMR bit set. Previously, there were two + * fixed memory regions available with which to share data between the + * device and the driver: the FIFO ('MEM') and the framebuffer. GMRs + * are our name for an extensible way of providing arbitrary DMA + * buffers for use between the driver and the SVGA device. They are a + * new alternative to framebuffer memory, usable for both 2D and 3D + * graphics operations. + * + * Since GMR mapping must be done synchronously with guest CPU + * execution, we use a new pair of SVGA registers: + * + * SVGA_REG_GMR_ID -- + * + * Read/write. + * This register holds the 32-bit ID (a small positive integer) + * of a GMR to create, delete, or redefine. Writing this register + * has no side-effects. + * + * SVGA_REG_GMR_DESCRIPTOR -- + * + * Write-only. + * Writing this register will create, delete, or redefine the GMR + * specified by the above ID register. If this register is zero, + * the GMR is deleted. Any pointers into this GMR (including those + * currently being processed by FIFO commands) will be + * synchronously invalidated. + * + * If this register is nonzero, it must be the physical page + * number (PPN) of a data structure which describes the physical + * layout of the memory region this GMR should describe. The + * descriptor structure will be read synchronously by the SVGA + * device when this register is written. The descriptor need not + * remain allocated for the lifetime of the GMR. + * + * The guest driver should write SVGA_REG_GMR_ID first, then + * SVGA_REG_GMR_DESCRIPTOR. + * + * SVGA_REG_GMR_MAX_IDS -- + * + * Read-only. + * The SVGA device may choose to support a maximum number of + * user-defined GMR IDs. This register holds the number of supported + * IDs. (The maximum supported ID plus 1) + * + * SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH -- + * + * Read-only. + * The SVGA device may choose to put a limit on the total number + * of SVGAGuestMemDescriptor structures it will read when defining + * a single GMR. + * + * The descriptor structure is an array of SVGAGuestMemDescriptor + * structures. Each structure may do one of three things: + * + * - Terminate the GMR descriptor list. + * (ppn==0, numPages==0) + * + * - Add a PPN or range of PPNs to the GMR's virtual address space. + * (ppn != 0, numPages != 0) + * + * - Provide the PPN of the next SVGAGuestMemDescriptor, in order to + * support multi-page GMR descriptor tables without forcing the + * driver to allocate physically contiguous memory. + * (ppn != 0, numPages == 0) + * + * Note that each physical page of SVGAGuestMemDescriptor structures + * can describe at least 2MB of guest memory. If the driver needs to + * use more than one page of descriptor structures, it must use one of + * its SVGAGuestMemDescriptors to point to an additional page. The + * device will never automatically cross a page boundary. + * + * Once the driver has described a GMR, it is immediately available + * for use via any FIFO command that uses an SVGAGuestPtr structure. + * These pointers include a GMR identifier plus an offset into that + * GMR. + * + * The driver must check the SVGA_CAP_GMR bit before using the GMR + * registers. + */ + +/* + * Special GMR IDs, allowing SVGAGuestPtrs to point to framebuffer + * memory as well. In the future, these IDs could even be used to + * allow legacy memory regions to be redefined by the guest as GMRs. + * + * Using the guest framebuffer (GFB) at BAR1 for general purpose DMA + * is being phased out. Please try to use user-defined GMRs whenever + * possible. + */ +#define SVGA_GMR_NULL ((uint32) -1) +#define SVGA_GMR_FRAMEBUFFER ((uint32) -2) // Guest Framebuffer (GFB) + +typedef +struct SVGAGuestMemDescriptor { + uint32 ppn; + uint32 numPages; +} SVGAGuestMemDescriptor; + +typedef +struct SVGAGuestPtr { + uint32 gmrId; + uint32 offset; +} SVGAGuestPtr; + + +/* + * SVGAGMRImageFormat -- + * + * This is a packed representation of the source 2D image format + * for a GMR-to-screen blit. Currently it is defined as an encoding + * of the screen's color depth and bits-per-pixel, however, 16 bits + * are reserved for future use to identify other encodings (such as + * RGBA or higher-precision images). + * + * Currently supported formats: + * + * bpp depth Format Name + * --- ----- ----------- + * 32 24 32-bit BGRX + * 24 24 24-bit BGR + * 16 16 RGB 5-6-5 + * 16 15 RGB 5-5-5 + * + */ + +typedef +struct SVGAGMRImageFormat { + union { + struct { + uint32 bitsPerPixel : 8; + uint32 colorDepth : 8; + uint32 reserved : 16; // Must be zero + }; + + uint32 value; + }; +} SVGAGMRImageFormat; + +/* + * SVGAColorBGRX -- + * + * A 24-bit color format (BGRX), which does not depend on the + * format of the legacy guest framebuffer (GFB) or the current + * GMRFB state. + */ + +typedef +struct SVGAColorBGRX { + union { + struct { + uint32 b : 8; + uint32 g : 8; + uint32 r : 8; + uint32 x : 8; // Unused + }; + + uint32 value; + }; +} SVGAColorBGRX; + + +/* + * SVGASignedRect -- + * SVGASignedPoint -- + * + * Signed rectangle and point primitives. These are used by the new + * 2D primitives for drawing to Screen Objects, which can occupy a + * signed virtual coordinate space. + * + * SVGASignedRect specifies a half-open interval: the (left, top) + * pixel is part of the rectangle, but the (right, bottom) pixel is + * not. + */ + +typedef +struct SVGASignedRect { + int32 left; + int32 top; + int32 right; + int32 bottom; +} SVGASignedRect; + +typedef +struct SVGASignedPoint { + int32 x; + int32 y; +} SVGASignedPoint; + + +/* + * Capabilities + * + * Note the holes in the bitfield. Missing bits have been deprecated, + * and must not be reused. Those capabilities will never be reported + * by new versions of the SVGA device. + */ + +#define SVGA_CAP_NONE 0x00000000 +#define SVGA_CAP_RECT_COPY 0x00000002 +#define SVGA_CAP_CURSOR 0x00000020 +#define SVGA_CAP_CURSOR_BYPASS 0x00000040 // Legacy (Use Cursor Bypass 3 instead) +#define SVGA_CAP_CURSOR_BYPASS_2 0x00000080 // Legacy (Use Cursor Bypass 3 instead) +#define SVGA_CAP_8BIT_EMULATION 0x00000100 +#define SVGA_CAP_ALPHA_CURSOR 0x00000200 +#define SVGA_CAP_3D 0x00004000 +#define SVGA_CAP_EXTENDED_FIFO 0x00008000 +#define SVGA_CAP_MULTIMON 0x00010000 // Legacy multi-monitor support +#define SVGA_CAP_PITCHLOCK 0x00020000 +#define SVGA_CAP_IRQMASK 0x00040000 +#define SVGA_CAP_DISPLAY_TOPOLOGY 0x00080000 // Legacy multi-monitor support +#define SVGA_CAP_GMR 0x00100000 +#define SVGA_CAP_TRACES 0x00200000 + + +/* + * FIFO register indices. + * + * The FIFO is a chunk of device memory mapped into guest physmem. It + * is always treated as 32-bit words. + * + * The guest driver gets to decide how to partition it between + * - FIFO registers (there are always at least 4, specifying where the + * following data area is and how much data it contains; there may be + * more registers following these, depending on the FIFO protocol + * version in use) + * - FIFO data, written by the guest and slurped out by the VMX. + * These indices are 32-bit word offsets into the FIFO. + */ + +enum { + /* + * Block 1 (basic registers): The originally defined FIFO registers. + * These exist and are valid for all versions of the FIFO protocol. + */ + + SVGA_FIFO_MIN = 0, + SVGA_FIFO_MAX, /* The distance from MIN to MAX must be at least 10K */ + SVGA_FIFO_NEXT_CMD, + SVGA_FIFO_STOP, + + /* + * Block 2 (extended registers): Mandatory registers for the extended + * FIFO. These exist if the SVGA caps register includes + * SVGA_CAP_EXTENDED_FIFO; some of them are valid only if their + * associated capability bit is enabled. + * + * Note that when originally defined, SVGA_CAP_EXTENDED_FIFO implied + * support only for (FIFO registers) CAPABILITIES, FLAGS, and FENCE. + * This means that the guest has to test individually (in most cases + * using FIFO caps) for the presence of registers after this; the VMX + * can define "extended FIFO" to mean whatever it wants, and currently + * won't enable it unless there's room for that set and much more. + */ + + SVGA_FIFO_CAPABILITIES = 4, + SVGA_FIFO_FLAGS, + // Valid with SVGA_FIFO_CAP_FENCE: + SVGA_FIFO_FENCE, + + /* + * Block 3a (optional extended registers): Additional registers for the + * extended FIFO, whose presence isn't actually implied by + * SVGA_CAP_EXTENDED_FIFO; these exist if SVGA_FIFO_MIN is high enough to + * leave room for them. + * + * These in block 3a, the VMX currently considers mandatory for the + * extended FIFO. + */ + + // Valid if exists (i.e. if extended FIFO enabled): + SVGA_FIFO_3D_HWVERSION, /* See SVGA3dHardwareVersion in svga3d_reg.h */ + // Valid with SVGA_FIFO_CAP_PITCHLOCK: + SVGA_FIFO_PITCHLOCK, + + // Valid with SVGA_FIFO_CAP_CURSOR_BYPASS_3: + SVGA_FIFO_CURSOR_ON, /* Cursor bypass 3 show/hide register */ + SVGA_FIFO_CURSOR_X, /* Cursor bypass 3 x register */ + SVGA_FIFO_CURSOR_Y, /* Cursor bypass 3 y register */ + SVGA_FIFO_CURSOR_COUNT, /* Incremented when any of the other 3 change */ + SVGA_FIFO_CURSOR_LAST_UPDATED,/* Last time the host updated the cursor */ + + // Valid with SVGA_FIFO_CAP_RESERVE: + SVGA_FIFO_RESERVED, /* Bytes past NEXT_CMD with real contents */ + + /* + * Valid with SVGA_FIFO_CAP_SCREEN_OBJECT: + * + * By default this is SVGA_ID_INVALID, to indicate that the cursor + * coordinates are specified relative to the virtual root. If this + * is set to a specific screen ID, cursor position is reinterpreted + * as a signed offset relative to that screen's origin. This is the + * only way to place the cursor on a non-rooted screen. + */ + SVGA_FIFO_CURSOR_SCREEN_ID, + + /* + * XXX: The gap here, up until SVGA_FIFO_3D_CAPS, can be used for new + * registers, but this must be done carefully and with judicious use of + * capability bits, since comparisons based on SVGA_FIFO_MIN aren't + * enough to tell you whether the register exists: we've shipped drivers + * and products that used SVGA_FIFO_3D_CAPS but didn't know about some of + * the earlier ones. The actual order of introduction was: + * - PITCHLOCK + * - 3D_CAPS + * - CURSOR_* (cursor bypass 3) + * - RESERVED + * So, code that wants to know whether it can use any of the + * aforementioned registers, or anything else added after PITCHLOCK and + * before 3D_CAPS, needs to reason about something other than + * SVGA_FIFO_MIN. + */ + + /* + * 3D caps block space; valid with 3D hardware version >= + * SVGA3D_HWVERSION_WS6_B1. + */ + SVGA_FIFO_3D_CAPS = 32, + SVGA_FIFO_3D_CAPS_LAST = 32 + 255, + + /* + * End of VMX's current definition of "extended-FIFO registers". + * Registers before here are always enabled/disabled as a block; either + * the extended FIFO is enabled and includes all preceding registers, or + * it's disabled entirely. + * + * Block 3b (truly optional extended registers): Additional registers for + * the extended FIFO, which the VMX already knows how to enable and + * disable with correct granularity. + * + * Registers after here exist if and only if the guest SVGA driver + * sets SVGA_FIFO_MIN high enough to leave room for them. + */ + + // Valid if register exists: + SVGA_FIFO_GUEST_3D_HWVERSION, /* Guest driver's 3D version */ + SVGA_FIFO_FENCE_GOAL, /* Matching target for SVGA_IRQFLAG_FENCE_GOAL */ + SVGA_FIFO_BUSY, /* See "FIFO Synchronization Registers" */ + + /* + * Always keep this last. This defines the maximum number of + * registers we know about. At power-on, this value is placed in + * the SVGA_REG_MEM_REGS register, and we expect the guest driver + * to allocate this much space in FIFO memory for registers. + */ + SVGA_FIFO_NUM_REGS +}; + + +/* + * Definition of registers included in extended FIFO support. + * + * The guest SVGA driver gets to allocate the FIFO between registers + * and data. It must always allocate at least 4 registers, but old + * drivers stopped there. + * + * The VMX will enable extended FIFO support if and only if the guest + * left enough room for all registers defined as part of the mandatory + * set for the extended FIFO. + * + * Note that the guest drivers typically allocate the FIFO only at + * initialization time, not at mode switches, so it's likely that the + * number of FIFO registers won't change without a reboot. + * + * All registers less than this value are guaranteed to be present if + * svgaUser->fifo.extended is set. Any later registers must be tested + * individually for compatibility at each use (in the VMX). + * + * This value is used only by the VMX, so it can change without + * affecting driver compatibility; keep it that way? + */ +#define SVGA_FIFO_EXTENDED_MANDATORY_REGS (SVGA_FIFO_3D_CAPS_LAST + 1) + + +/* + * FIFO Synchronization Registers + * + * This explains the relationship between the various FIFO + * sync-related registers in IOSpace and in FIFO space. + * + * SVGA_REG_SYNC -- + * + * The SYNC register can be used in two different ways by the guest: + * + * 1. If the guest wishes to fully sync (drain) the FIFO, + * it will write once to SYNC then poll on the BUSY + * register. The FIFO is sync'ed once BUSY is zero. + * + * 2. If the guest wants to asynchronously wake up the host, + * it will write once to SYNC without polling on BUSY. + * Ideally it will do this after some new commands have + * been placed in the FIFO, and after reading a zero + * from SVGA_FIFO_BUSY. + * + * (1) is the original behaviour that SYNC was designed to + * support. Originally, a write to SYNC would implicitly + * trigger a read from BUSY. This causes us to synchronously + * process the FIFO. + * + * This behaviour has since been changed so that writing SYNC + * will *not* implicitly cause a read from BUSY. Instead, it + * makes a channel call which asynchronously wakes up the MKS + * thread. + * + * New guests can use this new behaviour to implement (2) + * efficiently. This lets guests get the host's attention + * without waiting for the MKS to poll, which gives us much + * better CPU utilization on SMP hosts and on UP hosts while + * we're blocked on the host GPU. + * + * Old guests shouldn't notice the behaviour change. SYNC was + * never guaranteed to process the entire FIFO, since it was + * bounded to a particular number of CPU cycles. Old guests will + * still loop on the BUSY register until the FIFO is empty. + * + * Writing to SYNC currently has the following side-effects: + * + * - Sets SVGA_REG_BUSY to TRUE (in the monitor) + * - Asynchronously wakes up the MKS thread for FIFO processing + * - The value written to SYNC is recorded as a "reason", for + * stats purposes. + * + * If SVGA_FIFO_BUSY is available, drivers are advised to only + * write to SYNC if SVGA_FIFO_BUSY is FALSE. Drivers should set + * SVGA_FIFO_BUSY to TRUE after writing to SYNC. The MKS will + * eventually set SVGA_FIFO_BUSY on its own, but this approach + * lets the driver avoid sending multiple asynchronous wakeup + * messages to the MKS thread. + * + * SVGA_REG_BUSY -- + * + * This register is set to TRUE when SVGA_REG_SYNC is written, + * and it reads as FALSE when the FIFO has been completely + * drained. + * + * Every read from this register causes us to synchronously + * process FIFO commands. There is no guarantee as to how many + * commands each read will process. + * + * CPU time spent processing FIFO commands will be billed to + * the guest. + * + * New drivers should avoid using this register unless they + * need to guarantee that the FIFO is completely drained. It + * is overkill for performing a sync-to-fence. Older drivers + * will use this register for any type of synchronization. + * + * SVGA_FIFO_BUSY -- + * + * This register is a fast way for the guest driver to check + * whether the FIFO is already being processed. It reads and + * writes at normal RAM speeds, with no monitor intervention. + * + * If this register reads as TRUE, the host is guaranteeing that + * any new commands written into the FIFO will be noticed before + * the MKS goes back to sleep. + * + * If this register reads as FALSE, no such guarantee can be + * made. + * + * The guest should use this register to quickly determine + * whether or not it needs to wake up the host. If the guest + * just wrote a command or group of commands that it would like + * the host to begin processing, it should: + * + * 1. Read SVGA_FIFO_BUSY. If it reads as TRUE, no further + * action is necessary. + * + * 2. Write TRUE to SVGA_FIFO_BUSY. This informs future guest + * code that we've already sent a SYNC to the host and we + * don't need to send a duplicate. + * + * 3. Write a reason to SVGA_REG_SYNC. This will send an + * asynchronous wakeup to the MKS thread. + */ + + +/* + * FIFO Capabilities + * + * Fence -- Fence register and command are supported + * Accel Front -- Front buffer only commands are supported + * Pitch Lock -- Pitch lock register is supported + * Video -- SVGA Video overlay units are supported + * Escape -- Escape command is supported + * + * XXX: Add longer descriptions for each capability, including a list + * of the new features that each capability provides. + * + * SVGA_FIFO_CAP_SCREEN_OBJECT -- + * + * Provides dynamic multi-screen rendering, for improved Unity and + * multi-monitor modes. With Screen Object, the guest can + * dynamically create and destroy 'screens', which can represent + * Unity windows or virtual monitors. Screen Object also provides + * strong guarantees that DMA operations happen only when + * guest-initiated. Screen Object deprecates the BAR1 guest + * framebuffer (GFB) and all commands that work only with the GFB. + * + * New registers: + * FIFO_CURSOR_SCREEN_ID, VIDEO_DATA_GMRID, VIDEO_DST_SCREEN_ID + * + * New 2D commands: + * DEFINE_SCREEN, DESTROY_SCREEN, DEFINE_GMRFB, BLIT_GMRFB_TO_SCREEN, + * BLIT_SCREEN_TO_GMRFB, ANNOTATION_FILL, ANNOTATION_COPY + * + * New 3D commands: + * BLIT_SURFACE_TO_SCREEN + * + * New guarantees: + * + * - The host will not read or write guest memory, including the GFB, + * except when explicitly initiated by a DMA command. + * + * - All DMA, including legacy DMA like UPDATE and PRESENT_READBACK, + * is guaranteed to complete before any subsequent FENCEs. + * + * - All legacy commands which affect a Screen (UPDATE, PRESENT, + * PRESENT_READBACK) as well as new Screen blit commands will + * all behave consistently as blits, and memory will be read + * or written in FIFO order. + * + * For example, if you PRESENT from one SVGA3D surface to multiple + * places on the screen, the data copied will always be from the + * SVGA3D surface at the time the PRESENT was issued in the FIFO. + * This was not necessarily true on devices without Screen Object. + * + * This means that on devices that support Screen Object, the + * PRESENT_READBACK command should not be necessary unless you + * actually want to read back the results of 3D rendering into + * system memory. (And for that, the BLIT_SCREEN_TO_GMRFB + * command provides a strict superset of functionality.) + * + * - When a screen is resized, either using Screen Object commands or + * legacy multimon registers, its contents are preserved. + */ + +#define SVGA_FIFO_CAP_NONE 0 +#define SVGA_FIFO_CAP_FENCE (1<<0) +#define SVGA_FIFO_CAP_ACCELFRONT (1<<1) +#define SVGA_FIFO_CAP_PITCHLOCK (1<<2) +#define SVGA_FIFO_CAP_VIDEO (1<<3) +#define SVGA_FIFO_CAP_CURSOR_BYPASS_3 (1<<4) +#define SVGA_FIFO_CAP_ESCAPE (1<<5) +#define SVGA_FIFO_CAP_RESERVE (1<<6) +#define SVGA_FIFO_CAP_SCREEN_OBJECT (1<<7) + + +/* + * FIFO Flags + * + * Accel Front -- Driver should use front buffer only commands + */ + +#define SVGA_FIFO_FLAG_NONE 0 +#define SVGA_FIFO_FLAG_ACCELFRONT (1<<0) +#define SVGA_FIFO_FLAG_RESERVED (1<<31) // Internal use only + +/* + * FIFO reservation sentinel value + */ + +#define SVGA_FIFO_RESERVED_UNKNOWN 0xffffffff + + +/* + * Video overlay support + */ + +#define SVGA_NUM_OVERLAY_UNITS 32 + + +/* + * Video capabilities that the guest is currently using + */ + +#define SVGA_VIDEO_FLAG_COLORKEY 0x0001 + + +/* + * Offsets for the video overlay registers + */ + +enum { + SVGA_VIDEO_ENABLED = 0, + SVGA_VIDEO_FLAGS, + SVGA_VIDEO_DATA_OFFSET, + SVGA_VIDEO_FORMAT, + SVGA_VIDEO_COLORKEY, + SVGA_VIDEO_SIZE, // Deprecated + SVGA_VIDEO_WIDTH, + SVGA_VIDEO_HEIGHT, + SVGA_VIDEO_SRC_X, + SVGA_VIDEO_SRC_Y, + SVGA_VIDEO_SRC_WIDTH, + SVGA_VIDEO_SRC_HEIGHT, + SVGA_VIDEO_DST_X, // Signed int32 + SVGA_VIDEO_DST_Y, // Signed int32 + SVGA_VIDEO_DST_WIDTH, + SVGA_VIDEO_DST_HEIGHT, + SVGA_VIDEO_PITCH_1, + SVGA_VIDEO_PITCH_2, + SVGA_VIDEO_PITCH_3, + SVGA_VIDEO_DATA_GMRID, // Optional, defaults to SVGA_GMR_FRAMEBUFFER + SVGA_VIDEO_DST_SCREEN_ID, // Optional, defaults to virtual coords (SVGA_ID_INVALID) + SVGA_VIDEO_NUM_REGS +}; + + +/* + * SVGA Overlay Units + * + * width and height relate to the entire source video frame. + * srcX, srcY, srcWidth and srcHeight represent subset of the source + * video frame to be displayed. + */ + +typedef struct SVGAOverlayUnit { + uint32 enabled; + uint32 flags; + uint32 dataOffset; + uint32 format; + uint32 colorKey; + uint32 size; + uint32 width; + uint32 height; + uint32 srcX; + uint32 srcY; + uint32 srcWidth; + uint32 srcHeight; + int32 dstX; + int32 dstY; + uint32 dstWidth; + uint32 dstHeight; + uint32 pitches[3]; + uint32 dataGMRId; + uint32 dstScreenId; +} SVGAOverlayUnit; + + +/* + * SVGAScreenObject -- + * + * This is a new way to represent a guest's multi-monitor screen or + * Unity window. Screen objects are only supported if the + * SVGA_FIFO_CAP_SCREEN_OBJECT capability bit is set. + * + * If Screen Objects are supported, they can be used to fully + * replace the functionality provided by the framebuffer registers + * (SVGA_REG_WIDTH, HEIGHT, etc.) and by SVGA_CAP_DISPLAY_TOPOLOGY. + * + * The screen object is a struct with guaranteed binary + * compatibility. New flags can be added, and the struct may grow, + * but existing fields must retain their meaning. + * + */ + +#define SVGA_SCREEN_HAS_ROOT (1 << 0) // Screen is present in the virtual coord space +#define SVGA_SCREEN_IS_PRIMARY (1 << 1) // Guest considers this screen to be 'primary' +#define SVGA_SCREEN_FULLSCREEN_HINT (1 << 2) // Guest is running a fullscreen app here + +typedef +struct SVGAScreenObject { + uint32 structSize; // sizeof(SVGAScreenObject) + uint32 id; + uint32 flags; + struct { + uint32 width; + uint32 height; + } size; + struct { + int32 x; + int32 y; + } root; // Only used if SVGA_SCREEN_HAS_ROOT is set. +} SVGAScreenObject; + + +/* + * Commands in the command FIFO: + * + * Command IDs defined below are used for the traditional 2D FIFO + * communication (not all commands are available for all versions of the + * SVGA FIFO protocol). + * + * Note the holes in the command ID numbers: These commands have been + * deprecated, and the old IDs must not be reused. + * + * Command IDs from 1000 to 1999 are reserved for use by the SVGA3D + * protocol. + * + * Each command's parameters are described by the comments and + * structs below. + */ + +typedef enum { + SVGA_CMD_INVALID_CMD = 0, + SVGA_CMD_UPDATE = 1, + SVGA_CMD_RECT_COPY = 3, + SVGA_CMD_DEFINE_CURSOR = 19, + SVGA_CMD_DEFINE_ALPHA_CURSOR = 22, + SVGA_CMD_UPDATE_VERBOSE = 25, + SVGA_CMD_FRONT_ROP_FILL = 29, + SVGA_CMD_FENCE = 30, + SVGA_CMD_ESCAPE = 33, + SVGA_CMD_DEFINE_SCREEN = 34, + SVGA_CMD_DESTROY_SCREEN = 35, + SVGA_CMD_DEFINE_GMRFB = 36, + SVGA_CMD_BLIT_GMRFB_TO_SCREEN = 37, + SVGA_CMD_BLIT_SCREEN_TO_GMRFB = 38, + SVGA_CMD_ANNOTATION_FILL = 39, + SVGA_CMD_ANNOTATION_COPY = 40, + SVGA_CMD_MAX +} SVGAFifoCmdId; + +#define SVGA_CMD_MAX_ARGS 64 + + +/* + * SVGA_CMD_UPDATE -- + * + * This is a DMA transfer which copies from the Guest Framebuffer + * (GFB) at BAR1 + SVGA_REG_FB_OFFSET to any screens which + * intersect with the provided virtual rectangle. + * + * This command does not support using arbitrary guest memory as a + * data source- it only works with the pre-defined GFB memory. + * This command also does not support signed virtual coordinates. + * If you have defined screens (using SVGA_CMD_DEFINE_SCREEN) with + * negative root x/y coordinates, the negative portion of those + * screens will not be reachable by this command. + * + * This command is not necessary when using framebuffer + * traces. Traces are automatically enabled if the SVGA FIFO is + * disabled, and you may explicitly enable/disable traces using + * SVGA_REG_TRACES. With traces enabled, any write to the GFB will + * automatically act as if a subsequent SVGA_CMD_UPDATE was issued. + * + * Traces and SVGA_CMD_UPDATE are the only supported ways to render + * pseudocolor screen updates. The newer Screen Object commands + * only support true color formats. + * + * Availability: + * Always available. + */ + +typedef +struct { + uint32 x; + uint32 y; + uint32 width; + uint32 height; +} SVGAFifoCmdUpdate; + + +/* + * SVGA_CMD_RECT_COPY -- + * + * Perform a rectangular DMA transfer from one area of the GFB to + * another, and copy the result to any screens which intersect it. + * + * Availability: + * SVGA_CAP_RECT_COPY + */ + +typedef +struct { + uint32 srcX; + uint32 srcY; + uint32 destX; + uint32 destY; + uint32 width; + uint32 height; +} SVGAFifoCmdRectCopy; + + +/* + * SVGA_CMD_DEFINE_CURSOR -- + * + * Provide a new cursor image, as an AND/XOR mask. + * + * The recommended way to position the cursor overlay is by using + * the SVGA_FIFO_CURSOR_* registers, supported by the + * SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability. + * + * Availability: + * SVGA_CAP_CURSOR + */ + +typedef +struct { + uint32 id; // Reserved, must be zero. + uint32 hotspotX; + uint32 hotspotY; + uint32 width; + uint32 height; + uint32 andMaskDepth; // Value must be 1 or equal to BITS_PER_PIXEL + uint32 xorMaskDepth; // Value must be 1 or equal to BITS_PER_PIXEL + /* + * Followed by scanline data for AND mask, then XOR mask. + * Each scanline is padded to a 32-bit boundary. + */ +} SVGAFifoCmdDefineCursor; + + +/* + * SVGA_CMD_DEFINE_ALPHA_CURSOR -- + * + * Provide a new cursor image, in 32-bit BGRA format. + * + * The recommended way to position the cursor overlay is by using + * the SVGA_FIFO_CURSOR_* registers, supported by the + * SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability. + * + * Availability: + * SVGA_CAP_ALPHA_CURSOR + */ + +typedef +struct { + uint32 id; // Reserved, must be zero. + uint32 hotspotX; + uint32 hotspotY; + uint32 width; + uint32 height; + /* Followed by scanline data */ +} SVGAFifoCmdDefineAlphaCursor; + + +/* + * SVGA_CMD_UPDATE_VERBOSE -- + * + * Just like SVGA_CMD_UPDATE, but also provide a per-rectangle + * 'reason' value, an opaque cookie which is used by internal + * debugging tools. Third party drivers should not use this + * command. + * + * Availability: + * SVGA_CAP_EXTENDED_FIFO + */ + +typedef +struct { + uint32 x; + uint32 y; + uint32 width; + uint32 height; + uint32 reason; +} SVGAFifoCmdUpdateVerbose; + + +/* + * SVGA_CMD_FRONT_ROP_FILL -- + * + * This is a hint which tells the SVGA device that the driver has + * just filled a rectangular region of the GFB with a solid + * color. Instead of reading these pixels from the GFB, the device + * can assume that they all equal 'color'. This is primarily used + * for remote desktop protocols. + * + * Availability: + * SVGA_FIFO_CAP_ACCELFRONT + */ + +#define SVGA_ROP_COPY 0x03 + +typedef +struct { + uint32 color; // In the same format as the GFB + uint32 x; + uint32 y; + uint32 width; + uint32 height; + uint32 rop; // Must be SVGA_ROP_COPY +} SVGAFifoCmdFrontRopFill; + + +/* + * SVGA_CMD_FENCE -- + * + * Insert a synchronization fence. When the SVGA device reaches + * this command, it will copy the 'fence' value into the + * SVGA_FIFO_FENCE register. It will also compare the fence against + * SVGA_FIFO_FENCE_GOAL. If the fence matches the goal and the + * SVGA_IRQFLAG_FENCE_GOAL interrupt is enabled, the device will + * raise this interrupt. + * + * Availability: + * SVGA_FIFO_FENCE for this command, + * SVGA_CAP_IRQMASK for SVGA_FIFO_FENCE_GOAL. + */ + +typedef +struct { + uint32 fence; +} SVGAFifoCmdFence; + + +/* + * SVGA_CMD_ESCAPE -- + * + * Send an extended or vendor-specific variable length command. + * This is used for video overlay, third party plugins, and + * internal debugging tools. See svga_escape.h + * + * Availability: + * SVGA_FIFO_CAP_ESCAPE + */ + +typedef +struct { + uint32 nsid; + uint32 size; + /* followed by 'size' bytes of data */ +} SVGAFifoCmdEscape; + + +/* + * SVGA_CMD_DEFINE_SCREEN -- + * + * Define or redefine an SVGAScreenObject. See the description of + * SVGAScreenObject above. The video driver is responsible for + * generating new screen IDs. They should be small positive + * integers. The virtual device will have an implementation + * specific upper limit on the number of screen IDs + * supported. Drivers are responsible for recycling IDs. The first + * valid ID is zero. + * + * - Interaction with other registers: + * + * For backwards compatibility, when the GFB mode registers (WIDTH, + * HEIGHT, PITCHLOCK, BITS_PER_PIXEL) are modified, the SVGA device + * deletes all screens other than screen #0, and redefines screen + * #0 according to the specified mode. Drivers that use + * SVGA_CMD_DEFINE_SCREEN should destroy or redefine screen #0. + * + * If you use screen objects, do not use the legacy multi-mon + * registers (SVGA_REG_NUM_GUEST_DISPLAYS, SVGA_REG_DISPLAY_*). + * + * Availability: + * SVGA_FIFO_CAP_SCREEN_OBJECT + */ + +typedef +struct { + SVGAScreenObject screen; // Variable-length according to version +} SVGAFifoCmdDefineScreen; + + +/* + * SVGA_CMD_DESTROY_SCREEN -- + * + * Destroy an SVGAScreenObject. Its ID is immediately available for + * re-use. + * + * Availability: + * SVGA_FIFO_CAP_SCREEN_OBJECT + */ + +typedef +struct { + uint32 screenId; +} SVGAFifoCmdDestroyScreen; + + +/* + * SVGA_CMD_DEFINE_GMRFB -- + * + * This command sets a piece of SVGA device state called the + * Guest Memory Region Framebuffer, or GMRFB. The GMRFB is a + * piece of light-weight state which identifies the location and + * format of an image in guest memory or in BAR1. The GMRFB has + * an arbitrary size, and it doesn't need to match the geometry + * of the GFB or any screen object. + * + * The GMRFB can be redefined as often as you like. You could + * always use the same GMRFB, you could redefine it before + * rendering from a different guest screen, or you could even + * redefine it before every blit. + * + * There are multiple ways to use this command. The simplest way is + * to use it to move the framebuffer either to elsewhere in the GFB + * (BAR1) memory region, or to a user-defined GMR. This lets a + * driver use a framebuffer allocated entirely out of normal system + * memory, which we encourage. + * + * Another way to use this command is to set up a ring buffer of + * updates in GFB memory. If a driver wants to ensure that no + * frames are skipped by the SVGA device, it is important that the + * driver not modify the source data for a blit until the device is + * done processing the command. One efficient way to accomplish + * this is to use a ring of small DMA buffers. Each buffer is used + * for one blit, then we move on to the next buffer in the + * ring. The FENCE mechanism is used to protect each buffer from + * re-use until the device is finished with that buffer's + * corresponding blit. + * + * This command does not affect the meaning of SVGA_CMD_UPDATE. + * UPDATEs always occur from the legacy GFB memory area. This + * command has no support for pseudocolor GMRFBs. Currently only + * true-color 15, 16, and 24-bit depths are supported. Future + * devices may expose capabilities for additional framebuffer + * formats. + * + * The default GMRFB value is undefined. Drivers must always send + * this command at least once before performing any blit from the + * GMRFB. + * + * Availability: + * SVGA_FIFO_CAP_SCREEN_OBJECT + */ + +typedef +struct { + SVGAGuestPtr ptr; + uint32 bytesPerLine; + SVGAGMRImageFormat format; +} SVGAFifoCmdDefineGMRFB; + + +/* + * SVGA_CMD_BLIT_GMRFB_TO_SCREEN -- + * + * This is a guest-to-host blit. It performs a DMA operation to + * copy a rectangular region of pixels from the current GMRFB to + * one or more Screen Objects. + * + * The destination coordinate may be specified relative to a + * screen's origin (if a screen ID is specified) or relative to the + * virtual coordinate system's origin (if the screen ID is + * SVGA_ID_INVALID). The actual destination may span zero or more + * screens, in the case of a virtual destination rect or a rect + * which extends off the edge of the specified screen. + * + * This command writes to the screen's "base layer": the underlying + * framebuffer which exists below any cursor or video overlays. No + * action is necessary to explicitly hide or update any overlays + * which exist on top of the updated region. + * + * The SVGA device is guaranteed to finish reading from the GMRFB + * by the time any subsequent FENCE commands are reached. + * + * This command consumes an annotation. See the + * SVGA_CMD_ANNOTATION_* commands for details. + * + * Availability: + * SVGA_FIFO_CAP_SCREEN_OBJECT + */ + +typedef +struct { + SVGASignedPoint srcOrigin; + SVGASignedRect destRect; + uint32 destScreenId; +} SVGAFifoCmdBlitGMRFBToScreen; + + +/* + * SVGA_CMD_BLIT_SCREEN_TO_GMRFB -- + * + * This is a host-to-guest blit. It performs a DMA operation to + * copy a rectangular region of pixels from a single Screen Object + * back to the current GMRFB. + * + * Usage note: This command should be used rarely. It will + * typically be inefficient, but it is necessary for some types of + * synchronization between 3D (GPU) and 2D (CPU) rendering into + * overlapping areas of a screen. + * + * The source coordinate is specified relative to a screen's + * origin. The provided screen ID must be valid. If any parameters + * are invalid, the resulting pixel values are undefined. + * + * This command reads the screen's "base layer". Overlays like + * video and cursor are not included, but any data which was sent + * using a blit-to-screen primitive will be available, no matter + * whether the data's original source was the GMRFB or the 3D + * acceleration hardware. + * + * Note that our guest-to-host blits and host-to-guest blits aren't + * symmetric in their current implementation. While the parameters + * are identical, host-to-guest blits are a lot less featureful. + * They do not support clipping: If the source parameters don't + * fully fit within a screen, the blit fails. They must originate + * from exactly one screen. Virtual coordinates are not directly + * supported. + * + * Host-to-guest blits do support the same set of GMRFB formats + * offered by guest-to-host blits. + * + * The SVGA device is guaranteed to finish writing to the GMRFB by + * the time any subsequent FENCE commands are reached. + * + * Availability: + * SVGA_FIFO_CAP_SCREEN_OBJECT + */ + +typedef +struct { + SVGASignedPoint destOrigin; + SVGASignedRect srcRect; + uint32 srcScreenId; +} SVGAFifoCmdBlitScreenToGMRFB; + + +/* + * SVGA_CMD_ANNOTATION_FILL -- + * + * This is a blit annotation. This command stores a small piece of + * device state which is consumed by the next blit-to-screen + * command. The state is only cleared by commands which are + * specifically documented as consuming an annotation. Other + * commands (such as ESCAPEs for debugging) may intervene between + * the annotation and its associated blit. + * + * This annotation is a promise about the contents of the next + * blit: The video driver is guaranteeing that all pixels in that + * blit will have the same value, specified here as a color in + * SVGAColorBGRX format. + * + * The SVGA device can still render the blit correctly even if it + * ignores this annotation, but the annotation may allow it to + * perform the blit more efficiently, for example by ignoring the + * source data and performing a fill in hardware. + * + * This annotation is most important for performance when the + * user's display is being remoted over a network connection. + * + * Availability: + * SVGA_FIFO_CAP_SCREEN_OBJECT + */ + +typedef +struct { + SVGAColorBGRX color; +} SVGAFifoCmdAnnotationFill; + + +/* + * SVGA_CMD_ANNOTATION_COPY -- + * + * This is a blit annotation. See SVGA_CMD_ANNOTATION_FILL for more + * information about annotations. + * + * This annotation is a promise about the contents of the next + * blit: The video driver is guaranteeing that all pixels in that + * blit will have the same value as those which already exist at an + * identically-sized region on the same or a different screen. + * + * Note that the source pixels for the COPY in this annotation are + * sampled before applying the anqnotation's associated blit. They + * are allowed to overlap with the blit's destination pixels. + * + * The copy source rectangle is specified the same way as the blit + * destination: it can be a rectangle which spans zero or more + * screens, specified relative to either a screen or to the virtual + * coordinate system's origin. If the source rectangle includes + * pixels which are not from exactly one screen, the results are + * undefined. + * + * Availability: + * SVGA_FIFO_CAP_SCREEN_OBJECT + */ + +typedef +struct { + SVGASignedPoint srcOrigin; + uint32 srcScreenId; +} SVGAFifoCmdAnnotationCopy; + +#endif diff --git a/drivers/gpu/drm/vmwgfx/svga_types.h b/drivers/gpu/drm/vmwgfx/svga_types.h new file mode 100644 index 0000000..55836de --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/svga_types.h @@ -0,0 +1,45 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Silly typedefs for the svga headers. Currently the headers are shared + * between all components that talk to svga. And as such the headers are + * are in a completely different style and use weird defines. + * + * This file lets all the ugly be prefixed with svga*. + */ + +#ifndef _SVGA_TYPES_H_ +#define _SVGA_TYPES_H_ + +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef uint8_t uint8; +typedef int32_t int32; +typedef bool Bool; + +#endif -- cgit v0.10.2 From fb1d9738ca053ea8afa5e86af6463155f983b01c Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 10 Dec 2009 00:19:58 +0000 Subject: drm/vmwgfx: Add DRM driver for VMware Virtual GPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds the vmwgfx driver for the VWware Virtual GPU aka SVGA. The driver is under staging the same as Nouveau and Radeon KMS. Hopefully the 2D ioctls are bug free and don't need changing, so that part of the API should be stable. But there there is a pretty big chance that the 3D API will change in the future. Signed-off-by: Thomas Hellström Signed-off-by: Jakob Bornecrantz Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 91567ac..bc14ba7 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -30,4 +30,5 @@ obj-$(CONFIG_DRM_I830) += i830/ obj-$(CONFIG_DRM_I915) += i915/ obj-$(CONFIG_DRM_SIS) += sis/ obj-$(CONFIG_DRM_SAVAGE)+= savage/ +obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/ obj-$(CONFIG_DRM_VIA) +=via/ diff --git a/drivers/gpu/drm/vmwgfx/Kconfig b/drivers/gpu/drm/vmwgfx/Kconfig new file mode 100644 index 0000000..f20b8bc --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/Kconfig @@ -0,0 +1,13 @@ +config DRM_VMWGFX + tristate "DRM driver for VMware Virtual GPU" + depends on DRM && PCI + select FB_DEFERRED_IO + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select DRM_TTM + help + KMS enabled DRM driver for SVGA2 virtual hardware. + + If unsure say n. The compiled module will be + called vmwgfx.ko diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile new file mode 100644 index 0000000..1a3cb68 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/Makefile @@ -0,0 +1,9 @@ + +ccflags-y := -Iinclude/drm + +vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \ + vmwgfx_fb.o vmwgfx_ioctl.o vmwgfx_resource.o vmwgfx_buffer.o \ + vmwgfx_fifo.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \ + vmwgfx_overlay.o + +obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c new file mode 100644 index 0000000..d6f2d2b --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c @@ -0,0 +1,229 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "vmwgfx_drv.h" +#include "ttm/ttm_bo_driver.h" +#include "ttm/ttm_placement.h" + +static uint32_t vram_placement_flags = TTM_PL_FLAG_VRAM | + TTM_PL_FLAG_CACHED; + +static uint32_t vram_ne_placement_flags = TTM_PL_FLAG_VRAM | + TTM_PL_FLAG_CACHED | + TTM_PL_FLAG_NO_EVICT; + +static uint32_t sys_placement_flags = TTM_PL_FLAG_SYSTEM | + TTM_PL_FLAG_CACHED; + +struct ttm_placement vmw_vram_placement = { + .fpfn = 0, + .lpfn = 0, + .num_placement = 1, + .placement = &vram_placement_flags, + .num_busy_placement = 1, + .busy_placement = &vram_placement_flags +}; + +struct ttm_placement vmw_vram_ne_placement = { + .fpfn = 0, + .lpfn = 0, + .num_placement = 1, + .placement = &vram_ne_placement_flags, + .num_busy_placement = 1, + .busy_placement = &vram_ne_placement_flags +}; + +struct ttm_placement vmw_sys_placement = { + .fpfn = 0, + .lpfn = 0, + .num_placement = 1, + .placement = &sys_placement_flags, + .num_busy_placement = 1, + .busy_placement = &sys_placement_flags +}; + +struct vmw_ttm_backend { + struct ttm_backend backend; +}; + +static int vmw_ttm_populate(struct ttm_backend *backend, + unsigned long num_pages, struct page **pages, + struct page *dummy_read_page) +{ + return 0; +} + +static int vmw_ttm_bind(struct ttm_backend *backend, struct ttm_mem_reg *bo_mem) +{ + return 0; +} + +static int vmw_ttm_unbind(struct ttm_backend *backend) +{ + return 0; +} + +static void vmw_ttm_clear(struct ttm_backend *backend) +{ +} + +static void vmw_ttm_destroy(struct ttm_backend *backend) +{ + struct vmw_ttm_backend *vmw_be = + container_of(backend, struct vmw_ttm_backend, backend); + + kfree(vmw_be); +} + +static struct ttm_backend_func vmw_ttm_func = { + .populate = vmw_ttm_populate, + .clear = vmw_ttm_clear, + .bind = vmw_ttm_bind, + .unbind = vmw_ttm_unbind, + .destroy = vmw_ttm_destroy, +}; + +struct ttm_backend *vmw_ttm_backend_init(struct ttm_bo_device *bdev) +{ + struct vmw_ttm_backend *vmw_be; + + vmw_be = kmalloc(sizeof(*vmw_be), GFP_KERNEL); + if (!vmw_be) + return NULL; + + vmw_be->backend.func = &vmw_ttm_func; + + return &vmw_be->backend; +} + +int vmw_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags) +{ + return 0; +} + +int vmw_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, + struct ttm_mem_type_manager *man) +{ + struct vmw_private *dev_priv = + container_of(bdev, struct vmw_private, bdev); + + switch (type) { + case TTM_PL_SYSTEM: + /* System memory */ + + man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; + man->available_caching = TTM_PL_MASK_CACHING; + man->default_caching = TTM_PL_FLAG_CACHED; + break; + case TTM_PL_VRAM: + /* "On-card" video ram */ + man->gpu_offset = 0; + man->io_offset = dev_priv->vram_start; + man->io_size = dev_priv->vram_size; + man->flags = TTM_MEMTYPE_FLAG_FIXED | + TTM_MEMTYPE_FLAG_NEEDS_IOREMAP | TTM_MEMTYPE_FLAG_MAPPABLE; + man->io_addr = NULL; + man->available_caching = TTM_PL_MASK_CACHING; + man->default_caching = TTM_PL_FLAG_WC; + break; + default: + DRM_ERROR("Unsupported memory type %u\n", (unsigned)type); + return -EINVAL; + } + return 0; +} + +void vmw_evict_flags(struct ttm_buffer_object *bo, + struct ttm_placement *placement) +{ + *placement = vmw_sys_placement; +} + +/** + * FIXME: Proper access checks on buffers. + */ + +static int vmw_verify_access(struct ttm_buffer_object *bo, struct file *filp) +{ + return 0; +} + +/** + * FIXME: We're using the old vmware polling method to sync. + * Do this with fences instead. + */ + +static void *vmw_sync_obj_ref(void *sync_obj) +{ + return sync_obj; +} + +static void vmw_sync_obj_unref(void **sync_obj) +{ + *sync_obj = NULL; +} + +static int vmw_sync_obj_flush(void *sync_obj, void *sync_arg) +{ + struct vmw_private *dev_priv = (struct vmw_private *)sync_arg; + + mutex_lock(&dev_priv->hw_mutex); + vmw_write(dev_priv, SVGA_REG_SYNC, SVGA_SYNC_GENERIC); + mutex_unlock(&dev_priv->hw_mutex); + return 0; +} + +static bool vmw_sync_obj_signaled(void *sync_obj, void *sync_arg) +{ + struct vmw_private *dev_priv = (struct vmw_private *)sync_arg; + uint32_t sequence = (unsigned long) sync_obj; + + return vmw_fence_signaled(dev_priv, sequence); +} + +static int vmw_sync_obj_wait(void *sync_obj, void *sync_arg, + bool lazy, bool interruptible) +{ + struct vmw_private *dev_priv = (struct vmw_private *)sync_arg; + uint32_t sequence = (unsigned long) sync_obj; + + return vmw_wait_fence(dev_priv, false, sequence, false, 3*HZ); +} + +struct ttm_bo_driver vmw_bo_driver = { + .create_ttm_backend_entry = vmw_ttm_backend_init, + .invalidate_caches = vmw_invalidate_caches, + .init_mem_type = vmw_init_mem_type, + .evict_flags = vmw_evict_flags, + .move = NULL, + .verify_access = vmw_verify_access, + .sync_obj_signaled = vmw_sync_obj_signaled, + .sync_obj_wait = vmw_sync_obj_wait, + .sync_obj_flush = vmw_sync_obj_flush, + .sync_obj_unref = vmw_sync_obj_unref, + .sync_obj_ref = vmw_sync_obj_ref +}; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c new file mode 100644 index 0000000..7b48bb3 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -0,0 +1,735 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "drmP.h" +#include "vmwgfx_drv.h" +#include "ttm/ttm_placement.h" +#include "ttm/ttm_bo_driver.h" +#include "ttm/ttm_object.h" +#include "ttm/ttm_module.h" + +#define VMWGFX_DRIVER_NAME "vmwgfx" +#define VMWGFX_DRIVER_DESC "Linux drm driver for VMware graphics devices" +#define VMWGFX_CHIP_SVGAII 0 +#define VMW_FB_RESERVATION 0 + +/** + * Fully encoded drm commands. Might move to vmw_drm.h + */ + +#define DRM_IOCTL_VMW_GET_PARAM \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_GET_PARAM, \ + struct drm_vmw_getparam_arg) +#define DRM_IOCTL_VMW_ALLOC_DMABUF \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_ALLOC_DMABUF, \ + union drm_vmw_alloc_dmabuf_arg) +#define DRM_IOCTL_VMW_UNREF_DMABUF \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_DMABUF, \ + struct drm_vmw_unref_dmabuf_arg) +#define DRM_IOCTL_VMW_CURSOR_BYPASS \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_CURSOR_BYPASS, \ + struct drm_vmw_cursor_bypass_arg) + +#define DRM_IOCTL_VMW_CONTROL_STREAM \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_CONTROL_STREAM, \ + struct drm_vmw_control_stream_arg) +#define DRM_IOCTL_VMW_CLAIM_STREAM \ + DRM_IOR(DRM_COMMAND_BASE + DRM_VMW_CLAIM_STREAM, \ + struct drm_vmw_stream_arg) +#define DRM_IOCTL_VMW_UNREF_STREAM \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_STREAM, \ + struct drm_vmw_stream_arg) + +#define DRM_IOCTL_VMW_CREATE_CONTEXT \ + DRM_IOR(DRM_COMMAND_BASE + DRM_VMW_CREATE_CONTEXT, \ + struct drm_vmw_context_arg) +#define DRM_IOCTL_VMW_UNREF_CONTEXT \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_CONTEXT, \ + struct drm_vmw_context_arg) +#define DRM_IOCTL_VMW_CREATE_SURFACE \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_CREATE_SURFACE, \ + union drm_vmw_surface_create_arg) +#define DRM_IOCTL_VMW_UNREF_SURFACE \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_SURFACE, \ + struct drm_vmw_surface_arg) +#define DRM_IOCTL_VMW_REF_SURFACE \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_REF_SURFACE, \ + union drm_vmw_surface_reference_arg) +#define DRM_IOCTL_VMW_EXECBUF \ + DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_EXECBUF, \ + struct drm_vmw_execbuf_arg) +#define DRM_IOCTL_VMW_FIFO_DEBUG \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FIFO_DEBUG, \ + struct drm_vmw_fifo_debug_arg) +#define DRM_IOCTL_VMW_FENCE_WAIT \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FENCE_WAIT, \ + struct drm_vmw_fence_wait_arg) + + +/** + * The core DRM version of this macro doesn't account for + * DRM_COMMAND_BASE. + */ + +#define VMW_IOCTL_DEF(ioctl, func, flags) \ + [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func} + +/** + * Ioctl definitions. + */ + +static struct drm_ioctl_desc vmw_ioctls[] = { + VMW_IOCTL_DEF(DRM_IOCTL_VMW_GET_PARAM, vmw_getparam_ioctl, 0), + VMW_IOCTL_DEF(DRM_IOCTL_VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl, + 0), + VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl, + 0), + VMW_IOCTL_DEF(DRM_IOCTL_VMW_CURSOR_BYPASS, + vmw_kms_cursor_bypass_ioctl, 0), + + VMW_IOCTL_DEF(DRM_IOCTL_VMW_CONTROL_STREAM, vmw_overlay_ioctl, + 0), + VMW_IOCTL_DEF(DRM_IOCTL_VMW_CLAIM_STREAM, vmw_stream_claim_ioctl, + 0), + VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_STREAM, vmw_stream_unref_ioctl, + 0), + + VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_CONTEXT, vmw_context_define_ioctl, + 0), + VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl, + 0), + VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_SURFACE, vmw_surface_define_ioctl, + 0), + VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl, + 0), + VMW_IOCTL_DEF(DRM_IOCTL_VMW_REF_SURFACE, vmw_surface_reference_ioctl, + 0), + VMW_IOCTL_DEF(DRM_IOCTL_VMW_EXECBUF, vmw_execbuf_ioctl, + 0), + VMW_IOCTL_DEF(DRM_IOCTL_VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl, + 0), + VMW_IOCTL_DEF(DRM_IOCTL_VMW_FENCE_WAIT, vmw_fence_wait_ioctl, + 0) +}; + +static struct pci_device_id vmw_pci_id_list[] = { + {0x15ad, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VMWGFX_CHIP_SVGAII}, + {0, 0, 0} +}; + +static char *vmw_devname = "vmwgfx"; + +static int vmw_probe(struct pci_dev *, const struct pci_device_id *); +static void vmw_master_init(struct vmw_master *); + +static void vmw_print_capabilities(uint32_t capabilities) +{ + DRM_INFO("Capabilities:\n"); + if (capabilities & SVGA_CAP_RECT_COPY) + DRM_INFO(" Rect copy.\n"); + if (capabilities & SVGA_CAP_CURSOR) + DRM_INFO(" Cursor.\n"); + if (capabilities & SVGA_CAP_CURSOR_BYPASS) + DRM_INFO(" Cursor bypass.\n"); + if (capabilities & SVGA_CAP_CURSOR_BYPASS_2) + DRM_INFO(" Cursor bypass 2.\n"); + if (capabilities & SVGA_CAP_8BIT_EMULATION) + DRM_INFO(" 8bit emulation.\n"); + if (capabilities & SVGA_CAP_ALPHA_CURSOR) + DRM_INFO(" Alpha cursor.\n"); + if (capabilities & SVGA_CAP_3D) + DRM_INFO(" 3D.\n"); + if (capabilities & SVGA_CAP_EXTENDED_FIFO) + DRM_INFO(" Extended Fifo.\n"); + if (capabilities & SVGA_CAP_MULTIMON) + DRM_INFO(" Multimon.\n"); + if (capabilities & SVGA_CAP_PITCHLOCK) + DRM_INFO(" Pitchlock.\n"); + if (capabilities & SVGA_CAP_IRQMASK) + DRM_INFO(" Irq mask.\n"); + if (capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) + DRM_INFO(" Display Topology.\n"); + if (capabilities & SVGA_CAP_GMR) + DRM_INFO(" GMR.\n"); + if (capabilities & SVGA_CAP_TRACES) + DRM_INFO(" Traces.\n"); +} + +static int vmw_request_device(struct vmw_private *dev_priv) +{ + int ret; + + vmw_kms_save_vga(dev_priv); + + ret = vmw_fifo_init(dev_priv, &dev_priv->fifo); + if (unlikely(ret != 0)) { + DRM_ERROR("Unable to initialize FIFO.\n"); + return ret; + } + + return 0; +} + +static void vmw_release_device(struct vmw_private *dev_priv) +{ + vmw_fifo_release(dev_priv, &dev_priv->fifo); + vmw_kms_restore_vga(dev_priv); +} + + +static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) +{ + struct vmw_private *dev_priv; + int ret; + + dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); + if (unlikely(dev_priv == NULL)) { + DRM_ERROR("Failed allocating a device private struct.\n"); + return -ENOMEM; + } + memset(dev_priv, 0, sizeof(*dev_priv)); + + dev_priv->dev = dev; + dev_priv->vmw_chipset = chipset; + mutex_init(&dev_priv->hw_mutex); + mutex_init(&dev_priv->cmdbuf_mutex); + rwlock_init(&dev_priv->resource_lock); + idr_init(&dev_priv->context_idr); + idr_init(&dev_priv->surface_idr); + idr_init(&dev_priv->stream_idr); + ida_init(&dev_priv->gmr_ida); + mutex_init(&dev_priv->init_mutex); + init_waitqueue_head(&dev_priv->fence_queue); + init_waitqueue_head(&dev_priv->fifo_queue); + atomic_set(&dev_priv->fence_queue_waiters, 0); + atomic_set(&dev_priv->fifo_queue_waiters, 0); + INIT_LIST_HEAD(&dev_priv->gmr_lru); + + dev_priv->io_start = pci_resource_start(dev->pdev, 0); + dev_priv->vram_start = pci_resource_start(dev->pdev, 1); + dev_priv->mmio_start = pci_resource_start(dev->pdev, 2); + + mutex_lock(&dev_priv->hw_mutex); + dev_priv->capabilities = vmw_read(dev_priv, SVGA_REG_CAPABILITIES); + + if (dev_priv->capabilities & SVGA_CAP_GMR) { + dev_priv->max_gmr_descriptors = + vmw_read(dev_priv, + SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH); + dev_priv->max_gmr_ids = + vmw_read(dev_priv, SVGA_REG_GMR_MAX_IDS); + } + + dev_priv->vram_size = vmw_read(dev_priv, SVGA_REG_VRAM_SIZE); + dev_priv->mmio_size = vmw_read(dev_priv, SVGA_REG_MEM_SIZE); + dev_priv->fb_max_width = vmw_read(dev_priv, SVGA_REG_MAX_WIDTH); + dev_priv->fb_max_height = vmw_read(dev_priv, SVGA_REG_MAX_HEIGHT); + + mutex_unlock(&dev_priv->hw_mutex); + + vmw_print_capabilities(dev_priv->capabilities); + + if (dev_priv->capabilities & SVGA_CAP_GMR) { + DRM_INFO("Max GMR ids is %u\n", + (unsigned)dev_priv->max_gmr_ids); + DRM_INFO("Max GMR descriptors is %u\n", + (unsigned)dev_priv->max_gmr_descriptors); + } + DRM_INFO("VRAM at 0x%08x size is %u kiB\n", + dev_priv->vram_start, dev_priv->vram_size / 1024); + DRM_INFO("MMIO at 0x%08x size is %u kiB\n", + dev_priv->mmio_start, dev_priv->mmio_size / 1024); + + ret = vmw_ttm_global_init(dev_priv); + if (unlikely(ret != 0)) + goto out_err0; + + + vmw_master_init(&dev_priv->fbdev_master); + ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); + dev_priv->active_master = &dev_priv->fbdev_master; + + + ret = ttm_bo_device_init(&dev_priv->bdev, + dev_priv->bo_global_ref.ref.object, + &vmw_bo_driver, VMWGFX_FILE_PAGE_OFFSET, + false); + if (unlikely(ret != 0)) { + DRM_ERROR("Failed initializing TTM buffer object driver.\n"); + goto out_err1; + } + + ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_VRAM, + (dev_priv->vram_size >> PAGE_SHIFT)); + if (unlikely(ret != 0)) { + DRM_ERROR("Failed initializing memory manager for VRAM.\n"); + goto out_err2; + } + + dev_priv->mmio_mtrr = drm_mtrr_add(dev_priv->mmio_start, + dev_priv->mmio_size, DRM_MTRR_WC); + + dev_priv->mmio_virt = ioremap_wc(dev_priv->mmio_start, + dev_priv->mmio_size); + + if (unlikely(dev_priv->mmio_virt == NULL)) { + ret = -ENOMEM; + DRM_ERROR("Failed mapping MMIO.\n"); + goto out_err3; + } + + dev_priv->tdev = ttm_object_device_init + (dev_priv->mem_global_ref.object, 12); + + if (unlikely(dev_priv->tdev == NULL)) { + DRM_ERROR("Unable to initialize TTM object management.\n"); + ret = -ENOMEM; + goto out_err4; + } + + dev->dev_private = dev_priv; + + if (!dev->devname) + dev->devname = vmw_devname; + + if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { + ret = drm_irq_install(dev); + if (unlikely(ret != 0)) { + DRM_ERROR("Failed installing irq: %d\n", ret); + goto out_no_irq; + } + } + + ret = pci_request_regions(dev->pdev, "vmwgfx probe"); + dev_priv->stealth = (ret != 0); + if (dev_priv->stealth) { + /** + * Request at least the mmio PCI resource. + */ + + DRM_INFO("It appears like vesafb is loaded. " + "Ignore above error if any. Entering stealth mode.\n"); + ret = pci_request_region(dev->pdev, 2, "vmwgfx stealth probe"); + if (unlikely(ret != 0)) { + DRM_ERROR("Failed reserving the SVGA MMIO resource.\n"); + goto out_no_device; + } + vmw_kms_init(dev_priv); + vmw_overlay_init(dev_priv); + } else { + ret = vmw_request_device(dev_priv); + if (unlikely(ret != 0)) + goto out_no_device; + vmw_kms_init(dev_priv); + vmw_overlay_init(dev_priv); + vmw_fb_init(dev_priv); + } + + return 0; + +out_no_device: + if (dev_priv->capabilities & SVGA_CAP_IRQMASK) + drm_irq_uninstall(dev_priv->dev); + if (dev->devname == vmw_devname) + dev->devname = NULL; +out_no_irq: + ttm_object_device_release(&dev_priv->tdev); +out_err4: + iounmap(dev_priv->mmio_virt); +out_err3: + drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, + dev_priv->mmio_size, DRM_MTRR_WC); + (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); +out_err2: + (void)ttm_bo_device_release(&dev_priv->bdev); +out_err1: + vmw_ttm_global_release(dev_priv); +out_err0: + ida_destroy(&dev_priv->gmr_ida); + idr_destroy(&dev_priv->surface_idr); + idr_destroy(&dev_priv->context_idr); + idr_destroy(&dev_priv->stream_idr); + kfree(dev_priv); + return ret; +} + +static int vmw_driver_unload(struct drm_device *dev) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + + DRM_INFO(VMWGFX_DRIVER_NAME " unload.\n"); + + if (!dev_priv->stealth) { + vmw_fb_close(dev_priv); + vmw_kms_close(dev_priv); + vmw_overlay_close(dev_priv); + vmw_release_device(dev_priv); + pci_release_regions(dev->pdev); + } else { + vmw_kms_close(dev_priv); + vmw_overlay_close(dev_priv); + pci_release_region(dev->pdev, 2); + } + if (dev_priv->capabilities & SVGA_CAP_IRQMASK) + drm_irq_uninstall(dev_priv->dev); + if (dev->devname == vmw_devname) + dev->devname = NULL; + ttm_object_device_release(&dev_priv->tdev); + iounmap(dev_priv->mmio_virt); + drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, + dev_priv->mmio_size, DRM_MTRR_WC); + (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); + (void)ttm_bo_device_release(&dev_priv->bdev); + vmw_ttm_global_release(dev_priv); + ida_destroy(&dev_priv->gmr_ida); + idr_destroy(&dev_priv->surface_idr); + idr_destroy(&dev_priv->context_idr); + idr_destroy(&dev_priv->stream_idr); + + kfree(dev_priv); + + return 0; +} + +static void vmw_postclose(struct drm_device *dev, + struct drm_file *file_priv) +{ + struct vmw_fpriv *vmw_fp; + + vmw_fp = vmw_fpriv(file_priv); + ttm_object_file_release(&vmw_fp->tfile); + if (vmw_fp->locked_master) + drm_master_put(&vmw_fp->locked_master); + kfree(vmw_fp); +} + +static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + struct vmw_fpriv *vmw_fp; + int ret = -ENOMEM; + + vmw_fp = kzalloc(sizeof(*vmw_fp), GFP_KERNEL); + if (unlikely(vmw_fp == NULL)) + return ret; + + vmw_fp->tfile = ttm_object_file_init(dev_priv->tdev, 10); + if (unlikely(vmw_fp->tfile == NULL)) + goto out_no_tfile; + + file_priv->driver_priv = vmw_fp; + + if (unlikely(dev_priv->bdev.dev_mapping == NULL)) + dev_priv->bdev.dev_mapping = + file_priv->filp->f_path.dentry->d_inode->i_mapping; + + return 0; + +out_no_tfile: + kfree(vmw_fp); + return ret; +} + +static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct drm_file *file_priv = filp->private_data; + struct drm_device *dev = file_priv->minor->dev; + unsigned int nr = DRM_IOCTL_NR(cmd); + long ret; + + /* + * The driver private ioctls and TTM ioctls should be + * thread-safe. + */ + + if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) + && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) { + struct drm_ioctl_desc *ioctl = + &vmw_ioctls[nr - DRM_COMMAND_BASE]; + + if (unlikely(ioctl->cmd != cmd)) { + DRM_ERROR("Invalid command format, ioctl %d\n", + nr - DRM_COMMAND_BASE); + return -EINVAL; + } + return drm_ioctl(filp->f_path.dentry->d_inode, + filp, cmd, arg); + } + + /* + * Not all old drm ioctls are thread-safe. + */ + + lock_kernel(); + ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); + unlock_kernel(); + return ret; +} + +static int vmw_firstopen(struct drm_device *dev) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + dev_priv->is_opened = true; + + return 0; +} + +static void vmw_lastclose(struct drm_device *dev) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + struct drm_crtc *crtc; + struct drm_mode_set set; + int ret; + + /** + * Do nothing on the lastclose call from drm_unload. + */ + + if (!dev_priv->is_opened) + return; + + dev_priv->is_opened = false; + set.x = 0; + set.y = 0; + set.fb = NULL; + set.mode = NULL; + set.connectors = NULL; + set.num_connectors = 0; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + set.crtc = crtc; + ret = crtc->funcs->set_config(&set); + WARN_ON(ret != 0); + } + +} + +static void vmw_master_init(struct vmw_master *vmaster) +{ + ttm_lock_init(&vmaster->lock); +} + +static int vmw_master_create(struct drm_device *dev, + struct drm_master *master) +{ + struct vmw_master *vmaster; + + DRM_INFO("Master create.\n"); + vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL); + if (unlikely(vmaster == NULL)) + return -ENOMEM; + + ttm_lock_init(&vmaster->lock); + ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); + master->driver_priv = vmaster; + + return 0; +} + +static void vmw_master_destroy(struct drm_device *dev, + struct drm_master *master) +{ + struct vmw_master *vmaster = vmw_master(master); + + DRM_INFO("Master destroy.\n"); + master->driver_priv = NULL; + kfree(vmaster); +} + + +static int vmw_master_set(struct drm_device *dev, + struct drm_file *file_priv, + bool from_open) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); + struct vmw_master *active = dev_priv->active_master; + struct vmw_master *vmaster = vmw_master(file_priv->master); + int ret = 0; + + DRM_INFO("Master set.\n"); + if (dev_priv->stealth) { + ret = vmw_request_device(dev_priv); + if (unlikely(ret != 0)) + return ret; + } + + if (active) { + BUG_ON(active != &dev_priv->fbdev_master); + ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); + if (unlikely(ret != 0)) + goto out_no_active_lock; + + ttm_lock_set_kill(&active->lock, true, SIGTERM); + ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM); + if (unlikely(ret != 0)) { + DRM_ERROR("Unable to clean VRAM on " + "master drop.\n"); + } + + dev_priv->active_master = NULL; + } + + ttm_lock_set_kill(&vmaster->lock, false, SIGTERM); + if (!from_open) { + ttm_vt_unlock(&vmaster->lock); + BUG_ON(vmw_fp->locked_master != file_priv->master); + drm_master_put(&vmw_fp->locked_master); + } + + dev_priv->active_master = vmaster; + + return 0; + +out_no_active_lock: + vmw_release_device(dev_priv); + return ret; +} + +static void vmw_master_drop(struct drm_device *dev, + struct drm_file *file_priv, + bool from_release) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); + struct vmw_master *vmaster = vmw_master(file_priv->master); + int ret; + + DRM_INFO("Master drop.\n"); + + /** + * Make sure the master doesn't disappear while we have + * it locked. + */ + + vmw_fp->locked_master = drm_master_get(file_priv->master); + ret = ttm_vt_lock(&vmaster->lock, false, vmw_fp->tfile); + + if (unlikely((ret != 0))) { + DRM_ERROR("Unable to lock TTM at VT switch.\n"); + drm_master_put(&vmw_fp->locked_master); + } + + ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); + + if (dev_priv->stealth) { + ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM); + if (unlikely(ret != 0)) + DRM_ERROR("Unable to clean VRAM on master drop.\n"); + vmw_release_device(dev_priv); + } + dev_priv->active_master = &dev_priv->fbdev_master; + ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); + ttm_vt_unlock(&dev_priv->fbdev_master.lock); + + if (!dev_priv->stealth) + vmw_fb_on(dev_priv); +} + + +static void vmw_remove(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + + drm_put_dev(dev); +} + +static struct drm_driver driver = { + .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | + DRIVER_MODESET, + .load = vmw_driver_load, + .unload = vmw_driver_unload, + .firstopen = vmw_firstopen, + .lastclose = vmw_lastclose, + .irq_preinstall = vmw_irq_preinstall, + .irq_postinstall = vmw_irq_postinstall, + .irq_uninstall = vmw_irq_uninstall, + .irq_handler = vmw_irq_handler, + .reclaim_buffers_locked = NULL, + .get_map_ofs = drm_core_get_map_ofs, + .get_reg_ofs = drm_core_get_reg_ofs, + .ioctls = vmw_ioctls, + .num_ioctls = DRM_ARRAY_SIZE(vmw_ioctls), + .dma_quiescent = NULL, /*vmw_dma_quiescent, */ + .master_create = vmw_master_create, + .master_destroy = vmw_master_destroy, + .master_set = vmw_master_set, + .master_drop = vmw_master_drop, + .open = vmw_driver_open, + .postclose = vmw_postclose, + .fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .unlocked_ioctl = vmw_unlocked_ioctl, + .mmap = vmw_mmap, + .poll = drm_poll, + .fasync = drm_fasync, +#if defined(CONFIG_COMPAT) + .compat_ioctl = drm_compat_ioctl, +#endif + }, + .pci_driver = { + .name = VMWGFX_DRIVER_NAME, + .id_table = vmw_pci_id_list, + .probe = vmw_probe, + .remove = vmw_remove + }, + .name = VMWGFX_DRIVER_NAME, + .desc = VMWGFX_DRIVER_DESC, + .date = VMWGFX_DRIVER_DATE, + .major = VMWGFX_DRIVER_MAJOR, + .minor = VMWGFX_DRIVER_MINOR, + .patchlevel = VMWGFX_DRIVER_PATCHLEVEL +}; + +static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + return drm_get_dev(pdev, ent, &driver); +} + +static int __init vmwgfx_init(void) +{ + int ret; + ret = drm_init(&driver); + if (ret) + DRM_ERROR("Failed initializing DRM.\n"); + return ret; +} + +static void __exit vmwgfx_exit(void) +{ + drm_exit(&driver); +} + +module_init(vmwgfx_init); +module_exit(vmwgfx_exit); + +MODULE_AUTHOR("VMware Inc. and others"); +MODULE_DESCRIPTION("Standalone drm driver for the VMware SVGA device"); +MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h new file mode 100644 index 0000000..43546d0 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -0,0 +1,511 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _VMWGFX_DRV_H_ +#define _VMWGFX_DRV_H_ + +#include "vmwgfx_reg.h" +#include "drmP.h" +#include "vmwgfx_drm.h" +#include "drm_hashtab.h" +#include "ttm/ttm_bo_driver.h" +#include "ttm/ttm_object.h" +#include "ttm/ttm_lock.h" +#include "ttm/ttm_execbuf_util.h" +#include "ttm/ttm_module.h" + +#define VMWGFX_DRIVER_DATE "20090724" +#define VMWGFX_DRIVER_MAJOR 0 +#define VMWGFX_DRIVER_MINOR 1 +#define VMWGFX_DRIVER_PATCHLEVEL 2 +#define VMWGFX_FILE_PAGE_OFFSET 0x00100000 +#define VMWGFX_FIFO_STATIC_SIZE (1024*1024) +#define VMWGFX_MAX_RELOCATIONS 2048 +#define VMWGFX_MAX_GMRS 2048 + +struct vmw_fpriv { + struct drm_master *locked_master; + struct ttm_object_file *tfile; +}; + +struct vmw_dma_buffer { + struct ttm_buffer_object base; + struct list_head validate_list; + struct list_head gmr_lru; + uint32_t gmr_id; + bool gmr_bound; + uint32_t cur_validate_node; + bool on_validate_list; +}; + +struct vmw_resource { + struct kref kref; + struct vmw_private *dev_priv; + struct idr *idr; + int id; + enum ttm_object_type res_type; + bool avail; + void (*hw_destroy) (struct vmw_resource *res); + void (*res_free) (struct vmw_resource *res); + + /* TODO is a generic snooper needed? */ +#if 0 + void (*snoop)(struct vmw_resource *res, + struct ttm_object_file *tfile, + SVGA3dCmdHeader *header); + void *snoop_priv; +#endif +}; + +struct vmw_cursor_snooper { + struct drm_crtc *crtc; + size_t age; + uint32_t *image; +}; + +struct vmw_surface { + struct vmw_resource res; + uint32_t flags; + uint32_t format; + uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES]; + struct drm_vmw_size *sizes; + uint32_t num_sizes; + + /* TODO so far just a extra pointer */ + struct vmw_cursor_snooper snooper; +}; + +struct vmw_fifo_state { + unsigned long reserved_size; + __le32 *dynamic_buffer; + __le32 *static_buffer; + __le32 *last_buffer; + uint32_t last_data_size; + uint32_t last_buffer_size; + bool last_buffer_add; + unsigned long static_buffer_size; + bool using_bounce_buffer; + uint32_t capabilities; + struct rw_semaphore rwsem; +}; + +struct vmw_relocation { + SVGAGuestPtr *location; + uint32_t index; +}; + +struct vmw_sw_context{ + struct ida bo_list; + uint32_t last_cid; + bool cid_valid; + uint32_t last_sid; + bool sid_valid; + struct ttm_object_file *tfile; + struct list_head validate_nodes; + struct vmw_relocation relocs[VMWGFX_MAX_RELOCATIONS]; + uint32_t cur_reloc; + struct ttm_validate_buffer val_bufs[VMWGFX_MAX_GMRS]; + uint32_t cur_val_buf; +}; + +struct vmw_legacy_display; +struct vmw_overlay; + +struct vmw_master { + struct ttm_lock lock; +}; + +struct vmw_private { + struct ttm_bo_device bdev; + struct ttm_bo_global_ref bo_global_ref; + struct ttm_global_reference mem_global_ref; + + struct vmw_fifo_state fifo; + + struct drm_device *dev; + unsigned long vmw_chipset; + unsigned int io_start; + uint32_t vram_start; + uint32_t vram_size; + uint32_t mmio_start; + uint32_t mmio_size; + uint32_t fb_max_width; + uint32_t fb_max_height; + __le32 __iomem *mmio_virt; + int mmio_mtrr; + uint32_t capabilities; + uint32_t max_gmr_descriptors; + uint32_t max_gmr_ids; + struct mutex hw_mutex; + + /* + * VGA registers. + */ + + uint32_t vga_width; + uint32_t vga_height; + uint32_t vga_depth; + uint32_t vga_bpp; + uint32_t vga_pseudo; + uint32_t vga_red_mask; + uint32_t vga_blue_mask; + uint32_t vga_green_mask; + + /* + * Framebuffer info. + */ + + void *fb_info; + struct vmw_legacy_display *ldu_priv; + struct vmw_overlay *overlay_priv; + + /* + * Context and surface management. + */ + + rwlock_t resource_lock; + struct idr context_idr; + struct idr surface_idr; + struct idr stream_idr; + + /* + * Block lastclose from racing with firstopen. + */ + + struct mutex init_mutex; + + /* + * A resource manager for kernel-only surfaces and + * contexts. + */ + + struct ttm_object_device *tdev; + + /* + * Fencing and IRQs. + */ + + uint32_t fence_seq; + wait_queue_head_t fence_queue; + wait_queue_head_t fifo_queue; + atomic_t fence_queue_waiters; + atomic_t fifo_queue_waiters; + uint32_t last_read_sequence; + spinlock_t irq_lock; + + /* + * Device state + */ + + uint32_t traces_state; + uint32_t enable_state; + uint32_t config_done_state; + + /** + * Execbuf + */ + /** + * Protected by the cmdbuf mutex. + */ + + struct vmw_sw_context ctx; + uint32_t val_seq; + struct mutex cmdbuf_mutex; + + /** + * GMR management. Protected by the lru spinlock. + */ + + struct ida gmr_ida; + struct list_head gmr_lru; + + + /** + * Operating mode. + */ + + bool stealth; + bool is_opened; + + /** + * Master management. + */ + + struct vmw_master *active_master; + struct vmw_master fbdev_master; +}; + +static inline struct vmw_private *vmw_priv(struct drm_device *dev) +{ + return (struct vmw_private *)dev->dev_private; +} + +static inline struct vmw_fpriv *vmw_fpriv(struct drm_file *file_priv) +{ + return (struct vmw_fpriv *)file_priv->driver_priv; +} + +static inline struct vmw_master *vmw_master(struct drm_master *master) +{ + return (struct vmw_master *) master->driver_priv; +} + +static inline void vmw_write(struct vmw_private *dev_priv, + unsigned int offset, uint32_t value) +{ + outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT); + outl(value, dev_priv->io_start + VMWGFX_VALUE_PORT); +} + +static inline uint32_t vmw_read(struct vmw_private *dev_priv, + unsigned int offset) +{ + uint32_t val; + + outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT); + val = inl(dev_priv->io_start + VMWGFX_VALUE_PORT); + return val; +} + +/** + * GMR utilities - vmwgfx_gmr.c + */ + +extern int vmw_gmr_bind(struct vmw_private *dev_priv, + struct ttm_buffer_object *bo); +extern void vmw_gmr_unbind(struct vmw_private *dev_priv, int gmr_id); + +/** + * Resource utilities - vmwgfx_resource.c + */ + +extern struct vmw_resource *vmw_context_alloc(struct vmw_private *dev_priv); +extern void vmw_resource_unreference(struct vmw_resource **p_res); +extern struct vmw_resource *vmw_resource_reference(struct vmw_resource *res); +extern int vmw_context_destroy_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int vmw_context_define_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int vmw_context_check(struct vmw_private *dev_priv, + struct ttm_object_file *tfile, + int id); +extern void vmw_surface_res_free(struct vmw_resource *res); +extern int vmw_surface_init(struct vmw_private *dev_priv, + struct vmw_surface *srf, + void (*res_free) (struct vmw_resource *res)); +extern int vmw_user_surface_lookup(struct vmw_private *dev_priv, + struct ttm_object_file *tfile, + int sid, struct vmw_surface **out); +extern int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int vmw_surface_define_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int vmw_surface_check(struct vmw_private *dev_priv, + struct ttm_object_file *tfile, + int id); +extern void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo); +extern int vmw_dmabuf_init(struct vmw_private *dev_priv, + struct vmw_dma_buffer *vmw_bo, + size_t size, struct ttm_placement *placement, + bool interuptable, + void (*bo_free) (struct ttm_buffer_object *bo)); +extern int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int vmw_dmabuf_unref_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern uint32_t vmw_dmabuf_validate_node(struct ttm_buffer_object *bo, + uint32_t cur_validate_node); +extern void vmw_dmabuf_validate_clear(struct ttm_buffer_object *bo); +extern int vmw_user_dmabuf_lookup(struct ttm_object_file *tfile, + uint32_t id, struct vmw_dma_buffer **out); +extern uint32_t vmw_dmabuf_gmr(struct ttm_buffer_object *bo); +extern void vmw_dmabuf_set_gmr(struct ttm_buffer_object *bo, uint32_t id); +extern int vmw_gmr_id_alloc(struct vmw_private *dev_priv, uint32_t *p_id); +extern int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv, + struct vmw_dma_buffer *bo); +extern int vmw_dmabuf_from_vram(struct vmw_private *vmw_priv, + struct vmw_dma_buffer *bo); +extern int vmw_stream_claim_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int vmw_stream_unref_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int vmw_user_stream_lookup(struct vmw_private *dev_priv, + struct ttm_object_file *tfile, + uint32_t *inout_id, + struct vmw_resource **out); + + +/** + * Misc Ioctl functionality - vmwgfx_ioctl.c + */ + +extern int vmw_getparam_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int vmw_fifo_debug_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +/** + * Fifo utilities - vmwgfx_fifo.c + */ + +extern int vmw_fifo_init(struct vmw_private *dev_priv, + struct vmw_fifo_state *fifo); +extern void vmw_fifo_release(struct vmw_private *dev_priv, + struct vmw_fifo_state *fifo); +extern void *vmw_fifo_reserve(struct vmw_private *dev_priv, uint32_t bytes); +extern void vmw_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes); +extern int vmw_fifo_send_fence(struct vmw_private *dev_priv, + uint32_t *sequence); +extern void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason); +extern int vmw_fifo_mmap(struct file *filp, struct vm_area_struct *vma); + +/** + * TTM glue - vmwgfx_ttm_glue.c + */ + +extern int vmw_ttm_global_init(struct vmw_private *dev_priv); +extern void vmw_ttm_global_release(struct vmw_private *dev_priv); +extern int vmw_mmap(struct file *filp, struct vm_area_struct *vma); + +/** + * TTM buffer object driver - vmwgfx_buffer.c + */ + +extern struct ttm_placement vmw_vram_placement; +extern struct ttm_placement vmw_vram_ne_placement; +extern struct ttm_placement vmw_sys_placement; +extern struct ttm_bo_driver vmw_bo_driver; +extern int vmw_dma_quiescent(struct drm_device *dev); + +/** + * Command submission - vmwgfx_execbuf.c + */ + +extern int vmw_execbuf_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +/** + * IRQs and wating - vmwgfx_irq.c + */ + +extern irqreturn_t vmw_irq_handler(DRM_IRQ_ARGS); +extern int vmw_wait_fence(struct vmw_private *dev_priv, bool lazy, + uint32_t sequence, bool interruptible, + unsigned long timeout); +extern void vmw_irq_preinstall(struct drm_device *dev); +extern int vmw_irq_postinstall(struct drm_device *dev); +extern void vmw_irq_uninstall(struct drm_device *dev); +extern bool vmw_fence_signaled(struct vmw_private *dev_priv, + uint32_t sequence); +extern int vmw_fence_wait_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int vmw_fallback_wait(struct vmw_private *dev_priv, + bool lazy, + bool fifo_idle, + uint32_t sequence, + bool interruptible, + unsigned long timeout); + +/** + * Kernel framebuffer - vmwgfx_fb.c + */ + +int vmw_fb_init(struct vmw_private *vmw_priv); +int vmw_fb_close(struct vmw_private *dev_priv); +int vmw_fb_off(struct vmw_private *vmw_priv); +int vmw_fb_on(struct vmw_private *vmw_priv); + +/** + * Kernel modesetting - vmwgfx_kms.c + */ + +int vmw_kms_init(struct vmw_private *dev_priv); +int vmw_kms_close(struct vmw_private *dev_priv); +int vmw_kms_save_vga(struct vmw_private *vmw_priv); +int vmw_kms_restore_vga(struct vmw_private *vmw_priv); +int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv); +void vmw_kms_cursor_snoop(struct vmw_surface *srf, + struct ttm_object_file *tfile, + struct ttm_buffer_object *bo, + SVGA3dCmdHeader *header); + +/** + * Overlay control - vmwgfx_overlay.c + */ + +int vmw_overlay_init(struct vmw_private *dev_priv); +int vmw_overlay_close(struct vmw_private *dev_priv); +int vmw_overlay_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int vmw_overlay_stop_all(struct vmw_private *dev_priv); +int vmw_overlay_resume_all(struct vmw_private *dev_priv); +int vmw_overlay_pause_all(struct vmw_private *dev_priv); +int vmw_overlay_claim(struct vmw_private *dev_priv, uint32_t *out); +int vmw_overlay_unref(struct vmw_private *dev_priv, uint32_t stream_id); +int vmw_overlay_num_overlays(struct vmw_private *dev_priv); +int vmw_overlay_num_free_overlays(struct vmw_private *dev_priv); + +/** + * Inline helper functions + */ + +static inline void vmw_surface_unreference(struct vmw_surface **srf) +{ + struct vmw_surface *tmp_srf = *srf; + struct vmw_resource *res = &tmp_srf->res; + *srf = NULL; + + vmw_resource_unreference(&res); +} + +static inline struct vmw_surface *vmw_surface_reference(struct vmw_surface *srf) +{ + (void) vmw_resource_reference(&srf->res); + return srf; +} + +static inline void vmw_dmabuf_unreference(struct vmw_dma_buffer **buf) +{ + struct vmw_dma_buffer *tmp_buf = *buf; + struct ttm_buffer_object *bo = &tmp_buf->base; + *buf = NULL; + + ttm_bo_unref(&bo); +} + +static inline struct vmw_dma_buffer *vmw_dmabuf_reference(struct vmw_dma_buffer *buf) +{ + if (ttm_bo_reference(&buf->base)) + return buf; + return NULL; +} + +#endif diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c new file mode 100644 index 0000000..7a39f3e --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -0,0 +1,516 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "vmwgfx_drv.h" +#include "vmwgfx_reg.h" +#include "ttm/ttm_bo_api.h" +#include "ttm/ttm_placement.h" + +static int vmw_cmd_invalid(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + return capable(CAP_SYS_ADMIN) ? : -EINVAL; +} + +static int vmw_cmd_ok(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + return 0; +} + +static int vmw_cmd_cid_check(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_cid_cmd { + SVGA3dCmdHeader header; + __le32 cid; + } *cmd; + int ret; + + cmd = container_of(header, struct vmw_cid_cmd, header); + if (likely(sw_context->cid_valid && cmd->cid == sw_context->last_cid)) + return 0; + + ret = vmw_context_check(dev_priv, sw_context->tfile, cmd->cid); + if (unlikely(ret != 0)) { + DRM_ERROR("Could not find or use context %u\n", + (unsigned) cmd->cid); + return ret; + } + + sw_context->last_cid = cmd->cid; + sw_context->cid_valid = true; + + return 0; +} + +static int vmw_cmd_sid_check(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + uint32_t sid) +{ + if (unlikely((!sw_context->sid_valid || sid != sw_context->last_sid) && + sid != SVGA3D_INVALID_ID)) { + int ret = vmw_surface_check(dev_priv, sw_context->tfile, sid); + + if (unlikely(ret != 0)) { + DRM_ERROR("Could ot find or use surface %u\n", + (unsigned) sid); + return ret; + } + + sw_context->last_sid = sid; + sw_context->sid_valid = true; + } + return 0; +} + + +static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_sid_cmd { + SVGA3dCmdHeader header; + SVGA3dCmdSetRenderTarget body; + } *cmd; + int ret; + + ret = vmw_cmd_cid_check(dev_priv, sw_context, header); + if (unlikely(ret != 0)) + return ret; + + cmd = container_of(header, struct vmw_sid_cmd, header); + return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.target.sid); +} + +static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_sid_cmd { + SVGA3dCmdHeader header; + SVGA3dCmdSurfaceCopy body; + } *cmd; + int ret; + + cmd = container_of(header, struct vmw_sid_cmd, header); + ret = vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.src.sid); + if (unlikely(ret != 0)) + return ret; + return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.dest.sid); +} + +static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_sid_cmd { + SVGA3dCmdHeader header; + SVGA3dCmdSurfaceStretchBlt body; + } *cmd; + int ret; + + cmd = container_of(header, struct vmw_sid_cmd, header); + ret = vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.src.sid); + if (unlikely(ret != 0)) + return ret; + return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.dest.sid); +} + +static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_sid_cmd { + SVGA3dCmdHeader header; + SVGA3dCmdBlitSurfaceToScreen body; + } *cmd; + + cmd = container_of(header, struct vmw_sid_cmd, header); + return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.srcImage.sid); +} + +static int vmw_cmd_present_check(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_sid_cmd { + SVGA3dCmdHeader header; + SVGA3dCmdPresent body; + } *cmd; + + cmd = container_of(header, struct vmw_sid_cmd, header); + return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.sid); +} + +static int vmw_cmd_dma(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + uint32_t handle; + struct vmw_dma_buffer *vmw_bo = NULL; + struct ttm_buffer_object *bo; + struct vmw_surface *srf = NULL; + struct vmw_dma_cmd { + SVGA3dCmdHeader header; + SVGA3dCmdSurfaceDMA dma; + } *cmd; + struct vmw_relocation *reloc; + int ret; + uint32_t cur_validate_node; + struct ttm_validate_buffer *val_buf; + + + cmd = container_of(header, struct vmw_dma_cmd, header); + ret = vmw_cmd_sid_check(dev_priv, sw_context, cmd->dma.host.sid); + if (unlikely(ret != 0)) + return ret; + + handle = cmd->dma.guest.ptr.gmrId; + ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo); + if (unlikely(ret != 0)) { + DRM_ERROR("Could not find or use GMR region.\n"); + return -EINVAL; + } + bo = &vmw_bo->base; + + if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) { + DRM_ERROR("Max number of DMA commands per submission" + " exceeded\n"); + ret = -EINVAL; + goto out_no_reloc; + } + + reloc = &sw_context->relocs[sw_context->cur_reloc++]; + reloc->location = &cmd->dma.guest.ptr; + + cur_validate_node = vmw_dmabuf_validate_node(bo, sw_context->cur_val_buf); + if (unlikely(cur_validate_node >= VMWGFX_MAX_GMRS)) { + DRM_ERROR("Max number of DMA buffers per submission" + " exceeded.\n"); + ret = -EINVAL; + goto out_no_reloc; + } + + reloc->index = cur_validate_node; + if (unlikely(cur_validate_node == sw_context->cur_val_buf)) { + val_buf = &sw_context->val_bufs[cur_validate_node]; + val_buf->bo = ttm_bo_reference(bo); + val_buf->new_sync_obj_arg = (void *) dev_priv; + list_add_tail(&val_buf->head, &sw_context->validate_nodes); + ++sw_context->cur_val_buf; + } + + ret = vmw_user_surface_lookup(dev_priv, sw_context->tfile, + cmd->dma.host.sid, &srf); + if (ret) { + DRM_ERROR("could not find surface\n"); + goto out_no_reloc; + } + + vmw_kms_cursor_snoop(srf, sw_context->tfile, bo, header); + vmw_surface_unreference(&srf); + +out_no_reloc: + vmw_dmabuf_unreference(&vmw_bo); + return ret; +} + + +typedef int (*vmw_cmd_func) (struct vmw_private *, + struct vmw_sw_context *, + SVGA3dCmdHeader *); + +#define VMW_CMD_DEF(cmd, func) \ + [cmd - SVGA_3D_CMD_BASE] = func + +static vmw_cmd_func vmw_cmd_funcs[SVGA_3D_CMD_MAX] = { + VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE, &vmw_cmd_invalid), + VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DESTROY, &vmw_cmd_invalid), + VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_COPY, &vmw_cmd_surface_copy_check), + VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_STRETCHBLT, &vmw_cmd_stretch_blt_check), + VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DMA, &vmw_cmd_dma), + VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DEFINE, &vmw_cmd_invalid), + VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DESTROY, &vmw_cmd_invalid), + VMW_CMD_DEF(SVGA_3D_CMD_SETTRANSFORM, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_SETZRANGE, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERSTATE, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERTARGET, + &vmw_cmd_set_render_target_check), + VMW_CMD_DEF(SVGA_3D_CMD_SETTEXTURESTATE, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_SETMATERIAL, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTDATA, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTENABLED, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_SETVIEWPORT, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_SETCLIPPLANE, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_CLEAR, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_PRESENT, &vmw_cmd_present_check), + VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DEFINE, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DESTROY, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER_CONST, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_QUERY, &vmw_cmd_cid_check), + VMW_CMD_DEF(SVGA_3D_CMD_PRESENT_READBACK, &vmw_cmd_ok), + VMW_CMD_DEF(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN, + &vmw_cmd_blt_surf_screen_check) +}; + +static int vmw_cmd_check(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + void *buf, uint32_t *size) +{ + uint32_t cmd_id; + SVGA3dCmdHeader *header = (SVGA3dCmdHeader *) buf; + int ret; + + cmd_id = ((uint32_t *)buf)[0]; + if (cmd_id == SVGA_CMD_UPDATE) { + *size = 5 << 2; + return 0; + } + + cmd_id = le32_to_cpu(header->id); + *size = le32_to_cpu(header->size) + sizeof(SVGA3dCmdHeader); + + cmd_id -= SVGA_3D_CMD_BASE; + if (unlikely(cmd_id >= SVGA_3D_CMD_MAX - SVGA_3D_CMD_BASE)) + goto out_err; + + ret = vmw_cmd_funcs[cmd_id](dev_priv, sw_context, header); + if (unlikely(ret != 0)) + goto out_err; + + return 0; +out_err: + DRM_ERROR("Illegal / Invalid SVGA3D command: %d\n", + cmd_id + SVGA_3D_CMD_BASE); + return -EINVAL; +} + +static int vmw_cmd_check_all(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + void *buf, uint32_t size) +{ + int32_t cur_size = size; + int ret; + + while (cur_size > 0) { + ret = vmw_cmd_check(dev_priv, sw_context, buf, &size); + if (unlikely(ret != 0)) + return ret; + buf = (void *)((unsigned long) buf + size); + cur_size -= size; + } + + if (unlikely(cur_size != 0)) { + DRM_ERROR("Command verifier out of sync.\n"); + return -EINVAL; + } + + return 0; +} + +static void vmw_free_relocations(struct vmw_sw_context *sw_context) +{ + sw_context->cur_reloc = 0; +} + +static void vmw_apply_relocations(struct vmw_sw_context *sw_context) +{ + uint32_t i; + struct vmw_relocation *reloc; + struct ttm_validate_buffer *validate; + struct ttm_buffer_object *bo; + + for (i = 0; i < sw_context->cur_reloc; ++i) { + reloc = &sw_context->relocs[i]; + validate = &sw_context->val_bufs[reloc->index]; + bo = validate->bo; + reloc->location->offset += bo->offset; + reloc->location->gmrId = vmw_dmabuf_gmr(bo); + } + vmw_free_relocations(sw_context); +} + +static void vmw_clear_validations(struct vmw_sw_context *sw_context) +{ + struct ttm_validate_buffer *entry, *next; + + list_for_each_entry_safe(entry, next, &sw_context->validate_nodes, + head) { + list_del(&entry->head); + vmw_dmabuf_validate_clear(entry->bo); + ttm_bo_unref(&entry->bo); + sw_context->cur_val_buf--; + } + BUG_ON(sw_context->cur_val_buf != 0); +} + +static int vmw_validate_single_buffer(struct vmw_private *dev_priv, + struct ttm_buffer_object *bo) +{ + int ret; + + if (vmw_dmabuf_gmr(bo) != SVGA_GMR_NULL) + return 0; + + ret = vmw_gmr_bind(dev_priv, bo); + if (likely(ret == 0 || ret == -ERESTART)) + return ret; + + + ret = ttm_bo_validate(bo, &vmw_vram_placement, true, false); + return ret; +} + + +static int vmw_validate_buffers(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context) +{ + struct ttm_validate_buffer *entry; + int ret; + + list_for_each_entry(entry, &sw_context->validate_nodes, head) { + ret = vmw_validate_single_buffer(dev_priv, entry->bo); + if (unlikely(ret != 0)) + return ret; + } + return 0; +} + +int vmw_execbuf_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + struct drm_vmw_execbuf_arg *arg = (struct drm_vmw_execbuf_arg *)data; + struct drm_vmw_fence_rep fence_rep; + struct drm_vmw_fence_rep __user *user_fence_rep; + int ret; + void *user_cmd; + void *cmd; + uint32_t sequence; + struct vmw_sw_context *sw_context = &dev_priv->ctx; + struct vmw_master *vmaster = vmw_master(file_priv->master); + + ret = ttm_read_lock(&vmaster->lock, true); + if (unlikely(ret != 0)) + return ret; + + ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex); + if (unlikely(ret != 0)) { + ret = -ERESTART; + goto out_no_cmd_mutex; + } + + cmd = vmw_fifo_reserve(dev_priv, arg->command_size); + if (unlikely(cmd == NULL)) { + DRM_ERROR("Failed reserving fifo space for commands.\n"); + ret = -ENOMEM; + goto out_unlock; + } + + user_cmd = (void __user *)(unsigned long)arg->commands; + ret = copy_from_user(cmd, user_cmd, arg->command_size); + + if (unlikely(ret != 0)) { + DRM_ERROR("Failed copying commands.\n"); + goto out_commit; + } + + sw_context->tfile = vmw_fpriv(file_priv)->tfile; + sw_context->cid_valid = false; + sw_context->sid_valid = false; + sw_context->cur_reloc = 0; + sw_context->cur_val_buf = 0; + + INIT_LIST_HEAD(&sw_context->validate_nodes); + + ret = vmw_cmd_check_all(dev_priv, sw_context, cmd, arg->command_size); + if (unlikely(ret != 0)) + goto out_err; + ret = ttm_eu_reserve_buffers(&sw_context->validate_nodes, + dev_priv->val_seq++); + if (unlikely(ret != 0)) + goto out_err; + + ret = vmw_validate_buffers(dev_priv, sw_context); + if (unlikely(ret != 0)) + goto out_err; + + vmw_apply_relocations(sw_context); + vmw_fifo_commit(dev_priv, arg->command_size); + + ret = vmw_fifo_send_fence(dev_priv, &sequence); + + ttm_eu_fence_buffer_objects(&sw_context->validate_nodes, + (void *)(unsigned long) sequence); + vmw_clear_validations(sw_context); + mutex_unlock(&dev_priv->cmdbuf_mutex); + + /* + * This error is harmless, because if fence submission fails, + * vmw_fifo_send_fence will sync. + */ + + if (ret != 0) + DRM_ERROR("Fence submission error. Syncing.\n"); + + fence_rep.error = ret; + fence_rep.fence_seq = (uint64_t) sequence; + + user_fence_rep = (struct drm_vmw_fence_rep __user *) + (unsigned long)arg->fence_rep; + + /* + * copy_to_user errors will be detected by user space not + * seeing fence_rep::error filled in. + */ + + ret = copy_to_user(user_fence_rep, &fence_rep, sizeof(fence_rep)); + + vmw_kms_cursor_post_execbuf(dev_priv); + ttm_read_unlock(&vmaster->lock); + return 0; +out_err: + vmw_free_relocations(sw_context); + ttm_eu_backoff_reservation(&sw_context->validate_nodes); + vmw_clear_validations(sw_context); +out_commit: + vmw_fifo_commit(dev_priv, 0); +out_unlock: + mutex_unlock(&dev_priv->cmdbuf_mutex); +out_no_cmd_mutex: + ttm_read_unlock(&vmaster->lock); + return ret; +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c new file mode 100644 index 0000000..641dde7 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -0,0 +1,742 @@ +/************************************************************************** + * + * Copyright © 2007 David Airlie + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "drmP.h" +#include "vmwgfx_drv.h" + +#include "ttm/ttm_placement.h" + +#define VMW_DIRTY_DELAY (HZ / 30) + +struct vmw_fb_par { + struct vmw_private *vmw_priv; + + void *vmalloc; + + struct vmw_dma_buffer *vmw_bo; + struct ttm_bo_kmap_obj map; + + u32 pseudo_palette[17]; + + unsigned depth; + unsigned bpp; + + unsigned max_width; + unsigned max_height; + + void *bo_ptr; + unsigned bo_size; + bool bo_iowrite; + + struct { + spinlock_t lock; + bool active; + unsigned x1; + unsigned y1; + unsigned x2; + unsigned y2; + } dirty; +}; + +static int vmw_fb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info) +{ + struct vmw_fb_par *par = info->par; + u32 *pal = par->pseudo_palette; + + if (regno > 15) { + DRM_ERROR("Bad regno %u.\n", regno); + return 1; + } + + switch (par->depth) { + case 24: + case 32: + pal[regno] = ((red & 0xff00) << 8) | + (green & 0xff00) | + ((blue & 0xff00) >> 8); + break; + default: + DRM_ERROR("Bad depth %u, bpp %u.\n", par->depth, par->bpp); + return 1; + } + + return 0; +} + +static int vmw_fb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + int depth = var->bits_per_pixel; + struct vmw_fb_par *par = info->par; + struct vmw_private *vmw_priv = par->vmw_priv; + + switch (var->bits_per_pixel) { + case 32: + depth = (var->transp.length > 0) ? 32 : 24; + break; + default: + DRM_ERROR("Bad bpp %u.\n", var->bits_per_pixel); + return -EINVAL; + } + + switch (depth) { + case 24: + var->red.offset = 16; + var->green.offset = 8; + var->blue.offset = 0; + var->red.length = 8; + var->green.length = 8; + var->blue.length = 8; + var->transp.length = 0; + var->transp.offset = 0; + break; + case 32: + var->red.offset = 16; + var->green.offset = 8; + var->blue.offset = 0; + var->red.length = 8; + var->green.length = 8; + var->blue.length = 8; + var->transp.length = 8; + var->transp.offset = 24; + break; + default: + DRM_ERROR("Bad depth %u.\n", depth); + return -EINVAL; + } + + /* without multimon its hard to resize */ + if (!(vmw_priv->capabilities & SVGA_CAP_MULTIMON) && + (var->xres != par->max_width || + var->yres != par->max_height)) { + DRM_ERROR("Tried to resize, but we don't have multimon\n"); + return -EINVAL; + } + + if (var->xres > par->max_width || + var->yres > par->max_height) { + DRM_ERROR("Requested geom can not fit in framebuffer\n"); + return -EINVAL; + } + + return 0; +} + +static int vmw_fb_set_par(struct fb_info *info) +{ + struct vmw_fb_par *par = info->par; + struct vmw_private *vmw_priv = par->vmw_priv; + + if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) { + vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, 0); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, 0); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, 0); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); + + vmw_write(vmw_priv, SVGA_REG_ENABLE, 1); + vmw_write(vmw_priv, SVGA_REG_WIDTH, par->max_width); + vmw_write(vmw_priv, SVGA_REG_HEIGHT, par->max_height); + vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, par->bpp); + vmw_write(vmw_priv, SVGA_REG_DEPTH, par->depth); + vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000); + vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00); + vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff); + + /* TODO check if pitch and offset changes */ + + vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, info->var.xoffset); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, info->var.yoffset); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, info->var.xres); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, info->var.yres); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); + } else { + vmw_write(vmw_priv, SVGA_REG_WIDTH, info->var.xres); + vmw_write(vmw_priv, SVGA_REG_HEIGHT, info->var.yres); + + /* TODO check if pitch and offset changes */ + } + + return 0; +} + +static int vmw_fb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + return 0; +} + +static int vmw_fb_blank(int blank, struct fb_info *info) +{ + return 0; +} + +/* + * Dirty code + */ + +static void vmw_fb_dirty_flush(struct vmw_fb_par *par) +{ + struct vmw_private *vmw_priv = par->vmw_priv; + struct fb_info *info = vmw_priv->fb_info; + int stride = (info->fix.line_length / 4); + int *src = (int *)info->screen_base; + __le32 __iomem *vram_mem = par->bo_ptr; + unsigned long flags; + unsigned x, y, w, h; + int i, k; + struct { + uint32_t header; + SVGAFifoCmdUpdate body; + } *cmd; + + spin_lock_irqsave(&par->dirty.lock, flags); + if (!par->dirty.active) { + spin_unlock_irqrestore(&par->dirty.lock, flags); + return; + } + x = par->dirty.x1; + y = par->dirty.y1; + w = min(par->dirty.x2, info->var.xres) - x; + h = min(par->dirty.y2, info->var.yres) - y; + par->dirty.x1 = par->dirty.x2 = 0; + par->dirty.y1 = par->dirty.y2 = 0; + spin_unlock_irqrestore(&par->dirty.lock, flags); + + for (i = y * stride; i < info->fix.smem_len / 4; i += stride) { + for (k = i+x; k < i+x+w && k < info->fix.smem_len / 4; k++) + iowrite32(src[k], vram_mem + k); + } + +#if 0 + DRM_INFO("%s, (%u, %u) (%ux%u)\n", __func__, x, y, w, h); +#endif + + cmd = vmw_fifo_reserve(vmw_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) { + DRM_ERROR("Fifo reserve failed.\n"); + return; + } + + cmd->header = cpu_to_le32(SVGA_CMD_UPDATE); + cmd->body.x = cpu_to_le32(x); + cmd->body.y = cpu_to_le32(y); + cmd->body.width = cpu_to_le32(w); + cmd->body.height = cpu_to_le32(h); + vmw_fifo_commit(vmw_priv, sizeof(*cmd)); +} + +static void vmw_fb_dirty_mark(struct vmw_fb_par *par, + unsigned x1, unsigned y1, + unsigned width, unsigned height) +{ + struct fb_info *info = par->vmw_priv->fb_info; + unsigned long flags; + unsigned x2 = x1 + width; + unsigned y2 = y1 + height; + + spin_lock_irqsave(&par->dirty.lock, flags); + if (par->dirty.x1 == par->dirty.x2) { + par->dirty.x1 = x1; + par->dirty.y1 = y1; + par->dirty.x2 = x2; + par->dirty.y2 = y2; + /* if we are active start the dirty work + * we share the work with the defio system */ + if (par->dirty.active) + schedule_delayed_work(&info->deferred_work, VMW_DIRTY_DELAY); + } else { + if (x1 < par->dirty.x1) + par->dirty.x1 = x1; + if (y1 < par->dirty.y1) + par->dirty.y1 = y1; + if (x2 > par->dirty.x2) + par->dirty.x2 = x2; + if (y2 > par->dirty.y2) + par->dirty.y2 = y2; + } + spin_unlock_irqrestore(&par->dirty.lock, flags); +} + +static void vmw_deferred_io(struct fb_info *info, + struct list_head *pagelist) +{ + struct vmw_fb_par *par = info->par; + unsigned long start, end, min, max; + unsigned long flags; + struct page *page; + int y1, y2; + + min = ULONG_MAX; + max = 0; + list_for_each_entry(page, pagelist, lru) { + start = page->index << PAGE_SHIFT; + end = start + PAGE_SIZE - 1; + min = min(min, start); + max = max(max, end); + } + + if (min < max) { + y1 = min / info->fix.line_length; + y2 = (max / info->fix.line_length) + 1; + + spin_lock_irqsave(&par->dirty.lock, flags); + par->dirty.x1 = 0; + par->dirty.y1 = y1; + par->dirty.x2 = info->var.xres; + par->dirty.y2 = y2; + spin_unlock_irqrestore(&par->dirty.lock, flags); + } + + vmw_fb_dirty_flush(par); +}; + +struct fb_deferred_io vmw_defio = { + .delay = VMW_DIRTY_DELAY, + .deferred_io = vmw_deferred_io, +}; + +/* + * Draw code + */ + +static void vmw_fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) +{ + cfb_fillrect(info, rect); + vmw_fb_dirty_mark(info->par, rect->dx, rect->dy, + rect->width, rect->height); +} + +static void vmw_fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) +{ + cfb_copyarea(info, region); + vmw_fb_dirty_mark(info->par, region->dx, region->dy, + region->width, region->height); +} + +static void vmw_fb_imageblit(struct fb_info *info, const struct fb_image *image) +{ + cfb_imageblit(info, image); + vmw_fb_dirty_mark(info->par, image->dx, image->dy, + image->width, image->height); +} + +/* + * Bring up code + */ + +static struct fb_ops vmw_fb_ops = { + .owner = THIS_MODULE, + .fb_check_var = vmw_fb_check_var, + .fb_set_par = vmw_fb_set_par, + .fb_setcolreg = vmw_fb_setcolreg, + .fb_fillrect = vmw_fb_fillrect, + .fb_copyarea = vmw_fb_copyarea, + .fb_imageblit = vmw_fb_imageblit, + .fb_pan_display = vmw_fb_pan_display, + .fb_blank = vmw_fb_blank, +}; + +static int vmw_fb_create_bo(struct vmw_private *vmw_priv, + size_t size, struct vmw_dma_buffer **out) +{ + struct vmw_dma_buffer *vmw_bo; + struct ttm_placement ne_placement = vmw_vram_ne_placement; + int ret; + + ne_placement.lpfn = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; + + /* interuptable? */ + ret = ttm_write_lock(&vmw_priv->fbdev_master.lock, false); + if (unlikely(ret != 0)) + return ret; + + vmw_bo = kmalloc(sizeof(*vmw_bo), GFP_KERNEL); + if (!vmw_bo) + goto err_unlock; + + ret = vmw_dmabuf_init(vmw_priv, vmw_bo, size, + &ne_placement, + false, + &vmw_dmabuf_bo_free); + if (unlikely(ret != 0)) + goto err_unlock; /* init frees the buffer on failure */ + + *out = vmw_bo; + + ttm_write_unlock(&vmw_priv->fbdev_master.lock); + + return 0; + +err_unlock: + ttm_write_unlock(&vmw_priv->fbdev_master.lock); + return ret; +} + +int vmw_fb_init(struct vmw_private *vmw_priv) +{ + struct device *device = &vmw_priv->dev->pdev->dev; + struct vmw_fb_par *par; + struct fb_info *info; + unsigned initial_width, initial_height; + unsigned fb_width, fb_height; + unsigned fb_bbp, fb_depth, fb_offset, fb_pitch, fb_size; + int ret; + + initial_width = 800; + initial_height = 600; + + fb_bbp = 32; + fb_depth = 24; + + if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) { + fb_width = min(vmw_priv->fb_max_width, (unsigned)2048); + fb_height = min(vmw_priv->fb_max_height, (unsigned)2048); + } else { + fb_width = min(vmw_priv->fb_max_width, initial_width); + fb_height = min(vmw_priv->fb_max_height, initial_height); + } + + initial_width = min(fb_width, initial_width); + initial_height = min(fb_height, initial_height); + + vmw_write(vmw_priv, SVGA_REG_WIDTH, fb_width); + vmw_write(vmw_priv, SVGA_REG_HEIGHT, fb_height); + vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, fb_bbp); + vmw_write(vmw_priv, SVGA_REG_DEPTH, fb_depth); + vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000); + vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00); + vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff); + + fb_size = vmw_read(vmw_priv, SVGA_REG_FB_SIZE); + fb_offset = vmw_read(vmw_priv, SVGA_REG_FB_OFFSET); + fb_pitch = vmw_read(vmw_priv, SVGA_REG_BYTES_PER_LINE); + + DRM_DEBUG("width %u\n", vmw_read(vmw_priv, SVGA_REG_MAX_WIDTH)); + DRM_DEBUG("height %u\n", vmw_read(vmw_priv, SVGA_REG_MAX_HEIGHT)); + DRM_DEBUG("width %u\n", vmw_read(vmw_priv, SVGA_REG_WIDTH)); + DRM_DEBUG("height %u\n", vmw_read(vmw_priv, SVGA_REG_HEIGHT)); + DRM_DEBUG("bpp %u\n", vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL)); + DRM_DEBUG("depth %u\n", vmw_read(vmw_priv, SVGA_REG_DEPTH)); + DRM_DEBUG("bpl %u\n", vmw_read(vmw_priv, SVGA_REG_BYTES_PER_LINE)); + DRM_DEBUG("r mask %08x\n", vmw_read(vmw_priv, SVGA_REG_RED_MASK)); + DRM_DEBUG("g mask %08x\n", vmw_read(vmw_priv, SVGA_REG_GREEN_MASK)); + DRM_DEBUG("b mask %08x\n", vmw_read(vmw_priv, SVGA_REG_BLUE_MASK)); + DRM_DEBUG("fb_offset 0x%08x\n", fb_offset); + DRM_DEBUG("fb_pitch %u\n", fb_pitch); + DRM_DEBUG("fb_size %u kiB\n", fb_size / 1024); + + info = framebuffer_alloc(sizeof(*par), device); + if (!info) + return -ENOMEM; + + /* + * Par + */ + vmw_priv->fb_info = info; + par = info->par; + par->vmw_priv = vmw_priv; + par->depth = fb_depth; + par->bpp = fb_bbp; + par->vmalloc = NULL; + par->max_width = fb_width; + par->max_height = fb_height; + + /* + * Create buffers and alloc memory + */ + par->vmalloc = vmalloc(fb_size); + if (unlikely(par->vmalloc == NULL)) { + ret = -ENOMEM; + goto err_free; + } + + ret = vmw_fb_create_bo(vmw_priv, fb_size, &par->vmw_bo); + if (unlikely(ret != 0)) + goto err_free; + + ret = ttm_bo_kmap(&par->vmw_bo->base, + 0, + par->vmw_bo->base.num_pages, + &par->map); + if (unlikely(ret != 0)) + goto err_unref; + par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite); + par->bo_size = fb_size; + + /* + * Fixed and var + */ + strcpy(info->fix.id, "svgadrmfb"); + info->fix.type = FB_TYPE_PACKED_PIXELS; + info->fix.visual = FB_VISUAL_TRUECOLOR; + info->fix.type_aux = 0; + info->fix.xpanstep = 1; /* doing it in hw */ + info->fix.ypanstep = 1; /* doing it in hw */ + info->fix.ywrapstep = 0; + info->fix.accel = FB_ACCEL_NONE; + info->fix.line_length = fb_pitch; + + info->fix.smem_start = 0; + info->fix.smem_len = fb_size; + + info->fix.mmio_start = 0; + info->fix.mmio_len = 0; + + info->pseudo_palette = par->pseudo_palette; + info->screen_base = par->vmalloc; + info->screen_size = fb_size; + + info->flags = FBINFO_DEFAULT; + info->fbops = &vmw_fb_ops; + + /* 24 depth per default */ + info->var.red.offset = 16; + info->var.green.offset = 8; + info->var.blue.offset = 0; + info->var.red.length = 8; + info->var.green.length = 8; + info->var.blue.length = 8; + info->var.transp.offset = 0; + info->var.transp.length = 0; + + info->var.xres_virtual = fb_width; + info->var.yres_virtual = fb_height; + info->var.bits_per_pixel = par->bpp; + info->var.xoffset = 0; + info->var.yoffset = 0; + info->var.activate = FB_ACTIVATE_NOW; + info->var.height = -1; + info->var.width = -1; + + info->var.xres = initial_width; + info->var.yres = initial_height; + +#if 0 + info->pixmap.size = 64*1024; + info->pixmap.buf_align = 8; + info->pixmap.access_align = 32; + info->pixmap.flags = FB_PIXMAP_SYSTEM; + info->pixmap.scan_align = 1; +#else + info->pixmap.size = 0; + info->pixmap.buf_align = 8; + info->pixmap.access_align = 32; + info->pixmap.flags = FB_PIXMAP_SYSTEM; + info->pixmap.scan_align = 1; +#endif + + /* + * Dirty & Deferred IO + */ + par->dirty.x1 = par->dirty.x2 = 0; + par->dirty.y1 = par->dirty.y1 = 0; + par->dirty.active = true; + spin_lock_init(&par->dirty.lock); + info->fbdefio = &vmw_defio; + fb_deferred_io_init(info); + + ret = register_framebuffer(info); + if (unlikely(ret != 0)) + goto err_defio; + + return 0; + +err_defio: + fb_deferred_io_cleanup(info); + ttm_bo_kunmap(&par->map); +err_unref: + ttm_bo_unref((struct ttm_buffer_object **)&par->vmw_bo); +err_free: + vfree(par->vmalloc); + framebuffer_release(info); + vmw_priv->fb_info = NULL; + + return ret; +} + +int vmw_fb_close(struct vmw_private *vmw_priv) +{ + struct fb_info *info; + struct vmw_fb_par *par; + struct ttm_buffer_object *bo; + + if (!vmw_priv->fb_info) + return 0; + + info = vmw_priv->fb_info; + par = info->par; + bo = &par->vmw_bo->base; + par->vmw_bo = NULL; + + /* ??? order */ + fb_deferred_io_cleanup(info); + unregister_framebuffer(info); + + ttm_bo_kunmap(&par->map); + ttm_bo_unref(&bo); + + vfree(par->vmalloc); + framebuffer_release(info); + + return 0; +} + +int vmw_dmabuf_from_vram(struct vmw_private *vmw_priv, + struct vmw_dma_buffer *vmw_bo) +{ + struct ttm_buffer_object *bo = &vmw_bo->base; + int ret = 0; + + ret = ttm_bo_reserve(bo, false, false, false, 0); + if (unlikely(ret != 0)) + return ret; + + ret = ttm_bo_validate(bo, &vmw_sys_placement, false, false); + ttm_bo_unreserve(bo); + + return ret; +} + +int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv, + struct vmw_dma_buffer *vmw_bo) +{ + struct ttm_buffer_object *bo = &vmw_bo->base; + struct ttm_placement ne_placement = vmw_vram_ne_placement; + int ret = 0; + + ne_placement.lpfn = bo->num_pages; + + /* interuptable? */ + ret = ttm_write_lock(&vmw_priv->active_master->lock, false); + if (unlikely(ret != 0)) + return ret; + + ret = ttm_bo_reserve(bo, false, false, false, 0); + if (unlikely(ret != 0)) + goto err_unlock; + + if (vmw_bo->gmr_bound) { + vmw_gmr_unbind(vmw_priv, vmw_bo->gmr_id); + spin_lock(&bo->glob->lru_lock); + ida_remove(&vmw_priv->gmr_ida, vmw_bo->gmr_id); + spin_unlock(&bo->glob->lru_lock); + vmw_bo->gmr_bound = NULL; + } + + ret = ttm_bo_validate(bo, &ne_placement, false, false); + ttm_bo_unreserve(bo); +err_unlock: + ttm_write_unlock(&vmw_priv->active_master->lock); + + return ret; +} + +int vmw_fb_off(struct vmw_private *vmw_priv) +{ + struct fb_info *info; + struct vmw_fb_par *par; + unsigned long flags; + + if (!vmw_priv->fb_info) + return -EINVAL; + + info = vmw_priv->fb_info; + par = info->par; + + spin_lock_irqsave(&par->dirty.lock, flags); + par->dirty.active = false; + spin_unlock_irqrestore(&par->dirty.lock, flags); + + flush_scheduled_work(); + + par->bo_ptr = NULL; + ttm_bo_kunmap(&par->map); + + vmw_dmabuf_from_vram(vmw_priv, par->vmw_bo); + + return 0; +} + +int vmw_fb_on(struct vmw_private *vmw_priv) +{ + struct fb_info *info; + struct vmw_fb_par *par; + unsigned long flags; + bool dummy; + int ret; + + if (!vmw_priv->fb_info) + return -EINVAL; + + info = vmw_priv->fb_info; + par = info->par; + + /* we are already active */ + if (par->bo_ptr != NULL) + return 0; + + /* Make sure that all overlays are stoped when we take over */ + vmw_overlay_stop_all(vmw_priv); + + ret = vmw_dmabuf_to_start_of_vram(vmw_priv, par->vmw_bo); + if (unlikely(ret != 0)) { + DRM_ERROR("could not move buffer to start of VRAM\n"); + goto err_no_buffer; + } + + ret = ttm_bo_kmap(&par->vmw_bo->base, + 0, + par->vmw_bo->base.num_pages, + &par->map); + BUG_ON(ret != 0); + par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &dummy); + + spin_lock_irqsave(&par->dirty.lock, flags); + par->dirty.active = true; + spin_unlock_irqrestore(&par->dirty.lock, flags); + +err_no_buffer: + vmw_fb_set_par(info); + + vmw_fb_dirty_mark(par, 0, 0, info->var.xres, info->var.yres); + + /* If there already was stuff dirty we wont + * schedule a new work, so lets do it now */ + schedule_delayed_work(&info->deferred_work, 0); + + return 0; +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c new file mode 100644 index 0000000..76b0693 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c @@ -0,0 +1,521 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "vmwgfx_drv.h" +#include "drmP.h" +#include "ttm/ttm_placement.h" + +int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) +{ + __le32 __iomem *fifo_mem = dev_priv->mmio_virt; + uint32_t max; + uint32_t min; + uint32_t dummy; + int ret; + + fifo->static_buffer_size = VMWGFX_FIFO_STATIC_SIZE; + fifo->static_buffer = vmalloc(fifo->static_buffer_size); + if (unlikely(fifo->static_buffer == NULL)) + return -ENOMEM; + + fifo->last_buffer_size = VMWGFX_FIFO_STATIC_SIZE; + fifo->last_data_size = 0; + fifo->last_buffer_add = false; + fifo->last_buffer = vmalloc(fifo->last_buffer_size); + if (unlikely(fifo->last_buffer == NULL)) { + ret = -ENOMEM; + goto out_err; + } + + fifo->dynamic_buffer = NULL; + fifo->reserved_size = 0; + fifo->using_bounce_buffer = false; + + init_rwsem(&fifo->rwsem); + + /* + * Allow mapping the first page read-only to user-space. + */ + + DRM_INFO("width %d\n", vmw_read(dev_priv, SVGA_REG_WIDTH)); + DRM_INFO("height %d\n", vmw_read(dev_priv, SVGA_REG_HEIGHT)); + DRM_INFO("bpp %d\n", vmw_read(dev_priv, SVGA_REG_BITS_PER_PIXEL)); + + mutex_lock(&dev_priv->hw_mutex); + dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); + dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); + vmw_write(dev_priv, SVGA_REG_ENABLE, 1); + + min = 4; + if (dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO) + min = vmw_read(dev_priv, SVGA_REG_MEM_REGS); + min <<= 2; + + if (min < PAGE_SIZE) + min = PAGE_SIZE; + + iowrite32(min, fifo_mem + SVGA_FIFO_MIN); + iowrite32(dev_priv->mmio_size, fifo_mem + SVGA_FIFO_MAX); + wmb(); + iowrite32(min, fifo_mem + SVGA_FIFO_NEXT_CMD); + iowrite32(min, fifo_mem + SVGA_FIFO_STOP); + iowrite32(0, fifo_mem + SVGA_FIFO_BUSY); + mb(); + + vmw_write(dev_priv, SVGA_REG_CONFIG_DONE, 1); + mutex_unlock(&dev_priv->hw_mutex); + + max = ioread32(fifo_mem + SVGA_FIFO_MAX); + min = ioread32(fifo_mem + SVGA_FIFO_MIN); + fifo->capabilities = ioread32(fifo_mem + SVGA_FIFO_CAPABILITIES); + + DRM_INFO("Fifo max 0x%08x min 0x%08x cap 0x%08x\n", + (unsigned int) max, + (unsigned int) min, + (unsigned int) fifo->capabilities); + + dev_priv->fence_seq = (uint32_t) -100; + dev_priv->last_read_sequence = (uint32_t) -100; + iowrite32(dev_priv->last_read_sequence, fifo_mem + SVGA_FIFO_FENCE); + + return vmw_fifo_send_fence(dev_priv, &dummy); +out_err: + vfree(fifo->static_buffer); + fifo->static_buffer = NULL; + return ret; +} + +void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason) +{ + __le32 __iomem *fifo_mem = dev_priv->mmio_virt; + + mutex_lock(&dev_priv->hw_mutex); + + if (unlikely(ioread32(fifo_mem + SVGA_FIFO_BUSY) == 0)) { + iowrite32(1, fifo_mem + SVGA_FIFO_BUSY); + vmw_write(dev_priv, SVGA_REG_SYNC, reason); + } + + mutex_unlock(&dev_priv->hw_mutex); +} + +void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) +{ + __le32 __iomem *fifo_mem = dev_priv->mmio_virt; + + mutex_lock(&dev_priv->hw_mutex); + + while (vmw_read(dev_priv, SVGA_REG_BUSY) != 0) + vmw_write(dev_priv, SVGA_REG_SYNC, SVGA_SYNC_GENERIC); + + dev_priv->last_read_sequence = ioread32(fifo_mem + SVGA_FIFO_FENCE); + + vmw_write(dev_priv, SVGA_REG_CONFIG_DONE, + dev_priv->config_done_state); + vmw_write(dev_priv, SVGA_REG_ENABLE, + dev_priv->enable_state); + + mutex_unlock(&dev_priv->hw_mutex); + + if (likely(fifo->last_buffer != NULL)) { + vfree(fifo->last_buffer); + fifo->last_buffer = NULL; + } + + if (likely(fifo->static_buffer != NULL)) { + vfree(fifo->static_buffer); + fifo->static_buffer = NULL; + } + + if (likely(fifo->dynamic_buffer != NULL)) { + vfree(fifo->dynamic_buffer); + fifo->dynamic_buffer = NULL; + } +} + +static bool vmw_fifo_is_full(struct vmw_private *dev_priv, uint32_t bytes) +{ + __le32 __iomem *fifo_mem = dev_priv->mmio_virt; + uint32_t max = ioread32(fifo_mem + SVGA_FIFO_MAX); + uint32_t next_cmd = ioread32(fifo_mem + SVGA_FIFO_NEXT_CMD); + uint32_t min = ioread32(fifo_mem + SVGA_FIFO_MIN); + uint32_t stop = ioread32(fifo_mem + SVGA_FIFO_STOP); + + return ((max - next_cmd) + (stop - min) <= bytes); +} + +static int vmw_fifo_wait_noirq(struct vmw_private *dev_priv, + uint32_t bytes, bool interruptible, + unsigned long timeout) +{ + int ret = 0; + unsigned long end_jiffies = jiffies + timeout; + DEFINE_WAIT(__wait); + + DRM_INFO("Fifo wait noirq.\n"); + + for (;;) { + prepare_to_wait(&dev_priv->fifo_queue, &__wait, + (interruptible) ? + TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); + if (!vmw_fifo_is_full(dev_priv, bytes)) + break; + if (time_after_eq(jiffies, end_jiffies)) { + ret = -EBUSY; + DRM_ERROR("SVGA device lockup.\n"); + break; + } + schedule_timeout(1); + if (interruptible && signal_pending(current)) { + ret = -ERESTART; + break; + } + } + finish_wait(&dev_priv->fifo_queue, &__wait); + wake_up_all(&dev_priv->fifo_queue); + DRM_INFO("Fifo noirq exit.\n"); + return ret; +} + +static int vmw_fifo_wait(struct vmw_private *dev_priv, + uint32_t bytes, bool interruptible, + unsigned long timeout) +{ + long ret = 1L; + unsigned long irq_flags; + + if (likely(!vmw_fifo_is_full(dev_priv, bytes))) + return 0; + + vmw_fifo_ping_host(dev_priv, SVGA_SYNC_FIFOFULL); + if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) + return vmw_fifo_wait_noirq(dev_priv, bytes, + interruptible, timeout); + + mutex_lock(&dev_priv->hw_mutex); + if (atomic_add_return(1, &dev_priv->fifo_queue_waiters) > 0) { + spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); + outl(SVGA_IRQFLAG_FIFO_PROGRESS, + dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); + vmw_write(dev_priv, SVGA_REG_IRQMASK, + vmw_read(dev_priv, SVGA_REG_IRQMASK) | + SVGA_IRQFLAG_FIFO_PROGRESS); + spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); + } + mutex_unlock(&dev_priv->hw_mutex); + + if (interruptible) + ret = wait_event_interruptible_timeout + (dev_priv->fifo_queue, + !vmw_fifo_is_full(dev_priv, bytes), timeout); + else + ret = wait_event_timeout + (dev_priv->fifo_queue, + !vmw_fifo_is_full(dev_priv, bytes), timeout); + + if (unlikely(ret == -ERESTARTSYS)) + ret = -ERESTART; + else if (unlikely(ret == 0)) + ret = -EBUSY; + else if (likely(ret > 0)) + ret = 0; + + mutex_lock(&dev_priv->hw_mutex); + if (atomic_dec_and_test(&dev_priv->fifo_queue_waiters)) { + spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); + vmw_write(dev_priv, SVGA_REG_IRQMASK, + vmw_read(dev_priv, SVGA_REG_IRQMASK) & + ~SVGA_IRQFLAG_FIFO_PROGRESS); + spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); + } + mutex_unlock(&dev_priv->hw_mutex); + + return ret; +} + +void *vmw_fifo_reserve(struct vmw_private *dev_priv, uint32_t bytes) +{ + struct vmw_fifo_state *fifo_state = &dev_priv->fifo; + __le32 __iomem *fifo_mem = dev_priv->mmio_virt; + uint32_t max; + uint32_t min; + uint32_t next_cmd; + uint32_t reserveable = fifo_state->capabilities & SVGA_FIFO_CAP_RESERVE; + int ret; + + down_write(&fifo_state->rwsem); + max = ioread32(fifo_mem + SVGA_FIFO_MAX); + min = ioread32(fifo_mem + SVGA_FIFO_MIN); + next_cmd = ioread32(fifo_mem + SVGA_FIFO_NEXT_CMD); + + if (unlikely(bytes >= (max - min))) + goto out_err; + + BUG_ON(fifo_state->reserved_size != 0); + BUG_ON(fifo_state->dynamic_buffer != NULL); + + fifo_state->reserved_size = bytes; + + while (1) { + uint32_t stop = ioread32(fifo_mem + SVGA_FIFO_STOP); + bool need_bounce = false; + bool reserve_in_place = false; + + if (next_cmd >= stop) { + if (likely((next_cmd + bytes < max || + (next_cmd + bytes == max && stop > min)))) + reserve_in_place = true; + + else if (vmw_fifo_is_full(dev_priv, bytes)) { + ret = vmw_fifo_wait(dev_priv, bytes, + false, 3 * HZ); + if (unlikely(ret != 0)) + goto out_err; + } else + need_bounce = true; + + } else { + + if (likely((next_cmd + bytes < stop))) + reserve_in_place = true; + else { + ret = vmw_fifo_wait(dev_priv, bytes, + false, 3 * HZ); + if (unlikely(ret != 0)) + goto out_err; + } + } + + if (reserve_in_place) { + if (reserveable || bytes <= sizeof(uint32_t)) { + fifo_state->using_bounce_buffer = false; + + if (reserveable) + iowrite32(bytes, fifo_mem + + SVGA_FIFO_RESERVED); + return fifo_mem + (next_cmd >> 2); + } else { + need_bounce = true; + } + } + + if (need_bounce) { + fifo_state->using_bounce_buffer = true; + if (bytes < fifo_state->static_buffer_size) + return fifo_state->static_buffer; + else { + fifo_state->dynamic_buffer = vmalloc(bytes); + return fifo_state->dynamic_buffer; + } + } + } +out_err: + fifo_state->reserved_size = 0; + up_write(&fifo_state->rwsem); + return NULL; +} + +static void vmw_fifo_res_copy(struct vmw_fifo_state *fifo_state, + __le32 __iomem *fifo_mem, + uint32_t next_cmd, + uint32_t max, uint32_t min, uint32_t bytes) +{ + uint32_t chunk_size = max - next_cmd; + uint32_t rest; + uint32_t *buffer = (fifo_state->dynamic_buffer != NULL) ? + fifo_state->dynamic_buffer : fifo_state->static_buffer; + + if (bytes < chunk_size) + chunk_size = bytes; + + iowrite32(bytes, fifo_mem + SVGA_FIFO_RESERVED); + mb(); + memcpy_toio(fifo_mem + (next_cmd >> 2), buffer, chunk_size); + rest = bytes - chunk_size; + if (rest) + memcpy_toio(fifo_mem + (min >> 2), buffer + (chunk_size >> 2), + rest); +} + +static void vmw_fifo_slow_copy(struct vmw_fifo_state *fifo_state, + __le32 __iomem *fifo_mem, + uint32_t next_cmd, + uint32_t max, uint32_t min, uint32_t bytes) +{ + uint32_t *buffer = (fifo_state->dynamic_buffer != NULL) ? + fifo_state->dynamic_buffer : fifo_state->static_buffer; + + while (bytes > 0) { + iowrite32(*buffer++, fifo_mem + (next_cmd >> 2)); + next_cmd += sizeof(uint32_t); + if (unlikely(next_cmd == max)) + next_cmd = min; + mb(); + iowrite32(next_cmd, fifo_mem + SVGA_FIFO_NEXT_CMD); + mb(); + bytes -= sizeof(uint32_t); + } +} + +void vmw_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes) +{ + struct vmw_fifo_state *fifo_state = &dev_priv->fifo; + __le32 __iomem *fifo_mem = dev_priv->mmio_virt; + uint32_t next_cmd = ioread32(fifo_mem + SVGA_FIFO_NEXT_CMD); + uint32_t max = ioread32(fifo_mem + SVGA_FIFO_MAX); + uint32_t min = ioread32(fifo_mem + SVGA_FIFO_MIN); + bool reserveable = fifo_state->capabilities & SVGA_FIFO_CAP_RESERVE; + + BUG_ON((bytes & 3) != 0); + BUG_ON(bytes > fifo_state->reserved_size); + + fifo_state->reserved_size = 0; + + if (fifo_state->using_bounce_buffer) { + if (reserveable) + vmw_fifo_res_copy(fifo_state, fifo_mem, + next_cmd, max, min, bytes); + else + vmw_fifo_slow_copy(fifo_state, fifo_mem, + next_cmd, max, min, bytes); + + if (fifo_state->dynamic_buffer) { + vfree(fifo_state->dynamic_buffer); + fifo_state->dynamic_buffer = NULL; + } + + } + + if (fifo_state->using_bounce_buffer || reserveable) { + next_cmd += bytes; + if (next_cmd >= max) + next_cmd -= max - min; + mb(); + iowrite32(next_cmd, fifo_mem + SVGA_FIFO_NEXT_CMD); + } + + if (reserveable) + iowrite32(0, fifo_mem + SVGA_FIFO_RESERVED); + mb(); + vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); + up_write(&fifo_state->rwsem); +} + +int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *sequence) +{ + struct vmw_fifo_state *fifo_state = &dev_priv->fifo; + struct svga_fifo_cmd_fence *cmd_fence; + void *fm; + int ret = 0; + uint32_t bytes = sizeof(__le32) + sizeof(*cmd_fence); + + fm = vmw_fifo_reserve(dev_priv, bytes); + if (unlikely(fm == NULL)) { + down_write(&fifo_state->rwsem); + *sequence = dev_priv->fence_seq; + up_write(&fifo_state->rwsem); + ret = -ENOMEM; + (void)vmw_fallback_wait(dev_priv, false, true, *sequence, + false, 3*HZ); + goto out_err; + } + + do { + *sequence = dev_priv->fence_seq++; + } while (*sequence == 0); + + if (!(fifo_state->capabilities & SVGA_FIFO_CAP_FENCE)) { + + /* + * Don't request hardware to send a fence. The + * waiting code in vmwgfx_irq.c will emulate this. + */ + + vmw_fifo_commit(dev_priv, 0); + return 0; + } + + *(__le32 *) fm = cpu_to_le32(SVGA_CMD_FENCE); + cmd_fence = (struct svga_fifo_cmd_fence *) + ((unsigned long)fm + sizeof(__le32)); + + iowrite32(*sequence, &cmd_fence->fence); + fifo_state->last_buffer_add = true; + vmw_fifo_commit(dev_priv, bytes); + fifo_state->last_buffer_add = false; + +out_err: + return ret; +} + +/** + * Map the first page of the FIFO read-only to user-space. + */ + +static int vmw_fifo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + int ret; + unsigned long address = (unsigned long)vmf->virtual_address; + + if (address != vma->vm_start) + return VM_FAULT_SIGBUS; + + ret = vm_insert_pfn(vma, address, vma->vm_pgoff); + if (likely(ret == -EBUSY || ret == 0)) + return VM_FAULT_NOPAGE; + else if (ret == -ENOMEM) + return VM_FAULT_OOM; + + return VM_FAULT_SIGBUS; +} + +static struct vm_operations_struct vmw_fifo_vm_ops = { + .fault = vmw_fifo_vm_fault, + .open = NULL, + .close = NULL +}; + +int vmw_fifo_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct drm_file *file_priv; + struct vmw_private *dev_priv; + + file_priv = (struct drm_file *)filp->private_data; + dev_priv = vmw_priv(file_priv->minor->dev); + + if (vma->vm_pgoff != (dev_priv->mmio_start >> PAGE_SHIFT) || + (vma->vm_end - vma->vm_start) != PAGE_SIZE) + return -EINVAL; + + vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE); + vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_SHARED; + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + vma->vm_page_prot = ttm_io_prot(TTM_PL_FLAG_UNCACHED, + vma->vm_page_prot); + vma->vm_ops = &vmw_fifo_vm_ops; + return 0; +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c new file mode 100644 index 0000000..5f8908a --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c @@ -0,0 +1,213 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "vmwgfx_drv.h" +#include "drmP.h" +#include "ttm/ttm_bo_driver.h" + +/** + * FIXME: Adjust to the ttm lowmem / highmem storage to minimize + * the number of used descriptors. + */ + +static int vmw_gmr_build_descriptors(struct list_head *desc_pages, + struct page *pages[], + unsigned long num_pages) +{ + struct page *page, *next; + struct svga_guest_mem_descriptor *page_virtual = NULL; + struct svga_guest_mem_descriptor *desc_virtual = NULL; + unsigned int desc_per_page; + unsigned long prev_pfn; + unsigned long pfn; + int ret; + + desc_per_page = PAGE_SIZE / + sizeof(struct svga_guest_mem_descriptor) - 1; + + while (likely(num_pages != 0)) { + page = alloc_page(__GFP_HIGHMEM); + if (unlikely(page == NULL)) { + ret = -ENOMEM; + goto out_err; + } + + list_add_tail(&page->lru, desc_pages); + + /* + * Point previous page terminating descriptor to this + * page before unmapping it. + */ + + if (likely(page_virtual != NULL)) { + desc_virtual->ppn = page_to_pfn(page); + kunmap_atomic(page_virtual, KM_USER0); + } + + page_virtual = kmap_atomic(page, KM_USER0); + desc_virtual = page_virtual - 1; + prev_pfn = ~(0UL); + + while (likely(num_pages != 0)) { + pfn = page_to_pfn(*pages); + + if (pfn != prev_pfn + 1) { + + if (desc_virtual - page_virtual == + desc_per_page - 1) + break; + + (++desc_virtual)->ppn = cpu_to_le32(pfn); + desc_virtual->num_pages = cpu_to_le32(1); + } else { + uint32_t tmp = + le32_to_cpu(desc_virtual->num_pages); + desc_virtual->num_pages = cpu_to_le32(tmp + 1); + } + prev_pfn = pfn; + --num_pages; + ++pages; + } + + (++desc_virtual)->ppn = cpu_to_le32(0); + desc_virtual->num_pages = cpu_to_le32(0); + } + + if (likely(page_virtual != NULL)) + kunmap_atomic(page_virtual, KM_USER0); + + return 0; +out_err: + list_for_each_entry_safe(page, next, desc_pages, lru) { + list_del_init(&page->lru); + __free_page(page); + } + return ret; +} + +static inline void vmw_gmr_free_descriptors(struct list_head *desc_pages) +{ + struct page *page, *next; + + list_for_each_entry_safe(page, next, desc_pages, lru) { + list_del_init(&page->lru); + __free_page(page); + } +} + +static void vmw_gmr_fire_descriptors(struct vmw_private *dev_priv, + int gmr_id, struct list_head *desc_pages) +{ + struct page *page; + + if (unlikely(list_empty(desc_pages))) + return; + + page = list_entry(desc_pages->next, struct page, lru); + + mutex_lock(&dev_priv->hw_mutex); + + vmw_write(dev_priv, SVGA_REG_GMR_ID, gmr_id); + wmb(); + vmw_write(dev_priv, SVGA_REG_GMR_DESCRIPTOR, page_to_pfn(page)); + mb(); + + mutex_unlock(&dev_priv->hw_mutex); + +} + +/** + * FIXME: Adjust to the ttm lowmem / highmem storage to minimize + * the number of used descriptors. + */ + +static unsigned long vmw_gmr_count_descriptors(struct page *pages[], + unsigned long num_pages) +{ + unsigned long prev_pfn = ~(0UL); + unsigned long pfn; + unsigned long descriptors = 0; + + while (num_pages--) { + pfn = page_to_pfn(*pages++); + if (prev_pfn + 1 != pfn) + ++descriptors; + prev_pfn = pfn; + } + + return descriptors; +} + +int vmw_gmr_bind(struct vmw_private *dev_priv, + struct ttm_buffer_object *bo) +{ + struct ttm_tt *ttm = bo->ttm; + unsigned long descriptors; + int ret; + uint32_t id; + struct list_head desc_pages; + + if (!(dev_priv->capabilities & SVGA_CAP_GMR)) + return -EINVAL; + + ret = ttm_tt_populate(ttm); + if (unlikely(ret != 0)) + return ret; + + descriptors = vmw_gmr_count_descriptors(ttm->pages, ttm->num_pages); + if (unlikely(descriptors > dev_priv->max_gmr_descriptors)) + return -EINVAL; + + INIT_LIST_HEAD(&desc_pages); + ret = vmw_gmr_build_descriptors(&desc_pages, ttm->pages, + ttm->num_pages); + if (unlikely(ret != 0)) + return ret; + + ret = vmw_gmr_id_alloc(dev_priv, &id); + if (unlikely(ret != 0)) + goto out_no_id; + + vmw_gmr_fire_descriptors(dev_priv, id, &desc_pages); + vmw_gmr_free_descriptors(&desc_pages); + vmw_dmabuf_set_gmr(bo, id); + return 0; + +out_no_id: + vmw_gmr_free_descriptors(&desc_pages); + return ret; +} + +void vmw_gmr_unbind(struct vmw_private *dev_priv, int gmr_id) +{ + mutex_lock(&dev_priv->hw_mutex); + vmw_write(dev_priv, SVGA_REG_GMR_ID, gmr_id); + wmb(); + vmw_write(dev_priv, SVGA_REG_GMR_DESCRIPTOR, 0); + mb(); + mutex_unlock(&dev_priv->hw_mutex); +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c new file mode 100644 index 0000000..5fa6a4e --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -0,0 +1,81 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "vmwgfx_drv.h" +#include "vmwgfx_drm.h" + +int vmw_getparam_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + struct drm_vmw_getparam_arg *param = + (struct drm_vmw_getparam_arg *)data; + + switch (param->param) { + case DRM_VMW_PARAM_NUM_STREAMS: + param->value = vmw_overlay_num_overlays(dev_priv); + break; + case DRM_VMW_PARAM_NUM_FREE_STREAMS: + param->value = vmw_overlay_num_free_overlays(dev_priv); + break; + case DRM_VMW_PARAM_3D: + param->value = dev_priv->capabilities & SVGA_CAP_3D ? 1 : 0; + break; + case DRM_VMW_PARAM_FIFO_OFFSET: + param->value = dev_priv->mmio_start; + break; + default: + DRM_ERROR("Illegal vmwgfx get param request: %d\n", + param->param); + return -EINVAL; + } + + return 0; +} + +int vmw_fifo_debug_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + struct vmw_fifo_state *fifo_state = &dev_priv->fifo; + struct drm_vmw_fifo_debug_arg *arg = + (struct drm_vmw_fifo_debug_arg *)data; + __le32 __user *buffer = (__le32 __user *) + (unsigned long)arg->debug_buffer; + + if (unlikely(fifo_state->last_buffer == NULL)) + return -EINVAL; + + if (arg->debug_buffer_size < fifo_state->last_data_size) { + arg->used_size = arg->debug_buffer_size; + arg->did_not_fit = 1; + } else { + arg->used_size = fifo_state->last_data_size; + arg->did_not_fit = 0; + } + return copy_to_user(buffer, fifo_state->last_buffer, arg->used_size); +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c new file mode 100644 index 0000000..9e0f030 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c @@ -0,0 +1,295 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "drmP.h" +#include "vmwgfx_drv.h" + +#define VMW_FENCE_WRAP (1 << 24) + +irqreturn_t vmw_irq_handler(DRM_IRQ_ARGS) +{ + struct drm_device *dev = (struct drm_device *)arg; + struct vmw_private *dev_priv = vmw_priv(dev); + uint32_t status; + + spin_lock(&dev_priv->irq_lock); + status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); + spin_unlock(&dev_priv->irq_lock); + + if (status & SVGA_IRQFLAG_ANY_FENCE) + wake_up_all(&dev_priv->fence_queue); + if (status & SVGA_IRQFLAG_FIFO_PROGRESS) + wake_up_all(&dev_priv->fifo_queue); + + if (likely(status)) { + outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static bool vmw_fifo_idle(struct vmw_private *dev_priv, uint32_t sequence) +{ + uint32_t busy; + + mutex_lock(&dev_priv->hw_mutex); + busy = vmw_read(dev_priv, SVGA_REG_BUSY); + mutex_unlock(&dev_priv->hw_mutex); + + return (busy == 0); +} + + +bool vmw_fence_signaled(struct vmw_private *dev_priv, + uint32_t sequence) +{ + __le32 __iomem *fifo_mem = dev_priv->mmio_virt; + struct vmw_fifo_state *fifo_state; + bool ret; + + if (likely(dev_priv->last_read_sequence - sequence < VMW_FENCE_WRAP)) + return true; + + dev_priv->last_read_sequence = ioread32(fifo_mem + SVGA_FIFO_FENCE); + if (likely(dev_priv->last_read_sequence - sequence < VMW_FENCE_WRAP)) + return true; + + fifo_state = &dev_priv->fifo; + if (!(fifo_state->capabilities & SVGA_FIFO_CAP_FENCE) && + vmw_fifo_idle(dev_priv, sequence)) + return true; + + /** + * Below is to signal stale fences that have wrapped. + * First, block fence submission. + */ + + down_read(&fifo_state->rwsem); + + /** + * Then check if the sequence is higher than what we've actually + * emitted. Then the fence is stale and signaled. + */ + + ret = ((dev_priv->fence_seq - sequence) > VMW_FENCE_WRAP); + up_read(&fifo_state->rwsem); + + return ret; +} + +int vmw_fallback_wait(struct vmw_private *dev_priv, + bool lazy, + bool fifo_idle, + uint32_t sequence, + bool interruptible, + unsigned long timeout) +{ + struct vmw_fifo_state *fifo_state = &dev_priv->fifo; + + uint32_t count = 0; + uint32_t signal_seq; + int ret; + unsigned long end_jiffies = jiffies + timeout; + bool (*wait_condition)(struct vmw_private *, uint32_t); + DEFINE_WAIT(__wait); + + wait_condition = (fifo_idle) ? &vmw_fifo_idle : + &vmw_fence_signaled; + + /** + * Block command submission while waiting for idle. + */ + + if (fifo_idle) + down_read(&fifo_state->rwsem); + signal_seq = dev_priv->fence_seq; + ret = 0; + + for (;;) { + prepare_to_wait(&dev_priv->fence_queue, &__wait, + (interruptible) ? + TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); + if (wait_condition(dev_priv, sequence)) + break; + if (time_after_eq(jiffies, end_jiffies)) { + DRM_ERROR("SVGA device lockup.\n"); + break; + } + if (lazy) + schedule_timeout(1); + else if ((++count & 0x0F) == 0) { + /** + * FIXME: Use schedule_hr_timeout here for + * newer kernels and lower CPU utilization. + */ + + __set_current_state(TASK_RUNNING); + schedule(); + __set_current_state((interruptible) ? + TASK_INTERRUPTIBLE : + TASK_UNINTERRUPTIBLE); + } + if (interruptible && signal_pending(current)) { + ret = -ERESTART; + break; + } + } + finish_wait(&dev_priv->fence_queue, &__wait); + if (ret == 0 && fifo_idle) { + __le32 __iomem *fifo_mem = dev_priv->mmio_virt; + iowrite32(signal_seq, fifo_mem + SVGA_FIFO_FENCE); + } + wake_up_all(&dev_priv->fence_queue); + if (fifo_idle) + up_read(&fifo_state->rwsem); + + return ret; +} + +int vmw_wait_fence(struct vmw_private *dev_priv, + bool lazy, uint32_t sequence, + bool interruptible, unsigned long timeout) +{ + long ret; + unsigned long irq_flags; + struct vmw_fifo_state *fifo = &dev_priv->fifo; + + if (likely(dev_priv->last_read_sequence - sequence < VMW_FENCE_WRAP)) + return 0; + + if (likely(vmw_fence_signaled(dev_priv, sequence))) + return 0; + + vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); + + if (!(fifo->capabilities & SVGA_FIFO_CAP_FENCE)) + return vmw_fallback_wait(dev_priv, lazy, true, sequence, + interruptible, timeout); + + if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) + return vmw_fallback_wait(dev_priv, lazy, false, sequence, + interruptible, timeout); + + mutex_lock(&dev_priv->hw_mutex); + if (atomic_add_return(1, &dev_priv->fence_queue_waiters) > 0) { + spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); + outl(SVGA_IRQFLAG_ANY_FENCE, + dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); + vmw_write(dev_priv, SVGA_REG_IRQMASK, + vmw_read(dev_priv, SVGA_REG_IRQMASK) | + SVGA_IRQFLAG_ANY_FENCE); + spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); + } + mutex_unlock(&dev_priv->hw_mutex); + + if (interruptible) + ret = wait_event_interruptible_timeout + (dev_priv->fence_queue, + vmw_fence_signaled(dev_priv, sequence), + timeout); + else + ret = wait_event_timeout + (dev_priv->fence_queue, + vmw_fence_signaled(dev_priv, sequence), + timeout); + + if (unlikely(ret == -ERESTARTSYS)) + ret = -ERESTART; + else if (unlikely(ret == 0)) + ret = -EBUSY; + else if (likely(ret > 0)) + ret = 0; + + mutex_lock(&dev_priv->hw_mutex); + if (atomic_dec_and_test(&dev_priv->fence_queue_waiters)) { + spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); + vmw_write(dev_priv, SVGA_REG_IRQMASK, + vmw_read(dev_priv, SVGA_REG_IRQMASK) & + ~SVGA_IRQFLAG_ANY_FENCE); + spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); + } + mutex_unlock(&dev_priv->hw_mutex); + + return ret; +} + +void vmw_irq_preinstall(struct drm_device *dev) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + uint32_t status; + + if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) + return; + + spin_lock_init(&dev_priv->irq_lock); + status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); + outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); +} + +int vmw_irq_postinstall(struct drm_device *dev) +{ + return 0; +} + +void vmw_irq_uninstall(struct drm_device *dev) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + uint32_t status; + + if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) + return; + + mutex_lock(&dev_priv->hw_mutex); + vmw_write(dev_priv, SVGA_REG_IRQMASK, 0); + mutex_unlock(&dev_priv->hw_mutex); + + status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); + outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); +} + +#define VMW_FENCE_WAIT_TIMEOUT 3*HZ; + +int vmw_fence_wait_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_vmw_fence_wait_arg *arg = + (struct drm_vmw_fence_wait_arg *)data; + unsigned long timeout; + + if (!arg->cookie_valid) { + arg->cookie_valid = 1; + arg->kernel_cookie = jiffies + VMW_FENCE_WAIT_TIMEOUT; + } + + timeout = jiffies; + if (time_after_eq(timeout, (unsigned long)arg->kernel_cookie)) + return -EBUSY; + + timeout = (unsigned long)arg->kernel_cookie - timeout; + return vmw_wait_fence(vmw_priv(dev), true, arg->sequence, true, timeout); +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c new file mode 100644 index 0000000..e9403be --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -0,0 +1,872 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "vmwgfx_kms.h" + +/* Might need a hrtimer here? */ +#define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1) + + +void vmw_display_unit_cleanup(struct vmw_display_unit *du) +{ + if (du->cursor_surface) + vmw_surface_unreference(&du->cursor_surface); + if (du->cursor_dmabuf) + vmw_dmabuf_unreference(&du->cursor_dmabuf); + drm_crtc_cleanup(&du->crtc); + drm_encoder_cleanup(&du->encoder); + drm_connector_cleanup(&du->connector); +} + +/* + * Display Unit Cursor functions + */ + +int vmw_cursor_update_image(struct vmw_private *dev_priv, + u32 *image, u32 width, u32 height, + u32 hotspotX, u32 hotspotY) +{ + struct { + u32 cmd; + SVGAFifoCmdDefineAlphaCursor cursor; + } *cmd; + u32 image_size = width * height * 4; + u32 cmd_size = sizeof(*cmd) + image_size; + + if (!image) + return -EINVAL; + + cmd = vmw_fifo_reserve(dev_priv, cmd_size); + if (unlikely(cmd == NULL)) { + DRM_ERROR("Fifo reserve failed.\n"); + return -ENOMEM; + } + + memset(cmd, 0, sizeof(*cmd)); + + memcpy(&cmd[1], image, image_size); + + cmd->cmd = cpu_to_le32(SVGA_CMD_DEFINE_ALPHA_CURSOR); + cmd->cursor.id = cpu_to_le32(0); + cmd->cursor.width = cpu_to_le32(width); + cmd->cursor.height = cpu_to_le32(height); + cmd->cursor.hotspotX = cpu_to_le32(hotspotX); + cmd->cursor.hotspotY = cpu_to_le32(hotspotY); + + vmw_fifo_commit(dev_priv, cmd_size); + + return 0; +} + +void vmw_cursor_update_position(struct vmw_private *dev_priv, + bool show, int x, int y) +{ + __le32 __iomem *fifo_mem = dev_priv->mmio_virt; + uint32_t count; + + iowrite32(show ? 1 : 0, fifo_mem + SVGA_FIFO_CURSOR_ON); + iowrite32(x, fifo_mem + SVGA_FIFO_CURSOR_X); + iowrite32(y, fifo_mem + SVGA_FIFO_CURSOR_Y); + count = ioread32(fifo_mem + SVGA_FIFO_CURSOR_COUNT); + iowrite32(++count, fifo_mem + SVGA_FIFO_CURSOR_COUNT); +} + +int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, + uint32_t handle, uint32_t width, uint32_t height) +{ + struct vmw_private *dev_priv = vmw_priv(crtc->dev); + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; + struct vmw_display_unit *du = vmw_crtc_to_du(crtc); + struct vmw_surface *surface = NULL; + struct vmw_dma_buffer *dmabuf = NULL; + int ret; + + if (handle) { + ret = vmw_user_surface_lookup(dev_priv, tfile, + handle, &surface); + if (!ret) { + if (!surface->snooper.image) { + DRM_ERROR("surface not suitable for cursor\n"); + return -EINVAL; + } + } else { + ret = vmw_user_dmabuf_lookup(tfile, + handle, &dmabuf); + if (ret) { + DRM_ERROR("failed to find surface or dmabuf: %i\n", ret); + return -EINVAL; + } + } + } + + /* takedown old cursor */ + if (du->cursor_surface) { + du->cursor_surface->snooper.crtc = NULL; + vmw_surface_unreference(&du->cursor_surface); + } + if (du->cursor_dmabuf) + vmw_dmabuf_unreference(&du->cursor_dmabuf); + + /* setup new image */ + if (surface) { + /* vmw_user_surface_lookup takes one reference */ + du->cursor_surface = surface; + + du->cursor_surface->snooper.crtc = crtc; + du->cursor_age = du->cursor_surface->snooper.age; + vmw_cursor_update_image(dev_priv, surface->snooper.image, + 64, 64, du->hotspot_x, du->hotspot_y); + } else if (dmabuf) { + struct ttm_bo_kmap_obj map; + unsigned long kmap_offset; + unsigned long kmap_num; + void *virtual; + bool dummy; + + /* vmw_user_surface_lookup takes one reference */ + du->cursor_dmabuf = dmabuf; + + kmap_offset = 0; + kmap_num = (64*64*4) >> PAGE_SHIFT; + + ret = ttm_bo_reserve(&dmabuf->base, true, false, false, 0); + if (unlikely(ret != 0)) { + DRM_ERROR("reserve failed\n"); + return -EINVAL; + } + + ret = ttm_bo_kmap(&dmabuf->base, kmap_offset, kmap_num, &map); + if (unlikely(ret != 0)) + goto err_unreserve; + + virtual = ttm_kmap_obj_virtual(&map, &dummy); + vmw_cursor_update_image(dev_priv, virtual, 64, 64, + du->hotspot_x, du->hotspot_y); + + ttm_bo_kunmap(&map); +err_unreserve: + ttm_bo_unreserve(&dmabuf->base); + + } else { + vmw_cursor_update_position(dev_priv, false, 0, 0); + return 0; + } + + vmw_cursor_update_position(dev_priv, true, du->cursor_x, du->cursor_y); + + return 0; +} + +int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) +{ + struct vmw_private *dev_priv = vmw_priv(crtc->dev); + struct vmw_display_unit *du = vmw_crtc_to_du(crtc); + bool shown = du->cursor_surface || du->cursor_dmabuf ? true : false; + + du->cursor_x = x + crtc->x; + du->cursor_y = y + crtc->y; + + vmw_cursor_update_position(dev_priv, shown, + du->cursor_x, du->cursor_y); + + return 0; +} + +void vmw_kms_cursor_snoop(struct vmw_surface *srf, + struct ttm_object_file *tfile, + struct ttm_buffer_object *bo, + SVGA3dCmdHeader *header) +{ + struct ttm_bo_kmap_obj map; + unsigned long kmap_offset; + unsigned long kmap_num; + SVGA3dCopyBox *box; + unsigned box_count; + void *virtual; + bool dummy; + struct vmw_dma_cmd { + SVGA3dCmdHeader header; + SVGA3dCmdSurfaceDMA dma; + } *cmd; + int ret; + + cmd = container_of(header, struct vmw_dma_cmd, header); + + /* No snooper installed */ + if (!srf->snooper.image) + return; + + if (cmd->dma.host.face != 0 || cmd->dma.host.mipmap != 0) { + DRM_ERROR("face and mipmap for cursors should never != 0\n"); + return; + } + + if (cmd->header.size < 64) { + DRM_ERROR("at least one full copy box must be given\n"); + return; + } + + box = (SVGA3dCopyBox *)&cmd[1]; + box_count = (cmd->header.size - sizeof(SVGA3dCmdSurfaceDMA)) / + sizeof(SVGA3dCopyBox); + + if (cmd->dma.guest.pitch != (64 * 4) || + cmd->dma.guest.ptr.offset % PAGE_SIZE || + box->x != 0 || box->y != 0 || box->z != 0 || + box->srcx != 0 || box->srcy != 0 || box->srcz != 0 || + box->w != 64 || box->h != 64 || box->d != 1 || + box_count != 1) { + /* TODO handle none page aligned offsets */ + /* TODO handle partial uploads and pitch != 256 */ + /* TODO handle more then one copy (size != 64) */ + DRM_ERROR("lazy programer, cant handle wierd stuff\n"); + return; + } + + kmap_offset = cmd->dma.guest.ptr.offset >> PAGE_SHIFT; + kmap_num = (64*64*4) >> PAGE_SHIFT; + + ret = ttm_bo_reserve(bo, true, false, false, 0); + if (unlikely(ret != 0)) { + DRM_ERROR("reserve failed\n"); + return; + } + + ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map); + if (unlikely(ret != 0)) + goto err_unreserve; + + virtual = ttm_kmap_obj_virtual(&map, &dummy); + + memcpy(srf->snooper.image, virtual, 64*64*4); + srf->snooper.age++; + + /* we can't call this function from this function since execbuf has + * reserved fifo space. + * + * if (srf->snooper.crtc) + * vmw_ldu_crtc_cursor_update_image(dev_priv, + * srf->snooper.image, 64, 64, + * du->hotspot_x, du->hotspot_y); + */ + + ttm_bo_kunmap(&map); +err_unreserve: + ttm_bo_unreserve(bo); +} + +void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct vmw_display_unit *du; + struct drm_crtc *crtc; + + mutex_lock(&dev->mode_config.mutex); + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + du = vmw_crtc_to_du(crtc); + if (!du->cursor_surface || + du->cursor_age == du->cursor_surface->snooper.age) + continue; + + du->cursor_age = du->cursor_surface->snooper.age; + vmw_cursor_update_image(dev_priv, + du->cursor_surface->snooper.image, + 64, 64, du->hotspot_x, du->hotspot_y); + } + + mutex_unlock(&dev->mode_config.mutex); +} + +/* + * Generic framebuffer code + */ + +int vmw_framebuffer_create_handle(struct drm_framebuffer *fb, + struct drm_file *file_priv, + unsigned int *handle) +{ + if (handle) + handle = 0; + + return 0; +} + +/* + * Surface framebuffer code + */ + +#define vmw_framebuffer_to_vfbs(x) \ + container_of(x, struct vmw_framebuffer_surface, base.base) + +struct vmw_framebuffer_surface { + struct vmw_framebuffer base; + struct vmw_surface *surface; + struct delayed_work d_work; + struct mutex work_lock; + bool present_fs; +}; + +void vmw_framebuffer_surface_destroy(struct drm_framebuffer *framebuffer) +{ + struct vmw_framebuffer_surface *vfb = + vmw_framebuffer_to_vfbs(framebuffer); + + cancel_delayed_work_sync(&vfb->d_work); + drm_framebuffer_cleanup(framebuffer); + vmw_surface_unreference(&vfb->surface); + + kfree(framebuffer); +} + +static void vmw_framebuffer_present_fs_callback(struct work_struct *work) +{ + struct delayed_work *d_work = + container_of(work, struct delayed_work, work); + struct vmw_framebuffer_surface *vfbs = + container_of(d_work, struct vmw_framebuffer_surface, d_work); + struct vmw_surface *surf = vfbs->surface; + struct drm_framebuffer *framebuffer = &vfbs->base.base; + struct vmw_private *dev_priv = vmw_priv(framebuffer->dev); + + struct { + SVGA3dCmdHeader header; + SVGA3dCmdPresent body; + SVGA3dCopyRect cr; + } *cmd; + + mutex_lock(&vfbs->work_lock); + if (!vfbs->present_fs) + goto out_unlock; + + cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) + goto out_resched; + + cmd->header.id = cpu_to_le32(SVGA_3D_CMD_PRESENT); + cmd->header.size = cpu_to_le32(sizeof(cmd->body) + sizeof(cmd->cr)); + cmd->body.sid = cpu_to_le32(surf->res.id); + cmd->cr.x = cpu_to_le32(0); + cmd->cr.y = cpu_to_le32(0); + cmd->cr.srcx = cmd->cr.x; + cmd->cr.srcy = cmd->cr.y; + cmd->cr.w = cpu_to_le32(framebuffer->width); + cmd->cr.h = cpu_to_le32(framebuffer->height); + vfbs->present_fs = false; + vmw_fifo_commit(dev_priv, sizeof(*cmd)); +out_resched: + /** + * Will not re-add if already pending. + */ + schedule_delayed_work(&vfbs->d_work, VMWGFX_PRESENT_RATE); +out_unlock: + mutex_unlock(&vfbs->work_lock); +} + + +int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer, + unsigned flags, unsigned color, + struct drm_clip_rect *clips, + unsigned num_clips) +{ + struct vmw_private *dev_priv = vmw_priv(framebuffer->dev); + struct vmw_framebuffer_surface *vfbs = + vmw_framebuffer_to_vfbs(framebuffer); + struct vmw_surface *surf = vfbs->surface; + struct drm_clip_rect norect; + SVGA3dCopyRect *cr; + int i, inc = 1; + + struct { + SVGA3dCmdHeader header; + SVGA3dCmdPresent body; + SVGA3dCopyRect cr; + } *cmd; + + if (!num_clips || + !(dev_priv->fifo.capabilities & + SVGA_FIFO_CAP_SCREEN_OBJECT)) { + int ret; + + mutex_lock(&vfbs->work_lock); + vfbs->present_fs = true; + ret = schedule_delayed_work(&vfbs->d_work, VMWGFX_PRESENT_RATE); + mutex_unlock(&vfbs->work_lock); + if (ret) { + /** + * No work pending, Force immediate present. + */ + vmw_framebuffer_present_fs_callback(&vfbs->d_work.work); + } + return 0; + } + + if (!num_clips) { + num_clips = 1; + clips = &norect; + norect.x1 = norect.y1 = 0; + norect.x2 = framebuffer->width; + norect.y2 = framebuffer->height; + } else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) { + num_clips /= 2; + inc = 2; /* skip source rects */ + } + + cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd) + (num_clips - 1) * sizeof(cmd->cr)); + if (unlikely(cmd == NULL)) { + DRM_ERROR("Fifo reserve failed.\n"); + return -ENOMEM; + } + + memset(cmd, 0, sizeof(*cmd)); + + cmd->header.id = cpu_to_le32(SVGA_3D_CMD_PRESENT); + cmd->header.size = cpu_to_le32(sizeof(cmd->body) + num_clips * sizeof(cmd->cr)); + cmd->body.sid = cpu_to_le32(surf->res.id); + + for (i = 0, cr = &cmd->cr; i < num_clips; i++, cr++, clips += inc) { + cr->x = cpu_to_le16(clips->x1); + cr->y = cpu_to_le16(clips->y1); + cr->srcx = cr->x; + cr->srcy = cr->y; + cr->w = cpu_to_le16(clips->x2 - clips->x1); + cr->h = cpu_to_le16(clips->y2 - clips->y1); + } + + vmw_fifo_commit(dev_priv, sizeof(*cmd) + (num_clips - 1) * sizeof(cmd->cr)); + + return 0; +} + +static struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = { + .destroy = vmw_framebuffer_surface_destroy, + .dirty = vmw_framebuffer_surface_dirty, + .create_handle = vmw_framebuffer_create_handle, +}; + +int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, + struct vmw_surface *surface, + struct vmw_framebuffer **out, + unsigned width, unsigned height) + +{ + struct drm_device *dev = dev_priv->dev; + struct vmw_framebuffer_surface *vfbs; + int ret; + + vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL); + if (!vfbs) { + ret = -ENOMEM; + goto out_err1; + } + + ret = drm_framebuffer_init(dev, &vfbs->base.base, + &vmw_framebuffer_surface_funcs); + if (ret) + goto out_err2; + + if (!vmw_surface_reference(surface)) { + DRM_ERROR("failed to reference surface %p\n", surface); + goto out_err3; + } + + /* XXX get the first 3 from the surface info */ + vfbs->base.base.bits_per_pixel = 32; + vfbs->base.base.pitch = width * 32 / 4; + vfbs->base.base.depth = 24; + vfbs->base.base.width = width; + vfbs->base.base.height = height; + vfbs->base.pin = NULL; + vfbs->base.unpin = NULL; + vfbs->surface = surface; + mutex_init(&vfbs->work_lock); + INIT_DELAYED_WORK(&vfbs->d_work, &vmw_framebuffer_present_fs_callback); + *out = &vfbs->base; + + return 0; + +out_err3: + drm_framebuffer_cleanup(&vfbs->base.base); +out_err2: + kfree(vfbs); +out_err1: + return ret; +} + +/* + * Dmabuf framebuffer code + */ + +#define vmw_framebuffer_to_vfbd(x) \ + container_of(x, struct vmw_framebuffer_dmabuf, base.base) + +struct vmw_framebuffer_dmabuf { + struct vmw_framebuffer base; + struct vmw_dma_buffer *buffer; +}; + +void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer) +{ + struct vmw_framebuffer_dmabuf *vfbd = + vmw_framebuffer_to_vfbd(framebuffer); + + drm_framebuffer_cleanup(framebuffer); + vmw_dmabuf_unreference(&vfbd->buffer); + + kfree(vfbd); +} + +int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer, + unsigned flags, unsigned color, + struct drm_clip_rect *clips, + unsigned num_clips) +{ + struct vmw_private *dev_priv = vmw_priv(framebuffer->dev); + struct drm_clip_rect norect; + struct { + uint32_t header; + SVGAFifoCmdUpdate body; + } *cmd; + int i, increment = 1; + + if (!num_clips || + !(dev_priv->fifo.capabilities & + SVGA_FIFO_CAP_SCREEN_OBJECT)) { + num_clips = 1; + clips = &norect; + norect.x1 = norect.y1 = 0; + norect.x2 = framebuffer->width; + norect.y2 = framebuffer->height; + } else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) { + num_clips /= 2; + increment = 2; + } + + cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd) * num_clips); + if (unlikely(cmd == NULL)) { + DRM_ERROR("Fifo reserve failed.\n"); + return -ENOMEM; + } + + for (i = 0; i < num_clips; i++, clips += increment) { + cmd[i].header = cpu_to_le32(SVGA_CMD_UPDATE); + cmd[i].body.x = cpu_to_le32(clips[i].x1); + cmd[i].body.y = cpu_to_le32(clips[i].y1); + cmd[i].body.width = cpu_to_le32(clips[i].x2 - clips[i].x1); + cmd[i].body.height = cpu_to_le32(clips[i].y2 - clips[i].y1); + } + + vmw_fifo_commit(dev_priv, sizeof(*cmd) * num_clips); + + return 0; +} + +static struct drm_framebuffer_funcs vmw_framebuffer_dmabuf_funcs = { + .destroy = vmw_framebuffer_dmabuf_destroy, + .dirty = vmw_framebuffer_dmabuf_dirty, + .create_handle = vmw_framebuffer_create_handle, +}; + +static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb) +{ + struct vmw_private *dev_priv = vmw_priv(vfb->base.dev); + struct vmw_framebuffer_dmabuf *vfbd = + vmw_framebuffer_to_vfbd(&vfb->base); + int ret; + + vmw_overlay_pause_all(dev_priv); + + ret = vmw_dmabuf_to_start_of_vram(dev_priv, vfbd->buffer); + + if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { + vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); + vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, 0); + vmw_write(dev_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); + vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_X, 0); + vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_Y, 0); + vmw_write(dev_priv, SVGA_REG_DISPLAY_WIDTH, 0); + vmw_write(dev_priv, SVGA_REG_DISPLAY_HEIGHT, 0); + vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); + + vmw_write(dev_priv, SVGA_REG_ENABLE, 1); + vmw_write(dev_priv, SVGA_REG_WIDTH, vfb->base.width); + vmw_write(dev_priv, SVGA_REG_HEIGHT, vfb->base.height); + vmw_write(dev_priv, SVGA_REG_BITS_PER_PIXEL, vfb->base.bits_per_pixel); + vmw_write(dev_priv, SVGA_REG_DEPTH, vfb->base.depth); + vmw_write(dev_priv, SVGA_REG_RED_MASK, 0x00ff0000); + vmw_write(dev_priv, SVGA_REG_GREEN_MASK, 0x0000ff00); + vmw_write(dev_priv, SVGA_REG_BLUE_MASK, 0x000000ff); + } else + WARN_ON(true); + + vmw_overlay_resume_all(dev_priv); + + return 0; +} + +static int vmw_framebuffer_dmabuf_unpin(struct vmw_framebuffer *vfb) +{ + struct vmw_private *dev_priv = vmw_priv(vfb->base.dev); + struct vmw_framebuffer_dmabuf *vfbd = + vmw_framebuffer_to_vfbd(&vfb->base); + + if (!vfbd->buffer) { + WARN_ON(!vfbd->buffer); + return 0; + } + + return vmw_dmabuf_from_vram(dev_priv, vfbd->buffer); +} + +int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv, + struct vmw_dma_buffer *dmabuf, + struct vmw_framebuffer **out, + unsigned width, unsigned height) + +{ + struct drm_device *dev = dev_priv->dev; + struct vmw_framebuffer_dmabuf *vfbd; + int ret; + + vfbd = kzalloc(sizeof(*vfbd), GFP_KERNEL); + if (!vfbd) { + ret = -ENOMEM; + goto out_err1; + } + + ret = drm_framebuffer_init(dev, &vfbd->base.base, + &vmw_framebuffer_dmabuf_funcs); + if (ret) + goto out_err2; + + if (!vmw_dmabuf_reference(dmabuf)) { + DRM_ERROR("failed to reference dmabuf %p\n", dmabuf); + goto out_err3; + } + + /* XXX get the first 3 from the surface info */ + vfbd->base.base.bits_per_pixel = 32; + vfbd->base.base.pitch = width * 32 / 4; + vfbd->base.base.depth = 24; + vfbd->base.base.width = width; + vfbd->base.base.height = height; + vfbd->base.pin = vmw_framebuffer_dmabuf_pin; + vfbd->base.unpin = vmw_framebuffer_dmabuf_unpin; + vfbd->buffer = dmabuf; + *out = &vfbd->base; + + return 0; + +out_err3: + drm_framebuffer_cleanup(&vfbd->base.base); +out_err2: + kfree(vfbd); +out_err1: + return ret; +} + +/* + * Generic Kernel modesetting functions + */ + +static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, + struct drm_file *file_priv, + struct drm_mode_fb_cmd *mode_cmd) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; + struct vmw_framebuffer *vfb = NULL; + struct vmw_surface *surface = NULL; + struct vmw_dma_buffer *bo = NULL; + int ret; + + ret = vmw_user_surface_lookup(dev_priv, tfile, + mode_cmd->handle, &surface); + if (ret) + goto try_dmabuf; + + ret = vmw_kms_new_framebuffer_surface(dev_priv, surface, &vfb, + mode_cmd->width, mode_cmd->height); + + /* vmw_user_surface_lookup takes one ref so does new_fb */ + vmw_surface_unreference(&surface); + + if (ret) { + DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret); + return NULL; + } + return &vfb->base; + +try_dmabuf: + DRM_INFO("%s: trying buffer\n", __func__); + + ret = vmw_user_dmabuf_lookup(tfile, mode_cmd->handle, &bo); + if (ret) { + DRM_ERROR("failed to find buffer: %i\n", ret); + return NULL; + } + + ret = vmw_kms_new_framebuffer_dmabuf(dev_priv, bo, &vfb, + mode_cmd->width, mode_cmd->height); + + /* vmw_user_dmabuf_lookup takes one ref so does new_fb */ + vmw_dmabuf_unreference(&bo); + + if (ret) { + DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret); + return NULL; + } + + return &vfb->base; +} + +static int vmw_kms_fb_changed(struct drm_device *dev) +{ + return 0; +} + +static struct drm_mode_config_funcs vmw_kms_funcs = { + .fb_create = vmw_kms_fb_create, + .fb_changed = vmw_kms_fb_changed, +}; + +int vmw_kms_init(struct vmw_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + int ret; + + drm_mode_config_init(dev); + dev->mode_config.funcs = &vmw_kms_funcs; + dev->mode_config.min_width = 640; + dev->mode_config.min_height = 480; + dev->mode_config.max_width = 2048; + dev->mode_config.max_height = 2048; + + ret = vmw_kms_init_legacy_display_system(dev_priv); + + return 0; +} + +int vmw_kms_close(struct vmw_private *dev_priv) +{ + /* + * Docs says we should take the lock before calling this function + * but since it destroys encoders and our destructor calls + * drm_encoder_cleanup which takes the lock we deadlock. + */ + drm_mode_config_cleanup(dev_priv->dev); + vmw_kms_close_legacy_display_system(dev_priv); + return 0; +} + +int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_vmw_cursor_bypass_arg *arg = data; + struct vmw_display_unit *du; + struct drm_mode_object *obj; + struct drm_crtc *crtc; + int ret = 0; + + + mutex_lock(&dev->mode_config.mutex); + if (arg->flags & DRM_VMW_CURSOR_BYPASS_ALL) { + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + du = vmw_crtc_to_du(crtc); + du->hotspot_x = arg->xhot; + du->hotspot_y = arg->yhot; + } + + mutex_unlock(&dev->mode_config.mutex); + return 0; + } + + obj = drm_mode_object_find(dev, arg->crtc_id, DRM_MODE_OBJECT_CRTC); + if (!obj) { + ret = -EINVAL; + goto out; + } + + crtc = obj_to_crtc(obj); + du = vmw_crtc_to_du(crtc); + + du->hotspot_x = arg->xhot; + du->hotspot_y = arg->yhot; + +out: + mutex_unlock(&dev->mode_config.mutex); + + return ret; +} + +int vmw_kms_save_vga(struct vmw_private *vmw_priv) +{ + /* + * setup a single multimon monitor with the size + * of 0x0, this stops the UI from resizing when we + * change the framebuffer size + */ + if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) { + vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, 0); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, 0); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, 0); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); + } + + vmw_priv->vga_width = vmw_read(vmw_priv, SVGA_REG_WIDTH); + vmw_priv->vga_height = vmw_read(vmw_priv, SVGA_REG_HEIGHT); + vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL); + vmw_priv->vga_depth = vmw_read(vmw_priv, SVGA_REG_DEPTH); + vmw_priv->vga_pseudo = vmw_read(vmw_priv, SVGA_REG_PSEUDOCOLOR); + vmw_priv->vga_red_mask = vmw_read(vmw_priv, SVGA_REG_RED_MASK); + vmw_priv->vga_green_mask = vmw_read(vmw_priv, SVGA_REG_GREEN_MASK); + vmw_priv->vga_blue_mask = vmw_read(vmw_priv, SVGA_REG_BLUE_MASK); + + return 0; +} + +int vmw_kms_restore_vga(struct vmw_private *vmw_priv) +{ + vmw_write(vmw_priv, SVGA_REG_WIDTH, vmw_priv->vga_width); + vmw_write(vmw_priv, SVGA_REG_HEIGHT, vmw_priv->vga_height); + vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp); + vmw_write(vmw_priv, SVGA_REG_DEPTH, vmw_priv->vga_depth); + vmw_write(vmw_priv, SVGA_REG_PSEUDOCOLOR, vmw_priv->vga_pseudo); + vmw_write(vmw_priv, SVGA_REG_RED_MASK, vmw_priv->vga_red_mask); + vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, vmw_priv->vga_green_mask); + vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, vmw_priv->vga_blue_mask); + + /* TODO check for multimon */ + vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 0); + + return 0; +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h new file mode 100644 index 0000000..8b95249 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef VMWGFX_KMS_H_ +#define VMWGFX_KMS_H_ + +#include "drmP.h" +#include "vmwgfx_drv.h" + + +#define vmw_framebuffer_to_vfb(x) \ + container_of(x, struct vmw_framebuffer, base) + +/** + * Base class for framebuffers + * + * @pin is called the when ever a crtc uses this framebuffer + * @unpin is called + */ +struct vmw_framebuffer { + struct drm_framebuffer base; + int (*pin)(struct vmw_framebuffer *fb); + int (*unpin)(struct vmw_framebuffer *fb); +}; + + +#define vmw_crtc_to_du(x) \ + container_of(x, struct vmw_display_unit, crtc) + +/* + * Basic cursor manipulation + */ +int vmw_cursor_update_image(struct vmw_private *dev_priv, + u32 *image, u32 width, u32 height, + u32 hotspotX, u32 hotspotY); +void vmw_cursor_update_position(struct vmw_private *dev_priv, + bool show, int x, int y); + +/** + * Base class display unit. + * + * Since the SVGA hw doesn't have a concept of a crtc, encoder or connector + * so the display unit is all of them at the same time. This is true for both + * legacy multimon and screen objects. + */ +struct vmw_display_unit { + struct drm_crtc crtc; + struct drm_encoder encoder; + struct drm_connector connector; + + struct vmw_surface *cursor_surface; + struct vmw_dma_buffer *cursor_dmabuf; + size_t cursor_age; + + int cursor_x; + int cursor_y; + + int hotspot_x; + int hotspot_y; + + unsigned unit; +}; + +/* + * Shared display unit functions - vmwgfx_kms.c + */ +void vmw_display_unit_cleanup(struct vmw_display_unit *du); +int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, + uint32_t handle, uint32_t width, uint32_t height); +int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); + +/* + * Legacy display unit functions - vmwgfx_ldu.h + */ +int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv); +int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv); + +#endif diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c new file mode 100644 index 0000000..9089159 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -0,0 +1,516 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "vmwgfx_kms.h" + +#define vmw_crtc_to_ldu(x) \ + container_of(x, struct vmw_legacy_display_unit, base.crtc) +#define vmw_encoder_to_ldu(x) \ + container_of(x, struct vmw_legacy_display_unit, base.encoder) +#define vmw_connector_to_ldu(x) \ + container_of(x, struct vmw_legacy_display_unit, base.connector) + +struct vmw_legacy_display { + struct list_head active; + + unsigned num_active; + + struct vmw_framebuffer *fb; +}; + +/** + * Display unit using the legacy register interface. + */ +struct vmw_legacy_display_unit { + struct vmw_display_unit base; + + struct list_head active; + + unsigned unit; +}; + +static void vmw_ldu_destroy(struct vmw_legacy_display_unit *ldu) +{ + list_del_init(&ldu->active); + vmw_display_unit_cleanup(&ldu->base); + kfree(ldu); +} + + +/* + * Legacy Display Unit CRTC functions + */ + +static void vmw_ldu_crtc_save(struct drm_crtc *crtc) +{ +} + +static void vmw_ldu_crtc_restore(struct drm_crtc *crtc) +{ +} + +static void vmw_ldu_crtc_gamma_set(struct drm_crtc *crtc, + u16 *r, u16 *g, u16 *b, + uint32_t size) +{ +} + +static void vmw_ldu_crtc_destroy(struct drm_crtc *crtc) +{ + vmw_ldu_destroy(vmw_crtc_to_ldu(crtc)); +} + +static int vmw_ldu_commit_list(struct vmw_private *dev_priv) +{ + struct vmw_legacy_display *lds = dev_priv->ldu_priv; + struct vmw_legacy_display_unit *entry; + struct drm_crtc *crtc; + int i = 0; + + /* to stop the screen from changing size on resize */ + vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 0); + for (i = 0; i < lds->num_active; i++) { + vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, i); + vmw_write(dev_priv, SVGA_REG_DISPLAY_IS_PRIMARY, !i); + vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_X, 0); + vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_Y, 0); + vmw_write(dev_priv, SVGA_REG_DISPLAY_WIDTH, 0); + vmw_write(dev_priv, SVGA_REG_DISPLAY_HEIGHT, 0); + vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); + } + + /* Now set the mode */ + vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, lds->num_active); + i = 0; + list_for_each_entry(entry, &lds->active, active) { + crtc = &entry->base.crtc; + + vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, i); + vmw_write(dev_priv, SVGA_REG_DISPLAY_IS_PRIMARY, !i); + vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_X, crtc->x); + vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_Y, crtc->y); + vmw_write(dev_priv, SVGA_REG_DISPLAY_WIDTH, crtc->mode.hdisplay); + vmw_write(dev_priv, SVGA_REG_DISPLAY_HEIGHT, crtc->mode.vdisplay); + vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); + + i++; + } + + return 0; +} + +static int vmw_ldu_del_active(struct vmw_private *vmw_priv, + struct vmw_legacy_display_unit *ldu) +{ + struct vmw_legacy_display *ld = vmw_priv->ldu_priv; + if (list_empty(&ldu->active)) + return 0; + + list_del_init(&ldu->active); + if (--(ld->num_active) == 0) { + BUG_ON(!ld->fb); + if (ld->fb->unpin) + ld->fb->unpin(ld->fb); + ld->fb = NULL; + } + + return 0; +} + +static int vmw_ldu_add_active(struct vmw_private *vmw_priv, + struct vmw_legacy_display_unit *ldu, + struct vmw_framebuffer *vfb) +{ + struct vmw_legacy_display *ld = vmw_priv->ldu_priv; + struct vmw_legacy_display_unit *entry; + struct list_head *at; + + if (!list_empty(&ldu->active)) + return 0; + + at = &ld->active; + list_for_each_entry(entry, &ld->active, active) { + if (entry->unit > ldu->unit) + break; + + at = &entry->active; + } + + list_add(&ldu->active, at); + if (ld->num_active++ == 0) { + BUG_ON(ld->fb); + if (vfb->pin) + vfb->pin(vfb); + ld->fb = vfb; + } + + return 0; +} + +static int vmw_ldu_crtc_set_config(struct drm_mode_set *set) +{ + struct vmw_private *dev_priv; + struct vmw_legacy_display_unit *ldu; + struct drm_connector *connector; + struct drm_display_mode *mode; + struct drm_encoder *encoder; + struct vmw_framebuffer *vfb; + struct drm_framebuffer *fb; + struct drm_crtc *crtc; + + if (!set) + return -EINVAL; + + if (!set->crtc) + return -EINVAL; + + /* get the ldu */ + crtc = set->crtc; + ldu = vmw_crtc_to_ldu(crtc); + vfb = set->fb ? vmw_framebuffer_to_vfb(set->fb) : NULL; + dev_priv = vmw_priv(crtc->dev); + + if (set->num_connectors > 1) { + DRM_ERROR("to many connectors\n"); + return -EINVAL; + } + + if (set->num_connectors == 1 && + set->connectors[0] != &ldu->base.connector) { + DRM_ERROR("connector doesn't match %p %p\n", + set->connectors[0], &ldu->base.connector); + return -EINVAL; + } + + /* ldu only supports one fb active at the time */ + if (dev_priv->ldu_priv->fb && vfb && + dev_priv->ldu_priv->fb != vfb) { + DRM_ERROR("Multiple framebuffers not supported\n"); + return -EINVAL; + } + + /* since they always map one to one these are safe */ + connector = &ldu->base.connector; + encoder = &ldu->base.encoder; + + /* should we turn the crtc off? */ + if (set->num_connectors == 0 || !set->mode || !set->fb) { + + connector->encoder = NULL; + encoder->crtc = NULL; + crtc->fb = NULL; + + vmw_ldu_del_active(dev_priv, ldu); + + vmw_ldu_commit_list(dev_priv); + + return 0; + } + + + /* we now know we want to set a mode */ + mode = set->mode; + fb = set->fb; + + if (set->x + mode->hdisplay > fb->width || + set->y + mode->vdisplay > fb->height) { + DRM_ERROR("set outside of framebuffer\n"); + return -EINVAL; + } + + vmw_fb_off(dev_priv); + + crtc->fb = fb; + encoder->crtc = crtc; + connector->encoder = encoder; + crtc->x = set->x; + crtc->y = set->y; + crtc->mode = *mode; + + vmw_ldu_add_active(dev_priv, ldu, vfb); + + vmw_ldu_commit_list(dev_priv); + + return 0; +} + +static struct drm_crtc_funcs vmw_legacy_crtc_funcs = { + .save = vmw_ldu_crtc_save, + .restore = vmw_ldu_crtc_restore, + .cursor_set = vmw_du_crtc_cursor_set, + .cursor_move = vmw_du_crtc_cursor_move, + .gamma_set = vmw_ldu_crtc_gamma_set, + .destroy = vmw_ldu_crtc_destroy, + .set_config = vmw_ldu_crtc_set_config, +}; + +/* + * Legacy Display Unit encoder functions + */ + +static void vmw_ldu_encoder_destroy(struct drm_encoder *encoder) +{ + vmw_ldu_destroy(vmw_encoder_to_ldu(encoder)); +} + +static struct drm_encoder_funcs vmw_legacy_encoder_funcs = { + .destroy = vmw_ldu_encoder_destroy, +}; + +/* + * Legacy Display Unit connector functions + */ + +static void vmw_ldu_connector_dpms(struct drm_connector *connector, int mode) +{ +} + +static void vmw_ldu_connector_save(struct drm_connector *connector) +{ +} + +static void vmw_ldu_connector_restore(struct drm_connector *connector) +{ +} + +static enum drm_connector_status + vmw_ldu_connector_detect(struct drm_connector *connector) +{ + /* XXX vmwctrl should control connection status */ + if (vmw_connector_to_ldu(connector)->base.unit == 0) + return connector_status_connected; + return connector_status_disconnected; +} + +static struct drm_display_mode vmw_ldu_connector_builtin[] = { + /* 640x480@60Hz */ + { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, + 752, 800, 0, 480, 489, 492, 525, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, + /* 800x600@60Hz */ + { DRM_MODE("800x600", + DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, + 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, + 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 1024x768@60Hz */ + { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048, + 1184, 1344, 0, 768, 771, 777, 806, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, + /* 1152x864@75Hz */ + { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216, + 1344, 1600, 0, 864, 865, 868, 900, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 1280x768@60Hz */ + { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344, + 1472, 1664, 0, 768, 771, 778, 798, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 1280x800@60Hz */ + { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352, + 1480, 1680, 0, 800, 803, 809, 831, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, + /* 1280x960@60Hz */ + { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376, + 1488, 1800, 0, 960, 961, 964, 1000, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 1280x1024@60Hz */ + { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328, + 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 1360x768@60Hz */ + { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424, + 1536, 1792, 0, 768, 771, 777, 795, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 1440x1050@60Hz */ + { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488, + 1632, 1864, 0, 1050, 1053, 1057, 1089, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 1440x900@60Hz */ + { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520, + 1672, 1904, 0, 900, 903, 909, 934, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 1600x1200@60Hz */ + { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664, + 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 1680x1050@60Hz */ + { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784, + 1960, 2240, 0, 1050, 1053, 1059, 1089, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 1792x1344@60Hz */ + { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920, + 2120, 2448, 0, 1344, 1345, 1348, 1394, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 1853x1392@60Hz */ + { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952, + 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 1920x1200@60Hz */ + { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056, + 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 1920x1440@60Hz */ + { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048, + 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 2560x1600@60Hz */ + { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752, + 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* Terminate */ + { DRM_MODE("", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) }, +}; + +static int vmw_ldu_connector_fill_modes(struct drm_connector *connector, + uint32_t max_width, uint32_t max_height) +{ + struct drm_device *dev = connector->dev; + struct drm_display_mode *mode = NULL; + int i; + + for (i = 0; vmw_ldu_connector_builtin[i].type != 0; i++) { + if (vmw_ldu_connector_builtin[i].hdisplay > max_width || + vmw_ldu_connector_builtin[i].vdisplay > max_height) + continue; + + mode = drm_mode_duplicate(dev, &vmw_ldu_connector_builtin[i]); + if (!mode) + return 0; + mode->vrefresh = drm_mode_vrefresh(mode); + + drm_mode_probed_add(connector, mode); + } + + drm_mode_connector_list_update(connector); + + return 1; +} + +static int vmw_ldu_connector_set_property(struct drm_connector *connector, + struct drm_property *property, + uint64_t val) +{ + return 0; +} + +static void vmw_ldu_connector_destroy(struct drm_connector *connector) +{ + vmw_ldu_destroy(vmw_connector_to_ldu(connector)); +} + +static struct drm_connector_funcs vmw_legacy_connector_funcs = { + .dpms = vmw_ldu_connector_dpms, + .save = vmw_ldu_connector_save, + .restore = vmw_ldu_connector_restore, + .detect = vmw_ldu_connector_detect, + .fill_modes = vmw_ldu_connector_fill_modes, + .set_property = vmw_ldu_connector_set_property, + .destroy = vmw_ldu_connector_destroy, +}; + +static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) +{ + struct vmw_legacy_display_unit *ldu; + struct drm_device *dev = dev_priv->dev; + struct drm_connector *connector; + struct drm_encoder *encoder; + struct drm_crtc *crtc; + + ldu = kzalloc(sizeof(*ldu), GFP_KERNEL); + if (!ldu) + return -ENOMEM; + + ldu->unit = unit; + crtc = &ldu->base.crtc; + encoder = &ldu->base.encoder; + connector = &ldu->base.connector; + + drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, + DRM_MODE_CONNECTOR_LVDS); + /* Initial status */ + if (unit == 0) + connector->status = connector_status_connected; + else + connector->status = connector_status_disconnected; + + drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, + DRM_MODE_ENCODER_LVDS); + drm_mode_connector_attach_encoder(connector, encoder); + encoder->possible_crtcs = (1 << unit); + encoder->possible_clones = 0; + + INIT_LIST_HEAD(&ldu->active); + + drm_crtc_init(dev, crtc, &vmw_legacy_crtc_funcs); + + drm_connector_attach_property(connector, + dev->mode_config.dirty_info_property, + 1); + + return 0; +} + +int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) +{ + if (dev_priv->ldu_priv) { + DRM_INFO("ldu system already on\n"); + return -EINVAL; + } + + dev_priv->ldu_priv = kmalloc(GFP_KERNEL, sizeof(*dev_priv->ldu_priv)); + + if (!dev_priv->ldu_priv) + return -ENOMEM; + + INIT_LIST_HEAD(&dev_priv->ldu_priv->active); + dev_priv->ldu_priv->num_active = 0; + dev_priv->ldu_priv->fb = NULL; + + drm_mode_create_dirty_info_property(dev_priv->dev); + + vmw_ldu_init(dev_priv, 0); + vmw_ldu_init(dev_priv, 1); + vmw_ldu_init(dev_priv, 2); + vmw_ldu_init(dev_priv, 3); + vmw_ldu_init(dev_priv, 4); + vmw_ldu_init(dev_priv, 5); + vmw_ldu_init(dev_priv, 6); + vmw_ldu_init(dev_priv, 7); + + return 0; +} + +int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) +{ + if (!dev_priv->ldu_priv) + return -ENOSYS; + + BUG_ON(!list_empty(&dev_priv->ldu_priv->active)); + + kfree(dev_priv->ldu_priv); + + return 0; +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c new file mode 100644 index 0000000..bb6e6a0 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c @@ -0,0 +1,634 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "drmP.h" +#include "vmwgfx_drv.h" + +#include "ttm/ttm_placement.h" + +#include "svga_overlay.h" +#include "svga_escape.h" + +#define VMW_MAX_NUM_STREAMS 1 + +struct vmw_stream { + struct vmw_dma_buffer *buf; + bool claimed; + bool paused; + struct drm_vmw_control_stream_arg saved; +}; + +/** + * Overlay control + */ +struct vmw_overlay { + /* + * Each stream is a single overlay. In Xv these are called ports. + */ + struct mutex mutex; + struct vmw_stream stream[VMW_MAX_NUM_STREAMS]; +}; + +static inline struct vmw_overlay *vmw_overlay(struct drm_device *dev) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + return dev_priv ? dev_priv->overlay_priv : NULL; +} + +struct vmw_escape_header { + uint32_t cmd; + SVGAFifoCmdEscape body; +}; + +struct vmw_escape_video_flush { + struct vmw_escape_header escape; + SVGAEscapeVideoFlush flush; +}; + +static inline void fill_escape(struct vmw_escape_header *header, + uint32_t size) +{ + header->cmd = SVGA_CMD_ESCAPE; + header->body.nsid = SVGA_ESCAPE_NSID_VMWARE; + header->body.size = size; +} + +static inline void fill_flush(struct vmw_escape_video_flush *cmd, + uint32_t stream_id) +{ + fill_escape(&cmd->escape, sizeof(cmd->flush)); + cmd->flush.cmdType = SVGA_ESCAPE_VMWARE_VIDEO_FLUSH; + cmd->flush.streamId = stream_id; +} + +/** + * Pin or unpin a buffer in vram. + * + * @dev_priv: Driver private. + * @buf: DMA buffer to pin or unpin. + * @pin: Pin buffer in vram if true. + * @interruptible: Use interruptible wait. + * + * Takes the current masters ttm lock in read. + * + * Returns + * -ERESTARTSYS if interrupted by a signal. + */ +static int vmw_dmabuf_pin_in_vram(struct vmw_private *dev_priv, + struct vmw_dma_buffer *buf, + bool pin, bool interruptible) +{ + struct ttm_buffer_object *bo = &buf->base; + struct ttm_bo_global *glob = bo->glob; + struct ttm_placement *overlay_placement = &vmw_vram_placement; + int ret; + + ret = ttm_read_lock(&dev_priv->active_master->lock, interruptible); + if (unlikely(ret != 0)) + return ret; + + ret = ttm_bo_reserve(bo, interruptible, false, false, 0); + if (unlikely(ret != 0)) + goto err; + + if (buf->gmr_bound) { + vmw_gmr_unbind(dev_priv, buf->gmr_id); + spin_lock(&glob->lru_lock); + ida_remove(&dev_priv->gmr_ida, buf->gmr_id); + spin_unlock(&glob->lru_lock); + buf->gmr_bound = NULL; + } + + if (pin) + overlay_placement = &vmw_vram_ne_placement; + + ret = ttm_bo_validate(bo, overlay_placement, interruptible, false); + + ttm_bo_unreserve(bo); + +err: + ttm_read_unlock(&dev_priv->active_master->lock); + + return ret; +} + +/** + * Send put command to hw. + * + * Returns + * -ERESTARTSYS if interrupted by a signal. + */ +static int vmw_overlay_send_put(struct vmw_private *dev_priv, + struct vmw_dma_buffer *buf, + struct drm_vmw_control_stream_arg *arg, + bool interruptible) +{ + struct { + struct vmw_escape_header escape; + struct { + struct { + uint32_t cmdType; + uint32_t streamId; + } header; + struct { + uint32_t registerId; + uint32_t value; + } items[SVGA_VIDEO_PITCH_3 + 1]; + } body; + struct vmw_escape_video_flush flush; + } *cmds; + uint32_t offset; + int i, ret; + + for (;;) { + cmds = vmw_fifo_reserve(dev_priv, sizeof(*cmds)); + if (cmds) + break; + + ret = vmw_fallback_wait(dev_priv, false, true, 0, + interruptible, 3*HZ); + if (interruptible && ret == -ERESTARTSYS) + return ret; + else + BUG_ON(ret != 0); + } + + fill_escape(&cmds->escape, sizeof(cmds->body)); + cmds->body.header.cmdType = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS; + cmds->body.header.streamId = arg->stream_id; + + for (i = 0; i <= SVGA_VIDEO_PITCH_3; i++) + cmds->body.items[i].registerId = i; + + offset = buf->base.offset + arg->offset; + + cmds->body.items[SVGA_VIDEO_ENABLED].value = true; + cmds->body.items[SVGA_VIDEO_FLAGS].value = arg->flags; + cmds->body.items[SVGA_VIDEO_DATA_OFFSET].value = offset; + cmds->body.items[SVGA_VIDEO_FORMAT].value = arg->format; + cmds->body.items[SVGA_VIDEO_COLORKEY].value = arg->color_key; + cmds->body.items[SVGA_VIDEO_SIZE].value = arg->size; + cmds->body.items[SVGA_VIDEO_WIDTH].value = arg->width; + cmds->body.items[SVGA_VIDEO_HEIGHT].value = arg->height; + cmds->body.items[SVGA_VIDEO_SRC_X].value = arg->src.x; + cmds->body.items[SVGA_VIDEO_SRC_Y].value = arg->src.y; + cmds->body.items[SVGA_VIDEO_SRC_WIDTH].value = arg->src.w; + cmds->body.items[SVGA_VIDEO_SRC_HEIGHT].value = arg->src.h; + cmds->body.items[SVGA_VIDEO_DST_X].value = arg->dst.x; + cmds->body.items[SVGA_VIDEO_DST_Y].value = arg->dst.y; + cmds->body.items[SVGA_VIDEO_DST_WIDTH].value = arg->dst.w; + cmds->body.items[SVGA_VIDEO_DST_HEIGHT].value = arg->dst.h; + cmds->body.items[SVGA_VIDEO_PITCH_1].value = arg->pitch[0]; + cmds->body.items[SVGA_VIDEO_PITCH_2].value = arg->pitch[1]; + cmds->body.items[SVGA_VIDEO_PITCH_3].value = arg->pitch[2]; + + fill_flush(&cmds->flush, arg->stream_id); + + vmw_fifo_commit(dev_priv, sizeof(*cmds)); + + return 0; +} + +/** + * Send stop command to hw. + * + * Returns + * -ERESTARTSYS if interrupted by a signal. + */ +static int vmw_overlay_send_stop(struct vmw_private *dev_priv, + uint32_t stream_id, + bool interruptible) +{ + struct { + struct vmw_escape_header escape; + SVGAEscapeVideoSetRegs body; + struct vmw_escape_video_flush flush; + } *cmds; + int ret; + + for (;;) { + cmds = vmw_fifo_reserve(dev_priv, sizeof(*cmds)); + if (cmds) + break; + + ret = vmw_fallback_wait(dev_priv, false, true, 0, + interruptible, 3*HZ); + if (interruptible && ret == -ERESTARTSYS) + return ret; + else + BUG_ON(ret != 0); + } + + fill_escape(&cmds->escape, sizeof(cmds->body)); + cmds->body.header.cmdType = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS; + cmds->body.header.streamId = stream_id; + cmds->body.items[0].registerId = SVGA_VIDEO_ENABLED; + cmds->body.items[0].value = false; + fill_flush(&cmds->flush, stream_id); + + vmw_fifo_commit(dev_priv, sizeof(*cmds)); + + return 0; +} + +/** + * Stop or pause a stream. + * + * If the stream is paused the no evict flag is removed from the buffer + * but left in vram. This allows for instance mode_set to evict it + * should it need to. + * + * The caller must hold the overlay lock. + * + * @stream_id which stream to stop/pause. + * @pause true to pause, false to stop completely. + */ +static int vmw_overlay_stop(struct vmw_private *dev_priv, + uint32_t stream_id, bool pause, + bool interruptible) +{ + struct vmw_overlay *overlay = dev_priv->overlay_priv; + struct vmw_stream *stream = &overlay->stream[stream_id]; + int ret; + + /* no buffer attached the stream is completely stopped */ + if (!stream->buf) + return 0; + + /* If the stream is paused this is already done */ + if (!stream->paused) { + ret = vmw_overlay_send_stop(dev_priv, stream_id, + interruptible); + if (ret) + return ret; + + /* We just remove the NO_EVICT flag so no -ENOMEM */ + ret = vmw_dmabuf_pin_in_vram(dev_priv, stream->buf, false, + interruptible); + if (interruptible && ret == -ERESTARTSYS) + return ret; + else + BUG_ON(ret != 0); + } + + if (!pause) { + vmw_dmabuf_unreference(&stream->buf); + stream->paused = false; + } else { + stream->paused = true; + } + + return 0; +} + +/** + * Update a stream and send any put or stop fifo commands needed. + * + * The caller must hold the overlay lock. + * + * Returns + * -ENOMEM if buffer doesn't fit in vram. + * -ERESTARTSYS if interrupted. + */ +static int vmw_overlay_update_stream(struct vmw_private *dev_priv, + struct vmw_dma_buffer *buf, + struct drm_vmw_control_stream_arg *arg, + bool interruptible) +{ + struct vmw_overlay *overlay = dev_priv->overlay_priv; + struct vmw_stream *stream = &overlay->stream[arg->stream_id]; + int ret = 0; + + if (!buf) + return -EINVAL; + + DRM_DEBUG(" %s: old %p, new %p, %spaused\n", __func__, + stream->buf, buf, stream->paused ? "" : "not "); + + if (stream->buf != buf) { + ret = vmw_overlay_stop(dev_priv, arg->stream_id, + false, interruptible); + if (ret) + return ret; + } else if (!stream->paused) { + /* If the buffers match and not paused then just send + * the put command, no need to do anything else. + */ + ret = vmw_overlay_send_put(dev_priv, buf, arg, interruptible); + if (ret == 0) + stream->saved = *arg; + else + BUG_ON(!interruptible); + + return ret; + } + + /* We don't start the old stream if we are interrupted. + * Might return -ENOMEM if it can't fit the buffer in vram. + */ + ret = vmw_dmabuf_pin_in_vram(dev_priv, buf, true, interruptible); + if (ret) + return ret; + + ret = vmw_overlay_send_put(dev_priv, buf, arg, interruptible); + if (ret) { + /* This one needs to happen no matter what. We only remove + * the NO_EVICT flag so this is safe from -ENOMEM. + */ + BUG_ON(vmw_dmabuf_pin_in_vram(dev_priv, buf, false, false) != 0); + return ret; + } + + if (stream->buf != buf) + stream->buf = vmw_dmabuf_reference(buf); + stream->saved = *arg; + + return 0; +} + +/** + * Stop all streams. + * + * Used by the fb code when starting. + * + * Takes the overlay lock. + */ +int vmw_overlay_stop_all(struct vmw_private *dev_priv) +{ + struct vmw_overlay *overlay = dev_priv->overlay_priv; + int i, ret; + + if (!overlay) + return 0; + + mutex_lock(&overlay->mutex); + + for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) { + struct vmw_stream *stream = &overlay->stream[i]; + if (!stream->buf) + continue; + + ret = vmw_overlay_stop(dev_priv, i, false, false); + WARN_ON(ret != 0); + } + + mutex_unlock(&overlay->mutex); + + return 0; +} + +/** + * Try to resume all paused streams. + * + * Used by the kms code after moving a new scanout buffer to vram. + * + * Takes the overlay lock. + */ +int vmw_overlay_resume_all(struct vmw_private *dev_priv) +{ + struct vmw_overlay *overlay = dev_priv->overlay_priv; + int i, ret; + + if (!overlay) + return 0; + + mutex_lock(&overlay->mutex); + + for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) { + struct vmw_stream *stream = &overlay->stream[i]; + if (!stream->paused) + continue; + + ret = vmw_overlay_update_stream(dev_priv, stream->buf, + &stream->saved, false); + if (ret != 0) + DRM_INFO("%s: *warning* failed to resume stream %i\n", + __func__, i); + } + + mutex_unlock(&overlay->mutex); + + return 0; +} + +/** + * Pauses all active streams. + * + * Used by the kms code when moving a new scanout buffer to vram. + * + * Takes the overlay lock. + */ +int vmw_overlay_pause_all(struct vmw_private *dev_priv) +{ + struct vmw_overlay *overlay = dev_priv->overlay_priv; + int i, ret; + + if (!overlay) + return 0; + + mutex_lock(&overlay->mutex); + + for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) { + if (overlay->stream[i].paused) + DRM_INFO("%s: *warning* stream %i already paused\n", + __func__, i); + ret = vmw_overlay_stop(dev_priv, i, true, false); + WARN_ON(ret != 0); + } + + mutex_unlock(&overlay->mutex); + + return 0; +} + +int vmw_overlay_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; + struct vmw_private *dev_priv = vmw_priv(dev); + struct vmw_overlay *overlay = dev_priv->overlay_priv; + struct drm_vmw_control_stream_arg *arg = + (struct drm_vmw_control_stream_arg *)data; + struct vmw_dma_buffer *buf; + struct vmw_resource *res; + int ret; + + if (!overlay) + return -ENOSYS; + + ret = vmw_user_stream_lookup(dev_priv, tfile, &arg->stream_id, &res); + if (ret) + return ret; + + mutex_lock(&overlay->mutex); + + if (!arg->enabled) { + ret = vmw_overlay_stop(dev_priv, arg->stream_id, false, true); + goto out_unlock; + } + + ret = vmw_user_dmabuf_lookup(tfile, arg->handle, &buf); + if (ret) + goto out_unlock; + + ret = vmw_overlay_update_stream(dev_priv, buf, arg, true); + + vmw_dmabuf_unreference(&buf); + +out_unlock: + mutex_unlock(&overlay->mutex); + vmw_resource_unreference(&res); + + return ret; +} + +int vmw_overlay_num_overlays(struct vmw_private *dev_priv) +{ + if (!dev_priv->overlay_priv) + return 0; + + return VMW_MAX_NUM_STREAMS; +} + +int vmw_overlay_num_free_overlays(struct vmw_private *dev_priv) +{ + struct vmw_overlay *overlay = dev_priv->overlay_priv; + int i, k; + + if (!overlay) + return 0; + + mutex_lock(&overlay->mutex); + + for (i = 0, k = 0; i < VMW_MAX_NUM_STREAMS; i++) + if (!overlay->stream[i].claimed) + k++; + + mutex_unlock(&overlay->mutex); + + return k; +} + +int vmw_overlay_claim(struct vmw_private *dev_priv, uint32_t *out) +{ + struct vmw_overlay *overlay = dev_priv->overlay_priv; + int i; + + if (!overlay) + return -ENOSYS; + + mutex_lock(&overlay->mutex); + + for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) { + + if (overlay->stream[i].claimed) + continue; + + overlay->stream[i].claimed = true; + *out = i; + mutex_unlock(&overlay->mutex); + return 0; + } + + mutex_unlock(&overlay->mutex); + return -ESRCH; +} + +int vmw_overlay_unref(struct vmw_private *dev_priv, uint32_t stream_id) +{ + struct vmw_overlay *overlay = dev_priv->overlay_priv; + + BUG_ON(stream_id >= VMW_MAX_NUM_STREAMS); + + if (!overlay) + return -ENOSYS; + + mutex_lock(&overlay->mutex); + + WARN_ON(!overlay->stream[stream_id].claimed); + vmw_overlay_stop(dev_priv, stream_id, false, false); + overlay->stream[stream_id].claimed = false; + + mutex_unlock(&overlay->mutex); + return 0; +} + +int vmw_overlay_init(struct vmw_private *dev_priv) +{ + struct vmw_overlay *overlay; + int i; + + if (dev_priv->overlay_priv) + return -EINVAL; + + if (!(dev_priv->fifo.capabilities & SVGA_FIFO_CAP_VIDEO) && + (dev_priv->fifo.capabilities & SVGA_FIFO_CAP_ESCAPE)) { + DRM_INFO("hardware doesn't support overlays\n"); + return -ENOSYS; + } + + overlay = kmalloc(GFP_KERNEL, sizeof(*overlay)); + if (!overlay) + return -ENOMEM; + + memset(overlay, 0, sizeof(*overlay)); + mutex_init(&overlay->mutex); + for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) { + overlay->stream[i].buf = NULL; + overlay->stream[i].paused = false; + overlay->stream[i].claimed = false; + } + + dev_priv->overlay_priv = overlay; + + return 0; +} + +int vmw_overlay_close(struct vmw_private *dev_priv) +{ + struct vmw_overlay *overlay = dev_priv->overlay_priv; + bool forgotten_buffer = false; + int i; + + if (!overlay) + return -ENOSYS; + + for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) { + if (overlay->stream[i].buf) { + forgotten_buffer = true; + vmw_overlay_stop(dev_priv, i, false, false); + } + } + + WARN_ON(forgotten_buffer); + + dev_priv->overlay_priv = NULL; + kfree(overlay); + + return 0; +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_reg.h b/drivers/gpu/drm/vmwgfx/vmwgfx_reg.h new file mode 100644 index 0000000..9d0dd3a --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_reg.h @@ -0,0 +1,57 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * This file contains virtual hardware defines for kernel space. + */ + +#ifndef _VMWGFX_REG_H_ +#define _VMWGFX_REG_H_ + +#include + +#define VMWGFX_INDEX_PORT 0x0 +#define VMWGFX_VALUE_PORT 0x1 +#define VMWGFX_IRQSTATUS_PORT 0x8 + +struct svga_guest_mem_descriptor { + __le32 ppn; + __le32 num_pages; +}; + +struct svga_fifo_cmd_fence { + __le32 fence; +}; + +#define SVGA_SYNC_GENERIC 1 +#define SVGA_SYNC_FIFOFULL 2 + +#include "svga_types.h" + +#include "svga3d_reg.h" + +#endif diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c new file mode 100644 index 0000000..a1ceed0 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -0,0 +1,1192 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "vmwgfx_drv.h" +#include "vmwgfx_drm.h" +#include "ttm/ttm_object.h" +#include "ttm/ttm_placement.h" +#include "drmP.h" + +#define VMW_RES_CONTEXT ttm_driver_type0 +#define VMW_RES_SURFACE ttm_driver_type1 +#define VMW_RES_STREAM ttm_driver_type2 + +struct vmw_user_context { + struct ttm_base_object base; + struct vmw_resource res; +}; + +struct vmw_user_surface { + struct ttm_base_object base; + struct vmw_surface srf; +}; + +struct vmw_user_dma_buffer { + struct ttm_base_object base; + struct vmw_dma_buffer dma; +}; + +struct vmw_bo_user_rep { + uint32_t handle; + uint64_t map_handle; +}; + +struct vmw_stream { + struct vmw_resource res; + uint32_t stream_id; +}; + +struct vmw_user_stream { + struct ttm_base_object base; + struct vmw_stream stream; +}; + +static inline struct vmw_dma_buffer * +vmw_dma_buffer(struct ttm_buffer_object *bo) +{ + return container_of(bo, struct vmw_dma_buffer, base); +} + +static inline struct vmw_user_dma_buffer * +vmw_user_dma_buffer(struct ttm_buffer_object *bo) +{ + struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo); + return container_of(vmw_bo, struct vmw_user_dma_buffer, dma); +} + +struct vmw_resource *vmw_resource_reference(struct vmw_resource *res) +{ + kref_get(&res->kref); + return res; +} + +static void vmw_resource_release(struct kref *kref) +{ + struct vmw_resource *res = + container_of(kref, struct vmw_resource, kref); + struct vmw_private *dev_priv = res->dev_priv; + + idr_remove(res->idr, res->id); + write_unlock(&dev_priv->resource_lock); + + if (likely(res->hw_destroy != NULL)) + res->hw_destroy(res); + + if (res->res_free != NULL) + res->res_free(res); + else + kfree(res); + + write_lock(&dev_priv->resource_lock); +} + +void vmw_resource_unreference(struct vmw_resource **p_res) +{ + struct vmw_resource *res = *p_res; + struct vmw_private *dev_priv = res->dev_priv; + + *p_res = NULL; + write_lock(&dev_priv->resource_lock); + kref_put(&res->kref, vmw_resource_release); + write_unlock(&dev_priv->resource_lock); +} + +static int vmw_resource_init(struct vmw_private *dev_priv, + struct vmw_resource *res, + struct idr *idr, + enum ttm_object_type obj_type, + void (*res_free) (struct vmw_resource *res)) +{ + int ret; + + kref_init(&res->kref); + res->hw_destroy = NULL; + res->res_free = res_free; + res->res_type = obj_type; + res->idr = idr; + res->avail = false; + res->dev_priv = dev_priv; + + do { + if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0)) + return -ENOMEM; + + write_lock(&dev_priv->resource_lock); + ret = idr_get_new_above(idr, res, 1, &res->id); + write_unlock(&dev_priv->resource_lock); + + } while (ret == -EAGAIN); + + return ret; +} + +/** + * vmw_resource_activate + * + * @res: Pointer to the newly created resource + * @hw_destroy: Destroy function. NULL if none. + * + * Activate a resource after the hardware has been made aware of it. + * Set tye destroy function to @destroy. Typically this frees the + * resource and destroys the hardware resources associated with it. + * Activate basically means that the function vmw_resource_lookup will + * find it. + */ + +static void vmw_resource_activate(struct vmw_resource *res, + void (*hw_destroy) (struct vmw_resource *)) +{ + struct vmw_private *dev_priv = res->dev_priv; + + write_lock(&dev_priv->resource_lock); + res->avail = true; + res->hw_destroy = hw_destroy; + write_unlock(&dev_priv->resource_lock); +} + +struct vmw_resource *vmw_resource_lookup(struct vmw_private *dev_priv, + struct idr *idr, int id) +{ + struct vmw_resource *res; + + read_lock(&dev_priv->resource_lock); + res = idr_find(idr, id); + if (res && res->avail) + kref_get(&res->kref); + else + res = NULL; + read_unlock(&dev_priv->resource_lock); + + if (unlikely(res == NULL)) + return NULL; + + return res; +} + +/** + * Context management: + */ + +static void vmw_hw_context_destroy(struct vmw_resource *res) +{ + + struct vmw_private *dev_priv = res->dev_priv; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDestroyContext body; + } *cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); + + if (unlikely(cmd == NULL)) { + DRM_ERROR("Failed reserving FIFO space for surface " + "destruction.\n"); + return; + } + + cmd->header.id = cpu_to_le32(SVGA_3D_CMD_CONTEXT_DESTROY); + cmd->header.size = cpu_to_le32(sizeof(cmd->body)); + cmd->body.cid = cpu_to_le32(res->id); + + vmw_fifo_commit(dev_priv, sizeof(*cmd)); +} + +static int vmw_context_init(struct vmw_private *dev_priv, + struct vmw_resource *res, + void (*res_free) (struct vmw_resource *res)) +{ + int ret; + + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDefineContext body; + } *cmd; + + ret = vmw_resource_init(dev_priv, res, &dev_priv->context_idr, + VMW_RES_CONTEXT, res_free); + + if (unlikely(ret != 0)) { + if (res_free == NULL) + kfree(res); + else + res_free(res); + return ret; + } + + cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) { + DRM_ERROR("Fifo reserve failed.\n"); + vmw_resource_unreference(&res); + return -ENOMEM; + } + + cmd->header.id = cpu_to_le32(SVGA_3D_CMD_CONTEXT_DEFINE); + cmd->header.size = cpu_to_le32(sizeof(cmd->body)); + cmd->body.cid = cpu_to_le32(res->id); + + vmw_fifo_commit(dev_priv, sizeof(*cmd)); + vmw_resource_activate(res, vmw_hw_context_destroy); + return 0; +} + +struct vmw_resource *vmw_context_alloc(struct vmw_private *dev_priv) +{ + struct vmw_resource *res = kmalloc(sizeof(*res), GFP_KERNEL); + int ret; + + if (unlikely(res == NULL)) + return NULL; + + ret = vmw_context_init(dev_priv, res, NULL); + return (ret == 0) ? res : NULL; +} + +/** + * User-space context management: + */ + +static void vmw_user_context_free(struct vmw_resource *res) +{ + struct vmw_user_context *ctx = + container_of(res, struct vmw_user_context, res); + + kfree(ctx); +} + +/** + * This function is called when user space has no more references on the + * base object. It releases the base-object's reference on the resource object. + */ + +static void vmw_user_context_base_release(struct ttm_base_object **p_base) +{ + struct ttm_base_object *base = *p_base; + struct vmw_user_context *ctx = + container_of(base, struct vmw_user_context, base); + struct vmw_resource *res = &ctx->res; + + *p_base = NULL; + vmw_resource_unreference(&res); +} + +int vmw_context_destroy_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + struct vmw_resource *res; + struct vmw_user_context *ctx; + struct drm_vmw_context_arg *arg = (struct drm_vmw_context_arg *)data; + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; + int ret = 0; + + res = vmw_resource_lookup(dev_priv, &dev_priv->context_idr, arg->cid); + if (unlikely(res == NULL)) + return -EINVAL; + + if (res->res_free != &vmw_user_context_free) { + ret = -EINVAL; + goto out; + } + + ctx = container_of(res, struct vmw_user_context, res); + if (ctx->base.tfile != tfile && !ctx->base.shareable) { + ret = -EPERM; + goto out; + } + + ttm_ref_object_base_unref(tfile, ctx->base.hash.key, TTM_REF_USAGE); +out: + vmw_resource_unreference(&res); + return ret; +} + +int vmw_context_define_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + struct vmw_user_context *ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + struct vmw_resource *res; + struct vmw_resource *tmp; + struct drm_vmw_context_arg *arg = (struct drm_vmw_context_arg *)data; + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; + int ret; + + if (unlikely(ctx == NULL)) + return -ENOMEM; + + res = &ctx->res; + ctx->base.shareable = false; + ctx->base.tfile = NULL; + + ret = vmw_context_init(dev_priv, res, vmw_user_context_free); + if (unlikely(ret != 0)) + return ret; + + tmp = vmw_resource_reference(&ctx->res); + ret = ttm_base_object_init(tfile, &ctx->base, false, VMW_RES_CONTEXT, + &vmw_user_context_base_release, NULL); + + if (unlikely(ret != 0)) { + vmw_resource_unreference(&tmp); + goto out_err; + } + + arg->cid = res->id; +out_err: + vmw_resource_unreference(&res); + return ret; + +} + +int vmw_context_check(struct vmw_private *dev_priv, + struct ttm_object_file *tfile, + int id) +{ + struct vmw_resource *res; + int ret = 0; + + read_lock(&dev_priv->resource_lock); + res = idr_find(&dev_priv->context_idr, id); + if (res && res->avail) { + struct vmw_user_context *ctx = + container_of(res, struct vmw_user_context, res); + if (ctx->base.tfile != tfile && !ctx->base.shareable) + ret = -EPERM; + } else + ret = -EINVAL; + read_unlock(&dev_priv->resource_lock); + + return ret; +} + + +/** + * Surface management. + */ + +static void vmw_hw_surface_destroy(struct vmw_resource *res) +{ + + struct vmw_private *dev_priv = res->dev_priv; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDestroySurface body; + } *cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); + + if (unlikely(cmd == NULL)) { + DRM_ERROR("Failed reserving FIFO space for surface " + "destruction.\n"); + return; + } + + cmd->header.id = cpu_to_le32(SVGA_3D_CMD_SURFACE_DESTROY); + cmd->header.size = cpu_to_le32(sizeof(cmd->body)); + cmd->body.sid = cpu_to_le32(res->id); + + vmw_fifo_commit(dev_priv, sizeof(*cmd)); +} + +void vmw_surface_res_free(struct vmw_resource *res) +{ + struct vmw_surface *srf = container_of(res, struct vmw_surface, res); + + kfree(srf->sizes); + kfree(srf->snooper.image); + kfree(srf); +} + +int vmw_surface_init(struct vmw_private *dev_priv, + struct vmw_surface *srf, + void (*res_free) (struct vmw_resource *res)) +{ + int ret; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDefineSurface body; + } *cmd; + SVGA3dSize *cmd_size; + struct vmw_resource *res = &srf->res; + struct drm_vmw_size *src_size; + size_t submit_size; + uint32_t cmd_len; + int i; + + BUG_ON(res_free == NULL); + ret = vmw_resource_init(dev_priv, res, &dev_priv->surface_idr, + VMW_RES_SURFACE, res_free); + + if (unlikely(ret != 0)) { + res_free(res); + return ret; + } + + submit_size = sizeof(*cmd) + srf->num_sizes * sizeof(SVGA3dSize); + cmd_len = sizeof(cmd->body) + srf->num_sizes * sizeof(SVGA3dSize); + + cmd = vmw_fifo_reserve(dev_priv, submit_size); + if (unlikely(cmd == NULL)) { + DRM_ERROR("Fifo reserve failed for create surface.\n"); + vmw_resource_unreference(&res); + return -ENOMEM; + } + + cmd->header.id = cpu_to_le32(SVGA_3D_CMD_SURFACE_DEFINE); + cmd->header.size = cpu_to_le32(cmd_len); + cmd->body.sid = cpu_to_le32(res->id); + cmd->body.surfaceFlags = cpu_to_le32(srf->flags); + cmd->body.format = cpu_to_le32(srf->format); + for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) { + cmd->body.face[i].numMipLevels = + cpu_to_le32(srf->mip_levels[i]); + } + + cmd += 1; + cmd_size = (SVGA3dSize *) cmd; + src_size = srf->sizes; + + for (i = 0; i < srf->num_sizes; ++i, cmd_size++, src_size++) { + cmd_size->width = cpu_to_le32(src_size->width); + cmd_size->height = cpu_to_le32(src_size->height); + cmd_size->depth = cpu_to_le32(src_size->depth); + } + + vmw_fifo_commit(dev_priv, submit_size); + vmw_resource_activate(res, vmw_hw_surface_destroy); + return 0; +} + +static void vmw_user_surface_free(struct vmw_resource *res) +{ + struct vmw_surface *srf = container_of(res, struct vmw_surface, res); + struct vmw_user_surface *user_srf = + container_of(srf, struct vmw_user_surface, srf); + + kfree(srf->sizes); + kfree(srf->snooper.image); + kfree(user_srf); +} + +int vmw_user_surface_lookup(struct vmw_private *dev_priv, + struct ttm_object_file *tfile, + int sid, struct vmw_surface **out) +{ + struct vmw_resource *res; + struct vmw_surface *srf; + struct vmw_user_surface *user_srf; + + res = vmw_resource_lookup(dev_priv, &dev_priv->surface_idr, sid); + if (unlikely(res == NULL)) + return -EINVAL; + + if (res->res_free != &vmw_user_surface_free) + return -EINVAL; + + srf = container_of(res, struct vmw_surface, res); + user_srf = container_of(srf, struct vmw_user_surface, srf); + if (user_srf->base.tfile != tfile && !user_srf->base.shareable) + return -EPERM; + + *out = srf; + return 0; +} + +static void vmw_user_surface_base_release(struct ttm_base_object **p_base) +{ + struct ttm_base_object *base = *p_base; + struct vmw_user_surface *user_srf = + container_of(base, struct vmw_user_surface, base); + struct vmw_resource *res = &user_srf->srf.res; + + *p_base = NULL; + vmw_resource_unreference(&res); +} + +int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + struct vmw_resource *res; + struct vmw_surface *srf; + struct vmw_user_surface *user_srf; + struct drm_vmw_surface_arg *arg = (struct drm_vmw_surface_arg *)data; + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; + int ret = 0; + + res = vmw_resource_lookup(dev_priv, &dev_priv->surface_idr, arg->sid); + if (unlikely(res == NULL)) + return -EINVAL; + + if (res->res_free != &vmw_user_surface_free) { + ret = -EINVAL; + goto out; + } + + srf = container_of(res, struct vmw_surface, res); + user_srf = container_of(srf, struct vmw_user_surface, srf); + if (user_srf->base.tfile != tfile && !user_srf->base.shareable) { + ret = -EPERM; + goto out; + } + + ttm_ref_object_base_unref(tfile, user_srf->base.hash.key, + TTM_REF_USAGE); +out: + vmw_resource_unreference(&res); + return ret; +} + +int vmw_surface_define_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + struct vmw_user_surface *user_srf = + kmalloc(sizeof(*user_srf), GFP_KERNEL); + struct vmw_surface *srf; + struct vmw_resource *res; + struct vmw_resource *tmp; + union drm_vmw_surface_create_arg *arg = + (union drm_vmw_surface_create_arg *)data; + struct drm_vmw_surface_create_req *req = &arg->req; + struct drm_vmw_surface_arg *rep = &arg->rep; + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; + struct drm_vmw_size __user *user_sizes; + int ret; + int i; + + if (unlikely(user_srf == NULL)) + return -ENOMEM; + + srf = &user_srf->srf; + res = &srf->res; + + srf->flags = req->flags; + srf->format = req->format; + memcpy(srf->mip_levels, req->mip_levels, sizeof(srf->mip_levels)); + srf->num_sizes = 0; + for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) + srf->num_sizes += srf->mip_levels[i]; + + if (srf->num_sizes > DRM_VMW_MAX_SURFACE_FACES * + DRM_VMW_MAX_MIP_LEVELS) { + ret = -EINVAL; + goto out_err0; + } + + srf->sizes = kmalloc(srf->num_sizes * sizeof(*srf->sizes), GFP_KERNEL); + if (unlikely(srf->sizes == NULL)) { + ret = -ENOMEM; + goto out_err0; + } + + user_sizes = (struct drm_vmw_size __user *)(unsigned long) + req->size_addr; + + ret = copy_from_user(srf->sizes, user_sizes, + srf->num_sizes * sizeof(*srf->sizes)); + if (unlikely(ret != 0)) + goto out_err1; + + user_srf->base.shareable = false; + user_srf->base.tfile = NULL; + + /** + * From this point, the generic resource management functions + * destroy the object on failure. + */ + + ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free); + if (unlikely(ret != 0)) + return ret; + + tmp = vmw_resource_reference(&srf->res); + ret = ttm_base_object_init(tfile, &user_srf->base, + req->shareable, VMW_RES_SURFACE, + &vmw_user_surface_base_release, NULL); + + if (unlikely(ret != 0)) { + vmw_resource_unreference(&tmp); + vmw_resource_unreference(&res); + return ret; + } + + if (srf->flags & (1 << 9) && + srf->num_sizes == 1 && + srf->sizes[0].width == 64 && + srf->sizes[0].height == 64 && + srf->format == SVGA3D_A8R8G8B8) { + + srf->snooper.image = kmalloc(64 * 64 * 4, GFP_KERNEL); + /* clear the image */ + if (srf->snooper.image) + memset(srf->snooper.image, 0x00, 64 * 64 * 4); + else + DRM_ERROR("Failed to allocate cursor_image\n"); + + } else { + srf->snooper.image = NULL; + } + srf->snooper.crtc = NULL; + + rep->sid = res->id; + vmw_resource_unreference(&res); + return 0; +out_err1: + kfree(srf->sizes); +out_err0: + kfree(user_srf); + return ret; +} + +int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + union drm_vmw_surface_reference_arg *arg = + (union drm_vmw_surface_reference_arg *)data; + struct drm_vmw_surface_arg *req = &arg->req; + struct drm_vmw_surface_create_req *rep = &arg->rep; + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; + struct vmw_resource *res; + struct vmw_surface *srf; + struct vmw_user_surface *user_srf; + struct drm_vmw_size __user *user_sizes; + int ret; + + res = vmw_resource_lookup(dev_priv, &dev_priv->surface_idr, req->sid); + if (unlikely(res == NULL)) + return -EINVAL; + + if (res->res_free != &vmw_user_surface_free) { + ret = -EINVAL; + goto out; + } + + srf = container_of(res, struct vmw_surface, res); + user_srf = container_of(srf, struct vmw_user_surface, srf); + if (user_srf->base.tfile != tfile && !user_srf->base.shareable) { + DRM_ERROR("Tried to reference none shareable surface\n"); + ret = -EPERM; + goto out; + } + + ret = ttm_ref_object_add(tfile, &user_srf->base, TTM_REF_USAGE, NULL); + if (unlikely(ret != 0)) { + DRM_ERROR("Could not add a reference to a surface.\n"); + goto out; + } + + rep->flags = srf->flags; + rep->format = srf->format; + memcpy(rep->mip_levels, srf->mip_levels, sizeof(srf->mip_levels)); + user_sizes = (struct drm_vmw_size __user *)(unsigned long) + rep->size_addr; + + if (user_sizes) + ret = copy_to_user(user_sizes, srf->sizes, + srf->num_sizes * sizeof(*srf->sizes)); + if (unlikely(ret != 0)) { + DRM_ERROR("copy_to_user failed %p %u\n", + user_sizes, srf->num_sizes); + /** + * FIXME: Unreference surface here? + */ + goto out; + } +out: + vmw_resource_unreference(&res); + return ret; +} + +int vmw_surface_check(struct vmw_private *dev_priv, + struct ttm_object_file *tfile, + int id) +{ + struct vmw_resource *res; + int ret = 0; + + read_lock(&dev_priv->resource_lock); + res = idr_find(&dev_priv->surface_idr, id); + if (res && res->avail) { + struct vmw_surface *srf = + container_of(res, struct vmw_surface, res); + struct vmw_user_surface *usrf = + container_of(srf, struct vmw_user_surface, srf); + + if (usrf->base.tfile != tfile && !usrf->base.shareable) + ret = -EPERM; + } else + ret = -EINVAL; + read_unlock(&dev_priv->resource_lock); + + return ret; +} + +/** + * Buffer management. + */ + +static size_t vmw_dmabuf_acc_size(struct ttm_bo_global *glob, + unsigned long num_pages) +{ + static size_t bo_user_size = ~0; + + size_t page_array_size = + (num_pages * sizeof(void *) + PAGE_SIZE - 1) & PAGE_MASK; + + if (unlikely(bo_user_size == ~0)) { + bo_user_size = glob->ttm_bo_extra_size + + ttm_round_pot(sizeof(struct vmw_dma_buffer)); + } + + return bo_user_size + page_array_size; +} + +void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo) +{ + struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo); + struct ttm_bo_global *glob = bo->glob; + struct vmw_private *dev_priv = + container_of(bo->bdev, struct vmw_private, bdev); + + ttm_mem_global_free(glob->mem_glob, bo->acc_size); + if (vmw_bo->gmr_bound) { + vmw_gmr_unbind(dev_priv, vmw_bo->gmr_id); + spin_lock(&glob->lru_lock); + ida_remove(&dev_priv->gmr_ida, vmw_bo->gmr_id); + spin_unlock(&glob->lru_lock); + } + kfree(vmw_bo); +} + +int vmw_dmabuf_init(struct vmw_private *dev_priv, + struct vmw_dma_buffer *vmw_bo, + size_t size, struct ttm_placement *placement, + bool interruptible, + void (*bo_free) (struct ttm_buffer_object *bo)) +{ + struct ttm_bo_device *bdev = &dev_priv->bdev; + struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; + size_t acc_size; + int ret; + + BUG_ON(!bo_free); + + acc_size = + vmw_dmabuf_acc_size(bdev->glob, + (size + PAGE_SIZE - 1) >> PAGE_SHIFT); + + ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false); + if (unlikely(ret != 0)) { + /* we must free the bo here as + * ttm_buffer_object_init does so as well */ + bo_free(&vmw_bo->base); + return ret; + } + + memset(vmw_bo, 0, sizeof(*vmw_bo)); + + INIT_LIST_HEAD(&vmw_bo->gmr_lru); + INIT_LIST_HEAD(&vmw_bo->validate_list); + vmw_bo->gmr_id = 0; + vmw_bo->gmr_bound = false; + + ret = ttm_bo_init(bdev, &vmw_bo->base, size, + ttm_bo_type_device, placement, + 0, 0, interruptible, + NULL, acc_size, bo_free); + return ret; +} + +static void vmw_user_dmabuf_destroy(struct ttm_buffer_object *bo) +{ + struct vmw_user_dma_buffer *vmw_user_bo = vmw_user_dma_buffer(bo); + struct vmw_dma_buffer *vmw_bo = &vmw_user_bo->dma; + struct ttm_bo_global *glob = bo->glob; + struct vmw_private *dev_priv = + container_of(bo->bdev, struct vmw_private, bdev); + + ttm_mem_global_free(glob->mem_glob, bo->acc_size); + if (vmw_bo->gmr_bound) { + vmw_gmr_unbind(dev_priv, vmw_bo->gmr_id); + spin_lock(&glob->lru_lock); + ida_remove(&dev_priv->gmr_ida, vmw_bo->gmr_id); + spin_unlock(&glob->lru_lock); + } + kfree(vmw_user_bo); +} + +static void vmw_user_dmabuf_release(struct ttm_base_object **p_base) +{ + struct vmw_user_dma_buffer *vmw_user_bo; + struct ttm_base_object *base = *p_base; + struct ttm_buffer_object *bo; + + *p_base = NULL; + + if (unlikely(base == NULL)) + return; + + vmw_user_bo = container_of(base, struct vmw_user_dma_buffer, base); + bo = &vmw_user_bo->dma.base; + ttm_bo_unref(&bo); +} + +int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + union drm_vmw_alloc_dmabuf_arg *arg = + (union drm_vmw_alloc_dmabuf_arg *)data; + struct drm_vmw_alloc_dmabuf_req *req = &arg->req; + struct drm_vmw_dmabuf_rep *rep = &arg->rep; + struct vmw_user_dma_buffer *vmw_user_bo; + struct ttm_buffer_object *tmp; + struct vmw_master *vmaster = vmw_master(file_priv->master); + int ret; + + vmw_user_bo = kzalloc(sizeof(*vmw_user_bo), GFP_KERNEL); + if (unlikely(vmw_user_bo == NULL)) + return -ENOMEM; + + ret = ttm_read_lock(&vmaster->lock, true); + if (unlikely(ret != 0)) { + kfree(vmw_user_bo); + return ret; + } + + ret = vmw_dmabuf_init(dev_priv, &vmw_user_bo->dma, req->size, + &vmw_vram_placement, true, + &vmw_user_dmabuf_destroy); + if (unlikely(ret != 0)) + return ret; + + tmp = ttm_bo_reference(&vmw_user_bo->dma.base); + ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile, + &vmw_user_bo->base, + false, + ttm_buffer_type, + &vmw_user_dmabuf_release, NULL); + if (unlikely(ret != 0)) { + ttm_bo_unref(&tmp); + } else { + rep->handle = vmw_user_bo->base.hash.key; + rep->map_handle = vmw_user_bo->dma.base.addr_space_offset; + rep->cur_gmr_id = vmw_user_bo->base.hash.key; + rep->cur_gmr_offset = 0; + } + ttm_bo_unref(&tmp); + + ttm_read_unlock(&vmaster->lock); + + return 0; +} + +int vmw_dmabuf_unref_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_vmw_unref_dmabuf_arg *arg = + (struct drm_vmw_unref_dmabuf_arg *)data; + + return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile, + arg->handle, + TTM_REF_USAGE); +} + +uint32_t vmw_dmabuf_validate_node(struct ttm_buffer_object *bo, + uint32_t cur_validate_node) +{ + struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo); + + if (likely(vmw_bo->on_validate_list)) + return vmw_bo->cur_validate_node; + + vmw_bo->cur_validate_node = cur_validate_node; + vmw_bo->on_validate_list = true; + + return cur_validate_node; +} + +void vmw_dmabuf_validate_clear(struct ttm_buffer_object *bo) +{ + struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo); + + vmw_bo->on_validate_list = false; +} + +uint32_t vmw_dmabuf_gmr(struct ttm_buffer_object *bo) +{ + struct vmw_dma_buffer *vmw_bo; + + if (bo->mem.mem_type == TTM_PL_VRAM) + return SVGA_GMR_FRAMEBUFFER; + + vmw_bo = vmw_dma_buffer(bo); + + return (vmw_bo->gmr_bound) ? vmw_bo->gmr_id : SVGA_GMR_NULL; +} + +void vmw_dmabuf_set_gmr(struct ttm_buffer_object *bo, uint32_t id) +{ + struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo); + vmw_bo->gmr_bound = true; + vmw_bo->gmr_id = id; +} + +int vmw_user_dmabuf_lookup(struct ttm_object_file *tfile, + uint32_t handle, struct vmw_dma_buffer **out) +{ + struct vmw_user_dma_buffer *vmw_user_bo; + struct ttm_base_object *base; + + base = ttm_base_object_lookup(tfile, handle); + if (unlikely(base == NULL)) { + printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n", + (unsigned long)handle); + return -ESRCH; + } + + if (unlikely(base->object_type != ttm_buffer_type)) { + ttm_base_object_unref(&base); + printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n", + (unsigned long)handle); + return -EINVAL; + } + + vmw_user_bo = container_of(base, struct vmw_user_dma_buffer, base); + (void)ttm_bo_reference(&vmw_user_bo->dma.base); + ttm_base_object_unref(&base); + *out = &vmw_user_bo->dma; + + return 0; +} + +/** + * TODO: Implement a gmr id eviction mechanism. Currently we just fail + * when we're out of ids, causing GMR space to be allocated + * out of VRAM. + */ + +int vmw_gmr_id_alloc(struct vmw_private *dev_priv, uint32_t *p_id) +{ + struct ttm_bo_global *glob = dev_priv->bdev.glob; + int id; + int ret; + + do { + if (unlikely(ida_pre_get(&dev_priv->gmr_ida, GFP_KERNEL) == 0)) + return -ENOMEM; + + spin_lock(&glob->lru_lock); + ret = ida_get_new(&dev_priv->gmr_ida, &id); + spin_unlock(&glob->lru_lock); + } while (ret == -EAGAIN); + + if (unlikely(ret != 0)) + return ret; + + if (unlikely(id >= dev_priv->max_gmr_ids)) { + spin_lock(&glob->lru_lock); + ida_remove(&dev_priv->gmr_ida, id); + spin_unlock(&glob->lru_lock); + return -EBUSY; + } + + *p_id = (uint32_t) id; + return 0; +} + +/* + * Stream managment + */ + +static void vmw_stream_destroy(struct vmw_resource *res) +{ + struct vmw_private *dev_priv = res->dev_priv; + struct vmw_stream *stream; + int ret; + + DRM_INFO("%s: unref\n", __func__); + stream = container_of(res, struct vmw_stream, res); + + ret = vmw_overlay_unref(dev_priv, stream->stream_id); + WARN_ON(ret != 0); +} + +static int vmw_stream_init(struct vmw_private *dev_priv, + struct vmw_stream *stream, + void (*res_free) (struct vmw_resource *res)) +{ + struct vmw_resource *res = &stream->res; + int ret; + + ret = vmw_resource_init(dev_priv, res, &dev_priv->stream_idr, + VMW_RES_STREAM, res_free); + + if (unlikely(ret != 0)) { + if (res_free == NULL) + kfree(stream); + else + res_free(&stream->res); + return ret; + } + + ret = vmw_overlay_claim(dev_priv, &stream->stream_id); + if (ret) { + vmw_resource_unreference(&res); + return ret; + } + + DRM_INFO("%s: claimed\n", __func__); + + vmw_resource_activate(&stream->res, vmw_stream_destroy); + return 0; +} + +/** + * User-space context management: + */ + +static void vmw_user_stream_free(struct vmw_resource *res) +{ + struct vmw_user_stream *stream = + container_of(res, struct vmw_user_stream, stream.res); + + kfree(stream); +} + +/** + * This function is called when user space has no more references on the + * base object. It releases the base-object's reference on the resource object. + */ + +static void vmw_user_stream_base_release(struct ttm_base_object **p_base) +{ + struct ttm_base_object *base = *p_base; + struct vmw_user_stream *stream = + container_of(base, struct vmw_user_stream, base); + struct vmw_resource *res = &stream->stream.res; + + *p_base = NULL; + vmw_resource_unreference(&res); +} + +int vmw_stream_unref_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + struct vmw_resource *res; + struct vmw_user_stream *stream; + struct drm_vmw_stream_arg *arg = (struct drm_vmw_stream_arg *)data; + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; + int ret = 0; + + res = vmw_resource_lookup(dev_priv, &dev_priv->stream_idr, arg->stream_id); + if (unlikely(res == NULL)) + return -EINVAL; + + if (res->res_free != &vmw_user_stream_free) { + ret = -EINVAL; + goto out; + } + + stream = container_of(res, struct vmw_user_stream, stream.res); + if (stream->base.tfile != tfile) { + ret = -EINVAL; + goto out; + } + + ttm_ref_object_base_unref(tfile, stream->base.hash.key, TTM_REF_USAGE); +out: + vmw_resource_unreference(&res); + return ret; +} + +int vmw_stream_claim_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + struct vmw_user_stream *stream = kmalloc(sizeof(*stream), GFP_KERNEL); + struct vmw_resource *res; + struct vmw_resource *tmp; + struct drm_vmw_stream_arg *arg = (struct drm_vmw_stream_arg *)data; + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; + int ret; + + if (unlikely(stream == NULL)) + return -ENOMEM; + + res = &stream->stream.res; + stream->base.shareable = false; + stream->base.tfile = NULL; + + ret = vmw_stream_init(dev_priv, &stream->stream, vmw_user_stream_free); + if (unlikely(ret != 0)) + return ret; + + tmp = vmw_resource_reference(res); + ret = ttm_base_object_init(tfile, &stream->base, false, VMW_RES_STREAM, + &vmw_user_stream_base_release, NULL); + + if (unlikely(ret != 0)) { + vmw_resource_unreference(&tmp); + goto out_err; + } + + arg->stream_id = res->id; +out_err: + vmw_resource_unreference(&res); + return ret; +} + +int vmw_user_stream_lookup(struct vmw_private *dev_priv, + struct ttm_object_file *tfile, + uint32_t *inout_id, struct vmw_resource **out) +{ + struct vmw_user_stream *stream; + struct vmw_resource *res; + int ret; + + res = vmw_resource_lookup(dev_priv, &dev_priv->stream_idr, *inout_id); + if (unlikely(res == NULL)) + return -EINVAL; + + if (res->res_free != &vmw_user_stream_free) { + ret = -EINVAL; + goto err_ref; + } + + stream = container_of(res, struct vmw_user_stream, stream.res); + if (stream->base.tfile != tfile) { + ret = -EPERM; + goto err_ref; + } + + *inout_id = stream->stream.stream_id; + *out = res; + return 0; +err_ref: + vmw_resource_unreference(&res); + return ret; +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c new file mode 100644 index 0000000..e3df4ad --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c @@ -0,0 +1,99 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "drmP.h" +#include "vmwgfx_drv.h" + +int vmw_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct drm_file *file_priv; + struct vmw_private *dev_priv; + + if (unlikely(vma->vm_pgoff < VMWGFX_FILE_PAGE_OFFSET)) { + if (vmw_fifo_mmap(filp, vma) == 0) + return 0; + return drm_mmap(filp, vma); + } + + file_priv = (struct drm_file *)filp->private_data; + dev_priv = vmw_priv(file_priv->minor->dev); + return ttm_bo_mmap(filp, vma, &dev_priv->bdev); +} + +static int vmw_ttm_mem_global_init(struct ttm_global_reference *ref) +{ + DRM_INFO("global init.\n"); + return ttm_mem_global_init(ref->object); +} + +static void vmw_ttm_mem_global_release(struct ttm_global_reference *ref) +{ + ttm_mem_global_release(ref->object); +} + +int vmw_ttm_global_init(struct vmw_private *dev_priv) +{ + struct ttm_global_reference *global_ref; + int ret; + + global_ref = &dev_priv->mem_global_ref; + global_ref->global_type = TTM_GLOBAL_TTM_MEM; + global_ref->size = sizeof(struct ttm_mem_global); + global_ref->init = &vmw_ttm_mem_global_init; + global_ref->release = &vmw_ttm_mem_global_release; + + ret = ttm_global_item_ref(global_ref); + if (unlikely(ret != 0)) { + DRM_ERROR("Failed setting up TTM memory accounting.\n"); + return ret; + } + + dev_priv->bo_global_ref.mem_glob = + dev_priv->mem_global_ref.object; + global_ref = &dev_priv->bo_global_ref.ref; + global_ref->global_type = TTM_GLOBAL_TTM_BO; + global_ref->size = sizeof(struct ttm_bo_global); + global_ref->init = &ttm_bo_global_init; + global_ref->release = &ttm_bo_global_release; + ret = ttm_global_item_ref(global_ref); + + if (unlikely(ret != 0)) { + DRM_ERROR("Failed setting up TTM buffer objects.\n"); + goto out_no_bo; + } + + return 0; +out_no_bo: + ttm_global_item_unref(&dev_priv->mem_global_ref); + return ret; +} + +void vmw_ttm_global_release(struct vmw_private *dev_priv) +{ + ttm_global_item_unref(&dev_priv->bo_global_ref.ref); + ttm_global_item_unref(&dev_priv->mem_global_ref); +} diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index d21b346..89f725f 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -101,6 +101,8 @@ source "drivers/staging/p9auth/Kconfig" source "drivers/staging/line6/Kconfig" +source "drivers/gpu/drm/vmwgfx/Kconfig" + source "drivers/gpu/drm/radeon/Kconfig" source "drivers/staging/octeon/Kconfig" diff --git a/include/drm/Kbuild b/include/drm/Kbuild index b940fdf..1e83f85 100644 --- a/include/drm/Kbuild +++ b/include/drm/Kbuild @@ -7,4 +7,5 @@ unifdef-y += r128_drm.h unifdef-y += radeon_drm.h unifdef-y += sis_drm.h unifdef-y += savage_drm.h +unifdef-y += vmwgfx_drm.h unifdef-y += via_drm.h diff --git a/include/drm/vmwgfx_drm.h b/include/drm/vmwgfx_drm.h new file mode 100644 index 0000000..2be7e12 --- /dev/null +++ b/include/drm/vmwgfx_drm.h @@ -0,0 +1,574 @@ +/************************************************************************** + * + * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef __VMWGFX_DRM_H__ +#define __VMWGFX_DRM_H__ + +#define DRM_VMW_MAX_SURFACE_FACES 6 +#define DRM_VMW_MAX_MIP_LEVELS 24 + +#define DRM_VMW_EXT_NAME_LEN 128 + +#define DRM_VMW_GET_PARAM 0 +#define DRM_VMW_ALLOC_DMABUF 1 +#define DRM_VMW_UNREF_DMABUF 2 +#define DRM_VMW_CURSOR_BYPASS 3 +/* guarded by DRM_VMW_PARAM_NUM_STREAMS != 0*/ +#define DRM_VMW_CONTROL_STREAM 4 +#define DRM_VMW_CLAIM_STREAM 5 +#define DRM_VMW_UNREF_STREAM 6 +/* guarded by DRM_VMW_PARAM_3D == 1 */ +#define DRM_VMW_CREATE_CONTEXT 7 +#define DRM_VMW_UNREF_CONTEXT 8 +#define DRM_VMW_CREATE_SURFACE 9 +#define DRM_VMW_UNREF_SURFACE 10 +#define DRM_VMW_REF_SURFACE 11 +#define DRM_VMW_EXECBUF 12 +#define DRM_VMW_FIFO_DEBUG 13 +#define DRM_VMW_FENCE_WAIT 14 + + +/*************************************************************************/ +/** + * DRM_VMW_GET_PARAM - get device information. + * + * DRM_VMW_PARAM_FIFO_OFFSET: + * Offset to use to map the first page of the FIFO read-only. + * The fifo is mapped using the mmap() system call on the drm device. + * + * DRM_VMW_PARAM_OVERLAY_IOCTL: + * Does the driver support the overlay ioctl. + */ + +#define DRM_VMW_PARAM_NUM_STREAMS 0 +#define DRM_VMW_PARAM_NUM_FREE_STREAMS 1 +#define DRM_VMW_PARAM_3D 2 +#define DRM_VMW_PARAM_FIFO_OFFSET 3 + + +/** + * struct drm_vmw_getparam_arg + * + * @value: Returned value. //Out + * @param: Parameter to query. //In. + * + * Argument to the DRM_VMW_GET_PARAM Ioctl. + */ + +struct drm_vmw_getparam_arg { + uint64_t value; + uint32_t param; + uint32_t pad64; +}; + +/*************************************************************************/ +/** + * DRM_VMW_EXTENSION - Query device extensions. + */ + +/** + * struct drm_vmw_extension_rep + * + * @exists: The queried extension exists. + * @driver_ioctl_offset: Ioctl number of the first ioctl in the extension. + * @driver_sarea_offset: Offset to any space in the DRI SAREA + * used by the extension. + * @major: Major version number of the extension. + * @minor: Minor version number of the extension. + * @pl: Patch level version number of the extension. + * + * Output argument to the DRM_VMW_EXTENSION Ioctl. + */ + +struct drm_vmw_extension_rep { + int32_t exists; + uint32_t driver_ioctl_offset; + uint32_t driver_sarea_offset; + uint32_t major; + uint32_t minor; + uint32_t pl; + uint32_t pad64; +}; + +/** + * union drm_vmw_extension_arg + * + * @extension - Ascii name of the extension to be queried. //In + * @rep - Reply as defined above. //Out + * + * Argument to the DRM_VMW_EXTENSION Ioctl. + */ + +union drm_vmw_extension_arg { + char extension[DRM_VMW_EXT_NAME_LEN]; + struct drm_vmw_extension_rep rep; +}; + +/*************************************************************************/ +/** + * DRM_VMW_CREATE_CONTEXT - Create a host context. + * + * Allocates a device unique context id, and queues a create context command + * for the host. Does not wait for host completion. + */ + +/** + * struct drm_vmw_context_arg + * + * @cid: Device unique context ID. + * + * Output argument to the DRM_VMW_CREATE_CONTEXT Ioctl. + * Input argument to the DRM_VMW_UNREF_CONTEXT Ioctl. + */ + +struct drm_vmw_context_arg { + int32_t cid; + uint32_t pad64; +}; + +/*************************************************************************/ +/** + * DRM_VMW_UNREF_CONTEXT - Create a host context. + * + * Frees a global context id, and queues a destroy host command for the host. + * Does not wait for host completion. The context ID can be used directly + * in the command stream and shows up as the same context ID on the host. + */ + +/*************************************************************************/ +/** + * DRM_VMW_CREATE_SURFACE - Create a host suface. + * + * Allocates a device unique surface id, and queues a create surface command + * for the host. Does not wait for host completion. The surface ID can be + * used directly in the command stream and shows up as the same surface + * ID on the host. + */ + +/** + * struct drm_wmv_surface_create_req + * + * @flags: Surface flags as understood by the host. + * @format: Surface format as understood by the host. + * @mip_levels: Number of mip levels for each face. + * An unused face should have 0 encoded. + * @size_addr: Address of a user-space array of sruct drm_vmw_size + * cast to an uint64_t for 32-64 bit compatibility. + * The size of the array should equal the total number of mipmap levels. + * @shareable: Boolean whether other clients (as identified by file descriptors) + * may reference this surface. + * + * Input data to the DRM_VMW_CREATE_SURFACE Ioctl. + * Output data from the DRM_VMW_REF_SURFACE Ioctl. + */ + +struct drm_vmw_surface_create_req { + uint32_t flags; + uint32_t format; + uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES]; + uint64_t size_addr; + int32_t shareable; + uint32_t pad64; +}; + +/** + * struct drm_wmv_surface_arg + * + * @sid: Surface id of created surface or surface to destroy or reference. + * + * Output data from the DRM_VMW_CREATE_SURFACE Ioctl. + * Input argument to the DRM_VMW_UNREF_SURFACE Ioctl. + * Input argument to the DRM_VMW_REF_SURFACE Ioctl. + */ + +struct drm_vmw_surface_arg { + int32_t sid; + uint32_t pad64; +}; + +/** + * struct drm_vmw_size ioctl. + * + * @width - mip level width + * @height - mip level height + * @depth - mip level depth + * + * Description of a mip level. + * Input data to the DRM_WMW_CREATE_SURFACE Ioctl. + */ + +struct drm_vmw_size { + uint32_t width; + uint32_t height; + uint32_t depth; + uint32_t pad64; +}; + +/** + * union drm_vmw_surface_create_arg + * + * @rep: Output data as described above. + * @req: Input data as described above. + * + * Argument to the DRM_VMW_CREATE_SURFACE Ioctl. + */ + +union drm_vmw_surface_create_arg { + struct drm_vmw_surface_arg rep; + struct drm_vmw_surface_create_req req; +}; + +/*************************************************************************/ +/** + * DRM_VMW_REF_SURFACE - Reference a host surface. + * + * Puts a reference on a host surface with a give sid, as previously + * returned by the DRM_VMW_CREATE_SURFACE ioctl. + * A reference will make sure the surface isn't destroyed while we hold + * it and will allow the calling client to use the surface ID in the command + * stream. + * + * On successful return, the Ioctl returns the surface information given + * in the DRM_VMW_CREATE_SURFACE ioctl. + */ + +/** + * union drm_vmw_surface_reference_arg + * + * @rep: Output data as described above. + * @req: Input data as described above. + * + * Argument to the DRM_VMW_REF_SURFACE Ioctl. + */ + +union drm_vmw_surface_reference_arg { + struct drm_vmw_surface_create_req rep; + struct drm_vmw_surface_arg req; +}; + +/*************************************************************************/ +/** + * DRM_VMW_UNREF_SURFACE - Unreference a host surface. + * + * Clear a reference previously put on a host surface. + * When all references are gone, including the one implicitly placed + * on creation, + * a destroy surface command will be queued for the host. + * Does not wait for completion. + */ + +/*************************************************************************/ +/** + * DRM_VMW_EXECBUF + * + * Submit a command buffer for execution on the host, and return a + * fence sequence that when signaled, indicates that the command buffer has + * executed. + */ + +/** + * struct drm_vmw_execbuf_arg + * + * @commands: User-space address of a command buffer cast to an uint64_t. + * @command-size: Size in bytes of the command buffer. + * @fence_rep: User-space address of a struct drm_vmw_fence_rep cast to an + * uint64_t. + * + * Argument to the DRM_VMW_EXECBUF Ioctl. + */ + +struct drm_vmw_execbuf_arg { + uint64_t commands; + uint32_t command_size; + uint32_t pad64; + uint64_t fence_rep; +}; + +/** + * struct drm_vmw_fence_rep + * + * @fence_seq: Fence sequence associated with a command submission. + * @error: This member should've been set to -EFAULT on submission. + * The following actions should be take on completion: + * error == -EFAULT: Fence communication failed. The host is synchronized. + * Use the last fence id read from the FIFO fence register. + * error != 0 && error != -EFAULT: + * Fence submission failed. The host is synchronized. Use the fence_seq member. + * error == 0: All is OK, The host may not be synchronized. + * Use the fence_seq member. + * + * Input / Output data to the DRM_VMW_EXECBUF Ioctl. + */ + +struct drm_vmw_fence_rep { + uint64_t fence_seq; + int32_t error; + uint32_t pad64; +}; + +/*************************************************************************/ +/** + * DRM_VMW_ALLOC_DMABUF + * + * Allocate a DMA buffer that is visible also to the host. + * NOTE: The buffer is + * identified by a handle and an offset, which are private to the guest, but + * useable in the command stream. The guest kernel may translate these + * and patch up the command stream accordingly. In the future, the offset may + * be zero at all times, or it may disappear from the interface before it is + * fixed. + * + * The DMA buffer may stay user-space mapped in the guest at all times, + * and is thus suitable for sub-allocation. + * + * DMA buffers are mapped using the mmap() syscall on the drm device. + */ + +/** + * struct drm_vmw_alloc_dmabuf_req + * + * @size: Required minimum size of the buffer. + * + * Input data to the DRM_VMW_ALLOC_DMABUF Ioctl. + */ + +struct drm_vmw_alloc_dmabuf_req { + uint32_t size; + uint32_t pad64; +}; + +/** + * struct drm_vmw_dmabuf_rep + * + * @map_handle: Offset to use in the mmap() call used to map the buffer. + * @handle: Handle unique to this buffer. Used for unreferencing. + * @cur_gmr_id: GMR id to use in the command stream when this buffer is + * referenced. See not above. + * @cur_gmr_offset: Offset to use in the command stream when this buffer is + * referenced. See note above. + * + * Output data from the DRM_VMW_ALLOC_DMABUF Ioctl. + */ + +struct drm_vmw_dmabuf_rep { + uint64_t map_handle; + uint32_t handle; + uint32_t cur_gmr_id; + uint32_t cur_gmr_offset; + uint32_t pad64; +}; + +/** + * union drm_vmw_dmabuf_arg + * + * @req: Input data as described above. + * @rep: Output data as described above. + * + * Argument to the DRM_VMW_ALLOC_DMABUF Ioctl. + */ + +union drm_vmw_alloc_dmabuf_arg { + struct drm_vmw_alloc_dmabuf_req req; + struct drm_vmw_dmabuf_rep rep; +}; + +/*************************************************************************/ +/** + * DRM_VMW_UNREF_DMABUF - Free a DMA buffer. + * + */ + +/** + * struct drm_vmw_unref_dmabuf_arg + * + * @handle: Handle indicating what buffer to free. Obtained from the + * DRM_VMW_ALLOC_DMABUF Ioctl. + * + * Argument to the DRM_VMW_UNREF_DMABUF Ioctl. + */ + +struct drm_vmw_unref_dmabuf_arg { + uint32_t handle; + uint32_t pad64; +}; + +/*************************************************************************/ +/** + * DRM_VMW_FIFO_DEBUG - Get last FIFO submission. + * + * This IOCTL copies the last FIFO submission directly out of the FIFO buffer. + */ + +/** + * struct drm_vmw_fifo_debug_arg + * + * @debug_buffer: User space address of a debug_buffer cast to an uint64_t //In + * @debug_buffer_size: Size in bytes of debug buffer //In + * @used_size: Number of bytes copied to the buffer // Out + * @did_not_fit: Boolean indicating that the fifo contents did not fit. //Out + * + * Argument to the DRM_VMW_FIFO_DEBUG Ioctl. + */ + +struct drm_vmw_fifo_debug_arg { + uint64_t debug_buffer; + uint32_t debug_buffer_size; + uint32_t used_size; + int32_t did_not_fit; + uint32_t pad64; +}; + +struct drm_vmw_fence_wait_arg { + uint64_t sequence; + uint64_t kernel_cookie; + int32_t cookie_valid; + int32_t pad64; +}; + +/*************************************************************************/ +/** + * DRM_VMW_CONTROL_STREAM - Control overlays, aka streams. + * + * This IOCTL controls the overlay units of the svga device. + * The SVGA overlay units does not work like regular hardware units in + * that they do not automaticaly read back the contents of the given dma + * buffer. But instead only read back for each call to this ioctl, and + * at any point between this call being made and a following call that + * either changes the buffer or disables the stream. + */ + +/** + * struct drm_vmw_rect + * + * Defines a rectangle. Used in the overlay ioctl to define + * source and destination rectangle. + */ + +struct drm_vmw_rect { + int32_t x; + int32_t y; + uint32_t w; + uint32_t h; +}; + +/** + * struct drm_vmw_control_stream_arg + * + * @stream_id: Stearm to control + * @enabled: If false all following arguments are ignored. + * @handle: Handle to buffer for getting data from. + * @format: Format of the overlay as understood by the host. + * @width: Width of the overlay. + * @height: Height of the overlay. + * @size: Size of the overlay in bytes. + * @pitch: Array of pitches, the two last are only used for YUV12 formats. + * @offset: Offset from start of dma buffer to overlay. + * @src: Source rect, must be within the defined area above. + * @dst: Destination rect, x and y may be negative. + * + * Argument to the DRM_VMW_CONTROL_STREAM Ioctl. + */ + +struct drm_vmw_control_stream_arg { + uint32_t stream_id; + uint32_t enabled; + + uint32_t flags; + uint32_t color_key; + + uint32_t handle; + uint32_t offset; + int32_t format; + uint32_t size; + uint32_t width; + uint32_t height; + uint32_t pitch[3]; + + uint32_t pad64; + struct drm_vmw_rect src; + struct drm_vmw_rect dst; +}; + +/*************************************************************************/ +/** + * DRM_VMW_CURSOR_BYPASS - Give extra information about cursor bypass. + * + */ + +#define DRM_VMW_CURSOR_BYPASS_ALL (1 << 0) +#define DRM_VMW_CURSOR_BYPASS_FLAGS (1) + +/** + * struct drm_vmw_cursor_bypass_arg + * + * @flags: Flags. + * @crtc_id: Crtc id, only used if DMR_CURSOR_BYPASS_ALL isn't passed. + * @xpos: X position of cursor. + * @ypos: Y position of cursor. + * @xhot: X hotspot. + * @yhot: Y hotspot. + * + * Argument to the DRM_VMW_CURSOR_BYPASS Ioctl. + */ + +struct drm_vmw_cursor_bypass_arg { + uint32_t flags; + uint32_t crtc_id; + int32_t xpos; + int32_t ypos; + int32_t xhot; + int32_t yhot; +}; + +/*************************************************************************/ +/** + * DRM_VMW_CLAIM_STREAM - Claim a single stream. + */ + +/** + * struct drm_vmw_context_arg + * + * @stream_id: Device unique context ID. + * + * Output argument to the DRM_VMW_CREATE_CONTEXT Ioctl. + * Input argument to the DRM_VMW_UNREF_CONTEXT Ioctl. + */ + +struct drm_vmw_stream_arg { + uint32_t stream_id; + uint32_t pad64; +}; + +/*************************************************************************/ +/** + * DRM_VMW_UNREF_STREAM - Unclaim a stream. + * + * Return a single stream that was claimed by this process. Also makes + * sure that the stream has been stopped. + */ + +#endif -- cgit v0.10.2 From b7b40ade58e621851896aa261452df99d4e9d99b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 9 Nov 2009 21:01:59 +0100 Subject: locking: Reorder functions in spinlock.c Separate spin_lock and rw_lock functions. Preempt-RT needs to exclude the rw_lock functions from being compiled. The reordering allows to do that with a single #ifdef. No functional change. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/kernel/spinlock.c b/kernel/spinlock.c index 41e0422..e6e1363 100644 --- a/kernel/spinlock.c +++ b/kernel/spinlock.c @@ -113,41 +113,6 @@ BUILD_LOCK_OPS(write, rwlock); #endif -#ifdef CONFIG_DEBUG_LOCK_ALLOC - -void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass) -{ - preempt_disable(); - spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); -} -EXPORT_SYMBOL(_spin_lock_nested); - -unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, - int subclass) -{ - unsigned long flags; - - local_irq_save(flags); - preempt_disable(); - spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); - LOCK_CONTENDED_FLAGS(lock, _raw_spin_trylock, _raw_spin_lock, - _raw_spin_lock_flags, &flags); - return flags; -} -EXPORT_SYMBOL(_spin_lock_irqsave_nested); - -void __lockfunc _spin_lock_nest_lock(spinlock_t *lock, - struct lockdep_map *nest_lock) -{ - preempt_disable(); - spin_acquire_nest(&lock->dep_map, 0, 0, nest_lock, _RET_IP_); - LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); -} -EXPORT_SYMBOL(_spin_lock_nest_lock); - -#endif - #ifndef CONFIG_INLINE_SPIN_TRYLOCK int __lockfunc _spin_trylock(spinlock_t *lock) { @@ -156,28 +121,20 @@ int __lockfunc _spin_trylock(spinlock_t *lock) EXPORT_SYMBOL(_spin_trylock); #endif -#ifndef CONFIG_INLINE_READ_TRYLOCK -int __lockfunc _read_trylock(rwlock_t *lock) -{ - return __read_trylock(lock); -} -EXPORT_SYMBOL(_read_trylock); -#endif - -#ifndef CONFIG_INLINE_WRITE_TRYLOCK -int __lockfunc _write_trylock(rwlock_t *lock) +#ifndef CONFIG_INLINE_SPIN_TRYLOCK_BH +int __lockfunc _spin_trylock_bh(spinlock_t *lock) { - return __write_trylock(lock); + return __spin_trylock_bh(lock); } -EXPORT_SYMBOL(_write_trylock); +EXPORT_SYMBOL(_spin_trylock_bh); #endif -#ifndef CONFIG_INLINE_READ_LOCK -void __lockfunc _read_lock(rwlock_t *lock) +#ifndef CONFIG_INLINE_SPIN_LOCK +void __lockfunc _spin_lock(spinlock_t *lock) { - __read_lock(lock); + __spin_lock(lock); } -EXPORT_SYMBOL(_read_lock); +EXPORT_SYMBOL(_spin_lock); #endif #ifndef CONFIG_INLINE_SPIN_LOCK_IRQSAVE @@ -204,84 +161,76 @@ void __lockfunc _spin_lock_bh(spinlock_t *lock) EXPORT_SYMBOL(_spin_lock_bh); #endif -#ifndef CONFIG_INLINE_READ_LOCK_IRQSAVE -unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock) -{ - return __read_lock_irqsave(lock); -} -EXPORT_SYMBOL(_read_lock_irqsave); -#endif - -#ifndef CONFIG_INLINE_READ_LOCK_IRQ -void __lockfunc _read_lock_irq(rwlock_t *lock) +#ifndef CONFIG_INLINE_SPIN_UNLOCK +void __lockfunc _spin_unlock(spinlock_t *lock) { - __read_lock_irq(lock); + __spin_unlock(lock); } -EXPORT_SYMBOL(_read_lock_irq); +EXPORT_SYMBOL(_spin_unlock); #endif -#ifndef CONFIG_INLINE_READ_LOCK_BH -void __lockfunc _read_lock_bh(rwlock_t *lock) +#ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE +void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) { - __read_lock_bh(lock); + __spin_unlock_irqrestore(lock, flags); } -EXPORT_SYMBOL(_read_lock_bh); +EXPORT_SYMBOL(_spin_unlock_irqrestore); #endif -#ifndef CONFIG_INLINE_WRITE_LOCK_IRQSAVE -unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock) +#ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQ +void __lockfunc _spin_unlock_irq(spinlock_t *lock) { - return __write_lock_irqsave(lock); + __spin_unlock_irq(lock); } -EXPORT_SYMBOL(_write_lock_irqsave); +EXPORT_SYMBOL(_spin_unlock_irq); #endif -#ifndef CONFIG_INLINE_WRITE_LOCK_IRQ -void __lockfunc _write_lock_irq(rwlock_t *lock) +#ifndef CONFIG_INLINE_SPIN_UNLOCK_BH +void __lockfunc _spin_unlock_bh(spinlock_t *lock) { - __write_lock_irq(lock); + __spin_unlock_bh(lock); } -EXPORT_SYMBOL(_write_lock_irq); +EXPORT_SYMBOL(_spin_unlock_bh); #endif -#ifndef CONFIG_INLINE_WRITE_LOCK_BH -void __lockfunc _write_lock_bh(rwlock_t *lock) +#ifndef CONFIG_INLINE_READ_TRYLOCK +int __lockfunc _read_trylock(rwlock_t *lock) { - __write_lock_bh(lock); + return __read_trylock(lock); } -EXPORT_SYMBOL(_write_lock_bh); +EXPORT_SYMBOL(_read_trylock); #endif -#ifndef CONFIG_INLINE_SPIN_LOCK -void __lockfunc _spin_lock(spinlock_t *lock) +#ifndef CONFIG_INLINE_READ_LOCK +void __lockfunc _read_lock(rwlock_t *lock) { - __spin_lock(lock); + __read_lock(lock); } -EXPORT_SYMBOL(_spin_lock); +EXPORT_SYMBOL(_read_lock); #endif -#ifndef CONFIG_INLINE_WRITE_LOCK -void __lockfunc _write_lock(rwlock_t *lock) +#ifndef CONFIG_INLINE_READ_LOCK_IRQSAVE +unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock) { - __write_lock(lock); + return __read_lock_irqsave(lock); } -EXPORT_SYMBOL(_write_lock); +EXPORT_SYMBOL(_read_lock_irqsave); #endif -#ifndef CONFIG_INLINE_SPIN_UNLOCK -void __lockfunc _spin_unlock(spinlock_t *lock) +#ifndef CONFIG_INLINE_READ_LOCK_IRQ +void __lockfunc _read_lock_irq(rwlock_t *lock) { - __spin_unlock(lock); + __read_lock_irq(lock); } -EXPORT_SYMBOL(_spin_unlock); +EXPORT_SYMBOL(_read_lock_irq); #endif -#ifndef CONFIG_INLINE_WRITE_UNLOCK -void __lockfunc _write_unlock(rwlock_t *lock) +#ifndef CONFIG_INLINE_READ_LOCK_BH +void __lockfunc _read_lock_bh(rwlock_t *lock) { - __write_unlock(lock); + __read_lock_bh(lock); } -EXPORT_SYMBOL(_write_unlock); +EXPORT_SYMBOL(_read_lock_bh); #endif #ifndef CONFIG_INLINE_READ_UNLOCK @@ -292,30 +241,6 @@ void __lockfunc _read_unlock(rwlock_t *lock) EXPORT_SYMBOL(_read_unlock); #endif -#ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE -void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) -{ - __spin_unlock_irqrestore(lock, flags); -} -EXPORT_SYMBOL(_spin_unlock_irqrestore); -#endif - -#ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQ -void __lockfunc _spin_unlock_irq(spinlock_t *lock) -{ - __spin_unlock_irq(lock); -} -EXPORT_SYMBOL(_spin_unlock_irq); -#endif - -#ifndef CONFIG_INLINE_SPIN_UNLOCK_BH -void __lockfunc _spin_unlock_bh(spinlock_t *lock) -{ - __spin_unlock_bh(lock); -} -EXPORT_SYMBOL(_spin_unlock_bh); -#endif - #ifndef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) { @@ -340,6 +265,54 @@ void __lockfunc _read_unlock_bh(rwlock_t *lock) EXPORT_SYMBOL(_read_unlock_bh); #endif +#ifndef CONFIG_INLINE_WRITE_TRYLOCK +int __lockfunc _write_trylock(rwlock_t *lock) +{ + return __write_trylock(lock); +} +EXPORT_SYMBOL(_write_trylock); +#endif + +#ifndef CONFIG_INLINE_WRITE_LOCK +void __lockfunc _write_lock(rwlock_t *lock) +{ + __write_lock(lock); +} +EXPORT_SYMBOL(_write_lock); +#endif + +#ifndef CONFIG_INLINE_WRITE_LOCK_IRQSAVE +unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock) +{ + return __write_lock_irqsave(lock); +} +EXPORT_SYMBOL(_write_lock_irqsave); +#endif + +#ifndef CONFIG_INLINE_WRITE_LOCK_IRQ +void __lockfunc _write_lock_irq(rwlock_t *lock) +{ + __write_lock_irq(lock); +} +EXPORT_SYMBOL(_write_lock_irq); +#endif + +#ifndef CONFIG_INLINE_WRITE_LOCK_BH +void __lockfunc _write_lock_bh(rwlock_t *lock) +{ + __write_lock_bh(lock); +} +EXPORT_SYMBOL(_write_lock_bh); +#endif + +#ifndef CONFIG_INLINE_WRITE_UNLOCK +void __lockfunc _write_unlock(rwlock_t *lock) +{ + __write_unlock(lock); +} +EXPORT_SYMBOL(_write_unlock); +#endif + #ifndef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) { @@ -364,12 +337,39 @@ void __lockfunc _write_unlock_bh(rwlock_t *lock) EXPORT_SYMBOL(_write_unlock_bh); #endif -#ifndef CONFIG_INLINE_SPIN_TRYLOCK_BH -int __lockfunc _spin_trylock_bh(spinlock_t *lock) +#ifdef CONFIG_DEBUG_LOCK_ALLOC + +void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass) { - return __spin_trylock_bh(lock); + preempt_disable(); + spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); + LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); } -EXPORT_SYMBOL(_spin_trylock_bh); +EXPORT_SYMBOL(_spin_lock_nested); + +unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, + int subclass) +{ + unsigned long flags; + + local_irq_save(flags); + preempt_disable(); + spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); + LOCK_CONTENDED_FLAGS(lock, _raw_spin_trylock, _raw_spin_lock, + _raw_spin_lock_flags, &flags); + return flags; +} +EXPORT_SYMBOL(_spin_lock_irqsave_nested); + +void __lockfunc _spin_lock_nest_lock(spinlock_t *lock, + struct lockdep_map *nest_lock) +{ + preempt_disable(); + spin_acquire_nest(&lock->dep_map, 0, 0, nest_lock, _RET_IP_); + LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); +} +EXPORT_SYMBOL(_spin_lock_nest_lock); + #endif notrace int in_lock_functions(unsigned long addr) -- cgit v0.10.2 From ef12f10994281e2e44526fa0abf23fdd7d5bd87f Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 7 Nov 2009 23:04:15 +0100 Subject: locking: Split rwlock from spinlock headers Move the rwlock defines and inlines into separate header files. This makes the selection for -rt easier. No functional change. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h new file mode 100644 index 0000000..73785b0 --- /dev/null +++ b/include/linux/rwlock.h @@ -0,0 +1,125 @@ +#ifndef __LINUX_RWLOCK_H +#define __LINUX_RWLOCK_H + +#ifndef __LINUX_SPINLOCK_H +# error "please don't include this file directly" +#endif + +/* + * rwlock related methods + * + * split out from spinlock.h + * + * portions Copyright 2005, Red Hat, Inc., Ingo Molnar + * Released under the General Public License (GPL). + */ + +#ifdef CONFIG_DEBUG_SPINLOCK + extern void __rwlock_init(rwlock_t *lock, const char *name, + struct lock_class_key *key); +# define rwlock_init(lock) \ +do { \ + static struct lock_class_key __key; \ + \ + __rwlock_init((lock), #lock, &__key); \ +} while (0) +#else +# define rwlock_init(lock) \ + do { *(lock) = __RW_LOCK_UNLOCKED(lock); } while (0) +#endif + +#ifdef CONFIG_DEBUG_SPINLOCK + extern void _raw_read_lock(rwlock_t *lock); +#define _raw_read_lock_flags(lock, flags) _raw_read_lock(lock) + extern int _raw_read_trylock(rwlock_t *lock); + extern void _raw_read_unlock(rwlock_t *lock); + extern void _raw_write_lock(rwlock_t *lock); +#define _raw_write_lock_flags(lock, flags) _raw_write_lock(lock) + extern int _raw_write_trylock(rwlock_t *lock); + extern void _raw_write_unlock(rwlock_t *lock); +#else +# define _raw_read_lock(rwlock) __raw_read_lock(&(rwlock)->raw_lock) +# define _raw_read_lock_flags(lock, flags) \ + __raw_read_lock_flags(&(lock)->raw_lock, *(flags)) +# define _raw_read_trylock(rwlock) __raw_read_trylock(&(rwlock)->raw_lock) +# define _raw_read_unlock(rwlock) __raw_read_unlock(&(rwlock)->raw_lock) +# define _raw_write_lock(rwlock) __raw_write_lock(&(rwlock)->raw_lock) +# define _raw_write_lock_flags(lock, flags) \ + __raw_write_lock_flags(&(lock)->raw_lock, *(flags)) +# define _raw_write_trylock(rwlock) __raw_write_trylock(&(rwlock)->raw_lock) +# define _raw_write_unlock(rwlock) __raw_write_unlock(&(rwlock)->raw_lock) +#endif + +#define read_can_lock(rwlock) __raw_read_can_lock(&(rwlock)->raw_lock) +#define write_can_lock(rwlock) __raw_write_can_lock(&(rwlock)->raw_lock) + +/* + * Define the various rw_lock methods. Note we define these + * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various + * methods are defined as nops in the case they are not required. + */ +#define read_trylock(lock) __cond_lock(lock, _read_trylock(lock)) +#define write_trylock(lock) __cond_lock(lock, _write_trylock(lock)) + +#define write_lock(lock) _write_lock(lock) +#define read_lock(lock) _read_lock(lock) + +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) + +#define read_lock_irqsave(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + flags = _read_lock_irqsave(lock); \ + } while (0) +#define write_lock_irqsave(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + flags = _write_lock_irqsave(lock); \ + } while (0) + +#else + +#define read_lock_irqsave(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _read_lock_irqsave(lock, flags); \ + } while (0) +#define write_lock_irqsave(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _write_lock_irqsave(lock, flags); \ + } while (0) + +#endif + +#define read_lock_irq(lock) _read_lock_irq(lock) +#define read_lock_bh(lock) _read_lock_bh(lock) +#define write_lock_irq(lock) _write_lock_irq(lock) +#define write_lock_bh(lock) _write_lock_bh(lock) +#define read_unlock(lock) _read_unlock(lock) +#define write_unlock(lock) _write_unlock(lock) +#define read_unlock_irq(lock) _read_unlock_irq(lock) +#define write_unlock_irq(lock) _write_unlock_irq(lock) + +#define read_unlock_irqrestore(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _read_unlock_irqrestore(lock, flags); \ + } while (0) +#define read_unlock_bh(lock) _read_unlock_bh(lock) + +#define write_unlock_irqrestore(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _write_unlock_irqrestore(lock, flags); \ + } while (0) +#define write_unlock_bh(lock) _write_unlock_bh(lock) + +#define write_trylock_irqsave(lock, flags) \ +({ \ + local_irq_save(flags); \ + write_trylock(lock) ? \ + 1 : ({ local_irq_restore(flags); 0; }); \ +}) + +#endif /* __LINUX_RWLOCK_H */ diff --git a/include/linux/rwlock_types.h b/include/linux/rwlock_types.h new file mode 100644 index 0000000..f8c9352 --- /dev/null +++ b/include/linux/rwlock_types.h @@ -0,0 +1,56 @@ +#ifndef __LINUX_RWLOCK_TYPES_H +#define __LINUX_RWLOCK_TYPES_H + +/* + * include/linux/rwlock_types.h - generic rwlock type definitions + * and initializers + * + * portions Copyright 2005, Red Hat, Inc., Ingo Molnar + * Released under the General Public License (GPL). + */ +typedef struct { + raw_rwlock_t raw_lock; +#ifdef CONFIG_GENERIC_LOCKBREAK + unsigned int break_lock; +#endif +#ifdef CONFIG_DEBUG_SPINLOCK + unsigned int magic, owner_cpu; + void *owner; +#endif +#ifdef CONFIG_DEBUG_LOCK_ALLOC + struct lockdep_map dep_map; +#endif +} rwlock_t; + +#define RWLOCK_MAGIC 0xdeaf1eed + +#ifdef CONFIG_DEBUG_LOCK_ALLOC +# define RW_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname } +#else +# define RW_DEP_MAP_INIT(lockname) +#endif + +#ifdef CONFIG_DEBUG_SPINLOCK +#define __RW_LOCK_UNLOCKED(lockname) \ + (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \ + .magic = RWLOCK_MAGIC, \ + .owner = SPINLOCK_OWNER_INIT, \ + .owner_cpu = -1, \ + RW_DEP_MAP_INIT(lockname) } +#else +#define __RW_LOCK_UNLOCKED(lockname) \ + (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \ + RW_DEP_MAP_INIT(lockname) } +#endif + +/* + * RW_LOCK_UNLOCKED defeat lockdep state tracking and is hence + * deprecated. + * + * Please use DEFINE_RWLOCK() or __RW_LOCK_UNLOCKED() as appropriate. + */ +#define RW_LOCK_UNLOCKED __RW_LOCK_UNLOCKED(old_style_rw_init) + +#define DEFINE_RWLOCK(x) rwlock_t x = __RW_LOCK_UNLOCKED(x) + +#endif /* __LINUX_RWLOCK_TYPES_H */ diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 71dccfe..a9aaa70 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -103,20 +103,6 @@ do { \ do { *(lock) = __SPIN_LOCK_UNLOCKED(lock); } while (0) #endif -#ifdef CONFIG_DEBUG_SPINLOCK - extern void __rwlock_init(rwlock_t *lock, const char *name, - struct lock_class_key *key); -# define rwlock_init(lock) \ -do { \ - static struct lock_class_key __key; \ - \ - __rwlock_init((lock), #lock, &__key); \ -} while (0) -#else -# define rwlock_init(lock) \ - do { *(lock) = __RW_LOCK_UNLOCKED(lock); } while (0) -#endif - #define spin_is_locked(lock) __raw_spin_is_locked(&(lock)->raw_lock) #ifdef CONFIG_GENERIC_LOCKBREAK @@ -146,43 +132,21 @@ static inline void smp_mb__after_lock(void) { smp_mb(); } #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) extern int _raw_spin_trylock(spinlock_t *lock); extern void _raw_spin_unlock(spinlock_t *lock); - extern void _raw_read_lock(rwlock_t *lock); -#define _raw_read_lock_flags(lock, flags) _raw_read_lock(lock) - extern int _raw_read_trylock(rwlock_t *lock); - extern void _raw_read_unlock(rwlock_t *lock); - extern void _raw_write_lock(rwlock_t *lock); -#define _raw_write_lock_flags(lock, flags) _raw_write_lock(lock) - extern int _raw_write_trylock(rwlock_t *lock); - extern void _raw_write_unlock(rwlock_t *lock); #else # define _raw_spin_lock(lock) __raw_spin_lock(&(lock)->raw_lock) # define _raw_spin_lock_flags(lock, flags) \ __raw_spin_lock_flags(&(lock)->raw_lock, *(flags)) # define _raw_spin_trylock(lock) __raw_spin_trylock(&(lock)->raw_lock) # define _raw_spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock) -# define _raw_read_lock(rwlock) __raw_read_lock(&(rwlock)->raw_lock) -# define _raw_read_lock_flags(lock, flags) \ - __raw_read_lock_flags(&(lock)->raw_lock, *(flags)) -# define _raw_read_trylock(rwlock) __raw_read_trylock(&(rwlock)->raw_lock) -# define _raw_read_unlock(rwlock) __raw_read_unlock(&(rwlock)->raw_lock) -# define _raw_write_lock(rwlock) __raw_write_lock(&(rwlock)->raw_lock) -# define _raw_write_lock_flags(lock, flags) \ - __raw_write_lock_flags(&(lock)->raw_lock, *(flags)) -# define _raw_write_trylock(rwlock) __raw_write_trylock(&(rwlock)->raw_lock) -# define _raw_write_unlock(rwlock) __raw_write_unlock(&(rwlock)->raw_lock) #endif -#define read_can_lock(rwlock) __raw_read_can_lock(&(rwlock)->raw_lock) -#define write_can_lock(rwlock) __raw_write_can_lock(&(rwlock)->raw_lock) - /* - * Define the various spin_lock and rw_lock methods. Note we define these - * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various - * methods are defined as nops in the case they are not required. + * Define the various spin_lock methods. Note we define these + * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The + * various methods are defined as nops in the case they are not + * required. */ #define spin_trylock(lock) __cond_lock(lock, _spin_trylock(lock)) -#define read_trylock(lock) __cond_lock(lock, _read_trylock(lock)) -#define write_trylock(lock) __cond_lock(lock, _write_trylock(lock)) #define spin_lock(lock) _spin_lock(lock) @@ -198,9 +162,6 @@ static inline void smp_mb__after_lock(void) { smp_mb(); } # define spin_lock_nest_lock(lock, nest_lock) _spin_lock(lock) #endif -#define write_lock(lock) _write_lock(lock) -#define read_lock(lock) _read_lock(lock) - #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) #define spin_lock_irqsave(lock, flags) \ @@ -208,16 +169,6 @@ static inline void smp_mb__after_lock(void) { smp_mb(); } typecheck(unsigned long, flags); \ flags = _spin_lock_irqsave(lock); \ } while (0) -#define read_lock_irqsave(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ - flags = _read_lock_irqsave(lock); \ - } while (0) -#define write_lock_irqsave(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ - flags = _write_lock_irqsave(lock); \ - } while (0) #ifdef CONFIG_DEBUG_LOCK_ALLOC #define spin_lock_irqsave_nested(lock, flags, subclass) \ @@ -240,16 +191,7 @@ static inline void smp_mb__after_lock(void) { smp_mb(); } typecheck(unsigned long, flags); \ _spin_lock_irqsave(lock, flags); \ } while (0) -#define read_lock_irqsave(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ - _read_lock_irqsave(lock, flags); \ - } while (0) -#define write_lock_irqsave(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ - _write_lock_irqsave(lock, flags); \ - } while (0) + #define spin_lock_irqsave_nested(lock, flags, subclass) \ spin_lock_irqsave(lock, flags) @@ -257,16 +199,8 @@ static inline void smp_mb__after_lock(void) { smp_mb(); } #define spin_lock_irq(lock) _spin_lock_irq(lock) #define spin_lock_bh(lock) _spin_lock_bh(lock) -#define read_lock_irq(lock) _read_lock_irq(lock) -#define read_lock_bh(lock) _read_lock_bh(lock) -#define write_lock_irq(lock) _write_lock_irq(lock) -#define write_lock_bh(lock) _write_lock_bh(lock) #define spin_unlock(lock) _spin_unlock(lock) -#define read_unlock(lock) _read_unlock(lock) -#define write_unlock(lock) _write_unlock(lock) #define spin_unlock_irq(lock) _spin_unlock_irq(lock) -#define read_unlock_irq(lock) _read_unlock_irq(lock) -#define write_unlock_irq(lock) _write_unlock_irq(lock) #define spin_unlock_irqrestore(lock, flags) \ do { \ @@ -275,20 +209,6 @@ static inline void smp_mb__after_lock(void) { smp_mb(); } } while (0) #define spin_unlock_bh(lock) _spin_unlock_bh(lock) -#define read_unlock_irqrestore(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ - _read_unlock_irqrestore(lock, flags); \ - } while (0) -#define read_unlock_bh(lock) _read_unlock_bh(lock) - -#define write_unlock_irqrestore(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ - _write_unlock_irqrestore(lock, flags); \ - } while (0) -#define write_unlock_bh(lock) _write_unlock_bh(lock) - #define spin_trylock_bh(lock) __cond_lock(lock, _spin_trylock_bh(lock)) #define spin_trylock_irq(lock) \ @@ -305,13 +225,6 @@ static inline void smp_mb__after_lock(void) { smp_mb(); } 1 : ({ local_irq_restore(flags); 0; }); \ }) -#define write_trylock_irqsave(lock, flags) \ -({ \ - local_irq_save(flags); \ - write_trylock(lock) ? \ - 1 : ({ local_irq_restore(flags); 0; }); \ -}) - /* * Pull the atomic_t declaration: * (asm-mips/atomic.h needs above definitions) @@ -335,6 +248,9 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); */ #define spin_can_lock(lock) (!spin_is_locked(lock)) +/* Include rwlock functions */ +#include + /* * Pull the _spin_*()/_read_*()/_write_*() functions/declarations: */ diff --git a/include/linux/spinlock_types.h b/include/linux/spinlock_types.h index 68d88f7..f979d5d 100644 --- a/include/linux/spinlock_types.h +++ b/include/linux/spinlock_types.h @@ -33,22 +33,6 @@ typedef struct { #define SPINLOCK_MAGIC 0xdead4ead -typedef struct { - raw_rwlock_t raw_lock; -#ifdef CONFIG_GENERIC_LOCKBREAK - unsigned int break_lock; -#endif -#ifdef CONFIG_DEBUG_SPINLOCK - unsigned int magic, owner_cpu; - void *owner; -#endif -#ifdef CONFIG_DEBUG_LOCK_ALLOC - struct lockdep_map dep_map; -#endif -} rwlock_t; - -#define RWLOCK_MAGIC 0xdeaf1eed - #define SPINLOCK_OWNER_INIT ((void *)-1L) #ifdef CONFIG_DEBUG_LOCK_ALLOC @@ -57,12 +41,6 @@ typedef struct { # define SPIN_DEP_MAP_INIT(lockname) #endif -#ifdef CONFIG_DEBUG_LOCK_ALLOC -# define RW_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname } -#else -# define RW_DEP_MAP_INIT(lockname) -#endif - #ifdef CONFIG_DEBUG_SPINLOCK # define __SPIN_LOCK_UNLOCKED(lockname) \ (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED, \ @@ -70,31 +48,22 @@ typedef struct { .owner = SPINLOCK_OWNER_INIT, \ .owner_cpu = -1, \ SPIN_DEP_MAP_INIT(lockname) } -#define __RW_LOCK_UNLOCKED(lockname) \ - (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \ - .magic = RWLOCK_MAGIC, \ - .owner = SPINLOCK_OWNER_INIT, \ - .owner_cpu = -1, \ - RW_DEP_MAP_INIT(lockname) } #else # define __SPIN_LOCK_UNLOCKED(lockname) \ (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED, \ SPIN_DEP_MAP_INIT(lockname) } -#define __RW_LOCK_UNLOCKED(lockname) \ - (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \ - RW_DEP_MAP_INIT(lockname) } #endif /* - * SPIN_LOCK_UNLOCKED and RW_LOCK_UNLOCKED defeat lockdep state tracking and - * are hence deprecated. - * Please use DEFINE_SPINLOCK()/DEFINE_RWLOCK() or - * __SPIN_LOCK_UNLOCKED()/__RW_LOCK_UNLOCKED() as appropriate. + * SPIN_LOCK_UNLOCKED defeats lockdep state tracking and is hence + * deprecated. + * Please use DEFINE_SPINLOCK() or __SPIN_LOCK_UNLOCKED() as + * appropriate. */ #define SPIN_LOCK_UNLOCKED __SPIN_LOCK_UNLOCKED(old_style_spin_init) -#define RW_LOCK_UNLOCKED __RW_LOCK_UNLOCKED(old_style_rw_init) #define DEFINE_SPINLOCK(x) spinlock_t x = __SPIN_LOCK_UNLOCKED(x) -#define DEFINE_RWLOCK(x) rwlock_t x = __RW_LOCK_UNLOCKED(x) + +#include #endif /* __LINUX_SPINLOCK_TYPES_H */ -- cgit v0.10.2 From 6b6b4792f89346e47437682c7ba3438e6681c0f9 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 16 Nov 2009 18:48:37 +0100 Subject: locking: Separate rwlock api from spinlock api Move the rwlock smp api defines and functions into a separate header file. Makes the -rt selection simpler and less intrusive. No functional change. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/include/linux/rwlock_api_smp.h b/include/linux/rwlock_api_smp.h new file mode 100644 index 0000000..090f876 --- /dev/null +++ b/include/linux/rwlock_api_smp.h @@ -0,0 +1,277 @@ +#ifndef __LINUX_RWLOCK_API_SMP_H +#define __LINUX_RWLOCK_API_SMP_H + +#ifndef __LINUX_SPINLOCK_API_SMP_H +# error "please don't include this file directly" +#endif + +/* + * include/linux/rwlock_api_smp.h + * + * spinlock API declarations on SMP (and debug) + * (implemented in kernel/spinlock.c) + * + * portions Copyright 2005, Red Hat, Inc., Ingo Molnar + * Released under the General Public License (GPL). + */ + +void __lockfunc _read_lock(rwlock_t *lock) __acquires(lock); +void __lockfunc _write_lock(rwlock_t *lock) __acquires(lock); +void __lockfunc _read_lock_bh(rwlock_t *lock) __acquires(lock); +void __lockfunc _write_lock_bh(rwlock_t *lock) __acquires(lock); +void __lockfunc _read_lock_irq(rwlock_t *lock) __acquires(lock); +void __lockfunc _write_lock_irq(rwlock_t *lock) __acquires(lock); +unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock) + __acquires(lock); +unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock) + __acquires(lock); +int __lockfunc _read_trylock(rwlock_t *lock); +int __lockfunc _write_trylock(rwlock_t *lock); +void __lockfunc _read_unlock(rwlock_t *lock) __releases(lock); +void __lockfunc _write_unlock(rwlock_t *lock) __releases(lock); +void __lockfunc _read_unlock_bh(rwlock_t *lock) __releases(lock); +void __lockfunc _write_unlock_bh(rwlock_t *lock) __releases(lock); +void __lockfunc _read_unlock_irq(rwlock_t *lock) __releases(lock); +void __lockfunc _write_unlock_irq(rwlock_t *lock) __releases(lock); +void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) + __releases(lock); +void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) + __releases(lock); + +#ifdef CONFIG_INLINE_READ_LOCK +#define _read_lock(lock) __read_lock(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_LOCK +#define _write_lock(lock) __write_lock(lock) +#endif + +#ifdef CONFIG_INLINE_READ_LOCK_BH +#define _read_lock_bh(lock) __read_lock_bh(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_LOCK_BH +#define _write_lock_bh(lock) __write_lock_bh(lock) +#endif + +#ifdef CONFIG_INLINE_READ_LOCK_IRQ +#define _read_lock_irq(lock) __read_lock_irq(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_LOCK_IRQ +#define _write_lock_irq(lock) __write_lock_irq(lock) +#endif + +#ifdef CONFIG_INLINE_READ_LOCK_IRQSAVE +#define _read_lock_irqsave(lock) __read_lock_irqsave(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_LOCK_IRQSAVE +#define _write_lock_irqsave(lock) __write_lock_irqsave(lock) +#endif + +#ifdef CONFIG_INLINE_READ_TRYLOCK +#define _read_trylock(lock) __read_trylock(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_TRYLOCK +#define _write_trylock(lock) __write_trylock(lock) +#endif + +#ifdef CONFIG_INLINE_READ_UNLOCK +#define _read_unlock(lock) __read_unlock(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_UNLOCK +#define _write_unlock(lock) __write_unlock(lock) +#endif + +#ifdef CONFIG_INLINE_READ_UNLOCK_BH +#define _read_unlock_bh(lock) __read_unlock_bh(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_UNLOCK_BH +#define _write_unlock_bh(lock) __write_unlock_bh(lock) +#endif + +#ifdef CONFIG_INLINE_READ_UNLOCK_IRQ +#define _read_unlock_irq(lock) __read_unlock_irq(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQ +#define _write_unlock_irq(lock) __write_unlock_irq(lock) +#endif + +#ifdef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE +#define _read_unlock_irqrestore(lock, flags) __read_unlock_irqrestore(lock, flags) +#endif + +#ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE +#define _write_unlock_irqrestore(lock, flags) __write_unlock_irqrestore(lock, flags) +#endif + +static inline int __read_trylock(rwlock_t *lock) +{ + preempt_disable(); + if (_raw_read_trylock(lock)) { + rwlock_acquire_read(&lock->dep_map, 0, 1, _RET_IP_); + return 1; + } + preempt_enable(); + return 0; +} + +static inline int __write_trylock(rwlock_t *lock) +{ + preempt_disable(); + if (_raw_write_trylock(lock)) { + rwlock_acquire(&lock->dep_map, 0, 1, _RET_IP_); + return 1; + } + preempt_enable(); + return 0; +} + +/* + * If lockdep is enabled then we use the non-preemption spin-ops + * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are + * not re-enabled during lock-acquire (which the preempt-spin-ops do): + */ +#if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC) + +static inline void __read_lock(rwlock_t *lock) +{ + preempt_disable(); + rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); +} + +static inline unsigned long __read_lock_irqsave(rwlock_t *lock) +{ + unsigned long flags; + + local_irq_save(flags); + preempt_disable(); + rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED_FLAGS(lock, _raw_read_trylock, _raw_read_lock, + _raw_read_lock_flags, &flags); + return flags; +} + +static inline void __read_lock_irq(rwlock_t *lock) +{ + local_irq_disable(); + preempt_disable(); + rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); +} + +static inline void __read_lock_bh(rwlock_t *lock) +{ + local_bh_disable(); + preempt_disable(); + rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); +} + +static inline unsigned long __write_lock_irqsave(rwlock_t *lock) +{ + unsigned long flags; + + local_irq_save(flags); + preempt_disable(); + rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED_FLAGS(lock, _raw_write_trylock, _raw_write_lock, + _raw_write_lock_flags, &flags); + return flags; +} + +static inline void __write_lock_irq(rwlock_t *lock) +{ + local_irq_disable(); + preempt_disable(); + rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED(lock, _raw_write_trylock, _raw_write_lock); +} + +static inline void __write_lock_bh(rwlock_t *lock) +{ + local_bh_disable(); + preempt_disable(); + rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED(lock, _raw_write_trylock, _raw_write_lock); +} + +static inline void __write_lock(rwlock_t *lock) +{ + preempt_disable(); + rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED(lock, _raw_write_trylock, _raw_write_lock); +} + +#endif /* CONFIG_PREEMPT */ + +static inline void __write_unlock(rwlock_t *lock) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + _raw_write_unlock(lock); + preempt_enable(); +} + +static inline void __read_unlock(rwlock_t *lock) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + _raw_read_unlock(lock); + preempt_enable(); +} + +static inline void __read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + _raw_read_unlock(lock); + local_irq_restore(flags); + preempt_enable(); +} + +static inline void __read_unlock_irq(rwlock_t *lock) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + _raw_read_unlock(lock); + local_irq_enable(); + preempt_enable(); +} + +static inline void __read_unlock_bh(rwlock_t *lock) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + _raw_read_unlock(lock); + preempt_enable_no_resched(); + local_bh_enable_ip((unsigned long)__builtin_return_address(0)); +} + +static inline void __write_unlock_irqrestore(rwlock_t *lock, + unsigned long flags) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + _raw_write_unlock(lock); + local_irq_restore(flags); + preempt_enable(); +} + +static inline void __write_unlock_irq(rwlock_t *lock) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + _raw_write_unlock(lock); + local_irq_enable(); + preempt_enable(); +} + +static inline void __write_unlock_bh(rwlock_t *lock) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + _raw_write_unlock(lock); + preempt_enable_no_resched(); + local_bh_enable_ip((unsigned long)__builtin_return_address(0)); +} + +#endif /* __LINUX_RWLOCK_API_SMP_H */ diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h index 8264a7f..a2b2c9d 100644 --- a/include/linux/spinlock_api_smp.h +++ b/include/linux/spinlock_api_smp.h @@ -24,102 +24,41 @@ void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass) __acquires(lock); void __lockfunc _spin_lock_nest_lock(spinlock_t *lock, struct lockdep_map *map) __acquires(lock); -void __lockfunc _read_lock(rwlock_t *lock) __acquires(lock); -void __lockfunc _write_lock(rwlock_t *lock) __acquires(lock); void __lockfunc _spin_lock_bh(spinlock_t *lock) __acquires(lock); -void __lockfunc _read_lock_bh(rwlock_t *lock) __acquires(lock); -void __lockfunc _write_lock_bh(rwlock_t *lock) __acquires(lock); void __lockfunc _spin_lock_irq(spinlock_t *lock) __acquires(lock); -void __lockfunc _read_lock_irq(rwlock_t *lock) __acquires(lock); -void __lockfunc _write_lock_irq(rwlock_t *lock) __acquires(lock); + unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock) __acquires(lock); unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, int subclass) __acquires(lock); -unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock) - __acquires(lock); -unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock) - __acquires(lock); int __lockfunc _spin_trylock(spinlock_t *lock); -int __lockfunc _read_trylock(rwlock_t *lock); -int __lockfunc _write_trylock(rwlock_t *lock); int __lockfunc _spin_trylock_bh(spinlock_t *lock); void __lockfunc _spin_unlock(spinlock_t *lock) __releases(lock); -void __lockfunc _read_unlock(rwlock_t *lock) __releases(lock); -void __lockfunc _write_unlock(rwlock_t *lock) __releases(lock); void __lockfunc _spin_unlock_bh(spinlock_t *lock) __releases(lock); -void __lockfunc _read_unlock_bh(rwlock_t *lock) __releases(lock); -void __lockfunc _write_unlock_bh(rwlock_t *lock) __releases(lock); void __lockfunc _spin_unlock_irq(spinlock_t *lock) __releases(lock); -void __lockfunc _read_unlock_irq(rwlock_t *lock) __releases(lock); -void __lockfunc _write_unlock_irq(rwlock_t *lock) __releases(lock); void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) __releases(lock); -void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) - __releases(lock); -void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) - __releases(lock); #ifdef CONFIG_INLINE_SPIN_LOCK #define _spin_lock(lock) __spin_lock(lock) #endif -#ifdef CONFIG_INLINE_READ_LOCK -#define _read_lock(lock) __read_lock(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_LOCK -#define _write_lock(lock) __write_lock(lock) -#endif - #ifdef CONFIG_INLINE_SPIN_LOCK_BH #define _spin_lock_bh(lock) __spin_lock_bh(lock) #endif -#ifdef CONFIG_INLINE_READ_LOCK_BH -#define _read_lock_bh(lock) __read_lock_bh(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_LOCK_BH -#define _write_lock_bh(lock) __write_lock_bh(lock) -#endif - #ifdef CONFIG_INLINE_SPIN_LOCK_IRQ #define _spin_lock_irq(lock) __spin_lock_irq(lock) #endif -#ifdef CONFIG_INLINE_READ_LOCK_IRQ -#define _read_lock_irq(lock) __read_lock_irq(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_LOCK_IRQ -#define _write_lock_irq(lock) __write_lock_irq(lock) -#endif - #ifdef CONFIG_INLINE_SPIN_LOCK_IRQSAVE #define _spin_lock_irqsave(lock) __spin_lock_irqsave(lock) #endif -#ifdef CONFIG_INLINE_READ_LOCK_IRQSAVE -#define _read_lock_irqsave(lock) __read_lock_irqsave(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_LOCK_IRQSAVE -#define _write_lock_irqsave(lock) __write_lock_irqsave(lock) -#endif - #ifdef CONFIG_INLINE_SPIN_TRYLOCK #define _spin_trylock(lock) __spin_trylock(lock) #endif -#ifdef CONFIG_INLINE_READ_TRYLOCK -#define _read_trylock(lock) __read_trylock(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_TRYLOCK -#define _write_trylock(lock) __write_trylock(lock) -#endif - #ifdef CONFIG_INLINE_SPIN_TRYLOCK_BH #define _spin_trylock_bh(lock) __spin_trylock_bh(lock) #endif @@ -128,50 +67,18 @@ void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) #define _spin_unlock(lock) __spin_unlock(lock) #endif -#ifdef CONFIG_INLINE_READ_UNLOCK -#define _read_unlock(lock) __read_unlock(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_UNLOCK -#define _write_unlock(lock) __write_unlock(lock) -#endif - #ifdef CONFIG_INLINE_SPIN_UNLOCK_BH #define _spin_unlock_bh(lock) __spin_unlock_bh(lock) #endif -#ifdef CONFIG_INLINE_READ_UNLOCK_BH -#define _read_unlock_bh(lock) __read_unlock_bh(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_UNLOCK_BH -#define _write_unlock_bh(lock) __write_unlock_bh(lock) -#endif - #ifdef CONFIG_INLINE_SPIN_UNLOCK_IRQ #define _spin_unlock_irq(lock) __spin_unlock_irq(lock) #endif -#ifdef CONFIG_INLINE_READ_UNLOCK_IRQ -#define _read_unlock_irq(lock) __read_unlock_irq(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQ -#define _write_unlock_irq(lock) __write_unlock_irq(lock) -#endif - #ifdef CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE #define _spin_unlock_irqrestore(lock, flags) __spin_unlock_irqrestore(lock, flags) #endif -#ifdef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE -#define _read_unlock_irqrestore(lock, flags) __read_unlock_irqrestore(lock, flags) -#endif - -#ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE -#define _write_unlock_irqrestore(lock, flags) __write_unlock_irqrestore(lock, flags) -#endif - static inline int __spin_trylock(spinlock_t *lock) { preempt_disable(); @@ -183,28 +90,6 @@ static inline int __spin_trylock(spinlock_t *lock) return 0; } -static inline int __read_trylock(rwlock_t *lock) -{ - preempt_disable(); - if (_raw_read_trylock(lock)) { - rwlock_acquire_read(&lock->dep_map, 0, 1, _RET_IP_); - return 1; - } - preempt_enable(); - return 0; -} - -static inline int __write_trylock(rwlock_t *lock) -{ - preempt_disable(); - if (_raw_write_trylock(lock)) { - rwlock_acquire(&lock->dep_map, 0, 1, _RET_IP_); - return 1; - } - preempt_enable(); - return 0; -} - /* * If lockdep is enabled then we use the non-preemption spin-ops * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are @@ -212,13 +97,6 @@ static inline int __write_trylock(rwlock_t *lock) */ #if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC) -static inline void __read_lock(rwlock_t *lock) -{ - preempt_disable(); - rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); -} - static inline unsigned long __spin_lock_irqsave(spinlock_t *lock) { unsigned long flags; @@ -255,62 +133,6 @@ static inline void __spin_lock_bh(spinlock_t *lock) LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); } -static inline unsigned long __read_lock_irqsave(rwlock_t *lock) -{ - unsigned long flags; - - local_irq_save(flags); - preempt_disable(); - rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED_FLAGS(lock, _raw_read_trylock, _raw_read_lock, - _raw_read_lock_flags, &flags); - return flags; -} - -static inline void __read_lock_irq(rwlock_t *lock) -{ - local_irq_disable(); - preempt_disable(); - rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); -} - -static inline void __read_lock_bh(rwlock_t *lock) -{ - local_bh_disable(); - preempt_disable(); - rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); -} - -static inline unsigned long __write_lock_irqsave(rwlock_t *lock) -{ - unsigned long flags; - - local_irq_save(flags); - preempt_disable(); - rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED_FLAGS(lock, _raw_write_trylock, _raw_write_lock, - _raw_write_lock_flags, &flags); - return flags; -} - -static inline void __write_lock_irq(rwlock_t *lock) -{ - local_irq_disable(); - preempt_disable(); - rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_write_trylock, _raw_write_lock); -} - -static inline void __write_lock_bh(rwlock_t *lock) -{ - local_bh_disable(); - preempt_disable(); - rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_write_trylock, _raw_write_lock); -} - static inline void __spin_lock(spinlock_t *lock) { preempt_disable(); @@ -318,13 +140,6 @@ static inline void __spin_lock(spinlock_t *lock) LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); } -static inline void __write_lock(rwlock_t *lock) -{ - preempt_disable(); - rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_write_trylock, _raw_write_lock); -} - #endif /* CONFIG_PREEMPT */ static inline void __spin_unlock(spinlock_t *lock) @@ -334,20 +149,6 @@ static inline void __spin_unlock(spinlock_t *lock) preempt_enable(); } -static inline void __write_unlock(rwlock_t *lock) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_write_unlock(lock); - preempt_enable(); -} - -static inline void __read_unlock(rwlock_t *lock) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_read_unlock(lock); - preempt_enable(); -} - static inline void __spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) { @@ -373,55 +174,6 @@ static inline void __spin_unlock_bh(spinlock_t *lock) local_bh_enable_ip((unsigned long)__builtin_return_address(0)); } -static inline void __read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_read_unlock(lock); - local_irq_restore(flags); - preempt_enable(); -} - -static inline void __read_unlock_irq(rwlock_t *lock) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_read_unlock(lock); - local_irq_enable(); - preempt_enable(); -} - -static inline void __read_unlock_bh(rwlock_t *lock) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_read_unlock(lock); - preempt_enable_no_resched(); - local_bh_enable_ip((unsigned long)__builtin_return_address(0)); -} - -static inline void __write_unlock_irqrestore(rwlock_t *lock, - unsigned long flags) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_write_unlock(lock); - local_irq_restore(flags); - preempt_enable(); -} - -static inline void __write_unlock_irq(rwlock_t *lock) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_write_unlock(lock); - local_irq_enable(); - preempt_enable(); -} - -static inline void __write_unlock_bh(rwlock_t *lock) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_write_unlock(lock); - preempt_enable_no_resched(); - local_bh_enable_ip((unsigned long)__builtin_return_address(0)); -} - static inline int __spin_trylock_bh(spinlock_t *lock) { local_bh_disable(); @@ -435,4 +187,6 @@ static inline int __spin_trylock_bh(spinlock_t *lock) return 0; } +#include + #endif /* __LINUX_SPINLOCK_API_SMP_H */ -- cgit v0.10.2 From 445c89514be242b1b0080056d50bdc1b72adeb5c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 2 Dec 2009 19:49:50 +0100 Subject: locking: Convert raw_spinlock to arch_spinlock The raw_spin* namespace was taken by lockdep for the architecture specific implementations. raw_spin_* would be the ideal name space for the spinlocks which are not converted to sleeping locks in preempt-rt. Linus suggested to convert the raw_ to arch_ locks and cleanup the name space instead of using an artifical name like core_spin, atomic_spin or whatever No functional change. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: David S. Miller Acked-by: Ingo Molnar Cc: linux-arch@vger.kernel.org diff --git a/arch/alpha/include/asm/spinlock.h b/arch/alpha/include/asm/spinlock.h index e38fb95..bdb26a1 100644 --- a/arch/alpha/include/asm/spinlock.h +++ b/arch/alpha/include/asm/spinlock.h @@ -17,13 +17,13 @@ #define __raw_spin_unlock_wait(x) \ do { cpu_relax(); } while ((x)->lock) -static inline void __raw_spin_unlock(raw_spinlock_t * lock) +static inline void __raw_spin_unlock(arch_spinlock_t * lock) { mb(); lock->lock = 0; } -static inline void __raw_spin_lock(raw_spinlock_t * lock) +static inline void __raw_spin_lock(arch_spinlock_t * lock) { long tmp; @@ -43,7 +43,7 @@ static inline void __raw_spin_lock(raw_spinlock_t * lock) : "m"(lock->lock) : "memory"); } -static inline int __raw_spin_trylock(raw_spinlock_t *lock) +static inline int __raw_spin_trylock(arch_spinlock_t *lock) { return !test_and_set_bit(0, &lock->lock); } diff --git a/arch/alpha/include/asm/spinlock_types.h b/arch/alpha/include/asm/spinlock_types.h index 8141eb5..bb94a51 100644 --- a/arch/alpha/include/asm/spinlock_types.h +++ b/arch/alpha/include/asm/spinlock_types.h @@ -7,7 +7,7 @@ typedef struct { volatile unsigned int lock; -} raw_spinlock_t; +} arch_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 0 } diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h index c13681a..4e7712e 100644 --- a/arch/arm/include/asm/spinlock.h +++ b/arch/arm/include/asm/spinlock.h @@ -23,7 +23,7 @@ #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) -static inline void __raw_spin_lock(raw_spinlock_t *lock) +static inline void __raw_spin_lock(arch_spinlock_t *lock) { unsigned long tmp; @@ -43,7 +43,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) smp_mb(); } -static inline int __raw_spin_trylock(raw_spinlock_t *lock) +static inline int __raw_spin_trylock(arch_spinlock_t *lock) { unsigned long tmp; @@ -63,7 +63,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) } } -static inline void __raw_spin_unlock(raw_spinlock_t *lock) +static inline void __raw_spin_unlock(arch_spinlock_t *lock) { smp_mb(); diff --git a/arch/arm/include/asm/spinlock_types.h b/arch/arm/include/asm/spinlock_types.h index 43e83f6..5e9d3ea 100644 --- a/arch/arm/include/asm/spinlock_types.h +++ b/arch/arm/include/asm/spinlock_types.h @@ -7,7 +7,7 @@ typedef struct { volatile unsigned int lock; -} raw_spinlock_t; +} arch_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 0 } diff --git a/arch/blackfin/include/asm/spinlock.h b/arch/blackfin/include/asm/spinlock.h index b0c7f0e..fc16b4c 100644 --- a/arch/blackfin/include/asm/spinlock.h +++ b/arch/blackfin/include/asm/spinlock.h @@ -24,29 +24,29 @@ asmlinkage void __raw_write_lock_asm(volatile int *ptr); asmlinkage int __raw_write_trylock_asm(volatile int *ptr); asmlinkage void __raw_write_unlock_asm(volatile int *ptr); -static inline int __raw_spin_is_locked(raw_spinlock_t *lock) +static inline int __raw_spin_is_locked(arch_spinlock_t *lock) { return __raw_spin_is_locked_asm(&lock->lock); } -static inline void __raw_spin_lock(raw_spinlock_t *lock) +static inline void __raw_spin_lock(arch_spinlock_t *lock) { __raw_spin_lock_asm(&lock->lock); } #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) -static inline int __raw_spin_trylock(raw_spinlock_t *lock) +static inline int __raw_spin_trylock(arch_spinlock_t *lock) { return __raw_spin_trylock_asm(&lock->lock); } -static inline void __raw_spin_unlock(raw_spinlock_t *lock) +static inline void __raw_spin_unlock(arch_spinlock_t *lock) { __raw_spin_unlock_asm(&lock->lock); } -static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) +static inline void __raw_spin_unlock_wait(arch_spinlock_t *lock) { while (__raw_spin_is_locked(lock)) cpu_relax(); diff --git a/arch/blackfin/include/asm/spinlock_types.h b/arch/blackfin/include/asm/spinlock_types.h index be75762..03b377a 100644 --- a/arch/blackfin/include/asm/spinlock_types.h +++ b/arch/blackfin/include/asm/spinlock_types.h @@ -15,7 +15,7 @@ typedef struct { volatile unsigned int lock; -} raw_spinlock_t; +} arch_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 0 } diff --git a/arch/cris/include/arch-v32/arch/spinlock.h b/arch/cris/include/arch-v32/arch/spinlock.h index 367a53e..e253457 100644 --- a/arch/cris/include/arch-v32/arch/spinlock.h +++ b/arch/cris/include/arch-v32/arch/spinlock.h @@ -9,12 +9,12 @@ extern void cris_spin_unlock(void *l, int val); extern void cris_spin_lock(void *l); extern int cris_spin_trylock(void *l); -static inline int __raw_spin_is_locked(raw_spinlock_t *x) +static inline int __raw_spin_is_locked(arch_spinlock_t *x) { return *(volatile signed char *)(&(x)->slock) <= 0; } -static inline void __raw_spin_unlock(raw_spinlock_t *lock) +static inline void __raw_spin_unlock(arch_spinlock_t *lock) { __asm__ volatile ("move.d %1,%0" \ : "=m" (lock->slock) \ @@ -22,24 +22,24 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock) : "memory"); } -static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) +static inline void __raw_spin_unlock_wait(arch_spinlock_t *lock) { while (__raw_spin_is_locked(lock)) cpu_relax(); } -static inline int __raw_spin_trylock(raw_spinlock_t *lock) +static inline int __raw_spin_trylock(arch_spinlock_t *lock) { return cris_spin_trylock((void *)&lock->slock); } -static inline void __raw_spin_lock(raw_spinlock_t *lock) +static inline void __raw_spin_lock(arch_spinlock_t *lock) { cris_spin_lock((void *)&lock->slock); } static inline void -__raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) +__raw_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { __raw_spin_lock(lock); } diff --git a/arch/ia64/include/asm/spinlock.h b/arch/ia64/include/asm/spinlock.h index 239ecdc..9fbdf7e 100644 --- a/arch/ia64/include/asm/spinlock.h +++ b/arch/ia64/include/asm/spinlock.h @@ -38,7 +38,7 @@ #define TICKET_BITS 15 #define TICKET_MASK ((1 << TICKET_BITS) - 1) -static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock) +static __always_inline void __ticket_spin_lock(arch_spinlock_t *lock) { int *p = (int *)&lock->lock, ticket, serve; @@ -58,7 +58,7 @@ static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock) } } -static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock) +static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock) { int tmp = ACCESS_ONCE(lock->lock); @@ -67,7 +67,7 @@ static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock) return 0; } -static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock) +static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock) { unsigned short *p = (unsigned short *)&lock->lock + 1, tmp; @@ -75,7 +75,7 @@ static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock) ACCESS_ONCE(*p) = (tmp + 2) & ~1; } -static __always_inline void __ticket_spin_unlock_wait(raw_spinlock_t *lock) +static __always_inline void __ticket_spin_unlock_wait(arch_spinlock_t *lock) { int *p = (int *)&lock->lock, ticket; @@ -89,53 +89,53 @@ static __always_inline void __ticket_spin_unlock_wait(raw_spinlock_t *lock) } } -static inline int __ticket_spin_is_locked(raw_spinlock_t *lock) +static inline int __ticket_spin_is_locked(arch_spinlock_t *lock) { long tmp = ACCESS_ONCE(lock->lock); return !!(((tmp >> TICKET_SHIFT) ^ tmp) & TICKET_MASK); } -static inline int __ticket_spin_is_contended(raw_spinlock_t *lock) +static inline int __ticket_spin_is_contended(arch_spinlock_t *lock) { long tmp = ACCESS_ONCE(lock->lock); return ((tmp - (tmp >> TICKET_SHIFT)) & TICKET_MASK) > 1; } -static inline int __raw_spin_is_locked(raw_spinlock_t *lock) +static inline int __raw_spin_is_locked(arch_spinlock_t *lock) { return __ticket_spin_is_locked(lock); } -static inline int __raw_spin_is_contended(raw_spinlock_t *lock) +static inline int __raw_spin_is_contended(arch_spinlock_t *lock) { return __ticket_spin_is_contended(lock); } #define __raw_spin_is_contended __raw_spin_is_contended -static __always_inline void __raw_spin_lock(raw_spinlock_t *lock) +static __always_inline void __raw_spin_lock(arch_spinlock_t *lock) { __ticket_spin_lock(lock); } -static __always_inline int __raw_spin_trylock(raw_spinlock_t *lock) +static __always_inline int __raw_spin_trylock(arch_spinlock_t *lock) { return __ticket_spin_trylock(lock); } -static __always_inline void __raw_spin_unlock(raw_spinlock_t *lock) +static __always_inline void __raw_spin_unlock(arch_spinlock_t *lock) { __ticket_spin_unlock(lock); } -static __always_inline void __raw_spin_lock_flags(raw_spinlock_t *lock, +static __always_inline void __raw_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { __raw_spin_lock(lock); } -static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) +static inline void __raw_spin_unlock_wait(arch_spinlock_t *lock) { __ticket_spin_unlock_wait(lock); } diff --git a/arch/ia64/include/asm/spinlock_types.h b/arch/ia64/include/asm/spinlock_types.h index 474e46f..447ccc6 100644 --- a/arch/ia64/include/asm/spinlock_types.h +++ b/arch/ia64/include/asm/spinlock_types.h @@ -7,7 +7,7 @@ typedef struct { volatile unsigned int lock; -} raw_spinlock_t; +} arch_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 0 } diff --git a/arch/m32r/include/asm/spinlock.h b/arch/m32r/include/asm/spinlock.h index dded923..0c01642 100644 --- a/arch/m32r/include/asm/spinlock.h +++ b/arch/m32r/include/asm/spinlock.h @@ -36,7 +36,7 @@ * __raw_spin_trylock() tries to get the lock and returns a result. * On the m32r, the result value is 1 (= Success) or 0 (= Failure). */ -static inline int __raw_spin_trylock(raw_spinlock_t *lock) +static inline int __raw_spin_trylock(arch_spinlock_t *lock) { int oldval; unsigned long tmp1, tmp2; @@ -69,7 +69,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) return (oldval > 0); } -static inline void __raw_spin_lock(raw_spinlock_t *lock) +static inline void __raw_spin_lock(arch_spinlock_t *lock) { unsigned long tmp0, tmp1; @@ -111,7 +111,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) ); } -static inline void __raw_spin_unlock(raw_spinlock_t *lock) +static inline void __raw_spin_unlock(arch_spinlock_t *lock) { mb(); lock->slock = 1; diff --git a/arch/m32r/include/asm/spinlock_types.h b/arch/m32r/include/asm/spinlock_types.h index 83f5210..17d15bd 100644 --- a/arch/m32r/include/asm/spinlock_types.h +++ b/arch/m32r/include/asm/spinlock_types.h @@ -7,7 +7,7 @@ typedef struct { volatile int slock; -} raw_spinlock_t; +} arch_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 1 } diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index 5b60a09..0f16d06 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h @@ -34,7 +34,7 @@ * becomes equal to the the initial value of the tail. */ -static inline int __raw_spin_is_locked(raw_spinlock_t *lock) +static inline int __raw_spin_is_locked(arch_spinlock_t *lock) { unsigned int counters = ACCESS_ONCE(lock->lock); @@ -45,7 +45,7 @@ static inline int __raw_spin_is_locked(raw_spinlock_t *lock) #define __raw_spin_unlock_wait(x) \ while (__raw_spin_is_locked(x)) { cpu_relax(); } -static inline int __raw_spin_is_contended(raw_spinlock_t *lock) +static inline int __raw_spin_is_contended(arch_spinlock_t *lock) { unsigned int counters = ACCESS_ONCE(lock->lock); @@ -53,7 +53,7 @@ static inline int __raw_spin_is_contended(raw_spinlock_t *lock) } #define __raw_spin_is_contended __raw_spin_is_contended -static inline void __raw_spin_lock(raw_spinlock_t *lock) +static inline void __raw_spin_lock(arch_spinlock_t *lock) { int my_ticket; int tmp; @@ -134,7 +134,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) smp_llsc_mb(); } -static inline void __raw_spin_unlock(raw_spinlock_t *lock) +static inline void __raw_spin_unlock(arch_spinlock_t *lock) { int tmp; @@ -174,7 +174,7 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock) } } -static inline unsigned int __raw_spin_trylock(raw_spinlock_t *lock) +static inline unsigned int __raw_spin_trylock(arch_spinlock_t *lock) { int tmp, tmp2, tmp3; diff --git a/arch/mips/include/asm/spinlock_types.h b/arch/mips/include/asm/spinlock_types.h index adeedaa..2e10608 100644 --- a/arch/mips/include/asm/spinlock_types.h +++ b/arch/mips/include/asm/spinlock_types.h @@ -12,7 +12,7 @@ typedef struct { * bits 15..28: ticket */ unsigned int lock; -} raw_spinlock_t; +} arch_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 0 } diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h index 8bc9e96..3a4ea77 100644 --- a/arch/parisc/include/asm/atomic.h +++ b/arch/parisc/include/asm/atomic.h @@ -27,18 +27,18 @@ # define ATOMIC_HASH_SIZE 4 # define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) (a))/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ])) -extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned; +extern arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned; /* Can't use raw_spin_lock_irq because of #include problems, so * this is the substitute */ #define _atomic_spin_lock_irqsave(l,f) do { \ - raw_spinlock_t *s = ATOMIC_HASH(l); \ + arch_spinlock_t *s = ATOMIC_HASH(l); \ local_irq_save(f); \ __raw_spin_lock(s); \ } while(0) #define _atomic_spin_unlock_irqrestore(l,f) do { \ - raw_spinlock_t *s = ATOMIC_HASH(l); \ + arch_spinlock_t *s = ATOMIC_HASH(l); \ __raw_spin_unlock(s); \ local_irq_restore(f); \ } while(0) diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h index fae03e1..69e8dca 100644 --- a/arch/parisc/include/asm/spinlock.h +++ b/arch/parisc/include/asm/spinlock.h @@ -5,7 +5,7 @@ #include #include -static inline int __raw_spin_is_locked(raw_spinlock_t *x) +static inline int __raw_spin_is_locked(arch_spinlock_t *x) { volatile unsigned int *a = __ldcw_align(x); return *a == 0; @@ -15,7 +15,7 @@ static inline int __raw_spin_is_locked(raw_spinlock_t *x) #define __raw_spin_unlock_wait(x) \ do { cpu_relax(); } while (__raw_spin_is_locked(x)) -static inline void __raw_spin_lock_flags(raw_spinlock_t *x, +static inline void __raw_spin_lock_flags(arch_spinlock_t *x, unsigned long flags) { volatile unsigned int *a; @@ -33,7 +33,7 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *x, mb(); } -static inline void __raw_spin_unlock(raw_spinlock_t *x) +static inline void __raw_spin_unlock(arch_spinlock_t *x) { volatile unsigned int *a; mb(); @@ -42,7 +42,7 @@ static inline void __raw_spin_unlock(raw_spinlock_t *x) mb(); } -static inline int __raw_spin_trylock(raw_spinlock_t *x) +static inline int __raw_spin_trylock(arch_spinlock_t *x) { volatile unsigned int *a; int ret; diff --git a/arch/parisc/include/asm/spinlock_types.h b/arch/parisc/include/asm/spinlock_types.h index 3f72f47..735caaf 100644 --- a/arch/parisc/include/asm/spinlock_types.h +++ b/arch/parisc/include/asm/spinlock_types.h @@ -9,10 +9,10 @@ typedef struct { volatile unsigned int lock[4]; # define __RAW_SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } } #endif -} raw_spinlock_t; +} arch_spinlock_t; typedef struct { - raw_spinlock_t lock; + arch_spinlock_t lock; volatile int counter; } raw_rwlock_t; diff --git a/arch/parisc/lib/bitops.c b/arch/parisc/lib/bitops.c index e3eb739..fdd7f58 100644 --- a/arch/parisc/lib/bitops.c +++ b/arch/parisc/lib/bitops.c @@ -12,7 +12,7 @@ #include #ifdef CONFIG_SMP -raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = { +arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = { [0 ... (ATOMIC_HASH_SIZE-1)] = __RAW_SPIN_LOCK_UNLOCKED }; #endif diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index 168fce7..20de73c 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h @@ -58,7 +58,7 @@ struct rtas_t { unsigned long entry; /* physical address pointer */ unsigned long base; /* physical address pointer */ unsigned long size; - raw_spinlock_t lock; + arch_spinlock_t lock; struct rtas_args args; struct device_node *dev; /* virtual address pointer */ }; diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h index 198266c..c0d44c9 100644 --- a/arch/powerpc/include/asm/spinlock.h +++ b/arch/powerpc/include/asm/spinlock.h @@ -54,7 +54,7 @@ * This returns the old value in the lock, so we succeeded * in getting the lock if the return value is 0. */ -static inline unsigned long arch_spin_trylock(raw_spinlock_t *lock) +static inline unsigned long arch_spin_trylock(arch_spinlock_t *lock) { unsigned long tmp, token; @@ -73,7 +73,7 @@ static inline unsigned long arch_spin_trylock(raw_spinlock_t *lock) return tmp; } -static inline int __raw_spin_trylock(raw_spinlock_t *lock) +static inline int __raw_spin_trylock(arch_spinlock_t *lock) { CLEAR_IO_SYNC; return arch_spin_trylock(lock) == 0; @@ -96,7 +96,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) #if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES) /* We only yield to the hypervisor if we are in shared processor mode */ #define SHARED_PROCESSOR (get_lppaca()->shared_proc) -extern void __spin_yield(raw_spinlock_t *lock); +extern void __spin_yield(arch_spinlock_t *lock); extern void __rw_yield(raw_rwlock_t *lock); #else /* SPLPAR || ISERIES */ #define __spin_yield(x) barrier() @@ -104,7 +104,7 @@ extern void __rw_yield(raw_rwlock_t *lock); #define SHARED_PROCESSOR 0 #endif -static inline void __raw_spin_lock(raw_spinlock_t *lock) +static inline void __raw_spin_lock(arch_spinlock_t *lock) { CLEAR_IO_SYNC; while (1) { @@ -120,7 +120,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) } static inline -void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) +void __raw_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { unsigned long flags_dis; @@ -140,7 +140,7 @@ void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) } } -static inline void __raw_spin_unlock(raw_spinlock_t *lock) +static inline void __raw_spin_unlock(arch_spinlock_t *lock) { SYNC_IO; __asm__ __volatile__("# __raw_spin_unlock\n\t" @@ -149,7 +149,7 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock) } #ifdef CONFIG_PPC64 -extern void __raw_spin_unlock_wait(raw_spinlock_t *lock); +extern void __raw_spin_unlock_wait(arch_spinlock_t *lock); #else #define __raw_spin_unlock_wait(lock) \ do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) diff --git a/arch/powerpc/include/asm/spinlock_types.h b/arch/powerpc/include/asm/spinlock_types.h index 74236c9..4312e5b 100644 --- a/arch/powerpc/include/asm/spinlock_types.h +++ b/arch/powerpc/include/asm/spinlock_types.h @@ -7,7 +7,7 @@ typedef struct { volatile unsigned int slock; -} raw_spinlock_t; +} arch_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 0 } diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index bf90361..579069c 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -978,7 +978,7 @@ int __init early_init_dt_scan_rtas(unsigned long node, return 1; } -static raw_spinlock_t timebase_lock; +static arch_spinlock_t timebase_lock; static u64 timebase = 0; void __cpuinit rtas_give_timebase(void) diff --git a/arch/powerpc/lib/locks.c b/arch/powerpc/lib/locks.c index 79d0fa3..b06294c 100644 --- a/arch/powerpc/lib/locks.c +++ b/arch/powerpc/lib/locks.c @@ -25,7 +25,7 @@ #include #include -void __spin_yield(raw_spinlock_t *lock) +void __spin_yield(arch_spinlock_t *lock) { unsigned int lock_value, holder_cpu, yield_count; @@ -82,7 +82,7 @@ void __rw_yield(raw_rwlock_t *rw) } #endif -void __raw_spin_unlock_wait(raw_spinlock_t *lock) +void __raw_spin_unlock_wait(arch_spinlock_t *lock) { while (lock->slock) { HMT_low(); diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index a461934..be36fec 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c @@ -71,7 +71,7 @@ static void pas_restart(char *cmd) } #ifdef CONFIG_SMP -static raw_spinlock_t timebase_lock; +static arch_spinlock_t timebase_lock; static unsigned long timebase; static void __devinit pas_give_timebase(void) diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h index c9af0d19..6121fa4 100644 --- a/arch/s390/include/asm/spinlock.h +++ b/arch/s390/include/asm/spinlock.h @@ -57,12 +57,12 @@ _raw_compare_and_swap(volatile unsigned int *lock, do { while (__raw_spin_is_locked(lock)) \ _raw_spin_relax(lock); } while (0) -extern void _raw_spin_lock_wait(raw_spinlock_t *); -extern void _raw_spin_lock_wait_flags(raw_spinlock_t *, unsigned long flags); -extern int _raw_spin_trylock_retry(raw_spinlock_t *); -extern void _raw_spin_relax(raw_spinlock_t *lock); +extern void _raw_spin_lock_wait(arch_spinlock_t *); +extern void _raw_spin_lock_wait_flags(arch_spinlock_t *, unsigned long flags); +extern int _raw_spin_trylock_retry(arch_spinlock_t *); +extern void _raw_spin_relax(arch_spinlock_t *lock); -static inline void __raw_spin_lock(raw_spinlock_t *lp) +static inline void __raw_spin_lock(arch_spinlock_t *lp) { int old; @@ -72,7 +72,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lp) _raw_spin_lock_wait(lp); } -static inline void __raw_spin_lock_flags(raw_spinlock_t *lp, +static inline void __raw_spin_lock_flags(arch_spinlock_t *lp, unsigned long flags) { int old; @@ -83,7 +83,7 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lp, _raw_spin_lock_wait_flags(lp, flags); } -static inline int __raw_spin_trylock(raw_spinlock_t *lp) +static inline int __raw_spin_trylock(arch_spinlock_t *lp) { int old; @@ -93,7 +93,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lp) return _raw_spin_trylock_retry(lp); } -static inline void __raw_spin_unlock(raw_spinlock_t *lp) +static inline void __raw_spin_unlock(arch_spinlock_t *lp) { _raw_compare_and_swap(&lp->owner_cpu, lp->owner_cpu, 0); } diff --git a/arch/s390/include/asm/spinlock_types.h b/arch/s390/include/asm/spinlock_types.h index 654abc4..a93638e 100644 --- a/arch/s390/include/asm/spinlock_types.h +++ b/arch/s390/include/asm/spinlock_types.h @@ -7,7 +7,7 @@ typedef struct { volatile unsigned int owner_cpu; -} __attribute__ ((aligned (4))) raw_spinlock_t; +} __attribute__ ((aligned (4))) arch_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 0 } diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index f7e0d30..d4cbf71 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c @@ -39,7 +39,7 @@ static inline void _raw_yield_cpu(int cpu) _raw_yield(); } -void _raw_spin_lock_wait(raw_spinlock_t *lp) +void _raw_spin_lock_wait(arch_spinlock_t *lp) { int count = spin_retry; unsigned int cpu = ~smp_processor_id(); @@ -59,7 +59,7 @@ void _raw_spin_lock_wait(raw_spinlock_t *lp) } EXPORT_SYMBOL(_raw_spin_lock_wait); -void _raw_spin_lock_wait_flags(raw_spinlock_t *lp, unsigned long flags) +void _raw_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) { int count = spin_retry; unsigned int cpu = ~smp_processor_id(); @@ -82,7 +82,7 @@ void _raw_spin_lock_wait_flags(raw_spinlock_t *lp, unsigned long flags) } EXPORT_SYMBOL(_raw_spin_lock_wait_flags); -int _raw_spin_trylock_retry(raw_spinlock_t *lp) +int _raw_spin_trylock_retry(arch_spinlock_t *lp) { unsigned int cpu = ~smp_processor_id(); int count; @@ -97,7 +97,7 @@ int _raw_spin_trylock_retry(raw_spinlock_t *lp) } EXPORT_SYMBOL(_raw_spin_trylock_retry); -void _raw_spin_relax(raw_spinlock_t *lock) +void _raw_spin_relax(arch_spinlock_t *lock) { unsigned int cpu = lock->owner_cpu; if (cpu != 0) diff --git a/arch/sh/include/asm/spinlock.h b/arch/sh/include/asm/spinlock.h index a28c9f0..5a05b3f 100644 --- a/arch/sh/include/asm/spinlock.h +++ b/arch/sh/include/asm/spinlock.h @@ -34,7 +34,7 @@ * * We make no fairness assumptions. They have a cost. */ -static inline void __raw_spin_lock(raw_spinlock_t *lock) +static inline void __raw_spin_lock(arch_spinlock_t *lock) { unsigned long tmp; unsigned long oldval; @@ -54,7 +54,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) ); } -static inline void __raw_spin_unlock(raw_spinlock_t *lock) +static inline void __raw_spin_unlock(arch_spinlock_t *lock) { unsigned long tmp; @@ -67,7 +67,7 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock) ); } -static inline int __raw_spin_trylock(raw_spinlock_t *lock) +static inline int __raw_spin_trylock(arch_spinlock_t *lock) { unsigned long tmp, oldval; diff --git a/arch/sh/include/asm/spinlock_types.h b/arch/sh/include/asm/spinlock_types.h index b4d244e..37712c3 100644 --- a/arch/sh/include/asm/spinlock_types.h +++ b/arch/sh/include/asm/spinlock_types.h @@ -7,7 +7,7 @@ typedef struct { volatile unsigned int lock; -} raw_spinlock_t; +} arch_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 1 } diff --git a/arch/sparc/include/asm/spinlock_32.h b/arch/sparc/include/asm/spinlock_32.h index 857630c..b2d8a67 100644 --- a/arch/sparc/include/asm/spinlock_32.h +++ b/arch/sparc/include/asm/spinlock_32.h @@ -15,7 +15,7 @@ #define __raw_spin_unlock_wait(lock) \ do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) -static inline void __raw_spin_lock(raw_spinlock_t *lock) +static inline void __raw_spin_lock(arch_spinlock_t *lock) { __asm__ __volatile__( "\n1:\n\t" @@ -35,7 +35,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) : "g2", "memory", "cc"); } -static inline int __raw_spin_trylock(raw_spinlock_t *lock) +static inline int __raw_spin_trylock(arch_spinlock_t *lock) { unsigned int result; __asm__ __volatile__("ldstub [%1], %0" @@ -45,7 +45,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) return (result == 0); } -static inline void __raw_spin_unlock(raw_spinlock_t *lock) +static inline void __raw_spin_unlock(arch_spinlock_t *lock) { __asm__ __volatile__("stb %%g0, [%0]" : : "r" (lock) : "memory"); } diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h index 43e5147..38e16c4 100644 --- a/arch/sparc/include/asm/spinlock_64.h +++ b/arch/sparc/include/asm/spinlock_64.h @@ -27,7 +27,7 @@ do { rmb(); \ } while((lp)->lock) -static inline void __raw_spin_lock(raw_spinlock_t *lock) +static inline void __raw_spin_lock(arch_spinlock_t *lock) { unsigned long tmp; @@ -46,7 +46,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) : "memory"); } -static inline int __raw_spin_trylock(raw_spinlock_t *lock) +static inline int __raw_spin_trylock(arch_spinlock_t *lock) { unsigned long result; @@ -59,7 +59,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) return (result == 0UL); } -static inline void __raw_spin_unlock(raw_spinlock_t *lock) +static inline void __raw_spin_unlock(arch_spinlock_t *lock) { __asm__ __volatile__( " stb %%g0, [%0]" @@ -68,7 +68,7 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock) : "memory"); } -static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) +static inline void __raw_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { unsigned long tmp1, tmp2; diff --git a/arch/sparc/include/asm/spinlock_types.h b/arch/sparc/include/asm/spinlock_types.h index 37cbe01..41d9a8f 100644 --- a/arch/sparc/include/asm/spinlock_types.h +++ b/arch/sparc/include/asm/spinlock_types.h @@ -7,7 +7,7 @@ typedef struct { volatile unsigned char lock; -} raw_spinlock_t; +} arch_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 0 } diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index efb3899..5655f75 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -731,34 +731,34 @@ static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS) -static inline int __raw_spin_is_locked(struct raw_spinlock *lock) +static inline int __raw_spin_is_locked(struct arch_spinlock *lock) { return PVOP_CALL1(int, pv_lock_ops.spin_is_locked, lock); } -static inline int __raw_spin_is_contended(struct raw_spinlock *lock) +static inline int __raw_spin_is_contended(struct arch_spinlock *lock) { return PVOP_CALL1(int, pv_lock_ops.spin_is_contended, lock); } #define __raw_spin_is_contended __raw_spin_is_contended -static __always_inline void __raw_spin_lock(struct raw_spinlock *lock) +static __always_inline void __raw_spin_lock(struct arch_spinlock *lock) { PVOP_VCALL1(pv_lock_ops.spin_lock, lock); } -static __always_inline void __raw_spin_lock_flags(struct raw_spinlock *lock, +static __always_inline void __raw_spin_lock_flags(struct arch_spinlock *lock, unsigned long flags) { PVOP_VCALL2(pv_lock_ops.spin_lock_flags, lock, flags); } -static __always_inline int __raw_spin_trylock(struct raw_spinlock *lock) +static __always_inline int __raw_spin_trylock(struct arch_spinlock *lock) { return PVOP_CALL1(int, pv_lock_ops.spin_trylock, lock); } -static __always_inline void __raw_spin_unlock(struct raw_spinlock *lock) +static __always_inline void __raw_spin_unlock(struct arch_spinlock *lock) { PVOP_VCALL1(pv_lock_ops.spin_unlock, lock); } diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 9357473..b1e70d5 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -318,14 +318,14 @@ struct pv_mmu_ops { phys_addr_t phys, pgprot_t flags); }; -struct raw_spinlock; +struct arch_spinlock; struct pv_lock_ops { - int (*spin_is_locked)(struct raw_spinlock *lock); - int (*spin_is_contended)(struct raw_spinlock *lock); - void (*spin_lock)(struct raw_spinlock *lock); - void (*spin_lock_flags)(struct raw_spinlock *lock, unsigned long flags); - int (*spin_trylock)(struct raw_spinlock *lock); - void (*spin_unlock)(struct raw_spinlock *lock); + int (*spin_is_locked)(struct arch_spinlock *lock); + int (*spin_is_contended)(struct arch_spinlock *lock); + void (*spin_lock)(struct arch_spinlock *lock); + void (*spin_lock_flags)(struct arch_spinlock *lock, unsigned long flags); + int (*spin_trylock)(struct arch_spinlock *lock); + void (*spin_unlock)(struct arch_spinlock *lock); }; /* This contains all the paravirt structures: we get a convenient diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index 4e77853..204b524 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h @@ -58,7 +58,7 @@ #if (NR_CPUS < 256) #define TICKET_SHIFT 8 -static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock) +static __always_inline void __ticket_spin_lock(arch_spinlock_t *lock) { short inc = 0x0100; @@ -77,7 +77,7 @@ static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock) : "memory", "cc"); } -static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock) +static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock) { int tmp, new; @@ -96,7 +96,7 @@ static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock) return tmp; } -static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock) +static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock) { asm volatile(UNLOCK_LOCK_PREFIX "incb %0" : "+m" (lock->slock) @@ -106,7 +106,7 @@ static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock) #else #define TICKET_SHIFT 16 -static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock) +static __always_inline void __ticket_spin_lock(arch_spinlock_t *lock) { int inc = 0x00010000; int tmp; @@ -127,7 +127,7 @@ static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock) : "memory", "cc"); } -static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock) +static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock) { int tmp; int new; @@ -149,7 +149,7 @@ static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock) return tmp; } -static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock) +static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock) { asm volatile(UNLOCK_LOCK_PREFIX "incw %0" : "+m" (lock->slock) @@ -158,14 +158,14 @@ static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock) } #endif -static inline int __ticket_spin_is_locked(raw_spinlock_t *lock) +static inline int __ticket_spin_is_locked(arch_spinlock_t *lock) { int tmp = ACCESS_ONCE(lock->slock); return !!(((tmp >> TICKET_SHIFT) ^ tmp) & ((1 << TICKET_SHIFT) - 1)); } -static inline int __ticket_spin_is_contended(raw_spinlock_t *lock) +static inline int __ticket_spin_is_contended(arch_spinlock_t *lock) { int tmp = ACCESS_ONCE(lock->slock); @@ -174,33 +174,33 @@ static inline int __ticket_spin_is_contended(raw_spinlock_t *lock) #ifndef CONFIG_PARAVIRT_SPINLOCKS -static inline int __raw_spin_is_locked(raw_spinlock_t *lock) +static inline int __raw_spin_is_locked(arch_spinlock_t *lock) { return __ticket_spin_is_locked(lock); } -static inline int __raw_spin_is_contended(raw_spinlock_t *lock) +static inline int __raw_spin_is_contended(arch_spinlock_t *lock) { return __ticket_spin_is_contended(lock); } #define __raw_spin_is_contended __raw_spin_is_contended -static __always_inline void __raw_spin_lock(raw_spinlock_t *lock) +static __always_inline void __raw_spin_lock(arch_spinlock_t *lock) { __ticket_spin_lock(lock); } -static __always_inline int __raw_spin_trylock(raw_spinlock_t *lock) +static __always_inline int __raw_spin_trylock(arch_spinlock_t *lock) { return __ticket_spin_trylock(lock); } -static __always_inline void __raw_spin_unlock(raw_spinlock_t *lock) +static __always_inline void __raw_spin_unlock(arch_spinlock_t *lock) { __ticket_spin_unlock(lock); } -static __always_inline void __raw_spin_lock_flags(raw_spinlock_t *lock, +static __always_inline void __raw_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { __raw_spin_lock(lock); @@ -208,7 +208,7 @@ static __always_inline void __raw_spin_lock_flags(raw_spinlock_t *lock, #endif /* CONFIG_PARAVIRT_SPINLOCKS */ -static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) +static inline void __raw_spin_unlock_wait(arch_spinlock_t *lock) { while (__raw_spin_is_locked(lock)) cpu_relax(); diff --git a/arch/x86/include/asm/spinlock_types.h b/arch/x86/include/asm/spinlock_types.h index 845f81c..2ae7637 100644 --- a/arch/x86/include/asm/spinlock_types.h +++ b/arch/x86/include/asm/spinlock_types.h @@ -5,9 +5,9 @@ # error "please don't include this file directly" #endif -typedef struct raw_spinlock { +typedef struct arch_spinlock { unsigned int slock; -} raw_spinlock_t; +} arch_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 0 } diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index b8ce165..0862d9d 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -188,7 +188,7 @@ void dump_stack(void) } EXPORT_SYMBOL(dump_stack); -static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED; +static arch_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED; static int die_owner = -1; static unsigned int die_nest_count; diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c index 3a7c5a4..a0f39e0 100644 --- a/arch/x86/kernel/paravirt-spinlocks.c +++ b/arch/x86/kernel/paravirt-spinlocks.c @@ -8,7 +8,7 @@ #include static inline void -default_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) +default_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { __raw_spin_lock(lock); } diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c index eed1568..9f908b9 100644 --- a/arch/x86/kernel/tsc_sync.c +++ b/arch/x86/kernel/tsc_sync.c @@ -33,7 +33,7 @@ static __cpuinitdata atomic_t stop_count; * we want to have the fastest, inlined, non-debug version * of a critical section, to be able to prove TSC time-warps: */ -static __cpuinitdata raw_spinlock_t sync_lock = __RAW_SPIN_LOCK_UNLOCKED; +static __cpuinitdata arch_spinlock_t sync_lock = __RAW_SPIN_LOCK_UNLOCKED; static __cpuinitdata cycles_t last_tsc; static __cpuinitdata cycles_t max_warp; diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 36a5141..24ded31 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c @@ -120,14 +120,14 @@ struct xen_spinlock { unsigned short spinners; /* count of waiting cpus */ }; -static int xen_spin_is_locked(struct raw_spinlock *lock) +static int xen_spin_is_locked(struct arch_spinlock *lock) { struct xen_spinlock *xl = (struct xen_spinlock *)lock; return xl->lock != 0; } -static int xen_spin_is_contended(struct raw_spinlock *lock) +static int xen_spin_is_contended(struct arch_spinlock *lock) { struct xen_spinlock *xl = (struct xen_spinlock *)lock; @@ -136,7 +136,7 @@ static int xen_spin_is_contended(struct raw_spinlock *lock) return xl->spinners != 0; } -static int xen_spin_trylock(struct raw_spinlock *lock) +static int xen_spin_trylock(struct arch_spinlock *lock) { struct xen_spinlock *xl = (struct xen_spinlock *)lock; u8 old = 1; @@ -181,7 +181,7 @@ static inline void unspinning_lock(struct xen_spinlock *xl, struct xen_spinlock __get_cpu_var(lock_spinners) = prev; } -static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enable) +static noinline int xen_spin_lock_slow(struct arch_spinlock *lock, bool irq_enable) { struct xen_spinlock *xl = (struct xen_spinlock *)lock; struct xen_spinlock *prev; @@ -254,7 +254,7 @@ out: return ret; } -static inline void __xen_spin_lock(struct raw_spinlock *lock, bool irq_enable) +static inline void __xen_spin_lock(struct arch_spinlock *lock, bool irq_enable) { struct xen_spinlock *xl = (struct xen_spinlock *)lock; unsigned timeout; @@ -291,12 +291,12 @@ static inline void __xen_spin_lock(struct raw_spinlock *lock, bool irq_enable) spin_time_accum_total(start_spin); } -static void xen_spin_lock(struct raw_spinlock *lock) +static void xen_spin_lock(struct arch_spinlock *lock) { __xen_spin_lock(lock, false); } -static void xen_spin_lock_flags(struct raw_spinlock *lock, unsigned long flags) +static void xen_spin_lock_flags(struct arch_spinlock *lock, unsigned long flags) { __xen_spin_lock(lock, !raw_irqs_disabled_flags(flags)); } @@ -317,7 +317,7 @@ static noinline void xen_spin_unlock_slow(struct xen_spinlock *xl) } } -static void xen_spin_unlock(struct raw_spinlock *lock) +static void xen_spin_unlock(struct arch_spinlock *lock) { struct xen_spinlock *xl = (struct xen_spinlock *)lock; diff --git a/include/asm-generic/bitops/atomic.h b/include/asm-generic/bitops/atomic.h index c894646..dcf0afa 100644 --- a/include/asm-generic/bitops/atomic.h +++ b/include/asm-generic/bitops/atomic.h @@ -15,18 +15,18 @@ # define ATOMIC_HASH_SIZE 4 # define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) a)/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ])) -extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned; +extern arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned; /* Can't use raw_spin_lock_irq because of #include problems, so * this is the substitute */ #define _atomic_spin_lock_irqsave(l,f) do { \ - raw_spinlock_t *s = ATOMIC_HASH(l); \ + arch_spinlock_t *s = ATOMIC_HASH(l); \ local_irq_save(f); \ __raw_spin_lock(s); \ } while(0) #define _atomic_spin_unlock_irqrestore(l,f) do { \ - raw_spinlock_t *s = ATOMIC_HASH(l); \ + arch_spinlock_t *s = ATOMIC_HASH(l); \ __raw_spin_unlock(s); \ local_irq_restore(f); \ } while(0) diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index a9aaa70..5ef7a4c 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -8,7 +8,7 @@ * * on SMP builds: * - * asm/spinlock_types.h: contains the raw_spinlock_t/raw_rwlock_t and the + * asm/spinlock_types.h: contains the arch_spinlock_t/raw_rwlock_t and the * initializers * * linux/spinlock_types.h: @@ -75,7 +75,7 @@ #define __lockfunc __attribute__((section(".spinlock.text"))) /* - * Pull the raw_spinlock_t and raw_rwlock_t definitions: + * Pull the arch_spinlock_t and raw_rwlock_t definitions: */ #include diff --git a/include/linux/spinlock_types.h b/include/linux/spinlock_types.h index f979d5d..d4af2d7 100644 --- a/include/linux/spinlock_types.h +++ b/include/linux/spinlock_types.h @@ -18,7 +18,7 @@ #include typedef struct { - raw_spinlock_t raw_lock; + arch_spinlock_t raw_lock; #ifdef CONFIG_GENERIC_LOCKBREAK unsigned int break_lock; #endif diff --git a/include/linux/spinlock_types_up.h b/include/linux/spinlock_types_up.h index 04135b0..34d3669 100644 --- a/include/linux/spinlock_types_up.h +++ b/include/linux/spinlock_types_up.h @@ -16,13 +16,13 @@ typedef struct { volatile unsigned int slock; -} raw_spinlock_t; +} arch_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 1 } #else -typedef struct { } raw_spinlock_t; +typedef struct { } arch_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { } diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h index d4841ed..8ee2ac1 100644 --- a/include/linux/spinlock_up.h +++ b/include/linux/spinlock_up.h @@ -20,19 +20,19 @@ #ifdef CONFIG_DEBUG_SPINLOCK #define __raw_spin_is_locked(x) ((x)->slock == 0) -static inline void __raw_spin_lock(raw_spinlock_t *lock) +static inline void __raw_spin_lock(arch_spinlock_t *lock) { lock->slock = 0; } static inline void -__raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) +__raw_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { local_irq_save(flags); lock->slock = 0; } -static inline int __raw_spin_trylock(raw_spinlock_t *lock) +static inline int __raw_spin_trylock(arch_spinlock_t *lock) { char oldval = lock->slock; @@ -41,7 +41,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) return oldval > 0; } -static inline void __raw_spin_unlock(raw_spinlock_t *lock) +static inline void __raw_spin_unlock(arch_spinlock_t *lock) { lock->slock = 1; } diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 429540c..7cc50c6 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -73,7 +73,7 @@ module_param(lock_stat, int, 0644); * to use a raw spinlock - we really dont want the spinlock * code to recurse back into the lockdep code... */ -static raw_spinlock_t lockdep_lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; +static arch_spinlock_t lockdep_lock = (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; static int graph_lock(void) { diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index a1ca495..5ac8ee0 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -423,7 +423,7 @@ struct ring_buffer_per_cpu { int cpu; struct ring_buffer *buffer; spinlock_t reader_lock; /* serialize readers */ - raw_spinlock_t lock; + arch_spinlock_t lock; struct lock_class_key lock_key; struct list_head *pages; struct buffer_page *head_page; /* read from head */ @@ -998,7 +998,7 @@ rb_allocate_cpu_buffer(struct ring_buffer *buffer, int cpu) cpu_buffer->buffer = buffer; spin_lock_init(&cpu_buffer->reader_lock); lockdep_set_class(&cpu_buffer->reader_lock, buffer->reader_lock_key); - cpu_buffer->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + cpu_buffer->lock = (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; bpage = kzalloc_node(ALIGN(sizeof(*bpage), cache_line_size()), GFP_KERNEL, cpu_to_node(cpu)); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c82dfd9..7d56cec 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -493,15 +493,15 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt) * protected by per_cpu spinlocks. But the action of the swap * needs its own lock. * - * This is defined as a raw_spinlock_t in order to help + * This is defined as a arch_spinlock_t in order to help * with performance when lockdep debugging is enabled. * * It is also used in other places outside the update_max_tr * so it needs to be defined outside of the * CONFIG_TRACER_MAX_TRACE. */ -static raw_spinlock_t ftrace_max_lock = - (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; +static arch_spinlock_t ftrace_max_lock = + (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; #ifdef CONFIG_TRACER_MAX_TRACE unsigned long __read_mostly tracing_max_latency; @@ -802,7 +802,7 @@ static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; static int cmdline_idx; -static raw_spinlock_t trace_cmdline_lock = __RAW_SPIN_LOCK_UNLOCKED; +static arch_spinlock_t trace_cmdline_lock = __RAW_SPIN_LOCK_UNLOCKED; /* temporary disable recording */ static atomic_t trace_record_cmdline_disabled __read_mostly; @@ -1251,8 +1251,8 @@ ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) */ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) { - static raw_spinlock_t trace_buf_lock = - (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + static arch_spinlock_t trace_buf_lock = + (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; static u32 trace_buf[TRACE_BUF_SIZE]; struct ftrace_event_call *call = &event_bprint; @@ -1334,7 +1334,7 @@ int trace_array_printk(struct trace_array *tr, int trace_array_vprintk(struct trace_array *tr, unsigned long ip, const char *fmt, va_list args) { - static raw_spinlock_t trace_buf_lock = __RAW_SPIN_LOCK_UNLOCKED; + static arch_spinlock_t trace_buf_lock = __RAW_SPIN_LOCK_UNLOCKED; static char trace_buf[TRACE_BUF_SIZE]; struct ftrace_event_call *call = &event_print; @@ -4307,8 +4307,8 @@ trace_printk_seq(struct trace_seq *s) static void __ftrace_dump(bool disable_tracing) { - static raw_spinlock_t ftrace_dump_lock = - (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + static arch_spinlock_t ftrace_dump_lock = + (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; /* use static because iter can be a bit big for the stack */ static struct trace_iterator iter; unsigned int old_userobj; diff --git a/kernel/trace/trace_clock.c b/kernel/trace/trace_clock.c index 878c03f..206ec3d 100644 --- a/kernel/trace/trace_clock.c +++ b/kernel/trace/trace_clock.c @@ -71,10 +71,10 @@ u64 notrace trace_clock(void) /* keep prev_time and lock in the same cacheline. */ static struct { u64 prev_time; - raw_spinlock_t lock; + arch_spinlock_t lock; } trace_clock_struct ____cacheline_aligned_in_smp = { - .lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED, + .lock = (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED, }; u64 notrace trace_clock_global(void) diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 26185d7..4cf7e83 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -28,8 +28,8 @@ static int wakeup_current_cpu; static unsigned wakeup_prio = -1; static int wakeup_rt; -static raw_spinlock_t wakeup_lock = - (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; +static arch_spinlock_t wakeup_lock = + (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; static void __wakeup_reset(struct trace_array *tr); diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index 8504ac7..9a82d56 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c @@ -27,8 +27,8 @@ static struct stack_trace max_stack_trace = { }; static unsigned long max_stack_size; -static raw_spinlock_t max_stack_lock = - (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; +static arch_spinlock_t max_stack_lock = + (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; static int stack_trace_disabled __read_mostly; static DEFINE_PER_CPU(int, trace_active); diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index 9c4b025..2acd501 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c @@ -23,7 +23,7 @@ void __spin_lock_init(spinlock_t *lock, const char *name, debug_check_no_locks_freed((void *)lock, sizeof(*lock)); lockdep_init_map(&lock->dep_map, name, key, 0); #endif - lock->raw_lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + lock->raw_lock = (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; lock->magic = SPINLOCK_MAGIC; lock->owner = SPINLOCK_OWNER_INIT; lock->owner_cpu = -1; -- cgit v0.10.2 From edc35bd72e2079b25f99c5da7d7a65dbbffc4a26 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 3 Dec 2009 12:38:57 +0100 Subject: locking: Rename __RAW_SPIN_LOCK_UNLOCKED to __ARCH_SPIN_LOCK_UNLOCKED Further name space cleanup. No functional change Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: David S. Miller Acked-by: Ingo Molnar Cc: linux-arch@vger.kernel.org diff --git a/arch/alpha/include/asm/spinlock_types.h b/arch/alpha/include/asm/spinlock_types.h index bb94a51..08975ee 100644 --- a/arch/alpha/include/asm/spinlock_types.h +++ b/arch/alpha/include/asm/spinlock_types.h @@ -9,7 +9,7 @@ typedef struct { volatile unsigned int lock; } arch_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { 0 } +#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } typedef struct { volatile unsigned int lock; diff --git a/arch/arm/include/asm/spinlock_types.h b/arch/arm/include/asm/spinlock_types.h index 5e9d3ea..9622e12 100644 --- a/arch/arm/include/asm/spinlock_types.h +++ b/arch/arm/include/asm/spinlock_types.h @@ -9,7 +9,7 @@ typedef struct { volatile unsigned int lock; } arch_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { 0 } +#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } typedef struct { volatile unsigned int lock; diff --git a/arch/blackfin/include/asm/spinlock_types.h b/arch/blackfin/include/asm/spinlock_types.h index 03b377a..c8a3928 100644 --- a/arch/blackfin/include/asm/spinlock_types.h +++ b/arch/blackfin/include/asm/spinlock_types.h @@ -17,7 +17,7 @@ typedef struct { volatile unsigned int lock; } arch_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { 0 } +#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } typedef struct { volatile unsigned int lock; diff --git a/arch/ia64/include/asm/spinlock_types.h b/arch/ia64/include/asm/spinlock_types.h index 447ccc6..6a11b65 100644 --- a/arch/ia64/include/asm/spinlock_types.h +++ b/arch/ia64/include/asm/spinlock_types.h @@ -9,7 +9,7 @@ typedef struct { volatile unsigned int lock; } arch_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { 0 } +#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } typedef struct { volatile unsigned int read_counter : 31; diff --git a/arch/m32r/include/asm/spinlock_types.h b/arch/m32r/include/asm/spinlock_types.h index 17d15bd..5873a87 100644 --- a/arch/m32r/include/asm/spinlock_types.h +++ b/arch/m32r/include/asm/spinlock_types.h @@ -9,7 +9,7 @@ typedef struct { volatile int slock; } arch_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { 1 } +#define __ARCH_SPIN_LOCK_UNLOCKED { 1 } typedef struct { volatile int lock; diff --git a/arch/mips/include/asm/spinlock_types.h b/arch/mips/include/asm/spinlock_types.h index 2e10608..b4c5efa 100644 --- a/arch/mips/include/asm/spinlock_types.h +++ b/arch/mips/include/asm/spinlock_types.h @@ -14,7 +14,7 @@ typedef struct { unsigned int lock; } arch_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { 0 } +#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } typedef struct { volatile unsigned int lock; diff --git a/arch/parisc/include/asm/spinlock_types.h b/arch/parisc/include/asm/spinlock_types.h index 735caaf..396d274 100644 --- a/arch/parisc/include/asm/spinlock_types.h +++ b/arch/parisc/include/asm/spinlock_types.h @@ -4,10 +4,10 @@ typedef struct { #ifdef CONFIG_PA20 volatile unsigned int slock; -# define __RAW_SPIN_LOCK_UNLOCKED { 1 } +# define __ARCH_SPIN_LOCK_UNLOCKED { 1 } #else volatile unsigned int lock[4]; -# define __RAW_SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } } +# define __ARCH_SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } } #endif } arch_spinlock_t; @@ -16,6 +16,6 @@ typedef struct { volatile int counter; } raw_rwlock_t; -#define __RAW_RW_LOCK_UNLOCKED { __RAW_SPIN_LOCK_UNLOCKED, 0 } +#define __RAW_RW_LOCK_UNLOCKED { __ARCH_SPIN_LOCK_UNLOCKED, 0 } #endif diff --git a/arch/parisc/lib/bitops.c b/arch/parisc/lib/bitops.c index fdd7f58..353963d 100644 --- a/arch/parisc/lib/bitops.c +++ b/arch/parisc/lib/bitops.c @@ -13,7 +13,7 @@ #ifdef CONFIG_SMP arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = { - [0 ... (ATOMIC_HASH_SIZE-1)] = __RAW_SPIN_LOCK_UNLOCKED + [0 ... (ATOMIC_HASH_SIZE-1)] = __ARCH_SPIN_LOCK_UNLOCKED }; #endif diff --git a/arch/powerpc/include/asm/spinlock_types.h b/arch/powerpc/include/asm/spinlock_types.h index 4312e5b..f5f39d8 100644 --- a/arch/powerpc/include/asm/spinlock_types.h +++ b/arch/powerpc/include/asm/spinlock_types.h @@ -9,7 +9,7 @@ typedef struct { volatile unsigned int slock; } arch_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { 0 } +#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } typedef struct { volatile signed int lock; diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 579069c..57dfa41 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -42,7 +42,7 @@ #include struct rtas_t rtas = { - .lock = __RAW_SPIN_LOCK_UNLOCKED + .lock = __ARCH_SPIN_LOCK_UNLOCKED }; EXPORT_SYMBOL(rtas); diff --git a/arch/s390/include/asm/spinlock_types.h b/arch/s390/include/asm/spinlock_types.h index a93638e..e25c037 100644 --- a/arch/s390/include/asm/spinlock_types.h +++ b/arch/s390/include/asm/spinlock_types.h @@ -9,7 +9,7 @@ typedef struct { volatile unsigned int owner_cpu; } __attribute__ ((aligned (4))) arch_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { 0 } +#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } typedef struct { volatile unsigned int lock; diff --git a/arch/sh/include/asm/spinlock_types.h b/arch/sh/include/asm/spinlock_types.h index 37712c3..a3be2db 100644 --- a/arch/sh/include/asm/spinlock_types.h +++ b/arch/sh/include/asm/spinlock_types.h @@ -9,7 +9,7 @@ typedef struct { volatile unsigned int lock; } arch_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { 1 } +#define __ARCH_SPIN_LOCK_UNLOCKED { 1 } typedef struct { volatile unsigned int lock; diff --git a/arch/sparc/include/asm/spinlock_types.h b/arch/sparc/include/asm/spinlock_types.h index 41d9a8f..c145e63 100644 --- a/arch/sparc/include/asm/spinlock_types.h +++ b/arch/sparc/include/asm/spinlock_types.h @@ -9,7 +9,7 @@ typedef struct { volatile unsigned char lock; } arch_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { 0 } +#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } typedef struct { volatile unsigned int lock; diff --git a/arch/x86/include/asm/spinlock_types.h b/arch/x86/include/asm/spinlock_types.h index 2ae7637..696f836 100644 --- a/arch/x86/include/asm/spinlock_types.h +++ b/arch/x86/include/asm/spinlock_types.h @@ -9,7 +9,7 @@ typedef struct arch_spinlock { unsigned int slock; } arch_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { 0 } +#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } typedef struct { unsigned int lock; diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 0862d9d..5b75afa 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -188,7 +188,7 @@ void dump_stack(void) } EXPORT_SYMBOL(dump_stack); -static arch_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED; +static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED; static int die_owner = -1; static unsigned int die_nest_count; diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c index 9f908b9..f171469 100644 --- a/arch/x86/kernel/tsc_sync.c +++ b/arch/x86/kernel/tsc_sync.c @@ -33,7 +33,7 @@ static __cpuinitdata atomic_t stop_count; * we want to have the fastest, inlined, non-debug version * of a critical section, to be able to prove TSC time-warps: */ -static __cpuinitdata arch_spinlock_t sync_lock = __RAW_SPIN_LOCK_UNLOCKED; +static __cpuinitdata arch_spinlock_t sync_lock = __ARCH_SPIN_LOCK_UNLOCKED; static __cpuinitdata cycles_t last_tsc; static __cpuinitdata cycles_t max_warp; diff --git a/include/linux/spinlock_types.h b/include/linux/spinlock_types.h index d4af2d7..7dadce3 100644 --- a/include/linux/spinlock_types.h +++ b/include/linux/spinlock_types.h @@ -43,14 +43,14 @@ typedef struct { #ifdef CONFIG_DEBUG_SPINLOCK # define __SPIN_LOCK_UNLOCKED(lockname) \ - (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED, \ + (spinlock_t) { .raw_lock = __ARCH_SPIN_LOCK_UNLOCKED, \ .magic = SPINLOCK_MAGIC, \ .owner = SPINLOCK_OWNER_INIT, \ .owner_cpu = -1, \ SPIN_DEP_MAP_INIT(lockname) } #else # define __SPIN_LOCK_UNLOCKED(lockname) \ - (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED, \ + (spinlock_t) { .raw_lock = __ARCH_SPIN_LOCK_UNLOCKED, \ SPIN_DEP_MAP_INIT(lockname) } #endif diff --git a/include/linux/spinlock_types_up.h b/include/linux/spinlock_types_up.h index 34d3669..10db021 100644 --- a/include/linux/spinlock_types_up.h +++ b/include/linux/spinlock_types_up.h @@ -18,13 +18,13 @@ typedef struct { volatile unsigned int slock; } arch_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { 1 } +#define __ARCH_SPIN_LOCK_UNLOCKED { 1 } #else typedef struct { } arch_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { } +#define __ARCH_SPIN_LOCK_UNLOCKED { } #endif diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 7cc50c6..2389e3f 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -73,7 +73,7 @@ module_param(lock_stat, int, 0644); * to use a raw spinlock - we really dont want the spinlock * code to recurse back into the lockdep code... */ -static arch_spinlock_t lockdep_lock = (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; +static arch_spinlock_t lockdep_lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; static int graph_lock(void) { diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 5ac8ee0..fb7a0fa 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -998,7 +998,7 @@ rb_allocate_cpu_buffer(struct ring_buffer *buffer, int cpu) cpu_buffer->buffer = buffer; spin_lock_init(&cpu_buffer->reader_lock); lockdep_set_class(&cpu_buffer->reader_lock, buffer->reader_lock_key); - cpu_buffer->lock = (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + cpu_buffer->lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; bpage = kzalloc_node(ALIGN(sizeof(*bpage), cache_line_size()), GFP_KERNEL, cpu_to_node(cpu)); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 7d56cec..63bc1cc 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -501,7 +501,7 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt) * CONFIG_TRACER_MAX_TRACE. */ static arch_spinlock_t ftrace_max_lock = - (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; #ifdef CONFIG_TRACER_MAX_TRACE unsigned long __read_mostly tracing_max_latency; @@ -802,7 +802,7 @@ static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; static int cmdline_idx; -static arch_spinlock_t trace_cmdline_lock = __RAW_SPIN_LOCK_UNLOCKED; +static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED; /* temporary disable recording */ static atomic_t trace_record_cmdline_disabled __read_mostly; @@ -1252,7 +1252,7 @@ ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) { static arch_spinlock_t trace_buf_lock = - (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; static u32 trace_buf[TRACE_BUF_SIZE]; struct ftrace_event_call *call = &event_bprint; @@ -1334,7 +1334,7 @@ int trace_array_printk(struct trace_array *tr, int trace_array_vprintk(struct trace_array *tr, unsigned long ip, const char *fmt, va_list args) { - static arch_spinlock_t trace_buf_lock = __RAW_SPIN_LOCK_UNLOCKED; + static arch_spinlock_t trace_buf_lock = __ARCH_SPIN_LOCK_UNLOCKED; static char trace_buf[TRACE_BUF_SIZE]; struct ftrace_event_call *call = &event_print; @@ -4308,7 +4308,7 @@ trace_printk_seq(struct trace_seq *s) static void __ftrace_dump(bool disable_tracing) { static arch_spinlock_t ftrace_dump_lock = - (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; /* use static because iter can be a bit big for the stack */ static struct trace_iterator iter; unsigned int old_userobj; diff --git a/kernel/trace/trace_clock.c b/kernel/trace/trace_clock.c index 206ec3d..433e2ed 100644 --- a/kernel/trace/trace_clock.c +++ b/kernel/trace/trace_clock.c @@ -74,7 +74,7 @@ static struct { arch_spinlock_t lock; } trace_clock_struct ____cacheline_aligned_in_smp = { - .lock = (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED, + .lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED, }; u64 notrace trace_clock_global(void) diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 4cf7e83..e347853 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -29,7 +29,7 @@ static unsigned wakeup_prio = -1; static int wakeup_rt; static arch_spinlock_t wakeup_lock = - (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; static void __wakeup_reset(struct trace_array *tr); diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index 9a82d56..728c352 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c @@ -28,7 +28,7 @@ static struct stack_trace max_stack_trace = { static unsigned long max_stack_size; static arch_spinlock_t max_stack_lock = - (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; static int stack_trace_disabled __read_mostly; static DEFINE_PER_CPU(int, trace_active); diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index 2acd501..f730041 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c @@ -23,7 +23,7 @@ void __spin_lock_init(spinlock_t *lock, const char *name, debug_check_no_locks_freed((void *)lock, sizeof(*lock)); lockdep_init_map(&lock->dep_map, name, key, 0); #endif - lock->raw_lock = (arch_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; + lock->raw_lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; lock->magic = SPINLOCK_MAGIC; lock->owner = SPINLOCK_OWNER_INIT; lock->owner_cpu = -1; -- cgit v0.10.2 From 0199c4e68d1f02894bdefe4b5d9e9ee4aedd8d62 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 2 Dec 2009 20:01:25 +0100 Subject: locking: Convert __raw_spin* functions to arch_spin* Name space cleanup. No functional change. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: David S. Miller Acked-by: Ingo Molnar Cc: linux-arch@vger.kernel.org diff --git a/arch/alpha/include/asm/spinlock.h b/arch/alpha/include/asm/spinlock.h index bdb26a1..4dac79f 100644 --- a/arch/alpha/include/asm/spinlock.h +++ b/arch/alpha/include/asm/spinlock.h @@ -12,18 +12,18 @@ * We make no fairness assumptions. They have a cost. */ -#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) -#define __raw_spin_is_locked(x) ((x)->lock != 0) -#define __raw_spin_unlock_wait(x) \ +#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) +#define arch_spin_is_locked(x) ((x)->lock != 0) +#define arch_spin_unlock_wait(x) \ do { cpu_relax(); } while ((x)->lock) -static inline void __raw_spin_unlock(arch_spinlock_t * lock) +static inline void arch_spin_unlock(arch_spinlock_t * lock) { mb(); lock->lock = 0; } -static inline void __raw_spin_lock(arch_spinlock_t * lock) +static inline void arch_spin_lock(arch_spinlock_t * lock) { long tmp; @@ -43,7 +43,7 @@ static inline void __raw_spin_lock(arch_spinlock_t * lock) : "m"(lock->lock) : "memory"); } -static inline int __raw_spin_trylock(arch_spinlock_t *lock) +static inline int arch_spin_trylock(arch_spinlock_t *lock) { return !test_and_set_bit(0, &lock->lock); } @@ -169,8 +169,8 @@ static inline void __raw_write_unlock(raw_rwlock_t * lock) #define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) #define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) -#define _raw_spin_relax(lock) cpu_relax() -#define _raw_read_relax(lock) cpu_relax() -#define _raw_write_relax(lock) cpu_relax() +#define arch_spin_relax(lock) cpu_relax() +#define arch_read_relax(lock) cpu_relax() +#define arch_write_relax(lock) cpu_relax() #endif /* _ALPHA_SPINLOCK_H */ diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h index 4e7712e..de62eb0 100644 --- a/arch/arm/include/asm/spinlock.h +++ b/arch/arm/include/asm/spinlock.h @@ -17,13 +17,13 @@ * Locked value: 1 */ -#define __raw_spin_is_locked(x) ((x)->lock != 0) -#define __raw_spin_unlock_wait(lock) \ - do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) +#define arch_spin_is_locked(x) ((x)->lock != 0) +#define arch_spin_unlock_wait(lock) \ + do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0) -#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) +#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) -static inline void __raw_spin_lock(arch_spinlock_t *lock) +static inline void arch_spin_lock(arch_spinlock_t *lock) { unsigned long tmp; @@ -43,7 +43,7 @@ static inline void __raw_spin_lock(arch_spinlock_t *lock) smp_mb(); } -static inline int __raw_spin_trylock(arch_spinlock_t *lock) +static inline int arch_spin_trylock(arch_spinlock_t *lock) { unsigned long tmp; @@ -63,7 +63,7 @@ static inline int __raw_spin_trylock(arch_spinlock_t *lock) } } -static inline void __raw_spin_unlock(arch_spinlock_t *lock) +static inline void arch_spin_unlock(arch_spinlock_t *lock) { smp_mb(); @@ -220,8 +220,8 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw) #define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) #define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) -#define _raw_spin_relax(lock) cpu_relax() -#define _raw_read_relax(lock) cpu_relax() -#define _raw_write_relax(lock) cpu_relax() +#define arch_spin_relax(lock) cpu_relax() +#define arch_read_relax(lock) cpu_relax() +#define arch_write_relax(lock) cpu_relax() #endif /* __ASM_SPINLOCK_H */ diff --git a/arch/blackfin/include/asm/spinlock.h b/arch/blackfin/include/asm/spinlock.h index fc16b4c..62d4954 100644 --- a/arch/blackfin/include/asm/spinlock.h +++ b/arch/blackfin/include/asm/spinlock.h @@ -24,31 +24,31 @@ asmlinkage void __raw_write_lock_asm(volatile int *ptr); asmlinkage int __raw_write_trylock_asm(volatile int *ptr); asmlinkage void __raw_write_unlock_asm(volatile int *ptr); -static inline int __raw_spin_is_locked(arch_spinlock_t *lock) +static inline int arch_spin_is_locked(arch_spinlock_t *lock) { return __raw_spin_is_locked_asm(&lock->lock); } -static inline void __raw_spin_lock(arch_spinlock_t *lock) +static inline void arch_spin_lock(arch_spinlock_t *lock) { __raw_spin_lock_asm(&lock->lock); } -#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) +#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) -static inline int __raw_spin_trylock(arch_spinlock_t *lock) +static inline int arch_spin_trylock(arch_spinlock_t *lock) { return __raw_spin_trylock_asm(&lock->lock); } -static inline void __raw_spin_unlock(arch_spinlock_t *lock) +static inline void arch_spin_unlock(arch_spinlock_t *lock) { __raw_spin_unlock_asm(&lock->lock); } -static inline void __raw_spin_unlock_wait(arch_spinlock_t *lock) +static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) { - while (__raw_spin_is_locked(lock)) + while (arch_spin_is_locked(lock)) cpu_relax(); } @@ -92,9 +92,9 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) __raw_write_unlock_asm(&rw->lock); } -#define _raw_spin_relax(lock) cpu_relax() -#define _raw_read_relax(lock) cpu_relax() -#define _raw_write_relax(lock) cpu_relax() +#define arch_spin_relax(lock) cpu_relax() +#define arch_read_relax(lock) cpu_relax() +#define arch_write_relax(lock) cpu_relax() #endif diff --git a/arch/cris/include/arch-v32/arch/spinlock.h b/arch/cris/include/arch-v32/arch/spinlock.h index e253457..a2e8a39 100644 --- a/arch/cris/include/arch-v32/arch/spinlock.h +++ b/arch/cris/include/arch-v32/arch/spinlock.h @@ -9,12 +9,12 @@ extern void cris_spin_unlock(void *l, int val); extern void cris_spin_lock(void *l); extern int cris_spin_trylock(void *l); -static inline int __raw_spin_is_locked(arch_spinlock_t *x) +static inline int arch_spin_is_locked(arch_spinlock_t *x) { return *(volatile signed char *)(&(x)->slock) <= 0; } -static inline void __raw_spin_unlock(arch_spinlock_t *lock) +static inline void arch_spin_unlock(arch_spinlock_t *lock) { __asm__ volatile ("move.d %1,%0" \ : "=m" (lock->slock) \ @@ -22,26 +22,26 @@ static inline void __raw_spin_unlock(arch_spinlock_t *lock) : "memory"); } -static inline void __raw_spin_unlock_wait(arch_spinlock_t *lock) +static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) { - while (__raw_spin_is_locked(lock)) + while (arch_spin_is_locked(lock)) cpu_relax(); } -static inline int __raw_spin_trylock(arch_spinlock_t *lock) +static inline int arch_spin_trylock(arch_spinlock_t *lock) { return cris_spin_trylock((void *)&lock->slock); } -static inline void __raw_spin_lock(arch_spinlock_t *lock) +static inline void arch_spin_lock(arch_spinlock_t *lock) { cris_spin_lock((void *)&lock->slock); } static inline void -__raw_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) +arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { - __raw_spin_lock(lock); + arch_spin_lock(lock); } /* @@ -68,64 +68,64 @@ static inline int __raw_write_can_lock(raw_rwlock_t *x) static inline void __raw_read_lock(raw_rwlock_t *rw) { - __raw_spin_lock(&rw->slock); + arch_spin_lock(&rw->slock); while (rw->lock == 0); rw->lock--; - __raw_spin_unlock(&rw->slock); + arch_spin_unlock(&rw->slock); } static inline void __raw_write_lock(raw_rwlock_t *rw) { - __raw_spin_lock(&rw->slock); + arch_spin_lock(&rw->slock); while (rw->lock != RW_LOCK_BIAS); rw->lock = 0; - __raw_spin_unlock(&rw->slock); + arch_spin_unlock(&rw->slock); } static inline void __raw_read_unlock(raw_rwlock_t *rw) { - __raw_spin_lock(&rw->slock); + arch_spin_lock(&rw->slock); rw->lock++; - __raw_spin_unlock(&rw->slock); + arch_spin_unlock(&rw->slock); } static inline void __raw_write_unlock(raw_rwlock_t *rw) { - __raw_spin_lock(&rw->slock); + arch_spin_lock(&rw->slock); while (rw->lock != RW_LOCK_BIAS); rw->lock = RW_LOCK_BIAS; - __raw_spin_unlock(&rw->slock); + arch_spin_unlock(&rw->slock); } static inline int __raw_read_trylock(raw_rwlock_t *rw) { int ret = 0; - __raw_spin_lock(&rw->slock); + arch_spin_lock(&rw->slock); if (rw->lock != 0) { rw->lock--; ret = 1; } - __raw_spin_unlock(&rw->slock); + arch_spin_unlock(&rw->slock); return ret; } static inline int __raw_write_trylock(raw_rwlock_t *rw) { int ret = 0; - __raw_spin_lock(&rw->slock); + arch_spin_lock(&rw->slock); if (rw->lock == RW_LOCK_BIAS) { rw->lock = 0; ret = 1; } - __raw_spin_unlock(&rw->slock); + arch_spin_unlock(&rw->slock); return 1; } #define _raw_read_lock_flags(lock, flags) _raw_read_lock(lock) #define _raw_write_lock_flags(lock, flags) _raw_write_lock(lock) -#define _raw_spin_relax(lock) cpu_relax() -#define _raw_read_relax(lock) cpu_relax() -#define _raw_write_relax(lock) cpu_relax() +#define arch_spin_relax(lock) cpu_relax() +#define arch_read_relax(lock) cpu_relax() +#define arch_write_relax(lock) cpu_relax() #endif /* __ASM_ARCH_SPINLOCK_H */ diff --git a/arch/ia64/include/asm/bitops.h b/arch/ia64/include/asm/bitops.h index 57a2787..6ebc229 100644 --- a/arch/ia64/include/asm/bitops.h +++ b/arch/ia64/include/asm/bitops.h @@ -127,7 +127,7 @@ clear_bit_unlock (int nr, volatile void *addr) * @addr: Address to start counting from * * Similarly to clear_bit_unlock, the implementation uses a store - * with release semantics. See also __raw_spin_unlock(). + * with release semantics. See also arch_spin_unlock(). */ static __inline__ void __clear_bit_unlock(int nr, void *addr) diff --git a/arch/ia64/include/asm/spinlock.h b/arch/ia64/include/asm/spinlock.h index 9fbdf7e..b06165f 100644 --- a/arch/ia64/include/asm/spinlock.h +++ b/arch/ia64/include/asm/spinlock.h @@ -17,7 +17,7 @@ #include #include -#define __raw_spin_lock_init(x) ((x)->lock = 0) +#define arch_spin_lock_init(x) ((x)->lock = 0) /* * Ticket locks are conceptually two parts, one indicating the current head of @@ -103,39 +103,39 @@ static inline int __ticket_spin_is_contended(arch_spinlock_t *lock) return ((tmp - (tmp >> TICKET_SHIFT)) & TICKET_MASK) > 1; } -static inline int __raw_spin_is_locked(arch_spinlock_t *lock) +static inline int arch_spin_is_locked(arch_spinlock_t *lock) { return __ticket_spin_is_locked(lock); } -static inline int __raw_spin_is_contended(arch_spinlock_t *lock) +static inline int arch_spin_is_contended(arch_spinlock_t *lock) { return __ticket_spin_is_contended(lock); } -#define __raw_spin_is_contended __raw_spin_is_contended +#define arch_spin_is_contended arch_spin_is_contended -static __always_inline void __raw_spin_lock(arch_spinlock_t *lock) +static __always_inline void arch_spin_lock(arch_spinlock_t *lock) { __ticket_spin_lock(lock); } -static __always_inline int __raw_spin_trylock(arch_spinlock_t *lock) +static __always_inline int arch_spin_trylock(arch_spinlock_t *lock) { return __ticket_spin_trylock(lock); } -static __always_inline void __raw_spin_unlock(arch_spinlock_t *lock) +static __always_inline void arch_spin_unlock(arch_spinlock_t *lock) { __ticket_spin_unlock(lock); } -static __always_inline void __raw_spin_lock_flags(arch_spinlock_t *lock, +static __always_inline void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { - __raw_spin_lock(lock); + arch_spin_lock(lock); } -static inline void __raw_spin_unlock_wait(arch_spinlock_t *lock) +static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) { __ticket_spin_unlock_wait(lock); } @@ -285,8 +285,8 @@ static inline int __raw_read_trylock(raw_rwlock_t *x) return (u32)ia64_cmpxchg4_acq((__u32 *)(x), new.word, old.word) == old.word; } -#define _raw_spin_relax(lock) cpu_relax() -#define _raw_read_relax(lock) cpu_relax() -#define _raw_write_relax(lock) cpu_relax() +#define arch_spin_relax(lock) cpu_relax() +#define arch_read_relax(lock) cpu_relax() +#define arch_write_relax(lock) cpu_relax() #endif /* _ASM_IA64_SPINLOCK_H */ diff --git a/arch/m32r/include/asm/spinlock.h b/arch/m32r/include/asm/spinlock.h index 0c01642..8acac95 100644 --- a/arch/m32r/include/asm/spinlock.h +++ b/arch/m32r/include/asm/spinlock.h @@ -24,19 +24,19 @@ * We make no fairness assumptions. They have a cost. */ -#define __raw_spin_is_locked(x) (*(volatile int *)(&(x)->slock) <= 0) -#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) -#define __raw_spin_unlock_wait(x) \ - do { cpu_relax(); } while (__raw_spin_is_locked(x)) +#define arch_spin_is_locked(x) (*(volatile int *)(&(x)->slock) <= 0) +#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) +#define arch_spin_unlock_wait(x) \ + do { cpu_relax(); } while (arch_spin_is_locked(x)) /** - * __raw_spin_trylock - Try spin lock and return a result + * arch_spin_trylock - Try spin lock and return a result * @lock: Pointer to the lock variable * - * __raw_spin_trylock() tries to get the lock and returns a result. + * arch_spin_trylock() tries to get the lock and returns a result. * On the m32r, the result value is 1 (= Success) or 0 (= Failure). */ -static inline int __raw_spin_trylock(arch_spinlock_t *lock) +static inline int arch_spin_trylock(arch_spinlock_t *lock) { int oldval; unsigned long tmp1, tmp2; @@ -50,7 +50,7 @@ static inline int __raw_spin_trylock(arch_spinlock_t *lock) * } */ __asm__ __volatile__ ( - "# __raw_spin_trylock \n\t" + "# arch_spin_trylock \n\t" "ldi %1, #0; \n\t" "mvfc %2, psw; \n\t" "clrpsw #0x40 -> nop; \n\t" @@ -69,7 +69,7 @@ static inline int __raw_spin_trylock(arch_spinlock_t *lock) return (oldval > 0); } -static inline void __raw_spin_lock(arch_spinlock_t *lock) +static inline void arch_spin_lock(arch_spinlock_t *lock) { unsigned long tmp0, tmp1; @@ -84,7 +84,7 @@ static inline void __raw_spin_lock(arch_spinlock_t *lock) * } */ __asm__ __volatile__ ( - "# __raw_spin_lock \n\t" + "# arch_spin_lock \n\t" ".fillinsn \n" "1: \n\t" "mvfc %1, psw; \n\t" @@ -111,7 +111,7 @@ static inline void __raw_spin_lock(arch_spinlock_t *lock) ); } -static inline void __raw_spin_unlock(arch_spinlock_t *lock) +static inline void arch_spin_unlock(arch_spinlock_t *lock) { mb(); lock->slock = 1; @@ -319,8 +319,8 @@ static inline int __raw_write_trylock(raw_rwlock_t *lock) #define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) #define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) -#define _raw_spin_relax(lock) cpu_relax() -#define _raw_read_relax(lock) cpu_relax() -#define _raw_write_relax(lock) cpu_relax() +#define arch_spin_relax(lock) cpu_relax() +#define arch_read_relax(lock) cpu_relax() +#define arch_write_relax(lock) cpu_relax() #endif /* _ASM_M32R_SPINLOCK_H */ diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index 0f16d06..95edeba 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h @@ -34,33 +34,33 @@ * becomes equal to the the initial value of the tail. */ -static inline int __raw_spin_is_locked(arch_spinlock_t *lock) +static inline int arch_spin_is_locked(arch_spinlock_t *lock) { unsigned int counters = ACCESS_ONCE(lock->lock); return ((counters >> 14) ^ counters) & 0x1fff; } -#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) -#define __raw_spin_unlock_wait(x) \ - while (__raw_spin_is_locked(x)) { cpu_relax(); } +#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) +#define arch_spin_unlock_wait(x) \ + while (arch_spin_is_locked(x)) { cpu_relax(); } -static inline int __raw_spin_is_contended(arch_spinlock_t *lock) +static inline int arch_spin_is_contended(arch_spinlock_t *lock) { unsigned int counters = ACCESS_ONCE(lock->lock); return (((counters >> 14) - counters) & 0x1fff) > 1; } -#define __raw_spin_is_contended __raw_spin_is_contended +#define arch_spin_is_contended arch_spin_is_contended -static inline void __raw_spin_lock(arch_spinlock_t *lock) +static inline void arch_spin_lock(arch_spinlock_t *lock) { int my_ticket; int tmp; if (R10000_LLSC_WAR) { __asm__ __volatile__ ( - " .set push # __raw_spin_lock \n" + " .set push # arch_spin_lock \n" " .set noreorder \n" " \n" "1: ll %[ticket], %[ticket_ptr] \n" @@ -94,7 +94,7 @@ static inline void __raw_spin_lock(arch_spinlock_t *lock) [my_ticket] "=&r" (my_ticket)); } else { __asm__ __volatile__ ( - " .set push # __raw_spin_lock \n" + " .set push # arch_spin_lock \n" " .set noreorder \n" " \n" " ll %[ticket], %[ticket_ptr] \n" @@ -134,7 +134,7 @@ static inline void __raw_spin_lock(arch_spinlock_t *lock) smp_llsc_mb(); } -static inline void __raw_spin_unlock(arch_spinlock_t *lock) +static inline void arch_spin_unlock(arch_spinlock_t *lock) { int tmp; @@ -142,7 +142,7 @@ static inline void __raw_spin_unlock(arch_spinlock_t *lock) if (R10000_LLSC_WAR) { __asm__ __volatile__ ( - " # __raw_spin_unlock \n" + " # arch_spin_unlock \n" "1: ll %[ticket], %[ticket_ptr] \n" " addiu %[ticket], %[ticket], 1 \n" " ori %[ticket], %[ticket], 0x2000 \n" @@ -153,7 +153,7 @@ static inline void __raw_spin_unlock(arch_spinlock_t *lock) [ticket] "=&r" (tmp)); } else { __asm__ __volatile__ ( - " .set push # __raw_spin_unlock \n" + " .set push # arch_spin_unlock \n" " .set noreorder \n" " \n" " ll %[ticket], %[ticket_ptr] \n" @@ -174,13 +174,13 @@ static inline void __raw_spin_unlock(arch_spinlock_t *lock) } } -static inline unsigned int __raw_spin_trylock(arch_spinlock_t *lock) +static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) { int tmp, tmp2, tmp3; if (R10000_LLSC_WAR) { __asm__ __volatile__ ( - " .set push # __raw_spin_trylock \n" + " .set push # arch_spin_trylock \n" " .set noreorder \n" " \n" "1: ll %[ticket], %[ticket_ptr] \n" @@ -204,7 +204,7 @@ static inline unsigned int __raw_spin_trylock(arch_spinlock_t *lock) [now_serving] "=&r" (tmp3)); } else { __asm__ __volatile__ ( - " .set push # __raw_spin_trylock \n" + " .set push # arch_spin_trylock \n" " .set noreorder \n" " \n" " ll %[ticket], %[ticket_ptr] \n" @@ -483,8 +483,8 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) #define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) #define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) -#define _raw_spin_relax(lock) cpu_relax() -#define _raw_read_relax(lock) cpu_relax() -#define _raw_write_relax(lock) cpu_relax() +#define arch_spin_relax(lock) cpu_relax() +#define arch_read_relax(lock) cpu_relax() +#define arch_write_relax(lock) cpu_relax() #endif /* _ASM_SPINLOCK_H */ diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h index 3a4ea77..716634d 100644 --- a/arch/parisc/include/asm/atomic.h +++ b/arch/parisc/include/asm/atomic.h @@ -34,12 +34,12 @@ extern arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned; #define _atomic_spin_lock_irqsave(l,f) do { \ arch_spinlock_t *s = ATOMIC_HASH(l); \ local_irq_save(f); \ - __raw_spin_lock(s); \ + arch_spin_lock(s); \ } while(0) #define _atomic_spin_unlock_irqrestore(l,f) do { \ arch_spinlock_t *s = ATOMIC_HASH(l); \ - __raw_spin_unlock(s); \ + arch_spin_unlock(s); \ local_irq_restore(f); \ } while(0) diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h index 69e8dca..235e7e3 100644 --- a/arch/parisc/include/asm/spinlock.h +++ b/arch/parisc/include/asm/spinlock.h @@ -5,17 +5,17 @@ #include #include -static inline int __raw_spin_is_locked(arch_spinlock_t *x) +static inline int arch_spin_is_locked(arch_spinlock_t *x) { volatile unsigned int *a = __ldcw_align(x); return *a == 0; } -#define __raw_spin_lock(lock) __raw_spin_lock_flags(lock, 0) -#define __raw_spin_unlock_wait(x) \ - do { cpu_relax(); } while (__raw_spin_is_locked(x)) +#define arch_spin_lock(lock) arch_spin_lock_flags(lock, 0) +#define arch_spin_unlock_wait(x) \ + do { cpu_relax(); } while (arch_spin_is_locked(x)) -static inline void __raw_spin_lock_flags(arch_spinlock_t *x, +static inline void arch_spin_lock_flags(arch_spinlock_t *x, unsigned long flags) { volatile unsigned int *a; @@ -33,7 +33,7 @@ static inline void __raw_spin_lock_flags(arch_spinlock_t *x, mb(); } -static inline void __raw_spin_unlock(arch_spinlock_t *x) +static inline void arch_spin_unlock(arch_spinlock_t *x) { volatile unsigned int *a; mb(); @@ -42,7 +42,7 @@ static inline void __raw_spin_unlock(arch_spinlock_t *x) mb(); } -static inline int __raw_spin_trylock(arch_spinlock_t *x) +static inline int arch_spin_trylock(arch_spinlock_t *x) { volatile unsigned int *a; int ret; @@ -73,9 +73,9 @@ static __inline__ void __raw_read_lock(raw_rwlock_t *rw) { unsigned long flags; local_irq_save(flags); - __raw_spin_lock_flags(&rw->lock, flags); + arch_spin_lock_flags(&rw->lock, flags); rw->counter++; - __raw_spin_unlock(&rw->lock); + arch_spin_unlock(&rw->lock); local_irq_restore(flags); } @@ -85,9 +85,9 @@ static __inline__ void __raw_read_unlock(raw_rwlock_t *rw) { unsigned long flags; local_irq_save(flags); - __raw_spin_lock_flags(&rw->lock, flags); + arch_spin_lock_flags(&rw->lock, flags); rw->counter--; - __raw_spin_unlock(&rw->lock); + arch_spin_unlock(&rw->lock); local_irq_restore(flags); } @@ -98,9 +98,9 @@ static __inline__ int __raw_read_trylock(raw_rwlock_t *rw) unsigned long flags; retry: local_irq_save(flags); - if (__raw_spin_trylock(&rw->lock)) { + if (arch_spin_trylock(&rw->lock)) { rw->counter++; - __raw_spin_unlock(&rw->lock); + arch_spin_unlock(&rw->lock); local_irq_restore(flags); return 1; } @@ -111,7 +111,7 @@ static __inline__ int __raw_read_trylock(raw_rwlock_t *rw) return 0; /* Wait until we have a realistic chance at the lock */ - while (__raw_spin_is_locked(&rw->lock) && rw->counter >= 0) + while (arch_spin_is_locked(&rw->lock) && rw->counter >= 0) cpu_relax(); goto retry; @@ -124,10 +124,10 @@ static __inline__ void __raw_write_lock(raw_rwlock_t *rw) unsigned long flags; retry: local_irq_save(flags); - __raw_spin_lock_flags(&rw->lock, flags); + arch_spin_lock_flags(&rw->lock, flags); if (rw->counter != 0) { - __raw_spin_unlock(&rw->lock); + arch_spin_unlock(&rw->lock); local_irq_restore(flags); while (rw->counter != 0) @@ -144,7 +144,7 @@ retry: static __inline__ void __raw_write_unlock(raw_rwlock_t *rw) { rw->counter = 0; - __raw_spin_unlock(&rw->lock); + arch_spin_unlock(&rw->lock); } /* Note that we have to ensure interrupts are disabled in case we're @@ -155,13 +155,13 @@ static __inline__ int __raw_write_trylock(raw_rwlock_t *rw) int result = 0; local_irq_save(flags); - if (__raw_spin_trylock(&rw->lock)) { + if (arch_spin_trylock(&rw->lock)) { if (rw->counter == 0) { rw->counter = -1; result = 1; } else { /* Read-locked. Oh well. */ - __raw_spin_unlock(&rw->lock); + arch_spin_unlock(&rw->lock); } } local_irq_restore(flags); @@ -190,8 +190,8 @@ static __inline__ int __raw_write_can_lock(raw_rwlock_t *rw) #define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) #define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) -#define _raw_spin_relax(lock) cpu_relax() -#define _raw_read_relax(lock) cpu_relax() -#define _raw_write_relax(lock) cpu_relax() +#define arch_spin_relax(lock) cpu_relax() +#define arch_read_relax(lock) cpu_relax() +#define arch_write_relax(lock) cpu_relax() #endif /* __ASM_SPINLOCK_H */ diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h index c0d44c9..cdcaf6b 100644 --- a/arch/powerpc/include/asm/spinlock.h +++ b/arch/powerpc/include/asm/spinlock.h @@ -28,7 +28,7 @@ #include #include -#define __raw_spin_is_locked(x) ((x)->slock != 0) +#define arch_spin_is_locked(x) ((x)->slock != 0) #ifdef CONFIG_PPC64 /* use 0x800000yy when locked, where yy == CPU number */ @@ -54,7 +54,7 @@ * This returns the old value in the lock, so we succeeded * in getting the lock if the return value is 0. */ -static inline unsigned long arch_spin_trylock(arch_spinlock_t *lock) +static inline unsigned long __arch_spin_trylock(arch_spinlock_t *lock) { unsigned long tmp, token; @@ -73,10 +73,10 @@ static inline unsigned long arch_spin_trylock(arch_spinlock_t *lock) return tmp; } -static inline int __raw_spin_trylock(arch_spinlock_t *lock) +static inline int arch_spin_trylock(arch_spinlock_t *lock) { CLEAR_IO_SYNC; - return arch_spin_trylock(lock) == 0; + return __arch_spin_trylock(lock) == 0; } /* @@ -104,11 +104,11 @@ extern void __rw_yield(raw_rwlock_t *lock); #define SHARED_PROCESSOR 0 #endif -static inline void __raw_spin_lock(arch_spinlock_t *lock) +static inline void arch_spin_lock(arch_spinlock_t *lock) { CLEAR_IO_SYNC; while (1) { - if (likely(arch_spin_trylock(lock) == 0)) + if (likely(__arch_spin_trylock(lock) == 0)) break; do { HMT_low(); @@ -120,13 +120,13 @@ static inline void __raw_spin_lock(arch_spinlock_t *lock) } static inline -void __raw_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) +void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { unsigned long flags_dis; CLEAR_IO_SYNC; while (1) { - if (likely(arch_spin_trylock(lock) == 0)) + if (likely(__arch_spin_trylock(lock) == 0)) break; local_save_flags(flags_dis); local_irq_restore(flags); @@ -140,19 +140,19 @@ void __raw_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) } } -static inline void __raw_spin_unlock(arch_spinlock_t *lock) +static inline void arch_spin_unlock(arch_spinlock_t *lock) { SYNC_IO; - __asm__ __volatile__("# __raw_spin_unlock\n\t" + __asm__ __volatile__("# arch_spin_unlock\n\t" LWSYNC_ON_SMP: : :"memory"); lock->slock = 0; } #ifdef CONFIG_PPC64 -extern void __raw_spin_unlock_wait(arch_spinlock_t *lock); +extern void arch_spin_unlock_wait(arch_spinlock_t *lock); #else -#define __raw_spin_unlock_wait(lock) \ - do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) +#define arch_spin_unlock_wait(lock) \ + do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0) #endif /* @@ -290,9 +290,9 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) #define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) #define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) -#define _raw_spin_relax(lock) __spin_yield(lock) -#define _raw_read_relax(lock) __rw_yield(lock) -#define _raw_write_relax(lock) __rw_yield(lock) +#define arch_spin_relax(lock) __spin_yield(lock) +#define arch_read_relax(lock) __rw_yield(lock) +#define arch_write_relax(lock) __rw_yield(lock) #endif /* __KERNEL__ */ #endif /* __ASM_SPINLOCK_H */ diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 57dfa41..fd0d294 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -80,13 +80,13 @@ static unsigned long lock_rtas(void) local_irq_save(flags); preempt_disable(); - __raw_spin_lock_flags(&rtas.lock, flags); + arch_spin_lock_flags(&rtas.lock, flags); return flags; } static void unlock_rtas(unsigned long flags) { - __raw_spin_unlock(&rtas.lock); + arch_spin_unlock(&rtas.lock); local_irq_restore(flags); preempt_enable(); } @@ -987,10 +987,10 @@ void __cpuinit rtas_give_timebase(void) local_irq_save(flags); hard_irq_disable(); - __raw_spin_lock(&timebase_lock); + arch_spin_lock(&timebase_lock); rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); timebase = get_tb(); - __raw_spin_unlock(&timebase_lock); + arch_spin_unlock(&timebase_lock); while (timebase) barrier(); @@ -1002,8 +1002,8 @@ void __cpuinit rtas_take_timebase(void) { while (!timebase) barrier(); - __raw_spin_lock(&timebase_lock); + arch_spin_lock(&timebase_lock); set_tb(timebase >> 32, timebase & 0xffffffff); timebase = 0; - __raw_spin_unlock(&timebase_lock); + arch_spin_unlock(&timebase_lock); } diff --git a/arch/powerpc/lib/locks.c b/arch/powerpc/lib/locks.c index b06294c..ee395e3 100644 --- a/arch/powerpc/lib/locks.c +++ b/arch/powerpc/lib/locks.c @@ -82,7 +82,7 @@ void __rw_yield(raw_rwlock_t *rw) } #endif -void __raw_spin_unlock_wait(arch_spinlock_t *lock) +void arch_spin_unlock_wait(arch_spinlock_t *lock) { while (lock->slock) { HMT_low(); @@ -92,4 +92,4 @@ void __raw_spin_unlock_wait(arch_spinlock_t *lock) HMT_medium(); } -EXPORT_SYMBOL(__raw_spin_unlock_wait); +EXPORT_SYMBOL(arch_spin_unlock_wait); diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index be36fec..242f809 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c @@ -80,11 +80,11 @@ static void __devinit pas_give_timebase(void) local_irq_save(flags); hard_irq_disable(); - __raw_spin_lock(&timebase_lock); + arch_spin_lock(&timebase_lock); mtspr(SPRN_TBCTL, TBCTL_FREEZE); isync(); timebase = get_tb(); - __raw_spin_unlock(&timebase_lock); + arch_spin_unlock(&timebase_lock); while (timebase) barrier(); @@ -97,10 +97,10 @@ static void __devinit pas_take_timebase(void) while (!timebase) smp_rmb(); - __raw_spin_lock(&timebase_lock); + arch_spin_lock(&timebase_lock); set_tb(timebase >> 32, timebase & 0xffffffff); timebase = 0; - __raw_spin_unlock(&timebase_lock); + arch_spin_unlock(&timebase_lock); } struct smp_ops_t pas_smp_ops = { diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h index 6121fa4..a94c146 100644 --- a/arch/s390/include/asm/spinlock.h +++ b/arch/s390/include/asm/spinlock.h @@ -52,27 +52,27 @@ _raw_compare_and_swap(volatile unsigned int *lock, * (the type definitions are in asm/spinlock_types.h) */ -#define __raw_spin_is_locked(x) ((x)->owner_cpu != 0) -#define __raw_spin_unlock_wait(lock) \ - do { while (__raw_spin_is_locked(lock)) \ - _raw_spin_relax(lock); } while (0) +#define arch_spin_is_locked(x) ((x)->owner_cpu != 0) +#define arch_spin_unlock_wait(lock) \ + do { while (arch_spin_is_locked(lock)) \ + arch_spin_relax(lock); } while (0) -extern void _raw_spin_lock_wait(arch_spinlock_t *); -extern void _raw_spin_lock_wait_flags(arch_spinlock_t *, unsigned long flags); -extern int _raw_spin_trylock_retry(arch_spinlock_t *); -extern void _raw_spin_relax(arch_spinlock_t *lock); +extern void arch_spin_lock_wait(arch_spinlock_t *); +extern void arch_spin_lock_wait_flags(arch_spinlock_t *, unsigned long flags); +extern int arch_spin_trylock_retry(arch_spinlock_t *); +extern void arch_spin_relax(arch_spinlock_t *lock); -static inline void __raw_spin_lock(arch_spinlock_t *lp) +static inline void arch_spin_lock(arch_spinlock_t *lp) { int old; old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); if (likely(old == 0)) return; - _raw_spin_lock_wait(lp); + arch_spin_lock_wait(lp); } -static inline void __raw_spin_lock_flags(arch_spinlock_t *lp, +static inline void arch_spin_lock_flags(arch_spinlock_t *lp, unsigned long flags) { int old; @@ -80,20 +80,20 @@ static inline void __raw_spin_lock_flags(arch_spinlock_t *lp, old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); if (likely(old == 0)) return; - _raw_spin_lock_wait_flags(lp, flags); + arch_spin_lock_wait_flags(lp, flags); } -static inline int __raw_spin_trylock(arch_spinlock_t *lp) +static inline int arch_spin_trylock(arch_spinlock_t *lp) { int old; old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); if (likely(old == 0)) return 1; - return _raw_spin_trylock_retry(lp); + return arch_spin_trylock_retry(lp); } -static inline void __raw_spin_unlock(arch_spinlock_t *lp) +static inline void arch_spin_unlock(arch_spinlock_t *lp) { _raw_compare_and_swap(&lp->owner_cpu, lp->owner_cpu, 0); } @@ -188,7 +188,7 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) return _raw_write_trylock_retry(rw); } -#define _raw_read_relax(lock) cpu_relax() -#define _raw_write_relax(lock) cpu_relax() +#define arch_read_relax(lock) cpu_relax() +#define arch_write_relax(lock) cpu_relax() #endif /* __ASM_SPINLOCK_H */ diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index d4cbf71..f459645 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c @@ -39,7 +39,7 @@ static inline void _raw_yield_cpu(int cpu) _raw_yield(); } -void _raw_spin_lock_wait(arch_spinlock_t *lp) +void arch_spin_lock_wait(arch_spinlock_t *lp) { int count = spin_retry; unsigned int cpu = ~smp_processor_id(); @@ -51,15 +51,15 @@ void _raw_spin_lock_wait(arch_spinlock_t *lp) _raw_yield_cpu(~owner); count = spin_retry; } - if (__raw_spin_is_locked(lp)) + if (arch_spin_is_locked(lp)) continue; if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) return; } } -EXPORT_SYMBOL(_raw_spin_lock_wait); +EXPORT_SYMBOL(arch_spin_lock_wait); -void _raw_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) +void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) { int count = spin_retry; unsigned int cpu = ~smp_processor_id(); @@ -72,7 +72,7 @@ void _raw_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) _raw_yield_cpu(~owner); count = spin_retry; } - if (__raw_spin_is_locked(lp)) + if (arch_spin_is_locked(lp)) continue; local_irq_disable(); if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) @@ -80,30 +80,30 @@ void _raw_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) local_irq_restore(flags); } } -EXPORT_SYMBOL(_raw_spin_lock_wait_flags); +EXPORT_SYMBOL(arch_spin_lock_wait_flags); -int _raw_spin_trylock_retry(arch_spinlock_t *lp) +int arch_spin_trylock_retry(arch_spinlock_t *lp) { unsigned int cpu = ~smp_processor_id(); int count; for (count = spin_retry; count > 0; count--) { - if (__raw_spin_is_locked(lp)) + if (arch_spin_is_locked(lp)) continue; if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) return 1; } return 0; } -EXPORT_SYMBOL(_raw_spin_trylock_retry); +EXPORT_SYMBOL(arch_spin_trylock_retry); -void _raw_spin_relax(arch_spinlock_t *lock) +void arch_spin_relax(arch_spinlock_t *lock) { unsigned int cpu = lock->owner_cpu; if (cpu != 0) _raw_yield_cpu(~cpu); } -EXPORT_SYMBOL(_raw_spin_relax); +EXPORT_SYMBOL(arch_spin_relax); void _raw_read_lock_wait(raw_rwlock_t *rw) { diff --git a/arch/sh/include/asm/spinlock.h b/arch/sh/include/asm/spinlock.h index 5a05b3f..da1c649 100644 --- a/arch/sh/include/asm/spinlock.h +++ b/arch/sh/include/asm/spinlock.h @@ -23,10 +23,10 @@ * Your basic SMP spinlocks, allowing only a single CPU anywhere */ -#define __raw_spin_is_locked(x) ((x)->lock <= 0) -#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) -#define __raw_spin_unlock_wait(x) \ - do { while (__raw_spin_is_locked(x)) cpu_relax(); } while (0) +#define arch_spin_is_locked(x) ((x)->lock <= 0) +#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) +#define arch_spin_unlock_wait(x) \ + do { while (arch_spin_is_locked(x)) cpu_relax(); } while (0) /* * Simple spin lock operations. There are two variants, one clears IRQ's @@ -34,14 +34,14 @@ * * We make no fairness assumptions. They have a cost. */ -static inline void __raw_spin_lock(arch_spinlock_t *lock) +static inline void arch_spin_lock(arch_spinlock_t *lock) { unsigned long tmp; unsigned long oldval; __asm__ __volatile__ ( "1: \n\t" - "movli.l @%2, %0 ! __raw_spin_lock \n\t" + "movli.l @%2, %0 ! arch_spin_lock \n\t" "mov %0, %1 \n\t" "mov #0, %0 \n\t" "movco.l %0, @%2 \n\t" @@ -54,12 +54,12 @@ static inline void __raw_spin_lock(arch_spinlock_t *lock) ); } -static inline void __raw_spin_unlock(arch_spinlock_t *lock) +static inline void arch_spin_unlock(arch_spinlock_t *lock) { unsigned long tmp; __asm__ __volatile__ ( - "mov #1, %0 ! __raw_spin_unlock \n\t" + "mov #1, %0 ! arch_spin_unlock \n\t" "mov.l %0, @%1 \n\t" : "=&z" (tmp) : "r" (&lock->lock) @@ -67,13 +67,13 @@ static inline void __raw_spin_unlock(arch_spinlock_t *lock) ); } -static inline int __raw_spin_trylock(arch_spinlock_t *lock) +static inline int arch_spin_trylock(arch_spinlock_t *lock) { unsigned long tmp, oldval; __asm__ __volatile__ ( "1: \n\t" - "movli.l @%2, %0 ! __raw_spin_trylock \n\t" + "movli.l @%2, %0 ! arch_spin_trylock \n\t" "mov %0, %1 \n\t" "mov #0, %0 \n\t" "movco.l %0, @%2 \n\t" @@ -219,8 +219,8 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) #define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) #define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) -#define _raw_spin_relax(lock) cpu_relax() -#define _raw_read_relax(lock) cpu_relax() -#define _raw_write_relax(lock) cpu_relax() +#define arch_spin_relax(lock) cpu_relax() +#define arch_read_relax(lock) cpu_relax() +#define arch_write_relax(lock) cpu_relax() #endif /* __ASM_SH_SPINLOCK_H */ diff --git a/arch/sparc/include/asm/spinlock_32.h b/arch/sparc/include/asm/spinlock_32.h index b2d8a67..9b0f2f5 100644 --- a/arch/sparc/include/asm/spinlock_32.h +++ b/arch/sparc/include/asm/spinlock_32.h @@ -10,12 +10,12 @@ #include -#define __raw_spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0) +#define arch_spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0) -#define __raw_spin_unlock_wait(lock) \ - do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) +#define arch_spin_unlock_wait(lock) \ + do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0) -static inline void __raw_spin_lock(arch_spinlock_t *lock) +static inline void arch_spin_lock(arch_spinlock_t *lock) { __asm__ __volatile__( "\n1:\n\t" @@ -35,7 +35,7 @@ static inline void __raw_spin_lock(arch_spinlock_t *lock) : "g2", "memory", "cc"); } -static inline int __raw_spin_trylock(arch_spinlock_t *lock) +static inline int arch_spin_trylock(arch_spinlock_t *lock) { unsigned int result; __asm__ __volatile__("ldstub [%1], %0" @@ -45,7 +45,7 @@ static inline int __raw_spin_trylock(arch_spinlock_t *lock) return (result == 0); } -static inline void __raw_spin_unlock(arch_spinlock_t *lock) +static inline void arch_spin_unlock(arch_spinlock_t *lock) { __asm__ __volatile__("stb %%g0, [%0]" : : "r" (lock) : "memory"); } @@ -176,13 +176,13 @@ static inline int arch_read_trylock(raw_rwlock_t *rw) #define __raw_write_unlock(rw) do { (rw)->lock = 0; } while(0) -#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) +#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) #define __raw_read_lock_flags(rw, flags) __raw_read_lock(rw) #define __raw_write_lock_flags(rw, flags) __raw_write_lock(rw) -#define _raw_spin_relax(lock) cpu_relax() -#define _raw_read_relax(lock) cpu_relax() -#define _raw_write_relax(lock) cpu_relax() +#define arch_spin_relax(lock) cpu_relax() +#define arch_read_relax(lock) cpu_relax() +#define arch_write_relax(lock) cpu_relax() #define __raw_read_can_lock(rw) (!((rw)->lock & 0xff)) #define __raw_write_can_lock(rw) (!(rw)->lock) diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h index 38e16c4..7cf58a2 100644 --- a/arch/sparc/include/asm/spinlock_64.h +++ b/arch/sparc/include/asm/spinlock_64.h @@ -21,13 +21,13 @@ * the spinner sections must be pre-V9 branches. */ -#define __raw_spin_is_locked(lp) ((lp)->lock != 0) +#define arch_spin_is_locked(lp) ((lp)->lock != 0) -#define __raw_spin_unlock_wait(lp) \ +#define arch_spin_unlock_wait(lp) \ do { rmb(); \ } while((lp)->lock) -static inline void __raw_spin_lock(arch_spinlock_t *lock) +static inline void arch_spin_lock(arch_spinlock_t *lock) { unsigned long tmp; @@ -46,7 +46,7 @@ static inline void __raw_spin_lock(arch_spinlock_t *lock) : "memory"); } -static inline int __raw_spin_trylock(arch_spinlock_t *lock) +static inline int arch_spin_trylock(arch_spinlock_t *lock) { unsigned long result; @@ -59,7 +59,7 @@ static inline int __raw_spin_trylock(arch_spinlock_t *lock) return (result == 0UL); } -static inline void __raw_spin_unlock(arch_spinlock_t *lock) +static inline void arch_spin_unlock(arch_spinlock_t *lock) { __asm__ __volatile__( " stb %%g0, [%0]" @@ -68,7 +68,7 @@ static inline void __raw_spin_unlock(arch_spinlock_t *lock) : "memory"); } -static inline void __raw_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) +static inline void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { unsigned long tmp1, tmp2; @@ -222,9 +222,9 @@ static int inline arch_write_trylock(raw_rwlock_t *lock) #define __raw_read_can_lock(rw) (!((rw)->lock & 0x80000000UL)) #define __raw_write_can_lock(rw) (!(rw)->lock) -#define _raw_spin_relax(lock) cpu_relax() -#define _raw_read_relax(lock) cpu_relax() -#define _raw_write_relax(lock) cpu_relax() +#define arch_spin_relax(lock) cpu_relax() +#define arch_read_relax(lock) cpu_relax() +#define arch_write_relax(lock) cpu_relax() #endif /* !(__ASSEMBLY__) */ diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 5655f75..dd59a85 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -731,34 +731,34 @@ static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS) -static inline int __raw_spin_is_locked(struct arch_spinlock *lock) +static inline int arch_spin_is_locked(struct arch_spinlock *lock) { return PVOP_CALL1(int, pv_lock_ops.spin_is_locked, lock); } -static inline int __raw_spin_is_contended(struct arch_spinlock *lock) +static inline int arch_spin_is_contended(struct arch_spinlock *lock) { return PVOP_CALL1(int, pv_lock_ops.spin_is_contended, lock); } -#define __raw_spin_is_contended __raw_spin_is_contended +#define arch_spin_is_contended arch_spin_is_contended -static __always_inline void __raw_spin_lock(struct arch_spinlock *lock) +static __always_inline void arch_spin_lock(struct arch_spinlock *lock) { PVOP_VCALL1(pv_lock_ops.spin_lock, lock); } -static __always_inline void __raw_spin_lock_flags(struct arch_spinlock *lock, +static __always_inline void arch_spin_lock_flags(struct arch_spinlock *lock, unsigned long flags) { PVOP_VCALL2(pv_lock_ops.spin_lock_flags, lock, flags); } -static __always_inline int __raw_spin_trylock(struct arch_spinlock *lock) +static __always_inline int arch_spin_trylock(struct arch_spinlock *lock) { return PVOP_CALL1(int, pv_lock_ops.spin_trylock, lock); } -static __always_inline void __raw_spin_unlock(struct arch_spinlock *lock) +static __always_inline void arch_spin_unlock(struct arch_spinlock *lock) { PVOP_VCALL1(pv_lock_ops.spin_unlock, lock); } diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index 204b524..ab9055f 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h @@ -174,43 +174,43 @@ static inline int __ticket_spin_is_contended(arch_spinlock_t *lock) #ifndef CONFIG_PARAVIRT_SPINLOCKS -static inline int __raw_spin_is_locked(arch_spinlock_t *lock) +static inline int arch_spin_is_locked(arch_spinlock_t *lock) { return __ticket_spin_is_locked(lock); } -static inline int __raw_spin_is_contended(arch_spinlock_t *lock) +static inline int arch_spin_is_contended(arch_spinlock_t *lock) { return __ticket_spin_is_contended(lock); } -#define __raw_spin_is_contended __raw_spin_is_contended +#define arch_spin_is_contended arch_spin_is_contended -static __always_inline void __raw_spin_lock(arch_spinlock_t *lock) +static __always_inline void arch_spin_lock(arch_spinlock_t *lock) { __ticket_spin_lock(lock); } -static __always_inline int __raw_spin_trylock(arch_spinlock_t *lock) +static __always_inline int arch_spin_trylock(arch_spinlock_t *lock) { return __ticket_spin_trylock(lock); } -static __always_inline void __raw_spin_unlock(arch_spinlock_t *lock) +static __always_inline void arch_spin_unlock(arch_spinlock_t *lock) { __ticket_spin_unlock(lock); } -static __always_inline void __raw_spin_lock_flags(arch_spinlock_t *lock, +static __always_inline void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { - __raw_spin_lock(lock); + arch_spin_lock(lock); } #endif /* CONFIG_PARAVIRT_SPINLOCKS */ -static inline void __raw_spin_unlock_wait(arch_spinlock_t *lock) +static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) { - while (__raw_spin_is_locked(lock)) + while (arch_spin_is_locked(lock)) cpu_relax(); } @@ -298,9 +298,9 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) #define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) #define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) -#define _raw_spin_relax(lock) cpu_relax() -#define _raw_read_relax(lock) cpu_relax() -#define _raw_write_relax(lock) cpu_relax() +#define arch_spin_relax(lock) cpu_relax() +#define arch_read_relax(lock) cpu_relax() +#define arch_write_relax(lock) cpu_relax() /* The {read|write|spin}_lock() on x86 are full memory barriers. */ static inline void smp_mb__after_lock(void) { } diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 5b75afa..0a0aa1c 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -207,11 +207,11 @@ unsigned __kprobes long oops_begin(void) /* racy, but better than risking deadlock. */ raw_local_irq_save(flags); cpu = smp_processor_id(); - if (!__raw_spin_trylock(&die_lock)) { + if (!arch_spin_trylock(&die_lock)) { if (cpu == die_owner) /* nested oops. should stop eventually */; else - __raw_spin_lock(&die_lock); + arch_spin_lock(&die_lock); } die_nest_count++; die_owner = cpu; @@ -231,7 +231,7 @@ void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) die_nest_count--; if (!die_nest_count) /* Nest count reaches zero, release the lock. */ - __raw_spin_unlock(&die_lock); + arch_spin_unlock(&die_lock); raw_local_irq_restore(flags); oops_exit(); diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c index a0f39e0..676b8c7 100644 --- a/arch/x86/kernel/paravirt-spinlocks.c +++ b/arch/x86/kernel/paravirt-spinlocks.c @@ -10,7 +10,7 @@ static inline void default_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { - __raw_spin_lock(lock); + arch_spin_lock(lock); } struct pv_lock_ops pv_lock_ops = { diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c index f171469..0aa5fed8 100644 --- a/arch/x86/kernel/tsc_sync.c +++ b/arch/x86/kernel/tsc_sync.c @@ -62,13 +62,13 @@ static __cpuinit void check_tsc_warp(void) * previous TSC that was measured (possibly on * another CPU) and update the previous TSC timestamp. */ - __raw_spin_lock(&sync_lock); + arch_spin_lock(&sync_lock); prev = last_tsc; rdtsc_barrier(); now = get_cycles(); rdtsc_barrier(); last_tsc = now; - __raw_spin_unlock(&sync_lock); + arch_spin_unlock(&sync_lock); /* * Be nice every now and then (and also check whether @@ -87,10 +87,10 @@ static __cpuinit void check_tsc_warp(void) * we saw a time-warp of the TSC going backwards: */ if (unlikely(prev > now)) { - __raw_spin_lock(&sync_lock); + arch_spin_lock(&sync_lock); max_warp = max(max_warp, prev - now); nr_warps++; - __raw_spin_unlock(&sync_lock); + arch_spin_unlock(&sync_lock); } } WARN(!(now-start), diff --git a/include/asm-generic/bitops/atomic.h b/include/asm-generic/bitops/atomic.h index dcf0afa..ecc44a8 100644 --- a/include/asm-generic/bitops/atomic.h +++ b/include/asm-generic/bitops/atomic.h @@ -22,12 +22,12 @@ extern arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned; #define _atomic_spin_lock_irqsave(l,f) do { \ arch_spinlock_t *s = ATOMIC_HASH(l); \ local_irq_save(f); \ - __raw_spin_lock(s); \ + arch_spin_lock(s); \ } while(0) #define _atomic_spin_unlock_irqrestore(l,f) do { \ arch_spinlock_t *s = ATOMIC_HASH(l); \ - __raw_spin_unlock(s); \ + arch_spin_unlock(s); \ local_irq_restore(f); \ } while(0) diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 5ef7a4c..de3a022 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -14,7 +14,7 @@ * linux/spinlock_types.h: * defines the generic type and initializers * - * asm/spinlock.h: contains the __raw_spin_*()/etc. lowlevel + * asm/spinlock.h: contains the arch_spin_*()/etc. lowlevel * implementations, mostly inline assembly code * * (also included on UP-debug builds:) @@ -34,7 +34,7 @@ * defines the generic type and initializers * * linux/spinlock_up.h: - * contains the __raw_spin_*()/etc. version of UP + * contains the arch_spin_*()/etc. version of UP * builds. (which are NOPs on non-debug, non-preempt * builds) * @@ -103,17 +103,17 @@ do { \ do { *(lock) = __SPIN_LOCK_UNLOCKED(lock); } while (0) #endif -#define spin_is_locked(lock) __raw_spin_is_locked(&(lock)->raw_lock) +#define spin_is_locked(lock) arch_spin_is_locked(&(lock)->raw_lock) #ifdef CONFIG_GENERIC_LOCKBREAK #define spin_is_contended(lock) ((lock)->break_lock) #else -#ifdef __raw_spin_is_contended -#define spin_is_contended(lock) __raw_spin_is_contended(&(lock)->raw_lock) +#ifdef arch_spin_is_contended +#define spin_is_contended(lock) arch_spin_is_contended(&(lock)->raw_lock) #else #define spin_is_contended(lock) (((void)(lock), 0)) -#endif /*__raw_spin_is_contended*/ +#endif /*arch_spin_is_contended*/ #endif /* The lock does not imply full memory barrier. */ @@ -125,7 +125,7 @@ static inline void smp_mb__after_lock(void) { smp_mb(); } * spin_unlock_wait - wait until the spinlock gets unlocked * @lock: the spinlock in question. */ -#define spin_unlock_wait(lock) __raw_spin_unlock_wait(&(lock)->raw_lock) +#define spin_unlock_wait(lock) arch_spin_unlock_wait(&(lock)->raw_lock) #ifdef CONFIG_DEBUG_SPINLOCK extern void _raw_spin_lock(spinlock_t *lock); @@ -133,11 +133,11 @@ static inline void smp_mb__after_lock(void) { smp_mb(); } extern int _raw_spin_trylock(spinlock_t *lock); extern void _raw_spin_unlock(spinlock_t *lock); #else -# define _raw_spin_lock(lock) __raw_spin_lock(&(lock)->raw_lock) +# define _raw_spin_lock(lock) arch_spin_lock(&(lock)->raw_lock) # define _raw_spin_lock_flags(lock, flags) \ - __raw_spin_lock_flags(&(lock)->raw_lock, *(flags)) -# define _raw_spin_trylock(lock) __raw_spin_trylock(&(lock)->raw_lock) -# define _raw_spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock) + arch_spin_lock_flags(&(lock)->raw_lock, *(flags)) +# define _raw_spin_trylock(lock) arch_spin_trylock(&(lock)->raw_lock) +# define _raw_spin_unlock(lock) arch_spin_unlock(&(lock)->raw_lock) #endif /* diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h index 8ee2ac1..1d3bcc3 100644 --- a/include/linux/spinlock_up.h +++ b/include/linux/spinlock_up.h @@ -18,21 +18,21 @@ */ #ifdef CONFIG_DEBUG_SPINLOCK -#define __raw_spin_is_locked(x) ((x)->slock == 0) +#define arch_spin_is_locked(x) ((x)->slock == 0) -static inline void __raw_spin_lock(arch_spinlock_t *lock) +static inline void arch_spin_lock(arch_spinlock_t *lock) { lock->slock = 0; } static inline void -__raw_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) +arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { local_irq_save(flags); lock->slock = 0; } -static inline int __raw_spin_trylock(arch_spinlock_t *lock) +static inline int arch_spin_trylock(arch_spinlock_t *lock) { char oldval = lock->slock; @@ -41,7 +41,7 @@ static inline int __raw_spin_trylock(arch_spinlock_t *lock) return oldval > 0; } -static inline void __raw_spin_unlock(arch_spinlock_t *lock) +static inline void arch_spin_unlock(arch_spinlock_t *lock) { lock->slock = 1; } @@ -57,20 +57,20 @@ static inline void __raw_spin_unlock(arch_spinlock_t *lock) #define __raw_write_unlock(lock) do { (void)(lock); } while (0) #else /* DEBUG_SPINLOCK */ -#define __raw_spin_is_locked(lock) ((void)(lock), 0) +#define arch_spin_is_locked(lock) ((void)(lock), 0) /* for sched.c and kernel_lock.c: */ -# define __raw_spin_lock(lock) do { (void)(lock); } while (0) -# define __raw_spin_lock_flags(lock, flags) do { (void)(lock); } while (0) -# define __raw_spin_unlock(lock) do { (void)(lock); } while (0) -# define __raw_spin_trylock(lock) ({ (void)(lock); 1; }) +# define arch_spin_lock(lock) do { (void)(lock); } while (0) +# define arch_spin_lock_flags(lock, flags) do { (void)(lock); } while (0) +# define arch_spin_unlock(lock) do { (void)(lock); } while (0) +# define arch_spin_trylock(lock) ({ (void)(lock); 1; }) #endif /* DEBUG_SPINLOCK */ -#define __raw_spin_is_contended(lock) (((void)(lock), 0)) +#define arch_spin_is_contended(lock) (((void)(lock), 0)) #define __raw_read_can_lock(lock) (((void)(lock), 1)) #define __raw_write_can_lock(lock) (((void)(lock), 1)) -#define __raw_spin_unlock_wait(lock) \ - do { cpu_relax(); } while (__raw_spin_is_locked(lock)) +#define arch_spin_unlock_wait(lock) \ + do { cpu_relax(); } while (arch_spin_is_locked(lock)) #endif /* __LINUX_SPINLOCK_UP_H */ diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 2389e3f..5feaddc 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -77,7 +77,7 @@ static arch_spinlock_t lockdep_lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED static int graph_lock(void) { - __raw_spin_lock(&lockdep_lock); + arch_spin_lock(&lockdep_lock); /* * Make sure that if another CPU detected a bug while * walking the graph we dont change it (while the other @@ -85,7 +85,7 @@ static int graph_lock(void) * dropped already) */ if (!debug_locks) { - __raw_spin_unlock(&lockdep_lock); + arch_spin_unlock(&lockdep_lock); return 0; } /* prevent any recursions within lockdep from causing deadlocks */ @@ -95,11 +95,11 @@ static int graph_lock(void) static inline int graph_unlock(void) { - if (debug_locks && !__raw_spin_is_locked(&lockdep_lock)) + if (debug_locks && !arch_spin_is_locked(&lockdep_lock)) return DEBUG_LOCKS_WARN_ON(1); current->lockdep_recursion--; - __raw_spin_unlock(&lockdep_lock); + arch_spin_unlock(&lockdep_lock); return 0; } @@ -111,7 +111,7 @@ static inline int debug_locks_off_graph_unlock(void) { int ret = debug_locks_off(); - __raw_spin_unlock(&lockdep_lock); + arch_spin_unlock(&lockdep_lock); return ret; } @@ -1170,9 +1170,9 @@ unsigned long lockdep_count_forward_deps(struct lock_class *class) this.class = class; local_irq_save(flags); - __raw_spin_lock(&lockdep_lock); + arch_spin_lock(&lockdep_lock); ret = __lockdep_count_forward_deps(&this); - __raw_spin_unlock(&lockdep_lock); + arch_spin_unlock(&lockdep_lock); local_irq_restore(flags); return ret; @@ -1197,9 +1197,9 @@ unsigned long lockdep_count_backward_deps(struct lock_class *class) this.class = class; local_irq_save(flags); - __raw_spin_lock(&lockdep_lock); + arch_spin_lock(&lockdep_lock); ret = __lockdep_count_backward_deps(&this); - __raw_spin_unlock(&lockdep_lock); + arch_spin_unlock(&lockdep_lock); local_irq_restore(flags); return ret; diff --git a/kernel/mutex-debug.h b/kernel/mutex-debug.h index 6b2d735..7bebbd1 100644 --- a/kernel/mutex-debug.h +++ b/kernel/mutex-debug.h @@ -43,13 +43,13 @@ static inline void mutex_clear_owner(struct mutex *lock) \ DEBUG_LOCKS_WARN_ON(in_interrupt()); \ local_irq_save(flags); \ - __raw_spin_lock(&(lock)->raw_lock); \ + arch_spin_lock(&(lock)->raw_lock); \ DEBUG_LOCKS_WARN_ON(l->magic != l); \ } while (0) #define spin_unlock_mutex(lock, flags) \ do { \ - __raw_spin_unlock(&(lock)->raw_lock); \ + arch_spin_unlock(&(lock)->raw_lock); \ local_irq_restore(flags); \ preempt_check_resched(); \ } while (0) diff --git a/kernel/spinlock.c b/kernel/spinlock.c index e6e1363..fbb5f8b 100644 --- a/kernel/spinlock.c +++ b/kernel/spinlock.c @@ -53,7 +53,7 @@ void __lockfunc __##op##_lock(locktype##_t *lock) \ if (!(lock)->break_lock) \ (lock)->break_lock = 1; \ while (!op##_can_lock(lock) && (lock)->break_lock) \ - _raw_##op##_relax(&lock->raw_lock); \ + arch_##op##_relax(&lock->raw_lock); \ } \ (lock)->break_lock = 0; \ } \ @@ -73,7 +73,7 @@ unsigned long __lockfunc __##op##_lock_irqsave(locktype##_t *lock) \ if (!(lock)->break_lock) \ (lock)->break_lock = 1; \ while (!op##_can_lock(lock) && (lock)->break_lock) \ - _raw_##op##_relax(&lock->raw_lock); \ + arch_##op##_relax(&lock->raw_lock); \ } \ (lock)->break_lock = 0; \ return flags; \ diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index fb7a0fa..f58c9ad 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -2834,7 +2834,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) int ret; local_irq_save(flags); - __raw_spin_lock(&cpu_buffer->lock); + arch_spin_lock(&cpu_buffer->lock); again: /* @@ -2923,7 +2923,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) goto again; out: - __raw_spin_unlock(&cpu_buffer->lock); + arch_spin_unlock(&cpu_buffer->lock); local_irq_restore(flags); return reader; @@ -3286,9 +3286,9 @@ ring_buffer_read_start(struct ring_buffer *buffer, int cpu) synchronize_sched(); spin_lock_irqsave(&cpu_buffer->reader_lock, flags); - __raw_spin_lock(&cpu_buffer->lock); + arch_spin_lock(&cpu_buffer->lock); rb_iter_reset(iter); - __raw_spin_unlock(&cpu_buffer->lock); + arch_spin_unlock(&cpu_buffer->lock); spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); return iter; @@ -3408,11 +3408,11 @@ void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu) if (RB_WARN_ON(cpu_buffer, local_read(&cpu_buffer->committing))) goto out; - __raw_spin_lock(&cpu_buffer->lock); + arch_spin_lock(&cpu_buffer->lock); rb_reset_cpu(cpu_buffer); - __raw_spin_unlock(&cpu_buffer->lock); + arch_spin_unlock(&cpu_buffer->lock); out: spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 63bc1cc..bb6b5e7 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -555,13 +555,13 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) return; WARN_ON_ONCE(!irqs_disabled()); - __raw_spin_lock(&ftrace_max_lock); + arch_spin_lock(&ftrace_max_lock); tr->buffer = max_tr.buffer; max_tr.buffer = buf; __update_max_tr(tr, tsk, cpu); - __raw_spin_unlock(&ftrace_max_lock); + arch_spin_unlock(&ftrace_max_lock); } /** @@ -581,7 +581,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) return; WARN_ON_ONCE(!irqs_disabled()); - __raw_spin_lock(&ftrace_max_lock); + arch_spin_lock(&ftrace_max_lock); ftrace_disable_cpu(); @@ -603,7 +603,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) WARN_ON_ONCE(ret && ret != -EAGAIN && ret != -EBUSY); __update_max_tr(tr, tsk, cpu); - __raw_spin_unlock(&ftrace_max_lock); + arch_spin_unlock(&ftrace_max_lock); } #endif /* CONFIG_TRACER_MAX_TRACE */ @@ -915,7 +915,7 @@ static void trace_save_cmdline(struct task_struct *tsk) * nor do we want to disable interrupts, * so if we miss here, then better luck next time. */ - if (!__raw_spin_trylock(&trace_cmdline_lock)) + if (!arch_spin_trylock(&trace_cmdline_lock)) return; idx = map_pid_to_cmdline[tsk->pid]; @@ -940,7 +940,7 @@ static void trace_save_cmdline(struct task_struct *tsk) memcpy(&saved_cmdlines[idx], tsk->comm, TASK_COMM_LEN); - __raw_spin_unlock(&trace_cmdline_lock); + arch_spin_unlock(&trace_cmdline_lock); } void trace_find_cmdline(int pid, char comm[]) @@ -958,14 +958,14 @@ void trace_find_cmdline(int pid, char comm[]) } preempt_disable(); - __raw_spin_lock(&trace_cmdline_lock); + arch_spin_lock(&trace_cmdline_lock); map = map_pid_to_cmdline[pid]; if (map != NO_CMDLINE_MAP) strcpy(comm, saved_cmdlines[map]); else strcpy(comm, "<...>"); - __raw_spin_unlock(&trace_cmdline_lock); + arch_spin_unlock(&trace_cmdline_lock); preempt_enable(); } @@ -1283,7 +1283,7 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) /* Lockdep uses trace_printk for lock tracing */ local_irq_save(flags); - __raw_spin_lock(&trace_buf_lock); + arch_spin_lock(&trace_buf_lock); len = vbin_printf(trace_buf, TRACE_BUF_SIZE, fmt, args); if (len > TRACE_BUF_SIZE || len < 0) @@ -1304,7 +1304,7 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) ring_buffer_unlock_commit(buffer, event); out_unlock: - __raw_spin_unlock(&trace_buf_lock); + arch_spin_unlock(&trace_buf_lock); local_irq_restore(flags); out: @@ -1360,7 +1360,7 @@ int trace_array_vprintk(struct trace_array *tr, pause_graph_tracing(); raw_local_irq_save(irq_flags); - __raw_spin_lock(&trace_buf_lock); + arch_spin_lock(&trace_buf_lock); len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args); size = sizeof(*entry) + len + 1; @@ -1378,7 +1378,7 @@ int trace_array_vprintk(struct trace_array *tr, ring_buffer_unlock_commit(buffer, event); out_unlock: - __raw_spin_unlock(&trace_buf_lock); + arch_spin_unlock(&trace_buf_lock); raw_local_irq_restore(irq_flags); unpause_graph_tracing(); out: @@ -2279,7 +2279,7 @@ tracing_cpumask_write(struct file *filp, const char __user *ubuf, mutex_lock(&tracing_cpumask_update_lock); local_irq_disable(); - __raw_spin_lock(&ftrace_max_lock); + arch_spin_lock(&ftrace_max_lock); for_each_tracing_cpu(cpu) { /* * Increase/decrease the disabled counter if we are @@ -2294,7 +2294,7 @@ tracing_cpumask_write(struct file *filp, const char __user *ubuf, atomic_dec(&global_trace.data[cpu]->disabled); } } - __raw_spin_unlock(&ftrace_max_lock); + arch_spin_unlock(&ftrace_max_lock); local_irq_enable(); cpumask_copy(tracing_cpumask, tracing_cpumask_new); @@ -4318,7 +4318,7 @@ static void __ftrace_dump(bool disable_tracing) /* only one dump */ local_irq_save(flags); - __raw_spin_lock(&ftrace_dump_lock); + arch_spin_lock(&ftrace_dump_lock); if (dump_ran) goto out; @@ -4393,7 +4393,7 @@ static void __ftrace_dump(bool disable_tracing) } out: - __raw_spin_unlock(&ftrace_dump_lock); + arch_spin_unlock(&ftrace_dump_lock); local_irq_restore(flags); } diff --git a/kernel/trace/trace_clock.c b/kernel/trace/trace_clock.c index 433e2ed..84a3a7b 100644 --- a/kernel/trace/trace_clock.c +++ b/kernel/trace/trace_clock.c @@ -94,7 +94,7 @@ u64 notrace trace_clock_global(void) if (unlikely(in_nmi())) goto out; - __raw_spin_lock(&trace_clock_struct.lock); + arch_spin_lock(&trace_clock_struct.lock); /* * TODO: if this happens often then maybe we should reset @@ -106,7 +106,7 @@ u64 notrace trace_clock_global(void) trace_clock_struct.prev_time = now; - __raw_spin_unlock(&trace_clock_struct.lock); + arch_spin_unlock(&trace_clock_struct.lock); out: raw_local_irq_restore(flags); diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index e347853..0271742 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -143,7 +143,7 @@ probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev, goto out; local_irq_save(flags); - __raw_spin_lock(&wakeup_lock); + arch_spin_lock(&wakeup_lock); /* We could race with grabbing wakeup_lock */ if (unlikely(!tracer_enabled || next != wakeup_task)) @@ -169,7 +169,7 @@ probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev, out_unlock: __wakeup_reset(wakeup_trace); - __raw_spin_unlock(&wakeup_lock); + arch_spin_unlock(&wakeup_lock); local_irq_restore(flags); out: atomic_dec(&wakeup_trace->data[cpu]->disabled); @@ -193,9 +193,9 @@ static void wakeup_reset(struct trace_array *tr) tracing_reset_online_cpus(tr); local_irq_save(flags); - __raw_spin_lock(&wakeup_lock); + arch_spin_lock(&wakeup_lock); __wakeup_reset(tr); - __raw_spin_unlock(&wakeup_lock); + arch_spin_unlock(&wakeup_lock); local_irq_restore(flags); } @@ -225,7 +225,7 @@ probe_wakeup(struct rq *rq, struct task_struct *p, int success) goto out; /* interrupts should be off from try_to_wake_up */ - __raw_spin_lock(&wakeup_lock); + arch_spin_lock(&wakeup_lock); /* check for races. */ if (!tracer_enabled || p->prio >= wakeup_prio) @@ -255,7 +255,7 @@ probe_wakeup(struct rq *rq, struct task_struct *p, int success) trace_function(wakeup_trace, CALLER_ADDR1, CALLER_ADDR2, flags, pc); out_locked: - __raw_spin_unlock(&wakeup_lock); + arch_spin_unlock(&wakeup_lock); out: atomic_dec(&wakeup_trace->data[cpu]->disabled); } diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index dc98309..280fea4 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -67,7 +67,7 @@ static int trace_test_buffer(struct trace_array *tr, unsigned long *count) /* Don't allow flipping of max traces now */ local_irq_save(flags); - __raw_spin_lock(&ftrace_max_lock); + arch_spin_lock(&ftrace_max_lock); cnt = ring_buffer_entries(tr->buffer); @@ -85,7 +85,7 @@ static int trace_test_buffer(struct trace_array *tr, unsigned long *count) break; } tracing_on(); - __raw_spin_unlock(&ftrace_max_lock); + arch_spin_unlock(&ftrace_max_lock); local_irq_restore(flags); if (count) diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index 728c352..678a512 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c @@ -54,7 +54,7 @@ static inline void check_stack(void) return; local_irq_save(flags); - __raw_spin_lock(&max_stack_lock); + arch_spin_lock(&max_stack_lock); /* a race could have already updated it */ if (this_size <= max_stack_size) @@ -103,7 +103,7 @@ static inline void check_stack(void) } out: - __raw_spin_unlock(&max_stack_lock); + arch_spin_unlock(&max_stack_lock); local_irq_restore(flags); } @@ -171,9 +171,9 @@ stack_max_size_write(struct file *filp, const char __user *ubuf, return ret; local_irq_save(flags); - __raw_spin_lock(&max_stack_lock); + arch_spin_lock(&max_stack_lock); *ptr = val; - __raw_spin_unlock(&max_stack_lock); + arch_spin_unlock(&max_stack_lock); local_irq_restore(flags); return count; @@ -207,7 +207,7 @@ t_next(struct seq_file *m, void *v, loff_t *pos) static void *t_start(struct seq_file *m, loff_t *pos) { local_irq_disable(); - __raw_spin_lock(&max_stack_lock); + arch_spin_lock(&max_stack_lock); if (*pos == 0) return SEQ_START_TOKEN; @@ -217,7 +217,7 @@ static void *t_start(struct seq_file *m, loff_t *pos) static void t_stop(struct seq_file *m, void *p) { - __raw_spin_unlock(&max_stack_lock); + arch_spin_unlock(&max_stack_lock); local_irq_enable(); } diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index f730041..1304fe0 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c @@ -106,7 +106,7 @@ static void __spin_lock_debug(spinlock_t *lock) for (;;) { for (i = 0; i < loops; i++) { - if (__raw_spin_trylock(&lock->raw_lock)) + if (arch_spin_trylock(&lock->raw_lock)) return; __delay(1); } @@ -128,14 +128,14 @@ static void __spin_lock_debug(spinlock_t *lock) void _raw_spin_lock(spinlock_t *lock) { debug_spin_lock_before(lock); - if (unlikely(!__raw_spin_trylock(&lock->raw_lock))) + if (unlikely(!arch_spin_trylock(&lock->raw_lock))) __spin_lock_debug(lock); debug_spin_lock_after(lock); } int _raw_spin_trylock(spinlock_t *lock) { - int ret = __raw_spin_trylock(&lock->raw_lock); + int ret = arch_spin_trylock(&lock->raw_lock); if (ret) debug_spin_lock_after(lock); @@ -151,7 +151,7 @@ int _raw_spin_trylock(spinlock_t *lock) void _raw_spin_unlock(spinlock_t *lock) { debug_spin_unlock(lock); - __raw_spin_unlock(&lock->raw_lock); + arch_spin_unlock(&lock->raw_lock); } static void rwlock_bug(rwlock_t *lock, const char *msg) -- cgit v0.10.2 From fb3a6bbc912b12347614e5742c7c61416cdb0ca0 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 3 Dec 2009 20:01:19 +0100 Subject: locking: Convert raw_rwlock to arch_rwlock Not strictly necessary for -rt as -rt does not have non sleeping rwlocks, but it's odd to not have a consistent naming convention. No functional change. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: David S. Miller Acked-by: Ingo Molnar Cc: linux-arch@vger.kernel.org diff --git a/arch/alpha/include/asm/spinlock.h b/arch/alpha/include/asm/spinlock.h index 4dac79f..e8b2970 100644 --- a/arch/alpha/include/asm/spinlock.h +++ b/arch/alpha/include/asm/spinlock.h @@ -50,17 +50,17 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) /***********************************************************/ -static inline int __raw_read_can_lock(raw_rwlock_t *lock) +static inline int __raw_read_can_lock(arch_rwlock_t *lock) { return (lock->lock & 1) == 0; } -static inline int __raw_write_can_lock(raw_rwlock_t *lock) +static inline int __raw_write_can_lock(arch_rwlock_t *lock) { return lock->lock == 0; } -static inline void __raw_read_lock(raw_rwlock_t *lock) +static inline void __raw_read_lock(arch_rwlock_t *lock) { long regx; @@ -80,7 +80,7 @@ static inline void __raw_read_lock(raw_rwlock_t *lock) : "m" (*lock) : "memory"); } -static inline void __raw_write_lock(raw_rwlock_t *lock) +static inline void __raw_write_lock(arch_rwlock_t *lock) { long regx; @@ -100,7 +100,7 @@ static inline void __raw_write_lock(raw_rwlock_t *lock) : "m" (*lock) : "memory"); } -static inline int __raw_read_trylock(raw_rwlock_t * lock) +static inline int __raw_read_trylock(arch_rwlock_t * lock) { long regx; int success; @@ -122,7 +122,7 @@ static inline int __raw_read_trylock(raw_rwlock_t * lock) return success; } -static inline int __raw_write_trylock(raw_rwlock_t * lock) +static inline int __raw_write_trylock(arch_rwlock_t * lock) { long regx; int success; @@ -144,7 +144,7 @@ static inline int __raw_write_trylock(raw_rwlock_t * lock) return success; } -static inline void __raw_read_unlock(raw_rwlock_t * lock) +static inline void __raw_read_unlock(arch_rwlock_t * lock) { long regx; __asm__ __volatile__( @@ -160,7 +160,7 @@ static inline void __raw_read_unlock(raw_rwlock_t * lock) : "m" (*lock) : "memory"); } -static inline void __raw_write_unlock(raw_rwlock_t * lock) +static inline void __raw_write_unlock(arch_rwlock_t * lock) { mb(); lock->lock = 0; diff --git a/arch/alpha/include/asm/spinlock_types.h b/arch/alpha/include/asm/spinlock_types.h index 08975ee..54c2afc 100644 --- a/arch/alpha/include/asm/spinlock_types.h +++ b/arch/alpha/include/asm/spinlock_types.h @@ -13,8 +13,8 @@ typedef struct { typedef struct { volatile unsigned int lock; -} raw_rwlock_t; +} arch_rwlock_t; -#define __RAW_RW_LOCK_UNLOCKED { 0 } +#define __ARCH_RW_LOCK_UNLOCKED { 0 } #endif diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h index de62eb0..a8671d8 100644 --- a/arch/arm/include/asm/spinlock.h +++ b/arch/arm/include/asm/spinlock.h @@ -86,7 +86,7 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) * just write zero since the lock is exclusively held. */ -static inline void __raw_write_lock(raw_rwlock_t *rw) +static inline void __raw_write_lock(arch_rwlock_t *rw) { unsigned long tmp; @@ -106,7 +106,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) smp_mb(); } -static inline int __raw_write_trylock(raw_rwlock_t *rw) +static inline int __raw_write_trylock(arch_rwlock_t *rw) { unsigned long tmp; @@ -126,7 +126,7 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) } } -static inline void __raw_write_unlock(raw_rwlock_t *rw) +static inline void __raw_write_unlock(arch_rwlock_t *rw) { smp_mb(); @@ -156,7 +156,7 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) * currently active. However, we know we won't have any write * locks. */ -static inline void __raw_read_lock(raw_rwlock_t *rw) +static inline void __raw_read_lock(arch_rwlock_t *rw) { unsigned long tmp, tmp2; @@ -176,7 +176,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) smp_mb(); } -static inline void __raw_read_unlock(raw_rwlock_t *rw) +static inline void __raw_read_unlock(arch_rwlock_t *rw) { unsigned long tmp, tmp2; @@ -198,7 +198,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw) : "cc"); } -static inline int __raw_read_trylock(raw_rwlock_t *rw) +static inline int __raw_read_trylock(arch_rwlock_t *rw) { unsigned long tmp, tmp2 = 1; diff --git a/arch/arm/include/asm/spinlock_types.h b/arch/arm/include/asm/spinlock_types.h index 9622e12..d14d197 100644 --- a/arch/arm/include/asm/spinlock_types.h +++ b/arch/arm/include/asm/spinlock_types.h @@ -13,8 +13,8 @@ typedef struct { typedef struct { volatile unsigned int lock; -} raw_rwlock_t; +} arch_rwlock_t; -#define __RAW_RW_LOCK_UNLOCKED { 0 } +#define __ARCH_RW_LOCK_UNLOCKED { 0 } #endif diff --git a/arch/blackfin/include/asm/spinlock.h b/arch/blackfin/include/asm/spinlock.h index 62d4954..7e1c56b 100644 --- a/arch/blackfin/include/asm/spinlock.h +++ b/arch/blackfin/include/asm/spinlock.h @@ -52,42 +52,42 @@ static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) cpu_relax(); } -static inline int __raw_read_can_lock(raw_rwlock_t *rw) +static inline int __raw_read_can_lock(arch_rwlock_t *rw) { return __raw_uncached_fetch_asm(&rw->lock) > 0; } -static inline int __raw_write_can_lock(raw_rwlock_t *rw) +static inline int __raw_write_can_lock(arch_rwlock_t *rw) { return __raw_uncached_fetch_asm(&rw->lock) == RW_LOCK_BIAS; } -static inline void __raw_read_lock(raw_rwlock_t *rw) +static inline void __raw_read_lock(arch_rwlock_t *rw) { __raw_read_lock_asm(&rw->lock); } -static inline int __raw_read_trylock(raw_rwlock_t *rw) +static inline int __raw_read_trylock(arch_rwlock_t *rw) { return __raw_read_trylock_asm(&rw->lock); } -static inline void __raw_read_unlock(raw_rwlock_t *rw) +static inline void __raw_read_unlock(arch_rwlock_t *rw) { __raw_read_unlock_asm(&rw->lock); } -static inline void __raw_write_lock(raw_rwlock_t *rw) +static inline void __raw_write_lock(arch_rwlock_t *rw) { __raw_write_lock_asm(&rw->lock); } -static inline int __raw_write_trylock(raw_rwlock_t *rw) +static inline int __raw_write_trylock(arch_rwlock_t *rw) { return __raw_write_trylock_asm(&rw->lock); } -static inline void __raw_write_unlock(raw_rwlock_t *rw) +static inline void __raw_write_unlock(arch_rwlock_t *rw) { __raw_write_unlock_asm(&rw->lock); } diff --git a/arch/blackfin/include/asm/spinlock_types.h b/arch/blackfin/include/asm/spinlock_types.h index c8a3928..1a33608 100644 --- a/arch/blackfin/include/asm/spinlock_types.h +++ b/arch/blackfin/include/asm/spinlock_types.h @@ -21,8 +21,8 @@ typedef struct { typedef struct { volatile unsigned int lock; -} raw_rwlock_t; +} arch_rwlock_t; -#define __RAW_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } +#define __ARCH_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } #endif diff --git a/arch/cris/include/arch-v32/arch/spinlock.h b/arch/cris/include/arch-v32/arch/spinlock.h index a2e8a39..1d7d3a8 100644 --- a/arch/cris/include/arch-v32/arch/spinlock.h +++ b/arch/cris/include/arch-v32/arch/spinlock.h @@ -56,17 +56,17 @@ arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) * */ -static inline int __raw_read_can_lock(raw_rwlock_t *x) +static inline int __raw_read_can_lock(arch_rwlock_t *x) { return (int)(x)->lock > 0; } -static inline int __raw_write_can_lock(raw_rwlock_t *x) +static inline int __raw_write_can_lock(arch_rwlock_t *x) { return (x)->lock == RW_LOCK_BIAS; } -static inline void __raw_read_lock(raw_rwlock_t *rw) +static inline void __raw_read_lock(arch_rwlock_t *rw) { arch_spin_lock(&rw->slock); while (rw->lock == 0); @@ -74,7 +74,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) arch_spin_unlock(&rw->slock); } -static inline void __raw_write_lock(raw_rwlock_t *rw) +static inline void __raw_write_lock(arch_rwlock_t *rw) { arch_spin_lock(&rw->slock); while (rw->lock != RW_LOCK_BIAS); @@ -82,14 +82,14 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) arch_spin_unlock(&rw->slock); } -static inline void __raw_read_unlock(raw_rwlock_t *rw) +static inline void __raw_read_unlock(arch_rwlock_t *rw) { arch_spin_lock(&rw->slock); rw->lock++; arch_spin_unlock(&rw->slock); } -static inline void __raw_write_unlock(raw_rwlock_t *rw) +static inline void __raw_write_unlock(arch_rwlock_t *rw) { arch_spin_lock(&rw->slock); while (rw->lock != RW_LOCK_BIAS); @@ -97,7 +97,7 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) arch_spin_unlock(&rw->slock); } -static inline int __raw_read_trylock(raw_rwlock_t *rw) +static inline int __raw_read_trylock(arch_rwlock_t *rw) { int ret = 0; arch_spin_lock(&rw->slock); @@ -109,7 +109,7 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw) return ret; } -static inline int __raw_write_trylock(raw_rwlock_t *rw) +static inline int __raw_write_trylock(arch_rwlock_t *rw) { int ret = 0; arch_spin_lock(&rw->slock); diff --git a/arch/ia64/include/asm/spinlock.h b/arch/ia64/include/asm/spinlock.h index b06165f..6715b6a 100644 --- a/arch/ia64/include/asm/spinlock.h +++ b/arch/ia64/include/asm/spinlock.h @@ -146,7 +146,7 @@ static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) #ifdef ASM_SUPPORTED static __always_inline void -__raw_read_lock_flags(raw_rwlock_t *lock, unsigned long flags) +__raw_read_lock_flags(arch_rwlock_t *lock, unsigned long flags) { __asm__ __volatile__ ( "tbit.nz p6, p0 = %1,%2\n" @@ -177,7 +177,7 @@ __raw_read_lock_flags(raw_rwlock_t *lock, unsigned long flags) #define __raw_read_lock(rw) \ do { \ - raw_rwlock_t *__read_lock_ptr = (rw); \ + arch_rwlock_t *__read_lock_ptr = (rw); \ \ while (unlikely(ia64_fetchadd(1, (int *) __read_lock_ptr, acq) < 0)) { \ ia64_fetchadd(-1, (int *) __read_lock_ptr, rel); \ @@ -190,14 +190,14 @@ do { \ #define __raw_read_unlock(rw) \ do { \ - raw_rwlock_t *__read_lock_ptr = (rw); \ + arch_rwlock_t *__read_lock_ptr = (rw); \ ia64_fetchadd(-1, (int *) __read_lock_ptr, rel); \ } while (0) #ifdef ASM_SUPPORTED static __always_inline void -__raw_write_lock_flags(raw_rwlock_t *lock, unsigned long flags) +__raw_write_lock_flags(arch_rwlock_t *lock, unsigned long flags) { __asm__ __volatile__ ( "tbit.nz p6, p0 = %1, %2\n" @@ -235,7 +235,7 @@ __raw_write_lock_flags(raw_rwlock_t *lock, unsigned long flags) (result == 0); \ }) -static inline void __raw_write_unlock(raw_rwlock_t *x) +static inline void __raw_write_unlock(arch_rwlock_t *x) { u8 *y = (u8 *)x; barrier(); @@ -265,7 +265,7 @@ static inline void __raw_write_unlock(raw_rwlock_t *x) (ia64_val == 0); \ }) -static inline void __raw_write_unlock(raw_rwlock_t *x) +static inline void __raw_write_unlock(arch_rwlock_t *x) { barrier(); x->write_lock = 0; @@ -273,10 +273,10 @@ static inline void __raw_write_unlock(raw_rwlock_t *x) #endif /* !ASM_SUPPORTED */ -static inline int __raw_read_trylock(raw_rwlock_t *x) +static inline int __raw_read_trylock(arch_rwlock_t *x) { union { - raw_rwlock_t lock; + arch_rwlock_t lock; __u32 word; } old, new; old.lock = new.lock = *x; diff --git a/arch/ia64/include/asm/spinlock_types.h b/arch/ia64/include/asm/spinlock_types.h index 6a11b65..e2b42a5 100644 --- a/arch/ia64/include/asm/spinlock_types.h +++ b/arch/ia64/include/asm/spinlock_types.h @@ -14,8 +14,8 @@ typedef struct { typedef struct { volatile unsigned int read_counter : 31; volatile unsigned int write_lock : 1; -} raw_rwlock_t; +} arch_rwlock_t; -#define __RAW_RW_LOCK_UNLOCKED { 0, 0 } +#define __ARCH_RW_LOCK_UNLOCKED { 0, 0 } #endif diff --git a/arch/m32r/include/asm/spinlock.h b/arch/m32r/include/asm/spinlock.h index 8acac95..1c76af8 100644 --- a/arch/m32r/include/asm/spinlock.h +++ b/arch/m32r/include/asm/spinlock.h @@ -148,7 +148,7 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) */ #define __raw_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS) -static inline void __raw_read_lock(raw_rwlock_t *rw) +static inline void __raw_read_lock(arch_rwlock_t *rw) { unsigned long tmp0, tmp1; @@ -199,7 +199,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) ); } -static inline void __raw_write_lock(raw_rwlock_t *rw) +static inline void __raw_write_lock(arch_rwlock_t *rw) { unsigned long tmp0, tmp1, tmp2; @@ -252,7 +252,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) ); } -static inline void __raw_read_unlock(raw_rwlock_t *rw) +static inline void __raw_read_unlock(arch_rwlock_t *rw) { unsigned long tmp0, tmp1; @@ -274,7 +274,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw) ); } -static inline void __raw_write_unlock(raw_rwlock_t *rw) +static inline void __raw_write_unlock(arch_rwlock_t *rw) { unsigned long tmp0, tmp1, tmp2; @@ -298,7 +298,7 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) ); } -static inline int __raw_read_trylock(raw_rwlock_t *lock) +static inline int __raw_read_trylock(arch_rwlock_t *lock) { atomic_t *count = (atomic_t*)lock; if (atomic_dec_return(count) >= 0) @@ -307,7 +307,7 @@ static inline int __raw_read_trylock(raw_rwlock_t *lock) return 0; } -static inline int __raw_write_trylock(raw_rwlock_t *lock) +static inline int __raw_write_trylock(arch_rwlock_t *lock) { atomic_t *count = (atomic_t *)lock; if (atomic_sub_and_test(RW_LOCK_BIAS, count)) diff --git a/arch/m32r/include/asm/spinlock_types.h b/arch/m32r/include/asm/spinlock_types.h index 5873a87..92e2767 100644 --- a/arch/m32r/include/asm/spinlock_types.h +++ b/arch/m32r/include/asm/spinlock_types.h @@ -13,11 +13,11 @@ typedef struct { typedef struct { volatile int lock; -} raw_rwlock_t; +} arch_rwlock_t; #define RW_LOCK_BIAS 0x01000000 #define RW_LOCK_BIAS_STR "0x01000000" -#define __RAW_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } +#define __ARCH_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } #endif /* _ASM_M32R_SPINLOCK_TYPES_H */ diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index 95edeba..7bf27c8 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h @@ -256,7 +256,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) */ #define __raw_write_can_lock(rw) (!(rw)->lock) -static inline void __raw_read_lock(raw_rwlock_t *rw) +static inline void __raw_read_lock(arch_rwlock_t *rw) { unsigned int tmp; @@ -301,7 +301,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) /* Note the use of sub, not subu which will make the kernel die with an overflow exception if we ever try to unlock an rwlock that is already unlocked or is being held by a writer. */ -static inline void __raw_read_unlock(raw_rwlock_t *rw) +static inline void __raw_read_unlock(arch_rwlock_t *rw) { unsigned int tmp; @@ -335,7 +335,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw) } } -static inline void __raw_write_lock(raw_rwlock_t *rw) +static inline void __raw_write_lock(arch_rwlock_t *rw) { unsigned int tmp; @@ -377,7 +377,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) smp_llsc_mb(); } -static inline void __raw_write_unlock(raw_rwlock_t *rw) +static inline void __raw_write_unlock(arch_rwlock_t *rw) { smp_mb(); @@ -389,7 +389,7 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) : "memory"); } -static inline int __raw_read_trylock(raw_rwlock_t *rw) +static inline int __raw_read_trylock(arch_rwlock_t *rw) { unsigned int tmp; int ret; @@ -433,7 +433,7 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw) return ret; } -static inline int __raw_write_trylock(raw_rwlock_t *rw) +static inline int __raw_write_trylock(arch_rwlock_t *rw) { unsigned int tmp; int ret; diff --git a/arch/mips/include/asm/spinlock_types.h b/arch/mips/include/asm/spinlock_types.h index b4c5efa..ee197c2 100644 --- a/arch/mips/include/asm/spinlock_types.h +++ b/arch/mips/include/asm/spinlock_types.h @@ -18,8 +18,8 @@ typedef struct { typedef struct { volatile unsigned int lock; -} raw_rwlock_t; +} arch_rwlock_t; -#define __RAW_RW_LOCK_UNLOCKED { 0 } +#define __ARCH_RW_LOCK_UNLOCKED { 0 } #endif diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h index 235e7e3..1ff3a0a 100644 --- a/arch/parisc/include/asm/spinlock.h +++ b/arch/parisc/include/asm/spinlock.h @@ -69,7 +69,7 @@ static inline int arch_spin_trylock(arch_spinlock_t *x) /* Note that we have to ensure interrupts are disabled in case we're * interrupted by some other code that wants to grab the same read lock */ -static __inline__ void __raw_read_lock(raw_rwlock_t *rw) +static __inline__ void __raw_read_lock(arch_rwlock_t *rw) { unsigned long flags; local_irq_save(flags); @@ -81,7 +81,7 @@ static __inline__ void __raw_read_lock(raw_rwlock_t *rw) /* Note that we have to ensure interrupts are disabled in case we're * interrupted by some other code that wants to grab the same read lock */ -static __inline__ void __raw_read_unlock(raw_rwlock_t *rw) +static __inline__ void __raw_read_unlock(arch_rwlock_t *rw) { unsigned long flags; local_irq_save(flags); @@ -93,7 +93,7 @@ static __inline__ void __raw_read_unlock(raw_rwlock_t *rw) /* Note that we have to ensure interrupts are disabled in case we're * interrupted by some other code that wants to grab the same read lock */ -static __inline__ int __raw_read_trylock(raw_rwlock_t *rw) +static __inline__ int __raw_read_trylock(arch_rwlock_t *rw) { unsigned long flags; retry: @@ -119,7 +119,7 @@ static __inline__ int __raw_read_trylock(raw_rwlock_t *rw) /* Note that we have to ensure interrupts are disabled in case we're * interrupted by some other code that wants to read_trylock() this lock */ -static __inline__ void __raw_write_lock(raw_rwlock_t *rw) +static __inline__ void __raw_write_lock(arch_rwlock_t *rw) { unsigned long flags; retry: @@ -141,7 +141,7 @@ retry: local_irq_restore(flags); } -static __inline__ void __raw_write_unlock(raw_rwlock_t *rw) +static __inline__ void __raw_write_unlock(arch_rwlock_t *rw) { rw->counter = 0; arch_spin_unlock(&rw->lock); @@ -149,7 +149,7 @@ static __inline__ void __raw_write_unlock(raw_rwlock_t *rw) /* Note that we have to ensure interrupts are disabled in case we're * interrupted by some other code that wants to read_trylock() this lock */ -static __inline__ int __raw_write_trylock(raw_rwlock_t *rw) +static __inline__ int __raw_write_trylock(arch_rwlock_t *rw) { unsigned long flags; int result = 0; @@ -173,7 +173,7 @@ static __inline__ int __raw_write_trylock(raw_rwlock_t *rw) * read_can_lock - would read_trylock() succeed? * @lock: the rwlock in question. */ -static __inline__ int __raw_read_can_lock(raw_rwlock_t *rw) +static __inline__ int __raw_read_can_lock(arch_rwlock_t *rw) { return rw->counter >= 0; } @@ -182,7 +182,7 @@ static __inline__ int __raw_read_can_lock(raw_rwlock_t *rw) * write_can_lock - would write_trylock() succeed? * @lock: the rwlock in question. */ -static __inline__ int __raw_write_can_lock(raw_rwlock_t *rw) +static __inline__ int __raw_write_can_lock(arch_rwlock_t *rw) { return !rw->counter; } diff --git a/arch/parisc/include/asm/spinlock_types.h b/arch/parisc/include/asm/spinlock_types.h index 396d274..8c373aa 100644 --- a/arch/parisc/include/asm/spinlock_types.h +++ b/arch/parisc/include/asm/spinlock_types.h @@ -14,8 +14,8 @@ typedef struct { typedef struct { arch_spinlock_t lock; volatile int counter; -} raw_rwlock_t; +} arch_rwlock_t; -#define __RAW_RW_LOCK_UNLOCKED { __ARCH_SPIN_LOCK_UNLOCKED, 0 } +#define __ARCH_RW_LOCK_UNLOCKED { __ARCH_SPIN_LOCK_UNLOCKED, 0 } #endif diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h index cdcaf6b..2fad2c0 100644 --- a/arch/powerpc/include/asm/spinlock.h +++ b/arch/powerpc/include/asm/spinlock.h @@ -97,7 +97,7 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) /* We only yield to the hypervisor if we are in shared processor mode */ #define SHARED_PROCESSOR (get_lppaca()->shared_proc) extern void __spin_yield(arch_spinlock_t *lock); -extern void __rw_yield(raw_rwlock_t *lock); +extern void __rw_yield(arch_rwlock_t *lock); #else /* SPLPAR || ISERIES */ #define __spin_yield(x) barrier() #define __rw_yield(x) barrier() @@ -181,7 +181,7 @@ extern void arch_spin_unlock_wait(arch_spinlock_t *lock); * This returns the old value in the lock + 1, * so we got a read lock if the return value is > 0. */ -static inline long arch_read_trylock(raw_rwlock_t *rw) +static inline long arch_read_trylock(arch_rwlock_t *rw) { long tmp; @@ -205,7 +205,7 @@ static inline long arch_read_trylock(raw_rwlock_t *rw) * This returns the old value in the lock, * so we got the write lock if the return value is 0. */ -static inline long arch_write_trylock(raw_rwlock_t *rw) +static inline long arch_write_trylock(arch_rwlock_t *rw) { long tmp, token; @@ -225,7 +225,7 @@ static inline long arch_write_trylock(raw_rwlock_t *rw) return tmp; } -static inline void __raw_read_lock(raw_rwlock_t *rw) +static inline void __raw_read_lock(arch_rwlock_t *rw) { while (1) { if (likely(arch_read_trylock(rw) > 0)) @@ -239,7 +239,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) } } -static inline void __raw_write_lock(raw_rwlock_t *rw) +static inline void __raw_write_lock(arch_rwlock_t *rw) { while (1) { if (likely(arch_write_trylock(rw) == 0)) @@ -253,17 +253,17 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) } } -static inline int __raw_read_trylock(raw_rwlock_t *rw) +static inline int __raw_read_trylock(arch_rwlock_t *rw) { return arch_read_trylock(rw) > 0; } -static inline int __raw_write_trylock(raw_rwlock_t *rw) +static inline int __raw_write_trylock(arch_rwlock_t *rw) { return arch_write_trylock(rw) == 0; } -static inline void __raw_read_unlock(raw_rwlock_t *rw) +static inline void __raw_read_unlock(arch_rwlock_t *rw) { long tmp; @@ -280,7 +280,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw) : "cr0", "xer", "memory"); } -static inline void __raw_write_unlock(raw_rwlock_t *rw) +static inline void __raw_write_unlock(arch_rwlock_t *rw) { __asm__ __volatile__("# write_unlock\n\t" LWSYNC_ON_SMP: : :"memory"); diff --git a/arch/powerpc/include/asm/spinlock_types.h b/arch/powerpc/include/asm/spinlock_types.h index f5f39d8..2351adc 100644 --- a/arch/powerpc/include/asm/spinlock_types.h +++ b/arch/powerpc/include/asm/spinlock_types.h @@ -13,8 +13,8 @@ typedef struct { typedef struct { volatile signed int lock; -} raw_rwlock_t; +} arch_rwlock_t; -#define __RAW_RW_LOCK_UNLOCKED { 0 } +#define __ARCH_RW_LOCK_UNLOCKED { 0 } #endif diff --git a/arch/powerpc/lib/locks.c b/arch/powerpc/lib/locks.c index ee395e3..58e14fb 100644 --- a/arch/powerpc/lib/locks.c +++ b/arch/powerpc/lib/locks.c @@ -55,7 +55,7 @@ void __spin_yield(arch_spinlock_t *lock) * This turns out to be the same for read and write locks, since * we only know the holder if it is write-locked. */ -void __rw_yield(raw_rwlock_t *rw) +void __rw_yield(arch_rwlock_t *rw) { int lock_value; unsigned int holder_cpu, yield_count; diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h index a94c146..7f98f0e 100644 --- a/arch/s390/include/asm/spinlock.h +++ b/arch/s390/include/asm/spinlock.h @@ -121,14 +121,14 @@ static inline void arch_spin_unlock(arch_spinlock_t *lp) */ #define __raw_write_can_lock(x) ((x)->lock == 0) -extern void _raw_read_lock_wait(raw_rwlock_t *lp); -extern void _raw_read_lock_wait_flags(raw_rwlock_t *lp, unsigned long flags); -extern int _raw_read_trylock_retry(raw_rwlock_t *lp); -extern void _raw_write_lock_wait(raw_rwlock_t *lp); -extern void _raw_write_lock_wait_flags(raw_rwlock_t *lp, unsigned long flags); -extern int _raw_write_trylock_retry(raw_rwlock_t *lp); - -static inline void __raw_read_lock(raw_rwlock_t *rw) +extern void _raw_read_lock_wait(arch_rwlock_t *lp); +extern void _raw_read_lock_wait_flags(arch_rwlock_t *lp, unsigned long flags); +extern int _raw_read_trylock_retry(arch_rwlock_t *lp); +extern void _raw_write_lock_wait(arch_rwlock_t *lp); +extern void _raw_write_lock_wait_flags(arch_rwlock_t *lp, unsigned long flags); +extern int _raw_write_trylock_retry(arch_rwlock_t *lp); + +static inline void __raw_read_lock(arch_rwlock_t *rw) { unsigned int old; old = rw->lock & 0x7fffffffU; @@ -136,7 +136,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) _raw_read_lock_wait(rw); } -static inline void __raw_read_lock_flags(raw_rwlock_t *rw, unsigned long flags) +static inline void __raw_read_lock_flags(arch_rwlock_t *rw, unsigned long flags) { unsigned int old; old = rw->lock & 0x7fffffffU; @@ -144,7 +144,7 @@ static inline void __raw_read_lock_flags(raw_rwlock_t *rw, unsigned long flags) _raw_read_lock_wait_flags(rw, flags); } -static inline void __raw_read_unlock(raw_rwlock_t *rw) +static inline void __raw_read_unlock(arch_rwlock_t *rw) { unsigned int old, cmp; @@ -155,24 +155,24 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw) } while (cmp != old); } -static inline void __raw_write_lock(raw_rwlock_t *rw) +static inline void __raw_write_lock(arch_rwlock_t *rw) { if (unlikely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) != 0)) _raw_write_lock_wait(rw); } -static inline void __raw_write_lock_flags(raw_rwlock_t *rw, unsigned long flags) +static inline void __raw_write_lock_flags(arch_rwlock_t *rw, unsigned long flags) { if (unlikely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) != 0)) _raw_write_lock_wait_flags(rw, flags); } -static inline void __raw_write_unlock(raw_rwlock_t *rw) +static inline void __raw_write_unlock(arch_rwlock_t *rw) { _raw_compare_and_swap(&rw->lock, 0x80000000, 0); } -static inline int __raw_read_trylock(raw_rwlock_t *rw) +static inline int __raw_read_trylock(arch_rwlock_t *rw) { unsigned int old; old = rw->lock & 0x7fffffffU; @@ -181,7 +181,7 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw) return _raw_read_trylock_retry(rw); } -static inline int __raw_write_trylock(raw_rwlock_t *rw) +static inline int __raw_write_trylock(arch_rwlock_t *rw) { if (likely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)) return 1; diff --git a/arch/s390/include/asm/spinlock_types.h b/arch/s390/include/asm/spinlock_types.h index e25c037..9c76656 100644 --- a/arch/s390/include/asm/spinlock_types.h +++ b/arch/s390/include/asm/spinlock_types.h @@ -13,8 +13,8 @@ typedef struct { typedef struct { volatile unsigned int lock; -} raw_rwlock_t; +} arch_rwlock_t; -#define __RAW_RW_LOCK_UNLOCKED { 0 } +#define __ARCH_RW_LOCK_UNLOCKED { 0 } #endif diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index f459645..09fee9a 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c @@ -105,7 +105,7 @@ void arch_spin_relax(arch_spinlock_t *lock) } EXPORT_SYMBOL(arch_spin_relax); -void _raw_read_lock_wait(raw_rwlock_t *rw) +void _raw_read_lock_wait(arch_rwlock_t *rw) { unsigned int old; int count = spin_retry; @@ -124,7 +124,7 @@ void _raw_read_lock_wait(raw_rwlock_t *rw) } EXPORT_SYMBOL(_raw_read_lock_wait); -void _raw_read_lock_wait_flags(raw_rwlock_t *rw, unsigned long flags) +void _raw_read_lock_wait_flags(arch_rwlock_t *rw, unsigned long flags) { unsigned int old; int count = spin_retry; @@ -145,7 +145,7 @@ void _raw_read_lock_wait_flags(raw_rwlock_t *rw, unsigned long flags) } EXPORT_SYMBOL(_raw_read_lock_wait_flags); -int _raw_read_trylock_retry(raw_rwlock_t *rw) +int _raw_read_trylock_retry(arch_rwlock_t *rw) { unsigned int old; int count = spin_retry; @@ -161,7 +161,7 @@ int _raw_read_trylock_retry(raw_rwlock_t *rw) } EXPORT_SYMBOL(_raw_read_trylock_retry); -void _raw_write_lock_wait(raw_rwlock_t *rw) +void _raw_write_lock_wait(arch_rwlock_t *rw) { int count = spin_retry; @@ -178,7 +178,7 @@ void _raw_write_lock_wait(raw_rwlock_t *rw) } EXPORT_SYMBOL(_raw_write_lock_wait); -void _raw_write_lock_wait_flags(raw_rwlock_t *rw, unsigned long flags) +void _raw_write_lock_wait_flags(arch_rwlock_t *rw, unsigned long flags) { int count = spin_retry; @@ -197,7 +197,7 @@ void _raw_write_lock_wait_flags(raw_rwlock_t *rw, unsigned long flags) } EXPORT_SYMBOL(_raw_write_lock_wait_flags); -int _raw_write_trylock_retry(raw_rwlock_t *rw) +int _raw_write_trylock_retry(arch_rwlock_t *rw) { int count = spin_retry; diff --git a/arch/sh/include/asm/spinlock.h b/arch/sh/include/asm/spinlock.h index da1c649..7f3626a 100644 --- a/arch/sh/include/asm/spinlock.h +++ b/arch/sh/include/asm/spinlock.h @@ -108,7 +108,7 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) */ #define __raw_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS) -static inline void __raw_read_lock(raw_rwlock_t *rw) +static inline void __raw_read_lock(arch_rwlock_t *rw) { unsigned long tmp; @@ -126,7 +126,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) ); } -static inline void __raw_read_unlock(raw_rwlock_t *rw) +static inline void __raw_read_unlock(arch_rwlock_t *rw) { unsigned long tmp; @@ -142,7 +142,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw) ); } -static inline void __raw_write_lock(raw_rwlock_t *rw) +static inline void __raw_write_lock(arch_rwlock_t *rw) { unsigned long tmp; @@ -160,7 +160,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) ); } -static inline void __raw_write_unlock(raw_rwlock_t *rw) +static inline void __raw_write_unlock(arch_rwlock_t *rw) { __asm__ __volatile__ ( "mov.l %1, @%0 ! __raw_write_unlock \n\t" @@ -170,7 +170,7 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) ); } -static inline int __raw_read_trylock(raw_rwlock_t *rw) +static inline int __raw_read_trylock(arch_rwlock_t *rw) { unsigned long tmp, oldval; @@ -193,7 +193,7 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw) return (oldval > 0); } -static inline int __raw_write_trylock(raw_rwlock_t *rw) +static inline int __raw_write_trylock(arch_rwlock_t *rw) { unsigned long tmp, oldval; diff --git a/arch/sh/include/asm/spinlock_types.h b/arch/sh/include/asm/spinlock_types.h index a3be2db..9b7560d 100644 --- a/arch/sh/include/asm/spinlock_types.h +++ b/arch/sh/include/asm/spinlock_types.h @@ -13,9 +13,9 @@ typedef struct { typedef struct { volatile unsigned int lock; -} raw_rwlock_t; +} arch_rwlock_t; #define RW_LOCK_BIAS 0x01000000 -#define __RAW_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } +#define __ARCH_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } #endif diff --git a/arch/sparc/include/asm/spinlock_32.h b/arch/sparc/include/asm/spinlock_32.h index 9b0f2f5..06d37e5 100644 --- a/arch/sparc/include/asm/spinlock_32.h +++ b/arch/sparc/include/asm/spinlock_32.h @@ -65,7 +65,7 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) * Sort of like atomic_t's on Sparc, but even more clever. * * ------------------------------------ - * | 24-bit counter | wlock | raw_rwlock_t + * | 24-bit counter | wlock | arch_rwlock_t * ------------------------------------ * 31 8 7 0 * @@ -76,9 +76,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) * * Unfortunately this scheme limits us to ~16,000,000 cpus. */ -static inline void arch_read_lock(raw_rwlock_t *rw) +static inline void arch_read_lock(arch_rwlock_t *rw) { - register raw_rwlock_t *lp asm("g1"); + register arch_rwlock_t *lp asm("g1"); lp = rw; __asm__ __volatile__( "mov %%o7, %%g4\n\t" @@ -96,9 +96,9 @@ do { unsigned long flags; \ local_irq_restore(flags); \ } while(0) -static inline void arch_read_unlock(raw_rwlock_t *rw) +static inline void arch_read_unlock(arch_rwlock_t *rw) { - register raw_rwlock_t *lp asm("g1"); + register arch_rwlock_t *lp asm("g1"); lp = rw; __asm__ __volatile__( "mov %%o7, %%g4\n\t" @@ -116,9 +116,9 @@ do { unsigned long flags; \ local_irq_restore(flags); \ } while(0) -static inline void __raw_write_lock(raw_rwlock_t *rw) +static inline void __raw_write_lock(arch_rwlock_t *rw) { - register raw_rwlock_t *lp asm("g1"); + register arch_rwlock_t *lp asm("g1"); lp = rw; __asm__ __volatile__( "mov %%o7, %%g4\n\t" @@ -130,7 +130,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) *(volatile __u32 *)&lp->lock = ~0U; } -static inline int __raw_write_trylock(raw_rwlock_t *rw) +static inline int __raw_write_trylock(arch_rwlock_t *rw) { unsigned int val; @@ -150,9 +150,9 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) return (val == 0); } -static inline int arch_read_trylock(raw_rwlock_t *rw) +static inline int arch_read_trylock(arch_rwlock_t *rw) { - register raw_rwlock_t *lp asm("g1"); + register arch_rwlock_t *lp asm("g1"); register int res asm("o0"); lp = rw; __asm__ __volatile__( diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h index 7cf58a2..2b22d7f 100644 --- a/arch/sparc/include/asm/spinlock_64.h +++ b/arch/sparc/include/asm/spinlock_64.h @@ -92,7 +92,7 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long fla /* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */ -static void inline arch_read_lock(raw_rwlock_t *lock) +static void inline arch_read_lock(arch_rwlock_t *lock) { unsigned long tmp1, tmp2; @@ -115,7 +115,7 @@ static void inline arch_read_lock(raw_rwlock_t *lock) : "memory"); } -static int inline arch_read_trylock(raw_rwlock_t *lock) +static int inline arch_read_trylock(arch_rwlock_t *lock) { int tmp1, tmp2; @@ -136,7 +136,7 @@ static int inline arch_read_trylock(raw_rwlock_t *lock) return tmp1; } -static void inline arch_read_unlock(raw_rwlock_t *lock) +static void inline arch_read_unlock(arch_rwlock_t *lock) { unsigned long tmp1, tmp2; @@ -152,7 +152,7 @@ static void inline arch_read_unlock(raw_rwlock_t *lock) : "memory"); } -static void inline arch_write_lock(raw_rwlock_t *lock) +static void inline arch_write_lock(arch_rwlock_t *lock) { unsigned long mask, tmp1, tmp2; @@ -177,7 +177,7 @@ static void inline arch_write_lock(raw_rwlock_t *lock) : "memory"); } -static void inline arch_write_unlock(raw_rwlock_t *lock) +static void inline arch_write_unlock(arch_rwlock_t *lock) { __asm__ __volatile__( " stw %%g0, [%0]" @@ -186,7 +186,7 @@ static void inline arch_write_unlock(raw_rwlock_t *lock) : "memory"); } -static int inline arch_write_trylock(raw_rwlock_t *lock) +static int inline arch_write_trylock(arch_rwlock_t *lock) { unsigned long mask, tmp1, tmp2, result; diff --git a/arch/sparc/include/asm/spinlock_types.h b/arch/sparc/include/asm/spinlock_types.h index c145e63..9c454fd 100644 --- a/arch/sparc/include/asm/spinlock_types.h +++ b/arch/sparc/include/asm/spinlock_types.h @@ -13,8 +13,8 @@ typedef struct { typedef struct { volatile unsigned int lock; -} raw_rwlock_t; +} arch_rwlock_t; -#define __RAW_RW_LOCK_UNLOCKED { 0 } +#define __ARCH_RW_LOCK_UNLOCKED { 0 } #endif diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index ab9055f..99cb86e 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h @@ -232,7 +232,7 @@ static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) * read_can_lock - would read_trylock() succeed? * @lock: the rwlock in question. */ -static inline int __raw_read_can_lock(raw_rwlock_t *lock) +static inline int __raw_read_can_lock(arch_rwlock_t *lock) { return (int)(lock)->lock > 0; } @@ -241,12 +241,12 @@ static inline int __raw_read_can_lock(raw_rwlock_t *lock) * write_can_lock - would write_trylock() succeed? * @lock: the rwlock in question. */ -static inline int __raw_write_can_lock(raw_rwlock_t *lock) +static inline int __raw_write_can_lock(arch_rwlock_t *lock) { return (lock)->lock == RW_LOCK_BIAS; } -static inline void __raw_read_lock(raw_rwlock_t *rw) +static inline void __raw_read_lock(arch_rwlock_t *rw) { asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t" "jns 1f\n" @@ -255,7 +255,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) ::LOCK_PTR_REG (rw) : "memory"); } -static inline void __raw_write_lock(raw_rwlock_t *rw) +static inline void __raw_write_lock(arch_rwlock_t *rw) { asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t" "jz 1f\n" @@ -264,7 +264,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory"); } -static inline int __raw_read_trylock(raw_rwlock_t *lock) +static inline int __raw_read_trylock(arch_rwlock_t *lock) { atomic_t *count = (atomic_t *)lock; @@ -274,7 +274,7 @@ static inline int __raw_read_trylock(raw_rwlock_t *lock) return 0; } -static inline int __raw_write_trylock(raw_rwlock_t *lock) +static inline int __raw_write_trylock(arch_rwlock_t *lock) { atomic_t *count = (atomic_t *)lock; @@ -284,12 +284,12 @@ static inline int __raw_write_trylock(raw_rwlock_t *lock) return 0; } -static inline void __raw_read_unlock(raw_rwlock_t *rw) +static inline void __raw_read_unlock(arch_rwlock_t *rw) { asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory"); } -static inline void __raw_write_unlock(raw_rwlock_t *rw) +static inline void __raw_write_unlock(arch_rwlock_t *rw) { asm volatile(LOCK_PREFIX "addl %1, %0" : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory"); diff --git a/arch/x86/include/asm/spinlock_types.h b/arch/x86/include/asm/spinlock_types.h index 696f836..dcb48b2 100644 --- a/arch/x86/include/asm/spinlock_types.h +++ b/arch/x86/include/asm/spinlock_types.h @@ -13,8 +13,8 @@ typedef struct arch_spinlock { typedef struct { unsigned int lock; -} raw_rwlock_t; +} arch_rwlock_t; -#define __RAW_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } +#define __ARCH_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } #endif /* _ASM_X86_SPINLOCK_TYPES_H */ diff --git a/include/linux/rwlock_types.h b/include/linux/rwlock_types.h index f8c9352..bd31808 100644 --- a/include/linux/rwlock_types.h +++ b/include/linux/rwlock_types.h @@ -9,7 +9,7 @@ * Released under the General Public License (GPL). */ typedef struct { - raw_rwlock_t raw_lock; + arch_rwlock_t raw_lock; #ifdef CONFIG_GENERIC_LOCKBREAK unsigned int break_lock; #endif @@ -32,14 +32,14 @@ typedef struct { #ifdef CONFIG_DEBUG_SPINLOCK #define __RW_LOCK_UNLOCKED(lockname) \ - (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \ + (rwlock_t) { .raw_lock = __ARCH_RW_LOCK_UNLOCKED, \ .magic = RWLOCK_MAGIC, \ .owner = SPINLOCK_OWNER_INIT, \ .owner_cpu = -1, \ RW_DEP_MAP_INIT(lockname) } #else #define __RW_LOCK_UNLOCKED(lockname) \ - (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \ + (rwlock_t) { .raw_lock = __ARCH_RW_LOCK_UNLOCKED, \ RW_DEP_MAP_INIT(lockname) } #endif diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index de3a022..53bc221 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -8,7 +8,7 @@ * * on SMP builds: * - * asm/spinlock_types.h: contains the arch_spinlock_t/raw_rwlock_t and the + * asm/spinlock_types.h: contains the arch_spinlock_t/arch_rwlock_t and the * initializers * * linux/spinlock_types.h: @@ -75,7 +75,7 @@ #define __lockfunc __attribute__((section(".spinlock.text"))) /* - * Pull the arch_spinlock_t and raw_rwlock_t definitions: + * Pull the arch_spinlock_t and arch_rwlock_t definitions: */ #include diff --git a/include/linux/spinlock_types_up.h b/include/linux/spinlock_types_up.h index 10db021..c09b640 100644 --- a/include/linux/spinlock_types_up.h +++ b/include/linux/spinlock_types_up.h @@ -30,8 +30,8 @@ typedef struct { } arch_spinlock_t; typedef struct { /* no debug version on UP */ -} raw_rwlock_t; +} arch_rwlock_t; -#define __RAW_RW_LOCK_UNLOCKED { } +#define __ARCH_RW_LOCK_UNLOCKED { } #endif /* __LINUX_SPINLOCK_TYPES_UP_H */ diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index 1304fe0..3f72f10 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c @@ -41,7 +41,7 @@ void __rwlock_init(rwlock_t *lock, const char *name, debug_check_no_locks_freed((void *)lock, sizeof(*lock)); lockdep_init_map(&lock->dep_map, name, key, 0); #endif - lock->raw_lock = (raw_rwlock_t) __RAW_RW_LOCK_UNLOCKED; + lock->raw_lock = (arch_rwlock_t) __ARCH_RW_LOCK_UNLOCKED; lock->magic = RWLOCK_MAGIC; lock->owner = SPINLOCK_OWNER_INIT; lock->owner_cpu = -1; -- cgit v0.10.2 From e5931943d02bf751b1ec849c0d2ade23d76a8d41 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 3 Dec 2009 20:08:46 +0100 Subject: locking: Convert raw_rwlock functions to arch_rwlock Name space cleanup for rwlock functions. No functional change. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: David S. Miller Acked-by: Ingo Molnar Cc: linux-arch@vger.kernel.org diff --git a/arch/alpha/include/asm/spinlock.h b/arch/alpha/include/asm/spinlock.h index e8b2970..d0faca1 100644 --- a/arch/alpha/include/asm/spinlock.h +++ b/arch/alpha/include/asm/spinlock.h @@ -50,17 +50,17 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) /***********************************************************/ -static inline int __raw_read_can_lock(arch_rwlock_t *lock) +static inline int arch_read_can_lock(arch_rwlock_t *lock) { return (lock->lock & 1) == 0; } -static inline int __raw_write_can_lock(arch_rwlock_t *lock) +static inline int arch_write_can_lock(arch_rwlock_t *lock) { return lock->lock == 0; } -static inline void __raw_read_lock(arch_rwlock_t *lock) +static inline void arch_read_lock(arch_rwlock_t *lock) { long regx; @@ -80,7 +80,7 @@ static inline void __raw_read_lock(arch_rwlock_t *lock) : "m" (*lock) : "memory"); } -static inline void __raw_write_lock(arch_rwlock_t *lock) +static inline void arch_write_lock(arch_rwlock_t *lock) { long regx; @@ -100,7 +100,7 @@ static inline void __raw_write_lock(arch_rwlock_t *lock) : "m" (*lock) : "memory"); } -static inline int __raw_read_trylock(arch_rwlock_t * lock) +static inline int arch_read_trylock(arch_rwlock_t * lock) { long regx; int success; @@ -122,7 +122,7 @@ static inline int __raw_read_trylock(arch_rwlock_t * lock) return success; } -static inline int __raw_write_trylock(arch_rwlock_t * lock) +static inline int arch_write_trylock(arch_rwlock_t * lock) { long regx; int success; @@ -144,7 +144,7 @@ static inline int __raw_write_trylock(arch_rwlock_t * lock) return success; } -static inline void __raw_read_unlock(arch_rwlock_t * lock) +static inline void arch_read_unlock(arch_rwlock_t * lock) { long regx; __asm__ __volatile__( @@ -160,14 +160,14 @@ static inline void __raw_read_unlock(arch_rwlock_t * lock) : "m" (*lock) : "memory"); } -static inline void __raw_write_unlock(arch_rwlock_t * lock) +static inline void arch_write_unlock(arch_rwlock_t * lock) { mb(); lock->lock = 0; } -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) +#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) +#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) #define arch_spin_relax(lock) cpu_relax() #define arch_read_relax(lock) cpu_relax() diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h index a8671d8..c91c64c 100644 --- a/arch/arm/include/asm/spinlock.h +++ b/arch/arm/include/asm/spinlock.h @@ -86,7 +86,7 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) * just write zero since the lock is exclusively held. */ -static inline void __raw_write_lock(arch_rwlock_t *rw) +static inline void arch_write_lock(arch_rwlock_t *rw) { unsigned long tmp; @@ -106,7 +106,7 @@ static inline void __raw_write_lock(arch_rwlock_t *rw) smp_mb(); } -static inline int __raw_write_trylock(arch_rwlock_t *rw) +static inline int arch_write_trylock(arch_rwlock_t *rw) { unsigned long tmp; @@ -126,7 +126,7 @@ static inline int __raw_write_trylock(arch_rwlock_t *rw) } } -static inline void __raw_write_unlock(arch_rwlock_t *rw) +static inline void arch_write_unlock(arch_rwlock_t *rw) { smp_mb(); @@ -142,7 +142,7 @@ static inline void __raw_write_unlock(arch_rwlock_t *rw) } /* write_can_lock - would write_trylock() succeed? */ -#define __raw_write_can_lock(x) ((x)->lock == 0) +#define arch_write_can_lock(x) ((x)->lock == 0) /* * Read locks are a bit more hairy: @@ -156,7 +156,7 @@ static inline void __raw_write_unlock(arch_rwlock_t *rw) * currently active. However, we know we won't have any write * locks. */ -static inline void __raw_read_lock(arch_rwlock_t *rw) +static inline void arch_read_lock(arch_rwlock_t *rw) { unsigned long tmp, tmp2; @@ -176,7 +176,7 @@ static inline void __raw_read_lock(arch_rwlock_t *rw) smp_mb(); } -static inline void __raw_read_unlock(arch_rwlock_t *rw) +static inline void arch_read_unlock(arch_rwlock_t *rw) { unsigned long tmp, tmp2; @@ -198,7 +198,7 @@ static inline void __raw_read_unlock(arch_rwlock_t *rw) : "cc"); } -static inline int __raw_read_trylock(arch_rwlock_t *rw) +static inline int arch_read_trylock(arch_rwlock_t *rw) { unsigned long tmp, tmp2 = 1; @@ -215,10 +215,10 @@ static inline int __raw_read_trylock(arch_rwlock_t *rw) } /* read_can_lock - would read_trylock() succeed? */ -#define __raw_read_can_lock(x) ((x)->lock < 0x80000000) +#define arch_read_can_lock(x) ((x)->lock < 0x80000000) -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) +#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) +#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) #define arch_spin_relax(lock) cpu_relax() #define arch_read_relax(lock) cpu_relax() diff --git a/arch/blackfin/include/asm/spinlock.h b/arch/blackfin/include/asm/spinlock.h index 7e1c56b..1942ccf 100644 --- a/arch/blackfin/include/asm/spinlock.h +++ b/arch/blackfin/include/asm/spinlock.h @@ -17,12 +17,12 @@ asmlinkage int __raw_spin_is_locked_asm(volatile int *ptr); asmlinkage void __raw_spin_lock_asm(volatile int *ptr); asmlinkage int __raw_spin_trylock_asm(volatile int *ptr); asmlinkage void __raw_spin_unlock_asm(volatile int *ptr); -asmlinkage void __raw_read_lock_asm(volatile int *ptr); -asmlinkage int __raw_read_trylock_asm(volatile int *ptr); -asmlinkage void __raw_read_unlock_asm(volatile int *ptr); -asmlinkage void __raw_write_lock_asm(volatile int *ptr); -asmlinkage int __raw_write_trylock_asm(volatile int *ptr); -asmlinkage void __raw_write_unlock_asm(volatile int *ptr); +asmlinkage void arch_read_lock_asm(volatile int *ptr); +asmlinkage int arch_read_trylock_asm(volatile int *ptr); +asmlinkage void arch_read_unlock_asm(volatile int *ptr); +asmlinkage void arch_write_lock_asm(volatile int *ptr); +asmlinkage int arch_write_trylock_asm(volatile int *ptr); +asmlinkage void arch_write_unlock_asm(volatile int *ptr); static inline int arch_spin_is_locked(arch_spinlock_t *lock) { @@ -52,44 +52,44 @@ static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) cpu_relax(); } -static inline int __raw_read_can_lock(arch_rwlock_t *rw) +static inline int arch_read_can_lock(arch_rwlock_t *rw) { return __raw_uncached_fetch_asm(&rw->lock) > 0; } -static inline int __raw_write_can_lock(arch_rwlock_t *rw) +static inline int arch_write_can_lock(arch_rwlock_t *rw) { return __raw_uncached_fetch_asm(&rw->lock) == RW_LOCK_BIAS; } -static inline void __raw_read_lock(arch_rwlock_t *rw) +static inline void arch_read_lock(arch_rwlock_t *rw) { - __raw_read_lock_asm(&rw->lock); + arch_read_lock_asm(&rw->lock); } -static inline int __raw_read_trylock(arch_rwlock_t *rw) +static inline int arch_read_trylock(arch_rwlock_t *rw) { - return __raw_read_trylock_asm(&rw->lock); + return arch_read_trylock_asm(&rw->lock); } -static inline void __raw_read_unlock(arch_rwlock_t *rw) +static inline void arch_read_unlock(arch_rwlock_t *rw) { - __raw_read_unlock_asm(&rw->lock); + arch_read_unlock_asm(&rw->lock); } -static inline void __raw_write_lock(arch_rwlock_t *rw) +static inline void arch_write_lock(arch_rwlock_t *rw) { - __raw_write_lock_asm(&rw->lock); + arch_write_lock_asm(&rw->lock); } -static inline int __raw_write_trylock(arch_rwlock_t *rw) +static inline int arch_write_trylock(arch_rwlock_t *rw) { - return __raw_write_trylock_asm(&rw->lock); + return arch_write_trylock_asm(&rw->lock); } -static inline void __raw_write_unlock(arch_rwlock_t *rw) +static inline void arch_write_unlock(arch_rwlock_t *rw) { - __raw_write_unlock_asm(&rw->lock); + arch_write_unlock_asm(&rw->lock); } #define arch_spin_relax(lock) cpu_relax() diff --git a/arch/cris/include/arch-v32/arch/spinlock.h b/arch/cris/include/arch-v32/arch/spinlock.h index 1d7d3a8..f171a66 100644 --- a/arch/cris/include/arch-v32/arch/spinlock.h +++ b/arch/cris/include/arch-v32/arch/spinlock.h @@ -56,17 +56,17 @@ arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) * */ -static inline int __raw_read_can_lock(arch_rwlock_t *x) +static inline int arch_read_can_lock(arch_rwlock_t *x) { return (int)(x)->lock > 0; } -static inline int __raw_write_can_lock(arch_rwlock_t *x) +static inline int arch_write_can_lock(arch_rwlock_t *x) { return (x)->lock == RW_LOCK_BIAS; } -static inline void __raw_read_lock(arch_rwlock_t *rw) +static inline void arch_read_lock(arch_rwlock_t *rw) { arch_spin_lock(&rw->slock); while (rw->lock == 0); @@ -74,7 +74,7 @@ static inline void __raw_read_lock(arch_rwlock_t *rw) arch_spin_unlock(&rw->slock); } -static inline void __raw_write_lock(arch_rwlock_t *rw) +static inline void arch_write_lock(arch_rwlock_t *rw) { arch_spin_lock(&rw->slock); while (rw->lock != RW_LOCK_BIAS); @@ -82,14 +82,14 @@ static inline void __raw_write_lock(arch_rwlock_t *rw) arch_spin_unlock(&rw->slock); } -static inline void __raw_read_unlock(arch_rwlock_t *rw) +static inline void arch_read_unlock(arch_rwlock_t *rw) { arch_spin_lock(&rw->slock); rw->lock++; arch_spin_unlock(&rw->slock); } -static inline void __raw_write_unlock(arch_rwlock_t *rw) +static inline void arch_write_unlock(arch_rwlock_t *rw) { arch_spin_lock(&rw->slock); while (rw->lock != RW_LOCK_BIAS); @@ -97,7 +97,7 @@ static inline void __raw_write_unlock(arch_rwlock_t *rw) arch_spin_unlock(&rw->slock); } -static inline int __raw_read_trylock(arch_rwlock_t *rw) +static inline int arch_read_trylock(arch_rwlock_t *rw) { int ret = 0; arch_spin_lock(&rw->slock); @@ -109,7 +109,7 @@ static inline int __raw_read_trylock(arch_rwlock_t *rw) return ret; } -static inline int __raw_write_trylock(arch_rwlock_t *rw) +static inline int arch_write_trylock(arch_rwlock_t *rw) { int ret = 0; arch_spin_lock(&rw->slock); diff --git a/arch/ia64/include/asm/spinlock.h b/arch/ia64/include/asm/spinlock.h index 6715b6a..1a91c91 100644 --- a/arch/ia64/include/asm/spinlock.h +++ b/arch/ia64/include/asm/spinlock.h @@ -140,13 +140,13 @@ static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) __ticket_spin_unlock_wait(lock); } -#define __raw_read_can_lock(rw) (*(volatile int *)(rw) >= 0) -#define __raw_write_can_lock(rw) (*(volatile int *)(rw) == 0) +#define arch_read_can_lock(rw) (*(volatile int *)(rw) >= 0) +#define arch_write_can_lock(rw) (*(volatile int *)(rw) == 0) #ifdef ASM_SUPPORTED static __always_inline void -__raw_read_lock_flags(arch_rwlock_t *lock, unsigned long flags) +arch_read_lock_flags(arch_rwlock_t *lock, unsigned long flags) { __asm__ __volatile__ ( "tbit.nz p6, p0 = %1,%2\n" @@ -169,13 +169,13 @@ __raw_read_lock_flags(arch_rwlock_t *lock, unsigned long flags) : "p6", "p7", "r2", "memory"); } -#define __raw_read_lock(lock) __raw_read_lock_flags(lock, 0) +#define arch_read_lock(lock) arch_read_lock_flags(lock, 0) #else /* !ASM_SUPPORTED */ -#define __raw_read_lock_flags(rw, flags) __raw_read_lock(rw) +#define arch_read_lock_flags(rw, flags) arch_read_lock(rw) -#define __raw_read_lock(rw) \ +#define arch_read_lock(rw) \ do { \ arch_rwlock_t *__read_lock_ptr = (rw); \ \ @@ -188,7 +188,7 @@ do { \ #endif /* !ASM_SUPPORTED */ -#define __raw_read_unlock(rw) \ +#define arch_read_unlock(rw) \ do { \ arch_rwlock_t *__read_lock_ptr = (rw); \ ia64_fetchadd(-1, (int *) __read_lock_ptr, rel); \ @@ -197,7 +197,7 @@ do { \ #ifdef ASM_SUPPORTED static __always_inline void -__raw_write_lock_flags(arch_rwlock_t *lock, unsigned long flags) +arch_write_lock_flags(arch_rwlock_t *lock, unsigned long flags) { __asm__ __volatile__ ( "tbit.nz p6, p0 = %1, %2\n" @@ -221,9 +221,9 @@ __raw_write_lock_flags(arch_rwlock_t *lock, unsigned long flags) : "ar.ccv", "p6", "p7", "r2", "r29", "memory"); } -#define __raw_write_lock(rw) __raw_write_lock_flags(rw, 0) +#define arch_write_lock(rw) arch_write_lock_flags(rw, 0) -#define __raw_write_trylock(rw) \ +#define arch_write_trylock(rw) \ ({ \ register long result; \ \ @@ -235,7 +235,7 @@ __raw_write_lock_flags(arch_rwlock_t *lock, unsigned long flags) (result == 0); \ }) -static inline void __raw_write_unlock(arch_rwlock_t *x) +static inline void arch_write_unlock(arch_rwlock_t *x) { u8 *y = (u8 *)x; barrier(); @@ -244,9 +244,9 @@ static inline void __raw_write_unlock(arch_rwlock_t *x) #else /* !ASM_SUPPORTED */ -#define __raw_write_lock_flags(l, flags) __raw_write_lock(l) +#define arch_write_lock_flags(l, flags) arch_write_lock(l) -#define __raw_write_lock(l) \ +#define arch_write_lock(l) \ ({ \ __u64 ia64_val, ia64_set_val = ia64_dep_mi(-1, 0, 31, 1); \ __u32 *ia64_write_lock_ptr = (__u32 *) (l); \ @@ -257,7 +257,7 @@ static inline void __raw_write_unlock(arch_rwlock_t *x) } while (ia64_val); \ }) -#define __raw_write_trylock(rw) \ +#define arch_write_trylock(rw) \ ({ \ __u64 ia64_val; \ __u64 ia64_set_val = ia64_dep_mi(-1, 0, 31,1); \ @@ -265,7 +265,7 @@ static inline void __raw_write_unlock(arch_rwlock_t *x) (ia64_val == 0); \ }) -static inline void __raw_write_unlock(arch_rwlock_t *x) +static inline void arch_write_unlock(arch_rwlock_t *x) { barrier(); x->write_lock = 0; @@ -273,7 +273,7 @@ static inline void __raw_write_unlock(arch_rwlock_t *x) #endif /* !ASM_SUPPORTED */ -static inline int __raw_read_trylock(arch_rwlock_t *x) +static inline int arch_read_trylock(arch_rwlock_t *x) { union { arch_rwlock_t lock; diff --git a/arch/m32r/include/asm/spinlock.h b/arch/m32r/include/asm/spinlock.h index 1c76af8..179a064 100644 --- a/arch/m32r/include/asm/spinlock.h +++ b/arch/m32r/include/asm/spinlock.h @@ -140,15 +140,15 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) * read_can_lock - would read_trylock() succeed? * @lock: the rwlock in question. */ -#define __raw_read_can_lock(x) ((int)(x)->lock > 0) +#define arch_read_can_lock(x) ((int)(x)->lock > 0) /** * write_can_lock - would write_trylock() succeed? * @lock: the rwlock in question. */ -#define __raw_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS) +#define arch_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS) -static inline void __raw_read_lock(arch_rwlock_t *rw) +static inline void arch_read_lock(arch_rwlock_t *rw) { unsigned long tmp0, tmp1; @@ -199,7 +199,7 @@ static inline void __raw_read_lock(arch_rwlock_t *rw) ); } -static inline void __raw_write_lock(arch_rwlock_t *rw) +static inline void arch_write_lock(arch_rwlock_t *rw) { unsigned long tmp0, tmp1, tmp2; @@ -252,7 +252,7 @@ static inline void __raw_write_lock(arch_rwlock_t *rw) ); } -static inline void __raw_read_unlock(arch_rwlock_t *rw) +static inline void arch_read_unlock(arch_rwlock_t *rw) { unsigned long tmp0, tmp1; @@ -274,7 +274,7 @@ static inline void __raw_read_unlock(arch_rwlock_t *rw) ); } -static inline void __raw_write_unlock(arch_rwlock_t *rw) +static inline void arch_write_unlock(arch_rwlock_t *rw) { unsigned long tmp0, tmp1, tmp2; @@ -298,7 +298,7 @@ static inline void __raw_write_unlock(arch_rwlock_t *rw) ); } -static inline int __raw_read_trylock(arch_rwlock_t *lock) +static inline int arch_read_trylock(arch_rwlock_t *lock) { atomic_t *count = (atomic_t*)lock; if (atomic_dec_return(count) >= 0) @@ -307,7 +307,7 @@ static inline int __raw_read_trylock(arch_rwlock_t *lock) return 0; } -static inline int __raw_write_trylock(arch_rwlock_t *lock) +static inline int arch_write_trylock(arch_rwlock_t *lock) { atomic_t *count = (atomic_t *)lock; if (atomic_sub_and_test(RW_LOCK_BIAS, count)) @@ -316,8 +316,8 @@ static inline int __raw_write_trylock(arch_rwlock_t *lock) return 0; } -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) +#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) +#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) #define arch_spin_relax(lock) cpu_relax() #define arch_read_relax(lock) cpu_relax() diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index 7bf27c8..21ef9ef 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h @@ -248,21 +248,21 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) * read_can_lock - would read_trylock() succeed? * @lock: the rwlock in question. */ -#define __raw_read_can_lock(rw) ((rw)->lock >= 0) +#define arch_read_can_lock(rw) ((rw)->lock >= 0) /* * write_can_lock - would write_trylock() succeed? * @lock: the rwlock in question. */ -#define __raw_write_can_lock(rw) (!(rw)->lock) +#define arch_write_can_lock(rw) (!(rw)->lock) -static inline void __raw_read_lock(arch_rwlock_t *rw) +static inline void arch_read_lock(arch_rwlock_t *rw) { unsigned int tmp; if (R10000_LLSC_WAR) { __asm__ __volatile__( - " .set noreorder # __raw_read_lock \n" + " .set noreorder # arch_read_lock \n" "1: ll %1, %2 \n" " bltz %1, 1b \n" " addu %1, 1 \n" @@ -275,7 +275,7 @@ static inline void __raw_read_lock(arch_rwlock_t *rw) : "memory"); } else { __asm__ __volatile__( - " .set noreorder # __raw_read_lock \n" + " .set noreorder # arch_read_lock \n" "1: ll %1, %2 \n" " bltz %1, 2f \n" " addu %1, 1 \n" @@ -301,7 +301,7 @@ static inline void __raw_read_lock(arch_rwlock_t *rw) /* Note the use of sub, not subu which will make the kernel die with an overflow exception if we ever try to unlock an rwlock that is already unlocked or is being held by a writer. */ -static inline void __raw_read_unlock(arch_rwlock_t *rw) +static inline void arch_read_unlock(arch_rwlock_t *rw) { unsigned int tmp; @@ -309,7 +309,7 @@ static inline void __raw_read_unlock(arch_rwlock_t *rw) if (R10000_LLSC_WAR) { __asm__ __volatile__( - "1: ll %1, %2 # __raw_read_unlock \n" + "1: ll %1, %2 # arch_read_unlock \n" " sub %1, 1 \n" " sc %1, %0 \n" " beqzl %1, 1b \n" @@ -318,7 +318,7 @@ static inline void __raw_read_unlock(arch_rwlock_t *rw) : "memory"); } else { __asm__ __volatile__( - " .set noreorder # __raw_read_unlock \n" + " .set noreorder # arch_read_unlock \n" "1: ll %1, %2 \n" " sub %1, 1 \n" " sc %1, %0 \n" @@ -335,13 +335,13 @@ static inline void __raw_read_unlock(arch_rwlock_t *rw) } } -static inline void __raw_write_lock(arch_rwlock_t *rw) +static inline void arch_write_lock(arch_rwlock_t *rw) { unsigned int tmp; if (R10000_LLSC_WAR) { __asm__ __volatile__( - " .set noreorder # __raw_write_lock \n" + " .set noreorder # arch_write_lock \n" "1: ll %1, %2 \n" " bnez %1, 1b \n" " lui %1, 0x8000 \n" @@ -354,7 +354,7 @@ static inline void __raw_write_lock(arch_rwlock_t *rw) : "memory"); } else { __asm__ __volatile__( - " .set noreorder # __raw_write_lock \n" + " .set noreorder # arch_write_lock \n" "1: ll %1, %2 \n" " bnez %1, 2f \n" " lui %1, 0x8000 \n" @@ -377,26 +377,26 @@ static inline void __raw_write_lock(arch_rwlock_t *rw) smp_llsc_mb(); } -static inline void __raw_write_unlock(arch_rwlock_t *rw) +static inline void arch_write_unlock(arch_rwlock_t *rw) { smp_mb(); __asm__ __volatile__( - " # __raw_write_unlock \n" + " # arch_write_unlock \n" " sw $0, %0 \n" : "=m" (rw->lock) : "m" (rw->lock) : "memory"); } -static inline int __raw_read_trylock(arch_rwlock_t *rw) +static inline int arch_read_trylock(arch_rwlock_t *rw) { unsigned int tmp; int ret; if (R10000_LLSC_WAR) { __asm__ __volatile__( - " .set noreorder # __raw_read_trylock \n" + " .set noreorder # arch_read_trylock \n" " li %2, 0 \n" "1: ll %1, %3 \n" " bltz %1, 2f \n" @@ -413,7 +413,7 @@ static inline int __raw_read_trylock(arch_rwlock_t *rw) : "memory"); } else { __asm__ __volatile__( - " .set noreorder # __raw_read_trylock \n" + " .set noreorder # arch_read_trylock \n" " li %2, 0 \n" "1: ll %1, %3 \n" " bltz %1, 2f \n" @@ -433,14 +433,14 @@ static inline int __raw_read_trylock(arch_rwlock_t *rw) return ret; } -static inline int __raw_write_trylock(arch_rwlock_t *rw) +static inline int arch_write_trylock(arch_rwlock_t *rw) { unsigned int tmp; int ret; if (R10000_LLSC_WAR) { __asm__ __volatile__( - " .set noreorder # __raw_write_trylock \n" + " .set noreorder # arch_write_trylock \n" " li %2, 0 \n" "1: ll %1, %3 \n" " bnez %1, 2f \n" @@ -457,7 +457,7 @@ static inline int __raw_write_trylock(arch_rwlock_t *rw) : "memory"); } else { __asm__ __volatile__( - " .set noreorder # __raw_write_trylock \n" + " .set noreorder # arch_write_trylock \n" " li %2, 0 \n" "1: ll %1, %3 \n" " bnez %1, 2f \n" @@ -480,8 +480,8 @@ static inline int __raw_write_trylock(arch_rwlock_t *rw) return ret; } -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) +#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) +#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) #define arch_spin_relax(lock) cpu_relax() #define arch_read_relax(lock) cpu_relax() diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h index 1ff3a0a..74036f4 100644 --- a/arch/parisc/include/asm/spinlock.h +++ b/arch/parisc/include/asm/spinlock.h @@ -69,7 +69,7 @@ static inline int arch_spin_trylock(arch_spinlock_t *x) /* Note that we have to ensure interrupts are disabled in case we're * interrupted by some other code that wants to grab the same read lock */ -static __inline__ void __raw_read_lock(arch_rwlock_t *rw) +static __inline__ void arch_read_lock(arch_rwlock_t *rw) { unsigned long flags; local_irq_save(flags); @@ -81,7 +81,7 @@ static __inline__ void __raw_read_lock(arch_rwlock_t *rw) /* Note that we have to ensure interrupts are disabled in case we're * interrupted by some other code that wants to grab the same read lock */ -static __inline__ void __raw_read_unlock(arch_rwlock_t *rw) +static __inline__ void arch_read_unlock(arch_rwlock_t *rw) { unsigned long flags; local_irq_save(flags); @@ -93,7 +93,7 @@ static __inline__ void __raw_read_unlock(arch_rwlock_t *rw) /* Note that we have to ensure interrupts are disabled in case we're * interrupted by some other code that wants to grab the same read lock */ -static __inline__ int __raw_read_trylock(arch_rwlock_t *rw) +static __inline__ int arch_read_trylock(arch_rwlock_t *rw) { unsigned long flags; retry: @@ -119,7 +119,7 @@ static __inline__ int __raw_read_trylock(arch_rwlock_t *rw) /* Note that we have to ensure interrupts are disabled in case we're * interrupted by some other code that wants to read_trylock() this lock */ -static __inline__ void __raw_write_lock(arch_rwlock_t *rw) +static __inline__ void arch_write_lock(arch_rwlock_t *rw) { unsigned long flags; retry: @@ -141,7 +141,7 @@ retry: local_irq_restore(flags); } -static __inline__ void __raw_write_unlock(arch_rwlock_t *rw) +static __inline__ void arch_write_unlock(arch_rwlock_t *rw) { rw->counter = 0; arch_spin_unlock(&rw->lock); @@ -149,7 +149,7 @@ static __inline__ void __raw_write_unlock(arch_rwlock_t *rw) /* Note that we have to ensure interrupts are disabled in case we're * interrupted by some other code that wants to read_trylock() this lock */ -static __inline__ int __raw_write_trylock(arch_rwlock_t *rw) +static __inline__ int arch_write_trylock(arch_rwlock_t *rw) { unsigned long flags; int result = 0; @@ -173,7 +173,7 @@ static __inline__ int __raw_write_trylock(arch_rwlock_t *rw) * read_can_lock - would read_trylock() succeed? * @lock: the rwlock in question. */ -static __inline__ int __raw_read_can_lock(arch_rwlock_t *rw) +static __inline__ int arch_read_can_lock(arch_rwlock_t *rw) { return rw->counter >= 0; } @@ -182,13 +182,13 @@ static __inline__ int __raw_read_can_lock(arch_rwlock_t *rw) * write_can_lock - would write_trylock() succeed? * @lock: the rwlock in question. */ -static __inline__ int __raw_write_can_lock(arch_rwlock_t *rw) +static __inline__ int arch_write_can_lock(arch_rwlock_t *rw) { return !rw->counter; } -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) +#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) +#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) #define arch_spin_relax(lock) cpu_relax() #define arch_read_relax(lock) cpu_relax() diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h index 2fad2c0..764094c 100644 --- a/arch/powerpc/include/asm/spinlock.h +++ b/arch/powerpc/include/asm/spinlock.h @@ -166,8 +166,8 @@ extern void arch_spin_unlock_wait(arch_spinlock_t *lock); * read-locks. */ -#define __raw_read_can_lock(rw) ((rw)->lock >= 0) -#define __raw_write_can_lock(rw) (!(rw)->lock) +#define arch_read_can_lock(rw) ((rw)->lock >= 0) +#define arch_write_can_lock(rw) (!(rw)->lock) #ifdef CONFIG_PPC64 #define __DO_SIGN_EXTEND "extsw %0,%0\n" @@ -181,7 +181,7 @@ extern void arch_spin_unlock_wait(arch_spinlock_t *lock); * This returns the old value in the lock + 1, * so we got a read lock if the return value is > 0. */ -static inline long arch_read_trylock(arch_rwlock_t *rw) +static inline long __arch_read_trylock(arch_rwlock_t *rw) { long tmp; @@ -205,7 +205,7 @@ static inline long arch_read_trylock(arch_rwlock_t *rw) * This returns the old value in the lock, * so we got the write lock if the return value is 0. */ -static inline long arch_write_trylock(arch_rwlock_t *rw) +static inline long __arch_write_trylock(arch_rwlock_t *rw) { long tmp, token; @@ -225,10 +225,10 @@ static inline long arch_write_trylock(arch_rwlock_t *rw) return tmp; } -static inline void __raw_read_lock(arch_rwlock_t *rw) +static inline void arch_read_lock(arch_rwlock_t *rw) { while (1) { - if (likely(arch_read_trylock(rw) > 0)) + if (likely(__arch_read_trylock(rw) > 0)) break; do { HMT_low(); @@ -239,10 +239,10 @@ static inline void __raw_read_lock(arch_rwlock_t *rw) } } -static inline void __raw_write_lock(arch_rwlock_t *rw) +static inline void arch_write_lock(arch_rwlock_t *rw) { while (1) { - if (likely(arch_write_trylock(rw) == 0)) + if (likely(__arch_write_trylock(rw) == 0)) break; do { HMT_low(); @@ -253,17 +253,17 @@ static inline void __raw_write_lock(arch_rwlock_t *rw) } } -static inline int __raw_read_trylock(arch_rwlock_t *rw) +static inline int arch_read_trylock(arch_rwlock_t *rw) { - return arch_read_trylock(rw) > 0; + return __arch_read_trylock(rw) > 0; } -static inline int __raw_write_trylock(arch_rwlock_t *rw) +static inline int arch_write_trylock(arch_rwlock_t *rw) { - return arch_write_trylock(rw) == 0; + return __arch_write_trylock(rw) == 0; } -static inline void __raw_read_unlock(arch_rwlock_t *rw) +static inline void arch_read_unlock(arch_rwlock_t *rw) { long tmp; @@ -280,15 +280,15 @@ static inline void __raw_read_unlock(arch_rwlock_t *rw) : "cr0", "xer", "memory"); } -static inline void __raw_write_unlock(arch_rwlock_t *rw) +static inline void arch_write_unlock(arch_rwlock_t *rw) { __asm__ __volatile__("# write_unlock\n\t" LWSYNC_ON_SMP: : :"memory"); rw->lock = 0; } -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) +#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) +#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) #define arch_spin_relax(lock) __spin_yield(lock) #define arch_read_relax(lock) __rw_yield(lock) diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h index 7f98f0e..a587907 100644 --- a/arch/s390/include/asm/spinlock.h +++ b/arch/s390/include/asm/spinlock.h @@ -113,13 +113,13 @@ static inline void arch_spin_unlock(arch_spinlock_t *lp) * read_can_lock - would read_trylock() succeed? * @lock: the rwlock in question. */ -#define __raw_read_can_lock(x) ((int)(x)->lock >= 0) +#define arch_read_can_lock(x) ((int)(x)->lock >= 0) /** * write_can_lock - would write_trylock() succeed? * @lock: the rwlock in question. */ -#define __raw_write_can_lock(x) ((x)->lock == 0) +#define arch_write_can_lock(x) ((x)->lock == 0) extern void _raw_read_lock_wait(arch_rwlock_t *lp); extern void _raw_read_lock_wait_flags(arch_rwlock_t *lp, unsigned long flags); @@ -128,7 +128,7 @@ extern void _raw_write_lock_wait(arch_rwlock_t *lp); extern void _raw_write_lock_wait_flags(arch_rwlock_t *lp, unsigned long flags); extern int _raw_write_trylock_retry(arch_rwlock_t *lp); -static inline void __raw_read_lock(arch_rwlock_t *rw) +static inline void arch_read_lock(arch_rwlock_t *rw) { unsigned int old; old = rw->lock & 0x7fffffffU; @@ -136,7 +136,7 @@ static inline void __raw_read_lock(arch_rwlock_t *rw) _raw_read_lock_wait(rw); } -static inline void __raw_read_lock_flags(arch_rwlock_t *rw, unsigned long flags) +static inline void arch_read_lock_flags(arch_rwlock_t *rw, unsigned long flags) { unsigned int old; old = rw->lock & 0x7fffffffU; @@ -144,7 +144,7 @@ static inline void __raw_read_lock_flags(arch_rwlock_t *rw, unsigned long flags) _raw_read_lock_wait_flags(rw, flags); } -static inline void __raw_read_unlock(arch_rwlock_t *rw) +static inline void arch_read_unlock(arch_rwlock_t *rw) { unsigned int old, cmp; @@ -155,24 +155,24 @@ static inline void __raw_read_unlock(arch_rwlock_t *rw) } while (cmp != old); } -static inline void __raw_write_lock(arch_rwlock_t *rw) +static inline void arch_write_lock(arch_rwlock_t *rw) { if (unlikely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) != 0)) _raw_write_lock_wait(rw); } -static inline void __raw_write_lock_flags(arch_rwlock_t *rw, unsigned long flags) +static inline void arch_write_lock_flags(arch_rwlock_t *rw, unsigned long flags) { if (unlikely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) != 0)) _raw_write_lock_wait_flags(rw, flags); } -static inline void __raw_write_unlock(arch_rwlock_t *rw) +static inline void arch_write_unlock(arch_rwlock_t *rw) { _raw_compare_and_swap(&rw->lock, 0x80000000, 0); } -static inline int __raw_read_trylock(arch_rwlock_t *rw) +static inline int arch_read_trylock(arch_rwlock_t *rw) { unsigned int old; old = rw->lock & 0x7fffffffU; @@ -181,7 +181,7 @@ static inline int __raw_read_trylock(arch_rwlock_t *rw) return _raw_read_trylock_retry(rw); } -static inline int __raw_write_trylock(arch_rwlock_t *rw) +static inline int arch_write_trylock(arch_rwlock_t *rw) { if (likely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)) return 1; diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index 09fee9a..10754a3 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c @@ -115,7 +115,7 @@ void _raw_read_lock_wait(arch_rwlock_t *rw) _raw_yield(); count = spin_retry; } - if (!__raw_read_can_lock(rw)) + if (!arch_read_can_lock(rw)) continue; old = rw->lock & 0x7fffffffU; if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old) @@ -135,7 +135,7 @@ void _raw_read_lock_wait_flags(arch_rwlock_t *rw, unsigned long flags) _raw_yield(); count = spin_retry; } - if (!__raw_read_can_lock(rw)) + if (!arch_read_can_lock(rw)) continue; old = rw->lock & 0x7fffffffU; local_irq_disable(); @@ -151,7 +151,7 @@ int _raw_read_trylock_retry(arch_rwlock_t *rw) int count = spin_retry; while (count-- > 0) { - if (!__raw_read_can_lock(rw)) + if (!arch_read_can_lock(rw)) continue; old = rw->lock & 0x7fffffffU; if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old) @@ -170,7 +170,7 @@ void _raw_write_lock_wait(arch_rwlock_t *rw) _raw_yield(); count = spin_retry; } - if (!__raw_write_can_lock(rw)) + if (!arch_write_can_lock(rw)) continue; if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0) return; @@ -188,7 +188,7 @@ void _raw_write_lock_wait_flags(arch_rwlock_t *rw, unsigned long flags) _raw_yield(); count = spin_retry; } - if (!__raw_write_can_lock(rw)) + if (!arch_write_can_lock(rw)) continue; local_irq_disable(); if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0) @@ -202,7 +202,7 @@ int _raw_write_trylock_retry(arch_rwlock_t *rw) int count = spin_retry; while (count-- > 0) { - if (!__raw_write_can_lock(rw)) + if (!arch_write_can_lock(rw)) continue; if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0) return 1; diff --git a/arch/sh/include/asm/spinlock.h b/arch/sh/include/asm/spinlock.h index 7f3626a..bdc0f3b 100644 --- a/arch/sh/include/asm/spinlock.h +++ b/arch/sh/include/asm/spinlock.h @@ -100,21 +100,21 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) * read_can_lock - would read_trylock() succeed? * @lock: the rwlock in question. */ -#define __raw_read_can_lock(x) ((x)->lock > 0) +#define arch_read_can_lock(x) ((x)->lock > 0) /** * write_can_lock - would write_trylock() succeed? * @lock: the rwlock in question. */ -#define __raw_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS) +#define arch_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS) -static inline void __raw_read_lock(arch_rwlock_t *rw) +static inline void arch_read_lock(arch_rwlock_t *rw) { unsigned long tmp; __asm__ __volatile__ ( "1: \n\t" - "movli.l @%1, %0 ! __raw_read_lock \n\t" + "movli.l @%1, %0 ! arch_read_lock \n\t" "cmp/pl %0 \n\t" "bf 1b \n\t" "add #-1, %0 \n\t" @@ -126,13 +126,13 @@ static inline void __raw_read_lock(arch_rwlock_t *rw) ); } -static inline void __raw_read_unlock(arch_rwlock_t *rw) +static inline void arch_read_unlock(arch_rwlock_t *rw) { unsigned long tmp; __asm__ __volatile__ ( "1: \n\t" - "movli.l @%1, %0 ! __raw_read_unlock \n\t" + "movli.l @%1, %0 ! arch_read_unlock \n\t" "add #1, %0 \n\t" "movco.l %0, @%1 \n\t" "bf 1b \n\t" @@ -142,13 +142,13 @@ static inline void __raw_read_unlock(arch_rwlock_t *rw) ); } -static inline void __raw_write_lock(arch_rwlock_t *rw) +static inline void arch_write_lock(arch_rwlock_t *rw) { unsigned long tmp; __asm__ __volatile__ ( "1: \n\t" - "movli.l @%1, %0 ! __raw_write_lock \n\t" + "movli.l @%1, %0 ! arch_write_lock \n\t" "cmp/hs %2, %0 \n\t" "bf 1b \n\t" "sub %2, %0 \n\t" @@ -160,23 +160,23 @@ static inline void __raw_write_lock(arch_rwlock_t *rw) ); } -static inline void __raw_write_unlock(arch_rwlock_t *rw) +static inline void arch_write_unlock(arch_rwlock_t *rw) { __asm__ __volatile__ ( - "mov.l %1, @%0 ! __raw_write_unlock \n\t" + "mov.l %1, @%0 ! arch_write_unlock \n\t" : : "r" (&rw->lock), "r" (RW_LOCK_BIAS) : "t", "memory" ); } -static inline int __raw_read_trylock(arch_rwlock_t *rw) +static inline int arch_read_trylock(arch_rwlock_t *rw) { unsigned long tmp, oldval; __asm__ __volatile__ ( "1: \n\t" - "movli.l @%2, %0 ! __raw_read_trylock \n\t" + "movli.l @%2, %0 ! arch_read_trylock \n\t" "mov %0, %1 \n\t" "cmp/pl %0 \n\t" "bf 2f \n\t" @@ -193,13 +193,13 @@ static inline int __raw_read_trylock(arch_rwlock_t *rw) return (oldval > 0); } -static inline int __raw_write_trylock(arch_rwlock_t *rw) +static inline int arch_write_trylock(arch_rwlock_t *rw) { unsigned long tmp, oldval; __asm__ __volatile__ ( "1: \n\t" - "movli.l @%2, %0 ! __raw_write_trylock \n\t" + "movli.l @%2, %0 ! arch_write_trylock \n\t" "mov %0, %1 \n\t" "cmp/hs %3, %0 \n\t" "bf 2f \n\t" @@ -216,8 +216,8 @@ static inline int __raw_write_trylock(arch_rwlock_t *rw) return (oldval > (RW_LOCK_BIAS - 1)); } -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) +#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) +#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) #define arch_spin_relax(lock) cpu_relax() #define arch_read_relax(lock) cpu_relax() diff --git a/arch/sparc/include/asm/spinlock_32.h b/arch/sparc/include/asm/spinlock_32.h index 06d37e5..7f9b9db 100644 --- a/arch/sparc/include/asm/spinlock_32.h +++ b/arch/sparc/include/asm/spinlock_32.h @@ -76,7 +76,7 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) * * Unfortunately this scheme limits us to ~16,000,000 cpus. */ -static inline void arch_read_lock(arch_rwlock_t *rw) +static inline void __arch_read_lock(arch_rwlock_t *rw) { register arch_rwlock_t *lp asm("g1"); lp = rw; @@ -89,14 +89,14 @@ static inline void arch_read_lock(arch_rwlock_t *rw) : "g2", "g4", "memory", "cc"); } -#define __raw_read_lock(lock) \ +#define arch_read_lock(lock) \ do { unsigned long flags; \ local_irq_save(flags); \ - arch_read_lock(lock); \ + __arch_read_lock(lock); \ local_irq_restore(flags); \ } while(0) -static inline void arch_read_unlock(arch_rwlock_t *rw) +static inline void __arch_read_unlock(arch_rwlock_t *rw) { register arch_rwlock_t *lp asm("g1"); lp = rw; @@ -109,14 +109,14 @@ static inline void arch_read_unlock(arch_rwlock_t *rw) : "g2", "g4", "memory", "cc"); } -#define __raw_read_unlock(lock) \ +#define arch_read_unlock(lock) \ do { unsigned long flags; \ local_irq_save(flags); \ - arch_read_unlock(lock); \ + __arch_read_unlock(lock); \ local_irq_restore(flags); \ } while(0) -static inline void __raw_write_lock(arch_rwlock_t *rw) +static inline void arch_write_lock(arch_rwlock_t *rw) { register arch_rwlock_t *lp asm("g1"); lp = rw; @@ -130,7 +130,7 @@ static inline void __raw_write_lock(arch_rwlock_t *rw) *(volatile __u32 *)&lp->lock = ~0U; } -static inline int __raw_write_trylock(arch_rwlock_t *rw) +static inline int arch_write_trylock(arch_rwlock_t *rw) { unsigned int val; @@ -150,7 +150,7 @@ static inline int __raw_write_trylock(arch_rwlock_t *rw) return (val == 0); } -static inline int arch_read_trylock(arch_rwlock_t *rw) +static inline int __arch_read_trylock(arch_rwlock_t *rw) { register arch_rwlock_t *lp asm("g1"); register int res asm("o0"); @@ -165,27 +165,27 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) return res; } -#define __raw_read_trylock(lock) \ +#define arch_read_trylock(lock) \ ({ unsigned long flags; \ int res; \ local_irq_save(flags); \ - res = arch_read_trylock(lock); \ + res = __arch_read_trylock(lock); \ local_irq_restore(flags); \ res; \ }) -#define __raw_write_unlock(rw) do { (rw)->lock = 0; } while(0) +#define arch_write_unlock(rw) do { (rw)->lock = 0; } while(0) #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) -#define __raw_read_lock_flags(rw, flags) __raw_read_lock(rw) -#define __raw_write_lock_flags(rw, flags) __raw_write_lock(rw) +#define arch_read_lock_flags(rw, flags) arch_read_lock(rw) +#define arch_write_lock_flags(rw, flags) arch_write_lock(rw) #define arch_spin_relax(lock) cpu_relax() #define arch_read_relax(lock) cpu_relax() #define arch_write_relax(lock) cpu_relax() -#define __raw_read_can_lock(rw) (!((rw)->lock & 0xff)) -#define __raw_write_can_lock(rw) (!(rw)->lock) +#define arch_read_can_lock(rw) (!((rw)->lock & 0xff)) +#define arch_write_can_lock(rw) (!(rw)->lock) #endif /* !(__ASSEMBLY__) */ diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h index 2b22d7f..073936a 100644 --- a/arch/sparc/include/asm/spinlock_64.h +++ b/arch/sparc/include/asm/spinlock_64.h @@ -210,17 +210,17 @@ static int inline arch_write_trylock(arch_rwlock_t *lock) return result; } -#define __raw_read_lock(p) arch_read_lock(p) -#define __raw_read_lock_flags(p, f) arch_read_lock(p) -#define __raw_read_trylock(p) arch_read_trylock(p) -#define __raw_read_unlock(p) arch_read_unlock(p) -#define __raw_write_lock(p) arch_write_lock(p) -#define __raw_write_lock_flags(p, f) arch_write_lock(p) -#define __raw_write_unlock(p) arch_write_unlock(p) -#define __raw_write_trylock(p) arch_write_trylock(p) - -#define __raw_read_can_lock(rw) (!((rw)->lock & 0x80000000UL)) -#define __raw_write_can_lock(rw) (!(rw)->lock) +#define arch_read_lock(p) arch_read_lock(p) +#define arch_read_lock_flags(p, f) arch_read_lock(p) +#define arch_read_trylock(p) arch_read_trylock(p) +#define arch_read_unlock(p) arch_read_unlock(p) +#define arch_write_lock(p) arch_write_lock(p) +#define arch_write_lock_flags(p, f) arch_write_lock(p) +#define arch_write_unlock(p) arch_write_unlock(p) +#define arch_write_trylock(p) arch_write_trylock(p) + +#define arch_read_can_lock(rw) (!((rw)->lock & 0x80000000UL)) +#define arch_write_can_lock(rw) (!(rw)->lock) #define arch_spin_relax(lock) cpu_relax() #define arch_read_relax(lock) cpu_relax() diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index 99cb86e..3089f70 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h @@ -232,7 +232,7 @@ static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) * read_can_lock - would read_trylock() succeed? * @lock: the rwlock in question. */ -static inline int __raw_read_can_lock(arch_rwlock_t *lock) +static inline int arch_read_can_lock(arch_rwlock_t *lock) { return (int)(lock)->lock > 0; } @@ -241,12 +241,12 @@ static inline int __raw_read_can_lock(arch_rwlock_t *lock) * write_can_lock - would write_trylock() succeed? * @lock: the rwlock in question. */ -static inline int __raw_write_can_lock(arch_rwlock_t *lock) +static inline int arch_write_can_lock(arch_rwlock_t *lock) { return (lock)->lock == RW_LOCK_BIAS; } -static inline void __raw_read_lock(arch_rwlock_t *rw) +static inline void arch_read_lock(arch_rwlock_t *rw) { asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t" "jns 1f\n" @@ -255,7 +255,7 @@ static inline void __raw_read_lock(arch_rwlock_t *rw) ::LOCK_PTR_REG (rw) : "memory"); } -static inline void __raw_write_lock(arch_rwlock_t *rw) +static inline void arch_write_lock(arch_rwlock_t *rw) { asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t" "jz 1f\n" @@ -264,7 +264,7 @@ static inline void __raw_write_lock(arch_rwlock_t *rw) ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory"); } -static inline int __raw_read_trylock(arch_rwlock_t *lock) +static inline int arch_read_trylock(arch_rwlock_t *lock) { atomic_t *count = (atomic_t *)lock; @@ -274,7 +274,7 @@ static inline int __raw_read_trylock(arch_rwlock_t *lock) return 0; } -static inline int __raw_write_trylock(arch_rwlock_t *lock) +static inline int arch_write_trylock(arch_rwlock_t *lock) { atomic_t *count = (atomic_t *)lock; @@ -284,19 +284,19 @@ static inline int __raw_write_trylock(arch_rwlock_t *lock) return 0; } -static inline void __raw_read_unlock(arch_rwlock_t *rw) +static inline void arch_read_unlock(arch_rwlock_t *rw) { asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory"); } -static inline void __raw_write_unlock(arch_rwlock_t *rw) +static inline void arch_write_unlock(arch_rwlock_t *rw) { asm volatile(LOCK_PREFIX "addl %1, %0" : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory"); } -#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock) -#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock) +#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) +#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) #define arch_spin_relax(lock) cpu_relax() #define arch_read_relax(lock) cpu_relax() diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h index 73785b0..5725b03 100644 --- a/include/linux/rwlock.h +++ b/include/linux/rwlock.h @@ -38,20 +38,20 @@ do { \ extern int _raw_write_trylock(rwlock_t *lock); extern void _raw_write_unlock(rwlock_t *lock); #else -# define _raw_read_lock(rwlock) __raw_read_lock(&(rwlock)->raw_lock) +# define _raw_read_lock(rwlock) arch_read_lock(&(rwlock)->raw_lock) # define _raw_read_lock_flags(lock, flags) \ - __raw_read_lock_flags(&(lock)->raw_lock, *(flags)) -# define _raw_read_trylock(rwlock) __raw_read_trylock(&(rwlock)->raw_lock) -# define _raw_read_unlock(rwlock) __raw_read_unlock(&(rwlock)->raw_lock) -# define _raw_write_lock(rwlock) __raw_write_lock(&(rwlock)->raw_lock) + arch_read_lock_flags(&(lock)->raw_lock, *(flags)) +# define _raw_read_trylock(rwlock) arch_read_trylock(&(rwlock)->raw_lock) +# define _raw_read_unlock(rwlock) arch_read_unlock(&(rwlock)->raw_lock) +# define _raw_write_lock(rwlock) arch_write_lock(&(rwlock)->raw_lock) # define _raw_write_lock_flags(lock, flags) \ - __raw_write_lock_flags(&(lock)->raw_lock, *(flags)) -# define _raw_write_trylock(rwlock) __raw_write_trylock(&(rwlock)->raw_lock) -# define _raw_write_unlock(rwlock) __raw_write_unlock(&(rwlock)->raw_lock) + arch_write_lock_flags(&(lock)->raw_lock, *(flags)) +# define _raw_write_trylock(rwlock) arch_write_trylock(&(rwlock)->raw_lock) +# define _raw_write_unlock(rwlock) arch_write_unlock(&(rwlock)->raw_lock) #endif -#define read_can_lock(rwlock) __raw_read_can_lock(&(rwlock)->raw_lock) -#define write_can_lock(rwlock) __raw_write_can_lock(&(rwlock)->raw_lock) +#define read_can_lock(rwlock) arch_read_can_lock(&(rwlock)->raw_lock) +#define write_can_lock(rwlock) arch_write_can_lock(&(rwlock)->raw_lock) /* * Define the various rw_lock methods. Note we define these diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h index 1d3bcc3..b14f6a9 100644 --- a/include/linux/spinlock_up.h +++ b/include/linux/spinlock_up.h @@ -49,12 +49,12 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) /* * Read-write spinlocks. No debug version. */ -#define __raw_read_lock(lock) do { (void)(lock); } while (0) -#define __raw_write_lock(lock) do { (void)(lock); } while (0) -#define __raw_read_trylock(lock) ({ (void)(lock); 1; }) -#define __raw_write_trylock(lock) ({ (void)(lock); 1; }) -#define __raw_read_unlock(lock) do { (void)(lock); } while (0) -#define __raw_write_unlock(lock) do { (void)(lock); } while (0) +#define arch_read_lock(lock) do { (void)(lock); } while (0) +#define arch_write_lock(lock) do { (void)(lock); } while (0) +#define arch_read_trylock(lock) ({ (void)(lock); 1; }) +#define arch_write_trylock(lock) ({ (void)(lock); 1; }) +#define arch_read_unlock(lock) do { (void)(lock); } while (0) +#define arch_write_unlock(lock) do { (void)(lock); } while (0) #else /* DEBUG_SPINLOCK */ #define arch_spin_is_locked(lock) ((void)(lock), 0) @@ -67,8 +67,8 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) #define arch_spin_is_contended(lock) (((void)(lock), 0)) -#define __raw_read_can_lock(lock) (((void)(lock), 1)) -#define __raw_write_can_lock(lock) (((void)(lock), 1)) +#define arch_read_can_lock(lock) (((void)(lock), 1)) +#define arch_write_can_lock(lock) (((void)(lock), 1)) #define arch_spin_unlock_wait(lock) \ do { cpu_relax(); } while (arch_spin_is_locked(lock)) diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index 3f72f10..0cea0bf 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c @@ -176,7 +176,7 @@ static void __read_lock_debug(rwlock_t *lock) for (;;) { for (i = 0; i < loops; i++) { - if (__raw_read_trylock(&lock->raw_lock)) + if (arch_read_trylock(&lock->raw_lock)) return; __delay(1); } @@ -196,12 +196,12 @@ static void __read_lock_debug(rwlock_t *lock) void _raw_read_lock(rwlock_t *lock) { RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); - __raw_read_lock(&lock->raw_lock); + arch_read_lock(&lock->raw_lock); } int _raw_read_trylock(rwlock_t *lock) { - int ret = __raw_read_trylock(&lock->raw_lock); + int ret = arch_read_trylock(&lock->raw_lock); #ifndef CONFIG_SMP /* @@ -215,7 +215,7 @@ int _raw_read_trylock(rwlock_t *lock) void _raw_read_unlock(rwlock_t *lock) { RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); - __raw_read_unlock(&lock->raw_lock); + arch_read_unlock(&lock->raw_lock); } static inline void debug_write_lock_before(rwlock_t *lock) @@ -251,7 +251,7 @@ static void __write_lock_debug(rwlock_t *lock) for (;;) { for (i = 0; i < loops; i++) { - if (__raw_write_trylock(&lock->raw_lock)) + if (arch_write_trylock(&lock->raw_lock)) return; __delay(1); } @@ -271,13 +271,13 @@ static void __write_lock_debug(rwlock_t *lock) void _raw_write_lock(rwlock_t *lock) { debug_write_lock_before(lock); - __raw_write_lock(&lock->raw_lock); + arch_write_lock(&lock->raw_lock); debug_write_lock_after(lock); } int _raw_write_trylock(rwlock_t *lock) { - int ret = __raw_write_trylock(&lock->raw_lock); + int ret = arch_write_trylock(&lock->raw_lock); if (ret) debug_write_lock_after(lock); @@ -293,5 +293,5 @@ int _raw_write_trylock(rwlock_t *lock) void _raw_write_unlock(rwlock_t *lock) { debug_write_unlock(lock); - __raw_write_unlock(&lock->raw_lock); + arch_write_unlock(&lock->raw_lock); } -- cgit v0.10.2 From c2f21ce2e31286a0a32f8da0a7856e9ca1122ef3 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 2 Dec 2009 20:02:59 +0100 Subject: locking: Implement new raw_spinlock Now that the raw_spin name space is freed up, we can implement raw_spinlock and the related functions which are used to annotate the locks which are not converted to sleeping spinlocks in preempt-rt. A side effect is that only such locks can be used with the low level lock fsunctions which circumvent lockdep. For !rt spin_* functions are mapped to the raw_spin* implementations. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 53bc221..ef5a55d 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -80,7 +80,7 @@ #include /* - * Pull the __raw*() functions/declarations (UP-nondebug doesnt need them): + * Pull the arch_spin*() functions/declarations (UP-nondebug doesnt need them): */ #ifdef CONFIG_SMP # include @@ -89,30 +89,30 @@ #endif #ifdef CONFIG_DEBUG_SPINLOCK - extern void __spin_lock_init(spinlock_t *lock, const char *name, - struct lock_class_key *key); -# define spin_lock_init(lock) \ + extern void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name, + struct lock_class_key *key); +# define raw_spin_lock_init(lock) \ do { \ static struct lock_class_key __key; \ \ - __spin_lock_init((lock), #lock, &__key); \ + __raw_spin_lock_init((lock), #lock, &__key); \ } while (0) #else -# define spin_lock_init(lock) \ - do { *(lock) = __SPIN_LOCK_UNLOCKED(lock); } while (0) +# define raw_spin_lock_init(lock) \ + do { *(lock) = __RAW_SPIN_LOCK_UNLOCKED(lock); } while (0) #endif -#define spin_is_locked(lock) arch_spin_is_locked(&(lock)->raw_lock) +#define raw_spin_is_locked(lock) arch_spin_is_locked(&(lock)->raw_lock) #ifdef CONFIG_GENERIC_LOCKBREAK -#define spin_is_contended(lock) ((lock)->break_lock) +#define raw_spin_is_contended(lock) ((lock)->break_lock) #else #ifdef arch_spin_is_contended -#define spin_is_contended(lock) arch_spin_is_contended(&(lock)->raw_lock) +#define raw_spin_is_contended(lock) arch_spin_is_contended(&(lock)->raw_lock) #else -#define spin_is_contended(lock) (((void)(lock), 0)) +#define raw_spin_is_contended(lock) (((void)(lock), 0)) #endif /*arch_spin_is_contended*/ #endif @@ -122,22 +122,37 @@ static inline void smp_mb__after_lock(void) { smp_mb(); } #endif /** - * spin_unlock_wait - wait until the spinlock gets unlocked + * raw_spin_unlock_wait - wait until the spinlock gets unlocked * @lock: the spinlock in question. */ -#define spin_unlock_wait(lock) arch_spin_unlock_wait(&(lock)->raw_lock) +#define raw_spin_unlock_wait(lock) arch_spin_unlock_wait(&(lock)->raw_lock) #ifdef CONFIG_DEBUG_SPINLOCK - extern void _raw_spin_lock(spinlock_t *lock); + extern void _raw_spin_lock(raw_spinlock_t *lock); #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) - extern int _raw_spin_trylock(spinlock_t *lock); - extern void _raw_spin_unlock(spinlock_t *lock); + extern int _raw_spin_trylock(raw_spinlock_t *lock); + extern void _raw_spin_unlock(raw_spinlock_t *lock); #else -# define _raw_spin_lock(lock) arch_spin_lock(&(lock)->raw_lock) -# define _raw_spin_lock_flags(lock, flags) \ - arch_spin_lock_flags(&(lock)->raw_lock, *(flags)) -# define _raw_spin_trylock(lock) arch_spin_trylock(&(lock)->raw_lock) -# define _raw_spin_unlock(lock) arch_spin_unlock(&(lock)->raw_lock) +static inline void _raw_spin_lock(raw_spinlock_t *lock) +{ + arch_spin_lock(&lock->raw_lock); +} + +static inline void +_raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long *flags) +{ + arch_spin_lock_flags(&lock->raw_lock, *flags); +} + +static inline int _raw_spin_trylock(raw_spinlock_t *lock) +{ + return arch_spin_trylock(&(lock)->raw_lock); +} + +static inline void _raw_spin_unlock(raw_spinlock_t *lock) +{ + arch_spin_unlock(&lock->raw_lock); +} #endif /* @@ -146,38 +161,38 @@ static inline void smp_mb__after_lock(void) { smp_mb(); } * various methods are defined as nops in the case they are not * required. */ -#define spin_trylock(lock) __cond_lock(lock, _spin_trylock(lock)) +#define raw_spin_trylock(lock) __cond_lock(lock, _spin_trylock(lock)) -#define spin_lock(lock) _spin_lock(lock) +#define raw_spin_lock(lock) _spin_lock(lock) #ifdef CONFIG_DEBUG_LOCK_ALLOC -# define spin_lock_nested(lock, subclass) _spin_lock_nested(lock, subclass) -# define spin_lock_nest_lock(lock, nest_lock) \ +# define raw_spin_lock_nested(lock, subclass) _spin_lock_nested(lock, subclass) +# define raw_spin_lock_nest_lock(lock, nest_lock) \ do { \ typecheck(struct lockdep_map *, &(nest_lock)->dep_map);\ _spin_lock_nest_lock(lock, &(nest_lock)->dep_map); \ } while (0) #else -# define spin_lock_nested(lock, subclass) _spin_lock(lock) -# define spin_lock_nest_lock(lock, nest_lock) _spin_lock(lock) +# define raw_spin_lock_nested(lock, subclass) _spin_lock(lock) +# define raw_spin_lock_nest_lock(lock, nest_lock) _spin_lock(lock) #endif #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) -#define spin_lock_irqsave(lock, flags) \ +#define raw_spin_lock_irqsave(lock, flags) \ do { \ typecheck(unsigned long, flags); \ flags = _spin_lock_irqsave(lock); \ } while (0) #ifdef CONFIG_DEBUG_LOCK_ALLOC -#define spin_lock_irqsave_nested(lock, flags, subclass) \ +#define raw_spin_lock_irqsave_nested(lock, flags, subclass) \ do { \ typecheck(unsigned long, flags); \ flags = _spin_lock_irqsave_nested(lock, subclass); \ } while (0) #else -#define spin_lock_irqsave_nested(lock, flags, subclass) \ +#define raw_spin_lock_irqsave_nested(lock, flags, subclass) \ do { \ typecheck(unsigned long, flags); \ flags = _spin_lock_irqsave(lock); \ @@ -186,45 +201,178 @@ static inline void smp_mb__after_lock(void) { smp_mb(); } #else -#define spin_lock_irqsave(lock, flags) \ +#define raw_spin_lock_irqsave(lock, flags) \ do { \ typecheck(unsigned long, flags); \ _spin_lock_irqsave(lock, flags); \ } while (0) -#define spin_lock_irqsave_nested(lock, flags, subclass) \ - spin_lock_irqsave(lock, flags) +#define raw_spin_lock_irqsave_nested(lock, flags, subclass) \ + raw_spin_lock_irqsave(lock, flags) #endif -#define spin_lock_irq(lock) _spin_lock_irq(lock) -#define spin_lock_bh(lock) _spin_lock_bh(lock) -#define spin_unlock(lock) _spin_unlock(lock) -#define spin_unlock_irq(lock) _spin_unlock_irq(lock) +#define raw_spin_lock_irq(lock) _spin_lock_irq(lock) +#define raw_spin_lock_bh(lock) _spin_lock_bh(lock) +#define raw_spin_unlock(lock) _spin_unlock(lock) +#define raw_spin_unlock_irq(lock) _spin_unlock_irq(lock) -#define spin_unlock_irqrestore(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ +#define raw_spin_unlock_irqrestore(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ _spin_unlock_irqrestore(lock, flags); \ } while (0) -#define spin_unlock_bh(lock) _spin_unlock_bh(lock) +#define raw_spin_unlock_bh(lock) _spin_unlock_bh(lock) -#define spin_trylock_bh(lock) __cond_lock(lock, _spin_trylock_bh(lock)) +#define raw_spin_trylock_bh(lock) __cond_lock(lock, _spin_trylock_bh(lock)) -#define spin_trylock_irq(lock) \ +#define raw_spin_trylock_irq(lock) \ ({ \ local_irq_disable(); \ - spin_trylock(lock) ? \ + raw_spin_trylock(lock) ? \ 1 : ({ local_irq_enable(); 0; }); \ }) -#define spin_trylock_irqsave(lock, flags) \ +#define raw_spin_trylock_irqsave(lock, flags) \ ({ \ local_irq_save(flags); \ - spin_trylock(lock) ? \ + raw_spin_trylock(lock) ? \ 1 : ({ local_irq_restore(flags); 0; }); \ }) +/** + * raw_spin_can_lock - would raw_spin_trylock() succeed? + * @lock: the spinlock in question. + */ +#define raw_spin_can_lock(lock) (!raw_spin_is_locked(lock)) + +/* Include rwlock functions */ +#include + +/* + * Pull the _spin_*()/_read_*()/_write_*() functions/declarations: + */ +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) +# include +#else +# include +#endif + +/* + * Map the spin_lock functions to the raw variants for PREEMPT_RT=n + */ + +static inline raw_spinlock_t *spinlock_check(spinlock_t *lock) +{ + return &lock->rlock; +} + +#define spin_lock_init(_lock) \ +do { \ + spinlock_check(_lock); \ + raw_spin_lock_init(&(_lock)->rlock); \ +} while (0) + +static inline void spin_lock(spinlock_t *lock) +{ + raw_spin_lock(&lock->rlock); +} + +static inline void spin_lock_bh(spinlock_t *lock) +{ + raw_spin_lock_bh(&lock->rlock); +} + +static inline int spin_trylock(spinlock_t *lock) +{ + return raw_spin_trylock(&lock->rlock); +} + +#define spin_lock_nested(lock, subclass) \ +do { \ + raw_spin_lock_nested(spinlock_check(lock), subclass); \ +} while (0) + +#define spin_lock_nest_lock(lock, nest_lock) \ +do { \ + raw_spin_lock_nest_lock(spinlock_check(lock), nest_lock); \ +} while (0) + +static inline void spin_lock_irq(spinlock_t *lock) +{ + raw_spin_lock_irq(&lock->rlock); +} + +#define spin_lock_irqsave(lock, flags) \ +do { \ + raw_spin_lock_irqsave(spinlock_check(lock), flags); \ +} while (0) + +#define spin_lock_irqsave_nested(lock, flags, subclass) \ +do { \ + raw_spin_lock_irqsave_nested(spinlock_check(lock), flags, subclass); \ +} while (0) + +static inline void spin_unlock(spinlock_t *lock) +{ + raw_spin_unlock(&lock->rlock); +} + +static inline void spin_unlock_bh(spinlock_t *lock) +{ + raw_spin_unlock_bh(&lock->rlock); +} + +static inline void spin_unlock_irq(spinlock_t *lock) +{ + raw_spin_unlock_irq(&lock->rlock); +} + +static inline void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) +{ + raw_spin_unlock_irqrestore(&lock->rlock, flags); +} + +static inline int spin_trylock_bh(spinlock_t *lock) +{ + return raw_spin_trylock_bh(&lock->rlock); +} + +static inline int spin_trylock_irq(spinlock_t *lock) +{ + return raw_spin_trylock_irq(&lock->rlock); +} + +#define spin_trylock_irqsave(lock, flags) \ +({ \ + raw_spin_trylock_irqsave(spinlock_check(lock), flags); \ +}) + +static inline void spin_unlock_wait(spinlock_t *lock) +{ + raw_spin_unlock_wait(&lock->rlock); +} + +static inline int spin_is_locked(spinlock_t *lock) +{ + return raw_spin_is_locked(&lock->rlock); +} + +static inline int spin_is_contended(spinlock_t *lock) +{ + return raw_spin_is_contended(&lock->rlock); +} + +static inline int spin_can_lock(spinlock_t *lock) +{ + return raw_spin_can_lock(&lock->rlock); +} + +static inline void assert_spin_locked(spinlock_t *lock) +{ + assert_raw_spin_locked(&lock->rlock); +} + /* * Pull the atomic_t declaration: * (asm-mips/atomic.h needs above definitions) @@ -242,22 +390,4 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define atomic_dec_and_lock(atomic, lock) \ __cond_lock(lock, _atomic_dec_and_lock(atomic, lock)) -/** - * spin_can_lock - would spin_trylock() succeed? - * @lock: the spinlock in question. - */ -#define spin_can_lock(lock) (!spin_is_locked(lock)) - -/* Include rwlock functions */ -#include - -/* - * Pull the _spin_*()/_read_*()/_write_*() functions/declarations: - */ -#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) -# include -#else -# include -#endif - #endif /* __LINUX_SPINLOCK_H */ diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h index a2b2c9d..eabe506 100644 --- a/include/linux/spinlock_api_smp.h +++ b/include/linux/spinlock_api_smp.h @@ -17,26 +17,29 @@ int in_lock_functions(unsigned long addr); -#define assert_spin_locked(x) BUG_ON(!spin_is_locked(x)) +#define assert_raw_spin_locked(x) BUG_ON(!raw_spin_is_locked(x)) -void __lockfunc _spin_lock(spinlock_t *lock) __acquires(lock); -void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass) +void __lockfunc _spin_lock(raw_spinlock_t *lock) __acquires(lock); +void __lockfunc _spin_lock_nested(raw_spinlock_t *lock, int subclass) __acquires(lock); -void __lockfunc _spin_lock_nest_lock(spinlock_t *lock, struct lockdep_map *map) +void __lockfunc +_spin_lock_nest_lock(raw_spinlock_t *lock, struct lockdep_map *map) __acquires(lock); -void __lockfunc _spin_lock_bh(spinlock_t *lock) __acquires(lock); -void __lockfunc _spin_lock_irq(spinlock_t *lock) __acquires(lock); +void __lockfunc _spin_lock_bh(raw_spinlock_t *lock) __acquires(lock); +void __lockfunc _spin_lock_irq(raw_spinlock_t *lock) __acquires(lock); -unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock) +unsigned long __lockfunc _spin_lock_irqsave(raw_spinlock_t *lock) __acquires(lock); -unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, int subclass) +unsigned long __lockfunc +_spin_lock_irqsave_nested(raw_spinlock_t *lock, int subclass) __acquires(lock); -int __lockfunc _spin_trylock(spinlock_t *lock); -int __lockfunc _spin_trylock_bh(spinlock_t *lock); -void __lockfunc _spin_unlock(spinlock_t *lock) __releases(lock); -void __lockfunc _spin_unlock_bh(spinlock_t *lock) __releases(lock); -void __lockfunc _spin_unlock_irq(spinlock_t *lock) __releases(lock); -void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) +int __lockfunc _spin_trylock(raw_spinlock_t *lock); +int __lockfunc _spin_trylock_bh(raw_spinlock_t *lock); +void __lockfunc _spin_unlock(raw_spinlock_t *lock) __releases(lock); +void __lockfunc _spin_unlock_bh(raw_spinlock_t *lock) __releases(lock); +void __lockfunc _spin_unlock_irq(raw_spinlock_t *lock) __releases(lock); +void __lockfunc +_spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) __releases(lock); #ifdef CONFIG_INLINE_SPIN_LOCK @@ -79,7 +82,7 @@ void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) #define _spin_unlock_irqrestore(lock, flags) __spin_unlock_irqrestore(lock, flags) #endif -static inline int __spin_trylock(spinlock_t *lock) +static inline int __spin_trylock(raw_spinlock_t *lock) { preempt_disable(); if (_raw_spin_trylock(lock)) { @@ -97,7 +100,7 @@ static inline int __spin_trylock(spinlock_t *lock) */ #if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC) -static inline unsigned long __spin_lock_irqsave(spinlock_t *lock) +static inline unsigned long __spin_lock_irqsave(raw_spinlock_t *lock) { unsigned long flags; @@ -117,7 +120,7 @@ static inline unsigned long __spin_lock_irqsave(spinlock_t *lock) return flags; } -static inline void __spin_lock_irq(spinlock_t *lock) +static inline void __spin_lock_irq(raw_spinlock_t *lock) { local_irq_disable(); preempt_disable(); @@ -125,7 +128,7 @@ static inline void __spin_lock_irq(spinlock_t *lock) LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); } -static inline void __spin_lock_bh(spinlock_t *lock) +static inline void __spin_lock_bh(raw_spinlock_t *lock) { local_bh_disable(); preempt_disable(); @@ -133,7 +136,7 @@ static inline void __spin_lock_bh(spinlock_t *lock) LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); } -static inline void __spin_lock(spinlock_t *lock) +static inline void __spin_lock(raw_spinlock_t *lock) { preempt_disable(); spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); @@ -142,14 +145,14 @@ static inline void __spin_lock(spinlock_t *lock) #endif /* CONFIG_PREEMPT */ -static inline void __spin_unlock(spinlock_t *lock) +static inline void __spin_unlock(raw_spinlock_t *lock) { spin_release(&lock->dep_map, 1, _RET_IP_); _raw_spin_unlock(lock); preempt_enable(); } -static inline void __spin_unlock_irqrestore(spinlock_t *lock, +static inline void __spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) { spin_release(&lock->dep_map, 1, _RET_IP_); @@ -158,7 +161,7 @@ static inline void __spin_unlock_irqrestore(spinlock_t *lock, preempt_enable(); } -static inline void __spin_unlock_irq(spinlock_t *lock) +static inline void __spin_unlock_irq(raw_spinlock_t *lock) { spin_release(&lock->dep_map, 1, _RET_IP_); _raw_spin_unlock(lock); @@ -166,7 +169,7 @@ static inline void __spin_unlock_irq(spinlock_t *lock) preempt_enable(); } -static inline void __spin_unlock_bh(spinlock_t *lock) +static inline void __spin_unlock_bh(raw_spinlock_t *lock) { spin_release(&lock->dep_map, 1, _RET_IP_); _raw_spin_unlock(lock); @@ -174,7 +177,7 @@ static inline void __spin_unlock_bh(spinlock_t *lock) local_bh_enable_ip((unsigned long)__builtin_return_address(0)); } -static inline int __spin_trylock_bh(spinlock_t *lock) +static inline int __spin_trylock_bh(raw_spinlock_t *lock) { local_bh_disable(); preempt_disable(); diff --git a/include/linux/spinlock_api_up.h b/include/linux/spinlock_api_up.h index 04e1d31..3a9e27a 100644 --- a/include/linux/spinlock_api_up.h +++ b/include/linux/spinlock_api_up.h @@ -16,7 +16,7 @@ #define in_lock_functions(ADDR) 0 -#define assert_spin_locked(lock) do { (void)(lock); } while (0) +#define assert_raw_spin_locked(lock) do { (void)(lock); } while (0) /* * In the UP-nondebug case there's no real locking going on, so the diff --git a/include/linux/spinlock_types.h b/include/linux/spinlock_types.h index 7dadce3..851b778 100644 --- a/include/linux/spinlock_types.h +++ b/include/linux/spinlock_types.h @@ -17,7 +17,7 @@ #include -typedef struct { +typedef struct raw_spinlock { arch_spinlock_t raw_lock; #ifdef CONFIG_GENERIC_LOCKBREAK unsigned int break_lock; @@ -29,7 +29,7 @@ typedef struct { #ifdef CONFIG_DEBUG_LOCK_ALLOC struct lockdep_map dep_map; #endif -} spinlock_t; +} raw_spinlock_t; #define SPINLOCK_MAGIC 0xdead4ead @@ -42,18 +42,45 @@ typedef struct { #endif #ifdef CONFIG_DEBUG_SPINLOCK -# define __SPIN_LOCK_UNLOCKED(lockname) \ - (spinlock_t) { .raw_lock = __ARCH_SPIN_LOCK_UNLOCKED, \ - .magic = SPINLOCK_MAGIC, \ - .owner = SPINLOCK_OWNER_INIT, \ - .owner_cpu = -1, \ - SPIN_DEP_MAP_INIT(lockname) } +# define SPIN_DEBUG_INIT(lockname) \ + .magic = SPINLOCK_MAGIC, \ + .owner_cpu = -1, \ + .owner = SPINLOCK_OWNER_INIT, #else -# define __SPIN_LOCK_UNLOCKED(lockname) \ - (spinlock_t) { .raw_lock = __ARCH_SPIN_LOCK_UNLOCKED, \ - SPIN_DEP_MAP_INIT(lockname) } +# define SPIN_DEBUG_INIT(lockname) #endif +#define __RAW_SPIN_LOCK_INITIALIZER(lockname) \ + { \ + .raw_lock = __ARCH_SPIN_LOCK_UNLOCKED, \ + SPIN_DEBUG_INIT(lockname) \ + SPIN_DEP_MAP_INIT(lockname) } + +#define __RAW_SPIN_LOCK_UNLOCKED(lockname) \ + (raw_spinlock_t) __RAW_SPIN_LOCK_INITIALIZER(lockname) + +#define DEFINE_RAW_SPINLOCK(x) raw_spinlock_t x = __RAW_SPIN_LOCK_UNLOCKED(x) + +typedef struct spinlock { + union { + struct raw_spinlock rlock; + +#ifdef CONFIG_DEBUG_LOCK_ALLOC +# define LOCK_PADSIZE (offsetof(struct raw_spinlock, dep_map)) + struct { + u8 __padding[LOCK_PADSIZE]; + struct lockdep_map dep_map; + }; +#endif + }; +} spinlock_t; + +#define __SPIN_LOCK_INITIALIZER(lockname) \ + { { .rlock = __RAW_SPIN_LOCK_INITIALIZER(lockname) } } + +#define __SPIN_LOCK_UNLOCKED(lockname) \ + (spinlock_t ) __SPIN_LOCK_INITIALIZER(lockname) + /* * SPIN_LOCK_UNLOCKED defeats lockdep state tracking and is hence * deprecated. diff --git a/kernel/mutex-debug.h b/kernel/mutex-debug.h index 7bebbd1..57d527a 100644 --- a/kernel/mutex-debug.h +++ b/kernel/mutex-debug.h @@ -43,13 +43,13 @@ static inline void mutex_clear_owner(struct mutex *lock) \ DEBUG_LOCKS_WARN_ON(in_interrupt()); \ local_irq_save(flags); \ - arch_spin_lock(&(lock)->raw_lock); \ + arch_spin_lock(&(lock)->rlock.raw_lock);\ DEBUG_LOCKS_WARN_ON(l->magic != l); \ } while (0) -#define spin_unlock_mutex(lock, flags) \ - do { \ - arch_spin_unlock(&(lock)->raw_lock); \ - local_irq_restore(flags); \ - preempt_check_resched(); \ +#define spin_unlock_mutex(lock, flags) \ + do { \ + arch_spin_unlock(&(lock)->rlock.raw_lock); \ + local_irq_restore(flags); \ + preempt_check_resched(); \ } while (0) diff --git a/kernel/sched.c b/kernel/sched.c index fd05861..e6acf2d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -884,7 +884,7 @@ static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev) { #ifdef CONFIG_DEBUG_SPINLOCK /* this is a valid case when another task releases the spinlock */ - rq->lock.owner = current; + rq->lock.rlock.owner = current; #endif /* * If we are tracking spinlock dependencies then we have to diff --git a/kernel/spinlock.c b/kernel/spinlock.c index fbb5f8b..54eb7dd 100644 --- a/kernel/spinlock.c +++ b/kernel/spinlock.c @@ -32,6 +32,8 @@ * include/linux/spinlock_api_smp.h */ #else +#define raw_read_can_lock(l) read_can_lock(l) +#define raw_write_can_lock(l) write_can_lock(l) /* * We build the __lock_function inlines here. They are too large for * inlining all over the place, but here is only one user per function @@ -52,7 +54,7 @@ void __lockfunc __##op##_lock(locktype##_t *lock) \ \ if (!(lock)->break_lock) \ (lock)->break_lock = 1; \ - while (!op##_can_lock(lock) && (lock)->break_lock) \ + while (!raw_##op##_can_lock(lock) && (lock)->break_lock)\ arch_##op##_relax(&lock->raw_lock); \ } \ (lock)->break_lock = 0; \ @@ -72,7 +74,7 @@ unsigned long __lockfunc __##op##_lock_irqsave(locktype##_t *lock) \ \ if (!(lock)->break_lock) \ (lock)->break_lock = 1; \ - while (!op##_can_lock(lock) && (lock)->break_lock) \ + while (!raw_##op##_can_lock(lock) && (lock)->break_lock)\ arch_##op##_relax(&lock->raw_lock); \ } \ (lock)->break_lock = 0; \ @@ -107,14 +109,14 @@ void __lockfunc __##op##_lock_bh(locktype##_t *lock) \ * __[spin|read|write]_lock_irqsave() * __[spin|read|write]_lock_bh() */ -BUILD_LOCK_OPS(spin, spinlock); +BUILD_LOCK_OPS(spin, raw_spinlock); BUILD_LOCK_OPS(read, rwlock); BUILD_LOCK_OPS(write, rwlock); #endif #ifndef CONFIG_INLINE_SPIN_TRYLOCK -int __lockfunc _spin_trylock(spinlock_t *lock) +int __lockfunc _spin_trylock(raw_spinlock_t *lock) { return __spin_trylock(lock); } @@ -122,7 +124,7 @@ EXPORT_SYMBOL(_spin_trylock); #endif #ifndef CONFIG_INLINE_SPIN_TRYLOCK_BH -int __lockfunc _spin_trylock_bh(spinlock_t *lock) +int __lockfunc _spin_trylock_bh(raw_spinlock_t *lock) { return __spin_trylock_bh(lock); } @@ -130,7 +132,7 @@ EXPORT_SYMBOL(_spin_trylock_bh); #endif #ifndef CONFIG_INLINE_SPIN_LOCK -void __lockfunc _spin_lock(spinlock_t *lock) +void __lockfunc _spin_lock(raw_spinlock_t *lock) { __spin_lock(lock); } @@ -138,7 +140,7 @@ EXPORT_SYMBOL(_spin_lock); #endif #ifndef CONFIG_INLINE_SPIN_LOCK_IRQSAVE -unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock) +unsigned long __lockfunc _spin_lock_irqsave(raw_spinlock_t *lock) { return __spin_lock_irqsave(lock); } @@ -146,7 +148,7 @@ EXPORT_SYMBOL(_spin_lock_irqsave); #endif #ifndef CONFIG_INLINE_SPIN_LOCK_IRQ -void __lockfunc _spin_lock_irq(spinlock_t *lock) +void __lockfunc _spin_lock_irq(raw_spinlock_t *lock) { __spin_lock_irq(lock); } @@ -154,7 +156,7 @@ EXPORT_SYMBOL(_spin_lock_irq); #endif #ifndef CONFIG_INLINE_SPIN_LOCK_BH -void __lockfunc _spin_lock_bh(spinlock_t *lock) +void __lockfunc _spin_lock_bh(raw_spinlock_t *lock) { __spin_lock_bh(lock); } @@ -162,7 +164,7 @@ EXPORT_SYMBOL(_spin_lock_bh); #endif #ifndef CONFIG_INLINE_SPIN_UNLOCK -void __lockfunc _spin_unlock(spinlock_t *lock) +void __lockfunc _spin_unlock(raw_spinlock_t *lock) { __spin_unlock(lock); } @@ -170,7 +172,7 @@ EXPORT_SYMBOL(_spin_unlock); #endif #ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE -void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) +void __lockfunc _spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) { __spin_unlock_irqrestore(lock, flags); } @@ -178,7 +180,7 @@ EXPORT_SYMBOL(_spin_unlock_irqrestore); #endif #ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQ -void __lockfunc _spin_unlock_irq(spinlock_t *lock) +void __lockfunc _spin_unlock_irq(raw_spinlock_t *lock) { __spin_unlock_irq(lock); } @@ -186,7 +188,7 @@ EXPORT_SYMBOL(_spin_unlock_irq); #endif #ifndef CONFIG_INLINE_SPIN_UNLOCK_BH -void __lockfunc _spin_unlock_bh(spinlock_t *lock) +void __lockfunc _spin_unlock_bh(raw_spinlock_t *lock) { __spin_unlock_bh(lock); } @@ -339,7 +341,7 @@ EXPORT_SYMBOL(_write_unlock_bh); #ifdef CONFIG_DEBUG_LOCK_ALLOC -void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass) +void __lockfunc _spin_lock_nested(raw_spinlock_t *lock, int subclass) { preempt_disable(); spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); @@ -347,7 +349,7 @@ void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass) } EXPORT_SYMBOL(_spin_lock_nested); -unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, +unsigned long __lockfunc _spin_lock_irqsave_nested(raw_spinlock_t *lock, int subclass) { unsigned long flags; @@ -361,7 +363,7 @@ unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, } EXPORT_SYMBOL(_spin_lock_irqsave_nested); -void __lockfunc _spin_lock_nest_lock(spinlock_t *lock, +void __lockfunc _spin_lock_nest_lock(raw_spinlock_t *lock, struct lockdep_map *nest_lock) { preempt_disable(); diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index 0cea0bf..e705848 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c @@ -13,8 +13,8 @@ #include #include -void __spin_lock_init(spinlock_t *lock, const char *name, - struct lock_class_key *key) +void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name, + struct lock_class_key *key) { #ifdef CONFIG_DEBUG_LOCK_ALLOC /* @@ -29,7 +29,7 @@ void __spin_lock_init(spinlock_t *lock, const char *name, lock->owner_cpu = -1; } -EXPORT_SYMBOL(__spin_lock_init); +EXPORT_SYMBOL(__raw_spin_lock_init); void __rwlock_init(rwlock_t *lock, const char *name, struct lock_class_key *key) @@ -49,7 +49,7 @@ void __rwlock_init(rwlock_t *lock, const char *name, EXPORT_SYMBOL(__rwlock_init); -static void spin_bug(spinlock_t *lock, const char *msg) +static void spin_bug(raw_spinlock_t *lock, const char *msg) { struct task_struct *owner = NULL; @@ -73,7 +73,7 @@ static void spin_bug(spinlock_t *lock, const char *msg) #define SPIN_BUG_ON(cond, lock, msg) if (unlikely(cond)) spin_bug(lock, msg) static inline void -debug_spin_lock_before(spinlock_t *lock) +debug_spin_lock_before(raw_spinlock_t *lock) { SPIN_BUG_ON(lock->magic != SPINLOCK_MAGIC, lock, "bad magic"); SPIN_BUG_ON(lock->owner == current, lock, "recursion"); @@ -81,16 +81,16 @@ debug_spin_lock_before(spinlock_t *lock) lock, "cpu recursion"); } -static inline void debug_spin_lock_after(spinlock_t *lock) +static inline void debug_spin_lock_after(raw_spinlock_t *lock) { lock->owner_cpu = raw_smp_processor_id(); lock->owner = current; } -static inline void debug_spin_unlock(spinlock_t *lock) +static inline void debug_spin_unlock(raw_spinlock_t *lock) { SPIN_BUG_ON(lock->magic != SPINLOCK_MAGIC, lock, "bad magic"); - SPIN_BUG_ON(!spin_is_locked(lock), lock, "already unlocked"); + SPIN_BUG_ON(!raw_spin_is_locked(lock), lock, "already unlocked"); SPIN_BUG_ON(lock->owner != current, lock, "wrong owner"); SPIN_BUG_ON(lock->owner_cpu != raw_smp_processor_id(), lock, "wrong CPU"); @@ -98,7 +98,7 @@ static inline void debug_spin_unlock(spinlock_t *lock) lock->owner_cpu = -1; } -static void __spin_lock_debug(spinlock_t *lock) +static void __spin_lock_debug(raw_spinlock_t *lock) { u64 i; u64 loops = loops_per_jiffy * HZ; @@ -125,7 +125,7 @@ static void __spin_lock_debug(spinlock_t *lock) } } -void _raw_spin_lock(spinlock_t *lock) +void _raw_spin_lock(raw_spinlock_t *lock) { debug_spin_lock_before(lock); if (unlikely(!arch_spin_trylock(&lock->raw_lock))) @@ -133,7 +133,7 @@ void _raw_spin_lock(spinlock_t *lock) debug_spin_lock_after(lock); } -int _raw_spin_trylock(spinlock_t *lock) +int _raw_spin_trylock(raw_spinlock_t *lock) { int ret = arch_spin_trylock(&lock->raw_lock); @@ -148,7 +148,7 @@ int _raw_spin_trylock(spinlock_t *lock) return ret; } -void _raw_spin_unlock(spinlock_t *lock) +void _raw_spin_unlock(raw_spinlock_t *lock) { debug_spin_unlock(lock); arch_spin_unlock(&lock->raw_lock); -- cgit v0.10.2 From 5f6384c5fb6bfc9aac506e058974d3ba293951b3 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 8 Dec 2009 16:16:41 +0100 Subject: alpha: Fix fallout from locking changes spin_* functions are mostly static inline now. That causes the alpha compile to fail: CC arch/alpha/kernel/sys_sable.o cc1: warnings being treated as errors In file included from arch/alpha/kernel/sys_sable.c:25: arch/alpha/include/asm/core_t2.h: In function 't2_readb': arch/alpha/include/asm/core_t2.h:451: error: 'spinlock_check' is static but \ used in inline function 't2_readb' which is not static arch/alpha/include/asm/core_t2.h:456: error: 'spin_unlock_irqrestore' is \ static but used in inline function 't2_readb' which is not static That's caused by the "extern inline" magic which is used for the subarch specific read/write[bwl] functions. I tried to distangle the uncountable macro onion layers, but failed miserably. Last resort solution: switch the t2_hae_lock to raw_spinlock_t so the lock functions are pure macros and function calls again. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar Cc: Richard Henderson Cc: linux-alpha@vger.kernel.org diff --git a/arch/alpha/include/asm/core_t2.h b/arch/alpha/include/asm/core_t2.h index 46bfff5..471c072 100644 --- a/arch/alpha/include/asm/core_t2.h +++ b/arch/alpha/include/asm/core_t2.h @@ -435,7 +435,7 @@ extern inline void t2_outl(u32 b, unsigned long addr) set_hae(msb); \ } -extern spinlock_t t2_hae_lock; +extern raw_spinlock_t t2_hae_lock; /* * NOTE: take T2_DENSE_MEM off in each readX/writeX routine, since @@ -448,12 +448,12 @@ __EXTERN_INLINE u8 t2_readb(const volatile void __iomem *xaddr) unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM; unsigned long result, msb; unsigned long flags; - spin_lock_irqsave(&t2_hae_lock, flags); + raw_spin_lock_irqsave(&t2_hae_lock, flags); t2_set_hae; result = *(vip) ((addr << 5) + T2_SPARSE_MEM + 0x00); - spin_unlock_irqrestore(&t2_hae_lock, flags); + raw_spin_unlock_irqrestore(&t2_hae_lock, flags); return __kernel_extbl(result, addr & 3); } @@ -462,12 +462,12 @@ __EXTERN_INLINE u16 t2_readw(const volatile void __iomem *xaddr) unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM; unsigned long result, msb; unsigned long flags; - spin_lock_irqsave(&t2_hae_lock, flags); + raw_spin_lock_irqsave(&t2_hae_lock, flags); t2_set_hae; result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08); - spin_unlock_irqrestore(&t2_hae_lock, flags); + raw_spin_unlock_irqrestore(&t2_hae_lock, flags); return __kernel_extwl(result, addr & 3); } @@ -480,12 +480,12 @@ __EXTERN_INLINE u32 t2_readl(const volatile void __iomem *xaddr) unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM; unsigned long result, msb; unsigned long flags; - spin_lock_irqsave(&t2_hae_lock, flags); + raw_spin_lock_irqsave(&t2_hae_lock, flags); t2_set_hae; result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18); - spin_unlock_irqrestore(&t2_hae_lock, flags); + raw_spin_unlock_irqrestore(&t2_hae_lock, flags); return result & 0xffffffffUL; } @@ -494,14 +494,14 @@ __EXTERN_INLINE u64 t2_readq(const volatile void __iomem *xaddr) unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM; unsigned long r0, r1, work, msb; unsigned long flags; - spin_lock_irqsave(&t2_hae_lock, flags); + raw_spin_lock_irqsave(&t2_hae_lock, flags); t2_set_hae; work = (addr << 5) + T2_SPARSE_MEM + 0x18; r0 = *(vuip)(work); r1 = *(vuip)(work + (4 << 5)); - spin_unlock_irqrestore(&t2_hae_lock, flags); + raw_spin_unlock_irqrestore(&t2_hae_lock, flags); return r1 << 32 | r0; } @@ -510,13 +510,13 @@ __EXTERN_INLINE void t2_writeb(u8 b, volatile void __iomem *xaddr) unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM; unsigned long msb, w; unsigned long flags; - spin_lock_irqsave(&t2_hae_lock, flags); + raw_spin_lock_irqsave(&t2_hae_lock, flags); t2_set_hae; w = __kernel_insbl(b, addr & 3); *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x00) = w; - spin_unlock_irqrestore(&t2_hae_lock, flags); + raw_spin_unlock_irqrestore(&t2_hae_lock, flags); } __EXTERN_INLINE void t2_writew(u16 b, volatile void __iomem *xaddr) @@ -524,13 +524,13 @@ __EXTERN_INLINE void t2_writew(u16 b, volatile void __iomem *xaddr) unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM; unsigned long msb, w; unsigned long flags; - spin_lock_irqsave(&t2_hae_lock, flags); + raw_spin_lock_irqsave(&t2_hae_lock, flags); t2_set_hae; w = __kernel_inswl(b, addr & 3); *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08) = w; - spin_unlock_irqrestore(&t2_hae_lock, flags); + raw_spin_unlock_irqrestore(&t2_hae_lock, flags); } /* @@ -542,12 +542,12 @@ __EXTERN_INLINE void t2_writel(u32 b, volatile void __iomem *xaddr) unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM; unsigned long msb; unsigned long flags; - spin_lock_irqsave(&t2_hae_lock, flags); + raw_spin_lock_irqsave(&t2_hae_lock, flags); t2_set_hae; *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18) = b; - spin_unlock_irqrestore(&t2_hae_lock, flags); + raw_spin_unlock_irqrestore(&t2_hae_lock, flags); } __EXTERN_INLINE void t2_writeq(u64 b, volatile void __iomem *xaddr) @@ -555,14 +555,14 @@ __EXTERN_INLINE void t2_writeq(u64 b, volatile void __iomem *xaddr) unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM; unsigned long msb, work; unsigned long flags; - spin_lock_irqsave(&t2_hae_lock, flags); + raw_spin_lock_irqsave(&t2_hae_lock, flags); t2_set_hae; work = (addr << 5) + T2_SPARSE_MEM + 0x18; *(vuip)work = b; *(vuip)(work + (4 << 5)) = b >> 32; - spin_unlock_irqrestore(&t2_hae_lock, flags); + raw_spin_unlock_irqrestore(&t2_hae_lock, flags); } __EXTERN_INLINE void __iomem *t2_ioportmap(unsigned long addr) diff --git a/arch/alpha/kernel/core_t2.c b/arch/alpha/kernel/core_t2.c index d9980d4..e6d9056 100644 --- a/arch/alpha/kernel/core_t2.c +++ b/arch/alpha/kernel/core_t2.c @@ -74,7 +74,7 @@ # define DBG(args) #endif -DEFINE_SPINLOCK(t2_hae_lock); +DEFINE_RAW_SPINLOCK(t2_hae_lock); static volatile unsigned int t2_mcheck_any_expected; static volatile unsigned int t2_mcheck_last_taken; -- cgit v0.10.2 From 9828ea9d75c38fe3dce05d00566eed61c85732e6 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 3 Dec 2009 20:55:53 +0100 Subject: locking: Further name space cleanups The name space hierarchy for the internal lock functions is now a bit backwards. raw_spin* functions map to _spin* which use __spin*, while we would like to have _raw_spin* and __raw_spin*. _raw_spin* is already used by lock debugging, so rename those funtions to do_raw_spin* to free up the _raw_spin* name space. No functional change. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h index 5725b03..bd799bc 100644 --- a/include/linux/rwlock.h +++ b/include/linux/rwlock.h @@ -29,25 +29,25 @@ do { \ #endif #ifdef CONFIG_DEBUG_SPINLOCK - extern void _raw_read_lock(rwlock_t *lock); -#define _raw_read_lock_flags(lock, flags) _raw_read_lock(lock) - extern int _raw_read_trylock(rwlock_t *lock); - extern void _raw_read_unlock(rwlock_t *lock); - extern void _raw_write_lock(rwlock_t *lock); -#define _raw_write_lock_flags(lock, flags) _raw_write_lock(lock) - extern int _raw_write_trylock(rwlock_t *lock); - extern void _raw_write_unlock(rwlock_t *lock); + extern void do_raw_read_lock(rwlock_t *lock); +#define do_raw_read_lock_flags(lock, flags) do_raw_read_lock(lock) + extern int do_raw_read_trylock(rwlock_t *lock); + extern void do_raw_read_unlock(rwlock_t *lock); + extern void do_raw_write_lock(rwlock_t *lock); +#define do_raw_write_lock_flags(lock, flags) do_raw_write_lock(lock) + extern int do_raw_write_trylock(rwlock_t *lock); + extern void do_raw_write_unlock(rwlock_t *lock); #else -# define _raw_read_lock(rwlock) arch_read_lock(&(rwlock)->raw_lock) -# define _raw_read_lock_flags(lock, flags) \ +# define do_raw_read_lock(rwlock) arch_read_lock(&(rwlock)->raw_lock) +# define do_raw_read_lock_flags(lock, flags) \ arch_read_lock_flags(&(lock)->raw_lock, *(flags)) -# define _raw_read_trylock(rwlock) arch_read_trylock(&(rwlock)->raw_lock) -# define _raw_read_unlock(rwlock) arch_read_unlock(&(rwlock)->raw_lock) -# define _raw_write_lock(rwlock) arch_write_lock(&(rwlock)->raw_lock) -# define _raw_write_lock_flags(lock, flags) \ +# define do_raw_read_trylock(rwlock) arch_read_trylock(&(rwlock)->raw_lock) +# define do_raw_read_unlock(rwlock) arch_read_unlock(&(rwlock)->raw_lock) +# define do_raw_write_lock(rwlock) arch_write_lock(&(rwlock)->raw_lock) +# define do_raw_write_lock_flags(lock, flags) \ arch_write_lock_flags(&(lock)->raw_lock, *(flags)) -# define _raw_write_trylock(rwlock) arch_write_trylock(&(rwlock)->raw_lock) -# define _raw_write_unlock(rwlock) arch_write_unlock(&(rwlock)->raw_lock) +# define do_raw_write_trylock(rwlock) arch_write_trylock(&(rwlock)->raw_lock) +# define do_raw_write_unlock(rwlock) arch_write_unlock(&(rwlock)->raw_lock) #endif #define read_can_lock(rwlock) arch_read_can_lock(&(rwlock)->raw_lock) diff --git a/include/linux/rwlock_api_smp.h b/include/linux/rwlock_api_smp.h index 090f876..b3ba5ae 100644 --- a/include/linux/rwlock_api_smp.h +++ b/include/linux/rwlock_api_smp.h @@ -113,7 +113,7 @@ void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) static inline int __read_trylock(rwlock_t *lock) { preempt_disable(); - if (_raw_read_trylock(lock)) { + if (do_raw_read_trylock(lock)) { rwlock_acquire_read(&lock->dep_map, 0, 1, _RET_IP_); return 1; } @@ -124,7 +124,7 @@ static inline int __read_trylock(rwlock_t *lock) static inline int __write_trylock(rwlock_t *lock) { preempt_disable(); - if (_raw_write_trylock(lock)) { + if (do_raw_write_trylock(lock)) { rwlock_acquire(&lock->dep_map, 0, 1, _RET_IP_); return 1; } @@ -143,7 +143,7 @@ static inline void __read_lock(rwlock_t *lock) { preempt_disable(); rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); + LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); } static inline unsigned long __read_lock_irqsave(rwlock_t *lock) @@ -153,8 +153,8 @@ static inline unsigned long __read_lock_irqsave(rwlock_t *lock) local_irq_save(flags); preempt_disable(); rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED_FLAGS(lock, _raw_read_trylock, _raw_read_lock, - _raw_read_lock_flags, &flags); + LOCK_CONTENDED_FLAGS(lock, do_raw_read_trylock, do_raw_read_lock, + do_raw_read_lock_flags, &flags); return flags; } @@ -163,7 +163,7 @@ static inline void __read_lock_irq(rwlock_t *lock) local_irq_disable(); preempt_disable(); rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); + LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); } static inline void __read_lock_bh(rwlock_t *lock) @@ -171,7 +171,7 @@ static inline void __read_lock_bh(rwlock_t *lock) local_bh_disable(); preempt_disable(); rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); + LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); } static inline unsigned long __write_lock_irqsave(rwlock_t *lock) @@ -181,8 +181,8 @@ static inline unsigned long __write_lock_irqsave(rwlock_t *lock) local_irq_save(flags); preempt_disable(); rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED_FLAGS(lock, _raw_write_trylock, _raw_write_lock, - _raw_write_lock_flags, &flags); + LOCK_CONTENDED_FLAGS(lock, do_raw_write_trylock, do_raw_write_lock, + do_raw_write_lock_flags, &flags); return flags; } @@ -191,7 +191,7 @@ static inline void __write_lock_irq(rwlock_t *lock) local_irq_disable(); preempt_disable(); rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_write_trylock, _raw_write_lock); + LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); } static inline void __write_lock_bh(rwlock_t *lock) @@ -199,14 +199,14 @@ static inline void __write_lock_bh(rwlock_t *lock) local_bh_disable(); preempt_disable(); rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_write_trylock, _raw_write_lock); + LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); } static inline void __write_lock(rwlock_t *lock) { preempt_disable(); rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_write_trylock, _raw_write_lock); + LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); } #endif /* CONFIG_PREEMPT */ @@ -214,21 +214,21 @@ static inline void __write_lock(rwlock_t *lock) static inline void __write_unlock(rwlock_t *lock) { rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_write_unlock(lock); + do_raw_write_unlock(lock); preempt_enable(); } static inline void __read_unlock(rwlock_t *lock) { rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_read_unlock(lock); + do_raw_read_unlock(lock); preempt_enable(); } static inline void __read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) { rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_read_unlock(lock); + do_raw_read_unlock(lock); local_irq_restore(flags); preempt_enable(); } @@ -236,7 +236,7 @@ static inline void __read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) static inline void __read_unlock_irq(rwlock_t *lock) { rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_read_unlock(lock); + do_raw_read_unlock(lock); local_irq_enable(); preempt_enable(); } @@ -244,7 +244,7 @@ static inline void __read_unlock_irq(rwlock_t *lock) static inline void __read_unlock_bh(rwlock_t *lock) { rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_read_unlock(lock); + do_raw_read_unlock(lock); preempt_enable_no_resched(); local_bh_enable_ip((unsigned long)__builtin_return_address(0)); } @@ -253,7 +253,7 @@ static inline void __write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) { rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_write_unlock(lock); + do_raw_write_unlock(lock); local_irq_restore(flags); preempt_enable(); } @@ -261,7 +261,7 @@ static inline void __write_unlock_irqrestore(rwlock_t *lock, static inline void __write_unlock_irq(rwlock_t *lock) { rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_write_unlock(lock); + do_raw_write_unlock(lock); local_irq_enable(); preempt_enable(); } @@ -269,7 +269,7 @@ static inline void __write_unlock_irq(rwlock_t *lock) static inline void __write_unlock_bh(rwlock_t *lock) { rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_write_unlock(lock); + do_raw_write_unlock(lock); preempt_enable_no_resched(); local_bh_enable_ip((unsigned long)__builtin_return_address(0)); } diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index ef5a55d..0cbc58a 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -128,28 +128,28 @@ static inline void smp_mb__after_lock(void) { smp_mb(); } #define raw_spin_unlock_wait(lock) arch_spin_unlock_wait(&(lock)->raw_lock) #ifdef CONFIG_DEBUG_SPINLOCK - extern void _raw_spin_lock(raw_spinlock_t *lock); -#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) - extern int _raw_spin_trylock(raw_spinlock_t *lock); - extern void _raw_spin_unlock(raw_spinlock_t *lock); + extern void do_raw_spin_lock(raw_spinlock_t *lock); +#define do_raw_spin_lock_flags(lock, flags) do_raw_spin_lock(lock) + extern int do_raw_spin_trylock(raw_spinlock_t *lock); + extern void do_raw_spin_unlock(raw_spinlock_t *lock); #else -static inline void _raw_spin_lock(raw_spinlock_t *lock) +static inline void do_raw_spin_lock(raw_spinlock_t *lock) { arch_spin_lock(&lock->raw_lock); } static inline void -_raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long *flags) +do_raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long *flags) { arch_spin_lock_flags(&lock->raw_lock, *flags); } -static inline int _raw_spin_trylock(raw_spinlock_t *lock) +static inline int do_raw_spin_trylock(raw_spinlock_t *lock) { return arch_spin_trylock(&(lock)->raw_lock); } -static inline void _raw_spin_unlock(raw_spinlock_t *lock) +static inline void do_raw_spin_unlock(raw_spinlock_t *lock) { arch_spin_unlock(&lock->raw_lock); } diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h index eabe506..1be1fc5 100644 --- a/include/linux/spinlock_api_smp.h +++ b/include/linux/spinlock_api_smp.h @@ -85,7 +85,7 @@ _spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) static inline int __spin_trylock(raw_spinlock_t *lock) { preempt_disable(); - if (_raw_spin_trylock(lock)) { + if (do_raw_spin_trylock(lock)) { spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); return 1; } @@ -109,13 +109,13 @@ static inline unsigned long __spin_lock_irqsave(raw_spinlock_t *lock) spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); /* * On lockdep we dont want the hand-coded irq-enable of - * _raw_spin_lock_flags() code, because lockdep assumes + * do_raw_spin_lock_flags() code, because lockdep assumes * that interrupts are not re-enabled during lock-acquire: */ #ifdef CONFIG_LOCKDEP - LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); + LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); #else - _raw_spin_lock_flags(lock, &flags); + do_raw_spin_lock_flags(lock, &flags); #endif return flags; } @@ -125,7 +125,7 @@ static inline void __spin_lock_irq(raw_spinlock_t *lock) local_irq_disable(); preempt_disable(); spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); + LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } static inline void __spin_lock_bh(raw_spinlock_t *lock) @@ -133,14 +133,14 @@ static inline void __spin_lock_bh(raw_spinlock_t *lock) local_bh_disable(); preempt_disable(); spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); + LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } static inline void __spin_lock(raw_spinlock_t *lock) { preempt_disable(); spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); + LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } #endif /* CONFIG_PREEMPT */ @@ -148,7 +148,7 @@ static inline void __spin_lock(raw_spinlock_t *lock) static inline void __spin_unlock(raw_spinlock_t *lock) { spin_release(&lock->dep_map, 1, _RET_IP_); - _raw_spin_unlock(lock); + do_raw_spin_unlock(lock); preempt_enable(); } @@ -156,7 +156,7 @@ static inline void __spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) { spin_release(&lock->dep_map, 1, _RET_IP_); - _raw_spin_unlock(lock); + do_raw_spin_unlock(lock); local_irq_restore(flags); preempt_enable(); } @@ -164,7 +164,7 @@ static inline void __spin_unlock_irqrestore(raw_spinlock_t *lock, static inline void __spin_unlock_irq(raw_spinlock_t *lock) { spin_release(&lock->dep_map, 1, _RET_IP_); - _raw_spin_unlock(lock); + do_raw_spin_unlock(lock); local_irq_enable(); preempt_enable(); } @@ -172,7 +172,7 @@ static inline void __spin_unlock_irq(raw_spinlock_t *lock) static inline void __spin_unlock_bh(raw_spinlock_t *lock) { spin_release(&lock->dep_map, 1, _RET_IP_); - _raw_spin_unlock(lock); + do_raw_spin_unlock(lock); preempt_enable_no_resched(); local_bh_enable_ip((unsigned long)__builtin_return_address(0)); } @@ -181,7 +181,7 @@ static inline int __spin_trylock_bh(raw_spinlock_t *lock) { local_bh_disable(); preempt_disable(); - if (_raw_spin_trylock(lock)) { + if (do_raw_spin_trylock(lock)) { spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); return 1; } diff --git a/kernel/sched.c b/kernel/sched.c index e6acf2d..91c65dd 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6684,7 +6684,7 @@ SYSCALL_DEFINE0(sched_yield) */ __release(rq->lock); spin_release(&rq->lock.dep_map, 1, _THIS_IP_); - _raw_spin_unlock(&rq->lock); + do_raw_spin_unlock(&rq->lock); preempt_enable_no_resched(); schedule(); diff --git a/kernel/spinlock.c b/kernel/spinlock.c index 54eb7dd..795240b 100644 --- a/kernel/spinlock.c +++ b/kernel/spinlock.c @@ -48,7 +48,7 @@ void __lockfunc __##op##_lock(locktype##_t *lock) \ { \ for (;;) { \ preempt_disable(); \ - if (likely(_raw_##op##_trylock(lock))) \ + if (likely(do_raw_##op##_trylock(lock))) \ break; \ preempt_enable(); \ \ @@ -67,7 +67,7 @@ unsigned long __lockfunc __##op##_lock_irqsave(locktype##_t *lock) \ for (;;) { \ preempt_disable(); \ local_irq_save(flags); \ - if (likely(_raw_##op##_trylock(lock))) \ + if (likely(do_raw_##op##_trylock(lock))) \ break; \ local_irq_restore(flags); \ preempt_enable(); \ @@ -345,7 +345,7 @@ void __lockfunc _spin_lock_nested(raw_spinlock_t *lock, int subclass) { preempt_disable(); spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); + LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } EXPORT_SYMBOL(_spin_lock_nested); @@ -357,8 +357,8 @@ unsigned long __lockfunc _spin_lock_irqsave_nested(raw_spinlock_t *lock, local_irq_save(flags); preempt_disable(); spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); - LOCK_CONTENDED_FLAGS(lock, _raw_spin_trylock, _raw_spin_lock, - _raw_spin_lock_flags, &flags); + LOCK_CONTENDED_FLAGS(lock, do_raw_spin_trylock, do_raw_spin_lock, + do_raw_spin_lock_flags, &flags); return flags; } EXPORT_SYMBOL(_spin_lock_irqsave_nested); @@ -368,7 +368,7 @@ void __lockfunc _spin_lock_nest_lock(raw_spinlock_t *lock, { preempt_disable(); spin_acquire_nest(&lock->dep_map, 0, 0, nest_lock, _RET_IP_); - LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); + LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } EXPORT_SYMBOL(_spin_lock_nest_lock); diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c index 5526b46..fdd23cd 100644 --- a/lib/kernel_lock.c +++ b/lib/kernel_lock.c @@ -36,12 +36,12 @@ static __cacheline_aligned_in_smp DEFINE_SPINLOCK(kernel_flag); * If it successfully gets the lock, it should increment * the preemption count like any spinlock does. * - * (This works on UP too - _raw_spin_trylock will never + * (This works on UP too - do_raw_spin_trylock will never * return false in that case) */ int __lockfunc __reacquire_kernel_lock(void) { - while (!_raw_spin_trylock(&kernel_flag)) { + while (!do_raw_spin_trylock(&kernel_flag)) { if (need_resched()) return -EAGAIN; cpu_relax(); @@ -52,27 +52,27 @@ int __lockfunc __reacquire_kernel_lock(void) void __lockfunc __release_kernel_lock(void) { - _raw_spin_unlock(&kernel_flag); + do_raw_spin_unlock(&kernel_flag); preempt_enable_no_resched(); } /* * These are the BKL spinlocks - we try to be polite about preemption. * If SMP is not on (ie UP preemption), this all goes away because the - * _raw_spin_trylock() will always succeed. + * do_raw_spin_trylock() will always succeed. */ #ifdef CONFIG_PREEMPT static inline void __lock_kernel(void) { preempt_disable(); - if (unlikely(!_raw_spin_trylock(&kernel_flag))) { + if (unlikely(!do_raw_spin_trylock(&kernel_flag))) { /* * If preemption was disabled even before this * was called, there's nothing we can be polite * about - just spin. */ if (preempt_count() > 1) { - _raw_spin_lock(&kernel_flag); + do_raw_spin_lock(&kernel_flag); return; } @@ -85,7 +85,7 @@ static inline void __lock_kernel(void) while (spin_is_locked(&kernel_flag)) cpu_relax(); preempt_disable(); - } while (!_raw_spin_trylock(&kernel_flag)); + } while (!do_raw_spin_trylock(&kernel_flag)); } } @@ -96,7 +96,7 @@ static inline void __lock_kernel(void) */ static inline void __lock_kernel(void) { - _raw_spin_lock(&kernel_flag); + do_raw_spin_lock(&kernel_flag); } #endif @@ -106,7 +106,7 @@ static inline void __unlock_kernel(void) * the BKL is not covered by lockdep, so we open-code the * unlocking sequence (and thus avoid the dep-chain ops): */ - _raw_spin_unlock(&kernel_flag); + do_raw_spin_unlock(&kernel_flag); preempt_enable(); } diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index e705848..4755b98 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c @@ -125,7 +125,7 @@ static void __spin_lock_debug(raw_spinlock_t *lock) } } -void _raw_spin_lock(raw_spinlock_t *lock) +void do_raw_spin_lock(raw_spinlock_t *lock) { debug_spin_lock_before(lock); if (unlikely(!arch_spin_trylock(&lock->raw_lock))) @@ -133,7 +133,7 @@ void _raw_spin_lock(raw_spinlock_t *lock) debug_spin_lock_after(lock); } -int _raw_spin_trylock(raw_spinlock_t *lock) +int do_raw_spin_trylock(raw_spinlock_t *lock) { int ret = arch_spin_trylock(&lock->raw_lock); @@ -148,7 +148,7 @@ int _raw_spin_trylock(raw_spinlock_t *lock) return ret; } -void _raw_spin_unlock(raw_spinlock_t *lock) +void do_raw_spin_unlock(raw_spinlock_t *lock) { debug_spin_unlock(lock); arch_spin_unlock(&lock->raw_lock); @@ -193,13 +193,13 @@ static void __read_lock_debug(rwlock_t *lock) } #endif -void _raw_read_lock(rwlock_t *lock) +void do_raw_read_lock(rwlock_t *lock) { RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); arch_read_lock(&lock->raw_lock); } -int _raw_read_trylock(rwlock_t *lock) +int do_raw_read_trylock(rwlock_t *lock) { int ret = arch_read_trylock(&lock->raw_lock); @@ -212,7 +212,7 @@ int _raw_read_trylock(rwlock_t *lock) return ret; } -void _raw_read_unlock(rwlock_t *lock) +void do_raw_read_unlock(rwlock_t *lock) { RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); arch_read_unlock(&lock->raw_lock); @@ -268,14 +268,14 @@ static void __write_lock_debug(rwlock_t *lock) } #endif -void _raw_write_lock(rwlock_t *lock) +void do_raw_write_lock(rwlock_t *lock) { debug_write_lock_before(lock); arch_write_lock(&lock->raw_lock); debug_write_lock_after(lock); } -int _raw_write_trylock(rwlock_t *lock) +int do_raw_write_trylock(rwlock_t *lock) { int ret = arch_write_trylock(&lock->raw_lock); @@ -290,7 +290,7 @@ int _raw_write_trylock(rwlock_t *lock) return ret; } -void _raw_write_unlock(rwlock_t *lock) +void do_raw_write_unlock(rwlock_t *lock) { debug_write_unlock(lock); arch_write_unlock(&lock->raw_lock); -- cgit v0.10.2 From 9c1721aa4994f6625decbd915241f3a94ee2fe67 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 3 Dec 2009 21:52:18 +0100 Subject: locking: Cleanup the name space completely Make the name space hierarchy of locking functions consistent: raw_spin* -> _raw_spin* -> __raw_spin* No functional change. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h index bd799bc..71e0b00 100644 --- a/include/linux/rwlock.h +++ b/include/linux/rwlock.h @@ -38,7 +38,7 @@ do { \ extern int do_raw_write_trylock(rwlock_t *lock); extern void do_raw_write_unlock(rwlock_t *lock); #else -# define do_raw_read_lock(rwlock) arch_read_lock(&(rwlock)->raw_lock) +# define do_raw_read_lock(rwlock) arch_read_lock(&(rwlock)->raw_lock) # define do_raw_read_lock_flags(lock, flags) \ arch_read_lock_flags(&(lock)->raw_lock, *(flags)) # define do_raw_read_trylock(rwlock) arch_read_trylock(&(rwlock)->raw_lock) @@ -58,23 +58,23 @@ do { \ * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various * methods are defined as nops in the case they are not required. */ -#define read_trylock(lock) __cond_lock(lock, _read_trylock(lock)) -#define write_trylock(lock) __cond_lock(lock, _write_trylock(lock)) +#define read_trylock(lock) __cond_lock(lock, _raw_read_trylock(lock)) +#define write_trylock(lock) __cond_lock(lock, _raw_write_trylock(lock)) -#define write_lock(lock) _write_lock(lock) -#define read_lock(lock) _read_lock(lock) +#define write_lock(lock) _raw_write_lock(lock) +#define read_lock(lock) _raw_read_lock(lock) #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) #define read_lock_irqsave(lock, flags) \ do { \ typecheck(unsigned long, flags); \ - flags = _read_lock_irqsave(lock); \ + flags = _raw_read_lock_irqsave(lock); \ } while (0) #define write_lock_irqsave(lock, flags) \ do { \ typecheck(unsigned long, flags); \ - flags = _write_lock_irqsave(lock); \ + flags = _raw_write_lock_irqsave(lock); \ } while (0) #else @@ -82,38 +82,38 @@ do { \ #define read_lock_irqsave(lock, flags) \ do { \ typecheck(unsigned long, flags); \ - _read_lock_irqsave(lock, flags); \ + _raw_read_lock_irqsave(lock, flags); \ } while (0) #define write_lock_irqsave(lock, flags) \ do { \ typecheck(unsigned long, flags); \ - _write_lock_irqsave(lock, flags); \ + _raw_write_lock_irqsave(lock, flags); \ } while (0) #endif -#define read_lock_irq(lock) _read_lock_irq(lock) -#define read_lock_bh(lock) _read_lock_bh(lock) -#define write_lock_irq(lock) _write_lock_irq(lock) -#define write_lock_bh(lock) _write_lock_bh(lock) -#define read_unlock(lock) _read_unlock(lock) -#define write_unlock(lock) _write_unlock(lock) -#define read_unlock_irq(lock) _read_unlock_irq(lock) -#define write_unlock_irq(lock) _write_unlock_irq(lock) - -#define read_unlock_irqrestore(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ - _read_unlock_irqrestore(lock, flags); \ +#define read_lock_irq(lock) _raw_read_lock_irq(lock) +#define read_lock_bh(lock) _raw_read_lock_bh(lock) +#define write_lock_irq(lock) _raw_write_lock_irq(lock) +#define write_lock_bh(lock) _raw_write_lock_bh(lock) +#define read_unlock(lock) _raw_read_unlock(lock) +#define write_unlock(lock) _raw_write_unlock(lock) +#define read_unlock_irq(lock) _raw_read_unlock_irq(lock) +#define write_unlock_irq(lock) _raw_write_unlock_irq(lock) + +#define read_unlock_irqrestore(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _raw_read_unlock_irqrestore(lock, flags); \ } while (0) -#define read_unlock_bh(lock) _read_unlock_bh(lock) +#define read_unlock_bh(lock) _raw_read_unlock_bh(lock) #define write_unlock_irqrestore(lock, flags) \ do { \ typecheck(unsigned long, flags); \ - _write_unlock_irqrestore(lock, flags); \ + _raw_write_unlock_irqrestore(lock, flags); \ } while (0) -#define write_unlock_bh(lock) _write_unlock_bh(lock) +#define write_unlock_bh(lock) _raw_write_unlock_bh(lock) #define write_trylock_irqsave(lock, flags) \ ({ \ diff --git a/include/linux/rwlock_api_smp.h b/include/linux/rwlock_api_smp.h index b3ba5ae..9c9f049 100644 --- a/include/linux/rwlock_api_smp.h +++ b/include/linux/rwlock_api_smp.h @@ -15,102 +15,106 @@ * Released under the General Public License (GPL). */ -void __lockfunc _read_lock(rwlock_t *lock) __acquires(lock); -void __lockfunc _write_lock(rwlock_t *lock) __acquires(lock); -void __lockfunc _read_lock_bh(rwlock_t *lock) __acquires(lock); -void __lockfunc _write_lock_bh(rwlock_t *lock) __acquires(lock); -void __lockfunc _read_lock_irq(rwlock_t *lock) __acquires(lock); -void __lockfunc _write_lock_irq(rwlock_t *lock) __acquires(lock); -unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock) +void __lockfunc _raw_read_lock(rwlock_t *lock) __acquires(lock); +void __lockfunc _raw_write_lock(rwlock_t *lock) __acquires(lock); +void __lockfunc _raw_read_lock_bh(rwlock_t *lock) __acquires(lock); +void __lockfunc _raw_write_lock_bh(rwlock_t *lock) __acquires(lock); +void __lockfunc _raw_read_lock_irq(rwlock_t *lock) __acquires(lock); +void __lockfunc _raw_write_lock_irq(rwlock_t *lock) __acquires(lock); +unsigned long __lockfunc _raw_read_lock_irqsave(rwlock_t *lock) __acquires(lock); -unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock) +unsigned long __lockfunc _raw_write_lock_irqsave(rwlock_t *lock) __acquires(lock); -int __lockfunc _read_trylock(rwlock_t *lock); -int __lockfunc _write_trylock(rwlock_t *lock); -void __lockfunc _read_unlock(rwlock_t *lock) __releases(lock); -void __lockfunc _write_unlock(rwlock_t *lock) __releases(lock); -void __lockfunc _read_unlock_bh(rwlock_t *lock) __releases(lock); -void __lockfunc _write_unlock_bh(rwlock_t *lock) __releases(lock); -void __lockfunc _read_unlock_irq(rwlock_t *lock) __releases(lock); -void __lockfunc _write_unlock_irq(rwlock_t *lock) __releases(lock); -void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) +int __lockfunc _raw_read_trylock(rwlock_t *lock); +int __lockfunc _raw_write_trylock(rwlock_t *lock); +void __lockfunc _raw_read_unlock(rwlock_t *lock) __releases(lock); +void __lockfunc _raw_write_unlock(rwlock_t *lock) __releases(lock); +void __lockfunc _raw_read_unlock_bh(rwlock_t *lock) __releases(lock); +void __lockfunc _raw_write_unlock_bh(rwlock_t *lock) __releases(lock); +void __lockfunc _raw_read_unlock_irq(rwlock_t *lock) __releases(lock); +void __lockfunc _raw_write_unlock_irq(rwlock_t *lock) __releases(lock); +void __lockfunc +_raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) __releases(lock); -void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) +void __lockfunc +_raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) __releases(lock); #ifdef CONFIG_INLINE_READ_LOCK -#define _read_lock(lock) __read_lock(lock) +#define _raw_read_lock(lock) __raw_read_lock(lock) #endif #ifdef CONFIG_INLINE_WRITE_LOCK -#define _write_lock(lock) __write_lock(lock) +#define _raw_write_lock(lock) __raw_write_lock(lock) #endif #ifdef CONFIG_INLINE_READ_LOCK_BH -#define _read_lock_bh(lock) __read_lock_bh(lock) +#define _raw_read_lock_bh(lock) __raw_read_lock_bh(lock) #endif #ifdef CONFIG_INLINE_WRITE_LOCK_BH -#define _write_lock_bh(lock) __write_lock_bh(lock) +#define _raw_write_lock_bh(lock) __raw_write_lock_bh(lock) #endif #ifdef CONFIG_INLINE_READ_LOCK_IRQ -#define _read_lock_irq(lock) __read_lock_irq(lock) +#define _raw_read_lock_irq(lock) __raw_read_lock_irq(lock) #endif #ifdef CONFIG_INLINE_WRITE_LOCK_IRQ -#define _write_lock_irq(lock) __write_lock_irq(lock) +#define _raw_write_lock_irq(lock) __raw_write_lock_irq(lock) #endif #ifdef CONFIG_INLINE_READ_LOCK_IRQSAVE -#define _read_lock_irqsave(lock) __read_lock_irqsave(lock) +#define _raw_read_lock_irqsave(lock) __raw_read_lock_irqsave(lock) #endif #ifdef CONFIG_INLINE_WRITE_LOCK_IRQSAVE -#define _write_lock_irqsave(lock) __write_lock_irqsave(lock) +#define _raw_write_lock_irqsave(lock) __raw_write_lock_irqsave(lock) #endif #ifdef CONFIG_INLINE_READ_TRYLOCK -#define _read_trylock(lock) __read_trylock(lock) +#define _raw_read_trylock(lock) __raw_read_trylock(lock) #endif #ifdef CONFIG_INLINE_WRITE_TRYLOCK -#define _write_trylock(lock) __write_trylock(lock) +#define _raw_write_trylock(lock) __raw_write_trylock(lock) #endif #ifdef CONFIG_INLINE_READ_UNLOCK -#define _read_unlock(lock) __read_unlock(lock) +#define _raw_read_unlock(lock) __raw_read_unlock(lock) #endif #ifdef CONFIG_INLINE_WRITE_UNLOCK -#define _write_unlock(lock) __write_unlock(lock) +#define _raw_write_unlock(lock) __raw_write_unlock(lock) #endif #ifdef CONFIG_INLINE_READ_UNLOCK_BH -#define _read_unlock_bh(lock) __read_unlock_bh(lock) +#define _raw_read_unlock_bh(lock) __raw_read_unlock_bh(lock) #endif #ifdef CONFIG_INLINE_WRITE_UNLOCK_BH -#define _write_unlock_bh(lock) __write_unlock_bh(lock) +#define _raw_write_unlock_bh(lock) __raw_write_unlock_bh(lock) #endif #ifdef CONFIG_INLINE_READ_UNLOCK_IRQ -#define _read_unlock_irq(lock) __read_unlock_irq(lock) +#define _raw_read_unlock_irq(lock) __raw_read_unlock_irq(lock) #endif #ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQ -#define _write_unlock_irq(lock) __write_unlock_irq(lock) +#define _raw_write_unlock_irq(lock) __raw_write_unlock_irq(lock) #endif #ifdef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE -#define _read_unlock_irqrestore(lock, flags) __read_unlock_irqrestore(lock, flags) +#define _raw_read_unlock_irqrestore(lock, flags) \ + __raw_read_unlock_irqrestore(lock, flags) #endif #ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE -#define _write_unlock_irqrestore(lock, flags) __write_unlock_irqrestore(lock, flags) +#define _raw_write_unlock_irqrestore(lock, flags) \ + __raw_write_unlock_irqrestore(lock, flags) #endif -static inline int __read_trylock(rwlock_t *lock) +static inline int __raw_read_trylock(rwlock_t *lock) { preempt_disable(); if (do_raw_read_trylock(lock)) { @@ -121,7 +125,7 @@ static inline int __read_trylock(rwlock_t *lock) return 0; } -static inline int __write_trylock(rwlock_t *lock) +static inline int __raw_write_trylock(rwlock_t *lock) { preempt_disable(); if (do_raw_write_trylock(lock)) { @@ -139,14 +143,14 @@ static inline int __write_trylock(rwlock_t *lock) */ #if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC) -static inline void __read_lock(rwlock_t *lock) +static inline void __raw_read_lock(rwlock_t *lock) { preempt_disable(); rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); } -static inline unsigned long __read_lock_irqsave(rwlock_t *lock) +static inline unsigned long __raw_read_lock_irqsave(rwlock_t *lock) { unsigned long flags; @@ -158,7 +162,7 @@ static inline unsigned long __read_lock_irqsave(rwlock_t *lock) return flags; } -static inline void __read_lock_irq(rwlock_t *lock) +static inline void __raw_read_lock_irq(rwlock_t *lock) { local_irq_disable(); preempt_disable(); @@ -166,7 +170,7 @@ static inline void __read_lock_irq(rwlock_t *lock) LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); } -static inline void __read_lock_bh(rwlock_t *lock) +static inline void __raw_read_lock_bh(rwlock_t *lock) { local_bh_disable(); preempt_disable(); @@ -174,7 +178,7 @@ static inline void __read_lock_bh(rwlock_t *lock) LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); } -static inline unsigned long __write_lock_irqsave(rwlock_t *lock) +static inline unsigned long __raw_write_lock_irqsave(rwlock_t *lock) { unsigned long flags; @@ -186,7 +190,7 @@ static inline unsigned long __write_lock_irqsave(rwlock_t *lock) return flags; } -static inline void __write_lock_irq(rwlock_t *lock) +static inline void __raw_write_lock_irq(rwlock_t *lock) { local_irq_disable(); preempt_disable(); @@ -194,7 +198,7 @@ static inline void __write_lock_irq(rwlock_t *lock) LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); } -static inline void __write_lock_bh(rwlock_t *lock) +static inline void __raw_write_lock_bh(rwlock_t *lock) { local_bh_disable(); preempt_disable(); @@ -202,7 +206,7 @@ static inline void __write_lock_bh(rwlock_t *lock) LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); } -static inline void __write_lock(rwlock_t *lock) +static inline void __raw_write_lock(rwlock_t *lock) { preempt_disable(); rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); @@ -211,21 +215,22 @@ static inline void __write_lock(rwlock_t *lock) #endif /* CONFIG_PREEMPT */ -static inline void __write_unlock(rwlock_t *lock) +static inline void __raw_write_unlock(rwlock_t *lock) { rwlock_release(&lock->dep_map, 1, _RET_IP_); do_raw_write_unlock(lock); preempt_enable(); } -static inline void __read_unlock(rwlock_t *lock) +static inline void __raw_read_unlock(rwlock_t *lock) { rwlock_release(&lock->dep_map, 1, _RET_IP_); do_raw_read_unlock(lock); preempt_enable(); } -static inline void __read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) +static inline void +__raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) { rwlock_release(&lock->dep_map, 1, _RET_IP_); do_raw_read_unlock(lock); @@ -233,7 +238,7 @@ static inline void __read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) preempt_enable(); } -static inline void __read_unlock_irq(rwlock_t *lock) +static inline void __raw_read_unlock_irq(rwlock_t *lock) { rwlock_release(&lock->dep_map, 1, _RET_IP_); do_raw_read_unlock(lock); @@ -241,7 +246,7 @@ static inline void __read_unlock_irq(rwlock_t *lock) preempt_enable(); } -static inline void __read_unlock_bh(rwlock_t *lock) +static inline void __raw_read_unlock_bh(rwlock_t *lock) { rwlock_release(&lock->dep_map, 1, _RET_IP_); do_raw_read_unlock(lock); @@ -249,7 +254,7 @@ static inline void __read_unlock_bh(rwlock_t *lock) local_bh_enable_ip((unsigned long)__builtin_return_address(0)); } -static inline void __write_unlock_irqrestore(rwlock_t *lock, +static inline void __raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) { rwlock_release(&lock->dep_map, 1, _RET_IP_); @@ -258,7 +263,7 @@ static inline void __write_unlock_irqrestore(rwlock_t *lock, preempt_enable(); } -static inline void __write_unlock_irq(rwlock_t *lock) +static inline void __raw_write_unlock_irq(rwlock_t *lock) { rwlock_release(&lock->dep_map, 1, _RET_IP_); do_raw_write_unlock(lock); @@ -266,7 +271,7 @@ static inline void __write_unlock_irq(rwlock_t *lock) preempt_enable(); } -static inline void __write_unlock_bh(rwlock_t *lock) +static inline void __raw_write_unlock_bh(rwlock_t *lock) { rwlock_release(&lock->dep_map, 1, _RET_IP_); do_raw_write_unlock(lock); diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 0cbc58a..8608821 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -161,20 +161,22 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) * various methods are defined as nops in the case they are not * required. */ -#define raw_spin_trylock(lock) __cond_lock(lock, _spin_trylock(lock)) +#define raw_spin_trylock(lock) __cond_lock(lock, _raw_spin_trylock(lock)) -#define raw_spin_lock(lock) _spin_lock(lock) +#define raw_spin_lock(lock) _raw_spin_lock(lock) #ifdef CONFIG_DEBUG_LOCK_ALLOC -# define raw_spin_lock_nested(lock, subclass) _spin_lock_nested(lock, subclass) +# define raw_spin_lock_nested(lock, subclass) \ + _raw_spin_lock_nested(lock, subclass) + # define raw_spin_lock_nest_lock(lock, nest_lock) \ do { \ typecheck(struct lockdep_map *, &(nest_lock)->dep_map);\ - _spin_lock_nest_lock(lock, &(nest_lock)->dep_map); \ + _raw_spin_lock_nest_lock(lock, &(nest_lock)->dep_map); \ } while (0) #else -# define raw_spin_lock_nested(lock, subclass) _spin_lock(lock) -# define raw_spin_lock_nest_lock(lock, nest_lock) _spin_lock(lock) +# define raw_spin_lock_nested(lock, subclass) _raw_spin_lock(lock) +# define raw_spin_lock_nest_lock(lock, nest_lock) _raw_spin_lock(lock) #endif #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) @@ -182,20 +184,20 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) #define raw_spin_lock_irqsave(lock, flags) \ do { \ typecheck(unsigned long, flags); \ - flags = _spin_lock_irqsave(lock); \ + flags = _raw_spin_lock_irqsave(lock); \ } while (0) #ifdef CONFIG_DEBUG_LOCK_ALLOC #define raw_spin_lock_irqsave_nested(lock, flags, subclass) \ do { \ typecheck(unsigned long, flags); \ - flags = _spin_lock_irqsave_nested(lock, subclass); \ + flags = _raw_spin_lock_irqsave_nested(lock, subclass); \ } while (0) #else #define raw_spin_lock_irqsave_nested(lock, flags, subclass) \ do { \ typecheck(unsigned long, flags); \ - flags = _spin_lock_irqsave(lock); \ + flags = _raw_spin_lock_irqsave(lock); \ } while (0) #endif @@ -204,7 +206,7 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) #define raw_spin_lock_irqsave(lock, flags) \ do { \ typecheck(unsigned long, flags); \ - _spin_lock_irqsave(lock, flags); \ + _raw_spin_lock_irqsave(lock, flags); \ } while (0) #define raw_spin_lock_irqsave_nested(lock, flags, subclass) \ @@ -212,19 +214,20 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) #endif -#define raw_spin_lock_irq(lock) _spin_lock_irq(lock) -#define raw_spin_lock_bh(lock) _spin_lock_bh(lock) -#define raw_spin_unlock(lock) _spin_unlock(lock) -#define raw_spin_unlock_irq(lock) _spin_unlock_irq(lock) +#define raw_spin_lock_irq(lock) _raw_spin_lock_irq(lock) +#define raw_spin_lock_bh(lock) _raw_spin_lock_bh(lock) +#define raw_spin_unlock(lock) _raw_spin_unlock(lock) +#define raw_spin_unlock_irq(lock) _raw_spin_unlock_irq(lock) #define raw_spin_unlock_irqrestore(lock, flags) \ do { \ typecheck(unsigned long, flags); \ - _spin_unlock_irqrestore(lock, flags); \ + _raw_spin_unlock_irqrestore(lock, flags); \ } while (0) -#define raw_spin_unlock_bh(lock) _spin_unlock_bh(lock) +#define raw_spin_unlock_bh(lock) _raw_spin_unlock_bh(lock) -#define raw_spin_trylock_bh(lock) __cond_lock(lock, _spin_trylock_bh(lock)) +#define raw_spin_trylock_bh(lock) \ + __cond_lock(lock, _raw_spin_trylock_bh(lock)) #define raw_spin_trylock_irq(lock) \ ({ \ diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h index 1be1fc5..e253ccd 100644 --- a/include/linux/spinlock_api_smp.h +++ b/include/linux/spinlock_api_smp.h @@ -19,70 +19,71 @@ int in_lock_functions(unsigned long addr); #define assert_raw_spin_locked(x) BUG_ON(!raw_spin_is_locked(x)) -void __lockfunc _spin_lock(raw_spinlock_t *lock) __acquires(lock); -void __lockfunc _spin_lock_nested(raw_spinlock_t *lock, int subclass) - __acquires(lock); +void __lockfunc _raw_spin_lock(raw_spinlock_t *lock) __acquires(lock); +void __lockfunc _raw_spin_lock_nested(raw_spinlock_t *lock, int subclass) + __acquires(lock); void __lockfunc -_spin_lock_nest_lock(raw_spinlock_t *lock, struct lockdep_map *map) - __acquires(lock); -void __lockfunc _spin_lock_bh(raw_spinlock_t *lock) __acquires(lock); -void __lockfunc _spin_lock_irq(raw_spinlock_t *lock) __acquires(lock); - -unsigned long __lockfunc _spin_lock_irqsave(raw_spinlock_t *lock) - __acquires(lock); +_raw_spin_lock_nest_lock(raw_spinlock_t *lock, struct lockdep_map *map) + __acquires(lock); +void __lockfunc _raw_spin_lock_bh(raw_spinlock_t *lock) __acquires(lock); +void __lockfunc _raw_spin_lock_irq(raw_spinlock_t *lock) + __acquires(lock); + +unsigned long __lockfunc _raw_spin_lock_irqsave(raw_spinlock_t *lock) + __acquires(lock); unsigned long __lockfunc -_spin_lock_irqsave_nested(raw_spinlock_t *lock, int subclass) - __acquires(lock); -int __lockfunc _spin_trylock(raw_spinlock_t *lock); -int __lockfunc _spin_trylock_bh(raw_spinlock_t *lock); -void __lockfunc _spin_unlock(raw_spinlock_t *lock) __releases(lock); -void __lockfunc _spin_unlock_bh(raw_spinlock_t *lock) __releases(lock); -void __lockfunc _spin_unlock_irq(raw_spinlock_t *lock) __releases(lock); +_raw_spin_lock_irqsave_nested(raw_spinlock_t *lock, int subclass) + __acquires(lock); +int __lockfunc _raw_spin_trylock(raw_spinlock_t *lock); +int __lockfunc _raw_spin_trylock_bh(raw_spinlock_t *lock); +void __lockfunc _raw_spin_unlock(raw_spinlock_t *lock) __releases(lock); +void __lockfunc _raw_spin_unlock_bh(raw_spinlock_t *lock) __releases(lock); +void __lockfunc _raw_spin_unlock_irq(raw_spinlock_t *lock) __releases(lock); void __lockfunc -_spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) - __releases(lock); +_raw_spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) + __releases(lock); #ifdef CONFIG_INLINE_SPIN_LOCK -#define _spin_lock(lock) __spin_lock(lock) +#define _raw_spin_lock(lock) __raw_spin_lock(lock) #endif #ifdef CONFIG_INLINE_SPIN_LOCK_BH -#define _spin_lock_bh(lock) __spin_lock_bh(lock) +#define _raw_spin_lock_bh(lock) __raw_spin_lock_bh(lock) #endif #ifdef CONFIG_INLINE_SPIN_LOCK_IRQ -#define _spin_lock_irq(lock) __spin_lock_irq(lock) +#define _raw_spin_lock_irq(lock) __raw_spin_lock_irq(lock) #endif #ifdef CONFIG_INLINE_SPIN_LOCK_IRQSAVE -#define _spin_lock_irqsave(lock) __spin_lock_irqsave(lock) +#define _raw_spin_lock_irqsave(lock) __raw_spin_lock_irqsave(lock) #endif #ifdef CONFIG_INLINE_SPIN_TRYLOCK -#define _spin_trylock(lock) __spin_trylock(lock) +#define _raw_spin_trylock(lock) __raw_spin_trylock(lock) #endif #ifdef CONFIG_INLINE_SPIN_TRYLOCK_BH -#define _spin_trylock_bh(lock) __spin_trylock_bh(lock) +#define _raw_spin_trylock_bh(lock) __raw_spin_trylock_bh(lock) #endif #ifdef CONFIG_INLINE_SPIN_UNLOCK -#define _spin_unlock(lock) __spin_unlock(lock) +#define _raw_spin_unlock(lock) __raw_spin_unlock(lock) #endif #ifdef CONFIG_INLINE_SPIN_UNLOCK_BH -#define _spin_unlock_bh(lock) __spin_unlock_bh(lock) +#define _raw_spin_unlock_bh(lock) __raw_spin_unlock_bh(lock) #endif #ifdef CONFIG_INLINE_SPIN_UNLOCK_IRQ -#define _spin_unlock_irq(lock) __spin_unlock_irq(lock) +#define _raw_spin_unlock_irq(lock) __raw_spin_unlock_irq(lock) #endif #ifdef CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE -#define _spin_unlock_irqrestore(lock, flags) __spin_unlock_irqrestore(lock, flags) +#define _raw_spin_unlock_irqrestore(lock, flags) __raw_spin_unlock_irqrestore(lock, flags) #endif -static inline int __spin_trylock(raw_spinlock_t *lock) +static inline int __raw_spin_trylock(raw_spinlock_t *lock) { preempt_disable(); if (do_raw_spin_trylock(lock)) { @@ -100,7 +101,7 @@ static inline int __spin_trylock(raw_spinlock_t *lock) */ #if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC) -static inline unsigned long __spin_lock_irqsave(raw_spinlock_t *lock) +static inline unsigned long __raw_spin_lock_irqsave(raw_spinlock_t *lock) { unsigned long flags; @@ -120,7 +121,7 @@ static inline unsigned long __spin_lock_irqsave(raw_spinlock_t *lock) return flags; } -static inline void __spin_lock_irq(raw_spinlock_t *lock) +static inline void __raw_spin_lock_irq(raw_spinlock_t *lock) { local_irq_disable(); preempt_disable(); @@ -128,7 +129,7 @@ static inline void __spin_lock_irq(raw_spinlock_t *lock) LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } -static inline void __spin_lock_bh(raw_spinlock_t *lock) +static inline void __raw_spin_lock_bh(raw_spinlock_t *lock) { local_bh_disable(); preempt_disable(); @@ -136,7 +137,7 @@ static inline void __spin_lock_bh(raw_spinlock_t *lock) LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } -static inline void __spin_lock(raw_spinlock_t *lock) +static inline void __raw_spin_lock(raw_spinlock_t *lock) { preempt_disable(); spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); @@ -145,14 +146,14 @@ static inline void __spin_lock(raw_spinlock_t *lock) #endif /* CONFIG_PREEMPT */ -static inline void __spin_unlock(raw_spinlock_t *lock) +static inline void __raw_spin_unlock(raw_spinlock_t *lock) { spin_release(&lock->dep_map, 1, _RET_IP_); do_raw_spin_unlock(lock); preempt_enable(); } -static inline void __spin_unlock_irqrestore(raw_spinlock_t *lock, +static inline void __raw_spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) { spin_release(&lock->dep_map, 1, _RET_IP_); @@ -161,7 +162,7 @@ static inline void __spin_unlock_irqrestore(raw_spinlock_t *lock, preempt_enable(); } -static inline void __spin_unlock_irq(raw_spinlock_t *lock) +static inline void __raw_spin_unlock_irq(raw_spinlock_t *lock) { spin_release(&lock->dep_map, 1, _RET_IP_); do_raw_spin_unlock(lock); @@ -169,7 +170,7 @@ static inline void __spin_unlock_irq(raw_spinlock_t *lock) preempt_enable(); } -static inline void __spin_unlock_bh(raw_spinlock_t *lock) +static inline void __raw_spin_unlock_bh(raw_spinlock_t *lock) { spin_release(&lock->dep_map, 1, _RET_IP_); do_raw_spin_unlock(lock); @@ -177,7 +178,7 @@ static inline void __spin_unlock_bh(raw_spinlock_t *lock) local_bh_enable_ip((unsigned long)__builtin_return_address(0)); } -static inline int __spin_trylock_bh(raw_spinlock_t *lock) +static inline int __raw_spin_trylock_bh(raw_spinlock_t *lock) { local_bh_disable(); preempt_disable(); diff --git a/include/linux/spinlock_api_up.h b/include/linux/spinlock_api_up.h index 3a9e27a..af1f472 100644 --- a/include/linux/spinlock_api_up.h +++ b/include/linux/spinlock_api_up.h @@ -40,7 +40,8 @@ do { preempt_enable(); __release(lock); (void)(lock); } while (0) #define __UNLOCK_BH(lock) \ - do { preempt_enable_no_resched(); local_bh_enable(); __release(lock); (void)(lock); } while (0) + do { preempt_enable_no_resched(); local_bh_enable(); \ + __release(lock); (void)(lock); } while (0) #define __UNLOCK_IRQ(lock) \ do { local_irq_enable(); __UNLOCK(lock); } while (0) @@ -48,34 +49,37 @@ #define __UNLOCK_IRQRESTORE(lock, flags) \ do { local_irq_restore(flags); __UNLOCK(lock); } while (0) -#define _spin_lock(lock) __LOCK(lock) -#define _spin_lock_nested(lock, subclass) __LOCK(lock) -#define _read_lock(lock) __LOCK(lock) -#define _write_lock(lock) __LOCK(lock) -#define _spin_lock_bh(lock) __LOCK_BH(lock) -#define _read_lock_bh(lock) __LOCK_BH(lock) -#define _write_lock_bh(lock) __LOCK_BH(lock) -#define _spin_lock_irq(lock) __LOCK_IRQ(lock) -#define _read_lock_irq(lock) __LOCK_IRQ(lock) -#define _write_lock_irq(lock) __LOCK_IRQ(lock) -#define _spin_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) -#define _read_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) -#define _write_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) -#define _spin_trylock(lock) ({ __LOCK(lock); 1; }) -#define _read_trylock(lock) ({ __LOCK(lock); 1; }) -#define _write_trylock(lock) ({ __LOCK(lock); 1; }) -#define _spin_trylock_bh(lock) ({ __LOCK_BH(lock); 1; }) -#define _spin_unlock(lock) __UNLOCK(lock) -#define _read_unlock(lock) __UNLOCK(lock) -#define _write_unlock(lock) __UNLOCK(lock) -#define _spin_unlock_bh(lock) __UNLOCK_BH(lock) -#define _write_unlock_bh(lock) __UNLOCK_BH(lock) -#define _read_unlock_bh(lock) __UNLOCK_BH(lock) -#define _spin_unlock_irq(lock) __UNLOCK_IRQ(lock) -#define _read_unlock_irq(lock) __UNLOCK_IRQ(lock) -#define _write_unlock_irq(lock) __UNLOCK_IRQ(lock) -#define _spin_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags) -#define _read_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags) -#define _write_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags) +#define _raw_spin_lock(lock) __LOCK(lock) +#define _raw_spin_lock_nested(lock, subclass) __LOCK(lock) +#define _raw_read_lock(lock) __LOCK(lock) +#define _raw_write_lock(lock) __LOCK(lock) +#define _raw_spin_lock_bh(lock) __LOCK_BH(lock) +#define _raw_read_lock_bh(lock) __LOCK_BH(lock) +#define _raw_write_lock_bh(lock) __LOCK_BH(lock) +#define _raw_spin_lock_irq(lock) __LOCK_IRQ(lock) +#define _raw_read_lock_irq(lock) __LOCK_IRQ(lock) +#define _raw_write_lock_irq(lock) __LOCK_IRQ(lock) +#define _raw_spin_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) +#define _raw_read_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) +#define _raw_write_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) +#define _raw_spin_trylock(lock) ({ __LOCK(lock); 1; }) +#define _raw_read_trylock(lock) ({ __LOCK(lock); 1; }) +#define _raw_write_trylock(lock) ({ __LOCK(lock); 1; }) +#define _raw_spin_trylock_bh(lock) ({ __LOCK_BH(lock); 1; }) +#define _raw_spin_unlock(lock) __UNLOCK(lock) +#define _raw_read_unlock(lock) __UNLOCK(lock) +#define _raw_write_unlock(lock) __UNLOCK(lock) +#define _raw_spin_unlock_bh(lock) __UNLOCK_BH(lock) +#define _raw_write_unlock_bh(lock) __UNLOCK_BH(lock) +#define _raw_read_unlock_bh(lock) __UNLOCK_BH(lock) +#define _raw_spin_unlock_irq(lock) __UNLOCK_IRQ(lock) +#define _raw_read_unlock_irq(lock) __UNLOCK_IRQ(lock) +#define _raw_write_unlock_irq(lock) __UNLOCK_IRQ(lock) +#define _raw_spin_unlock_irqrestore(lock, flags) \ + __UNLOCK_IRQRESTORE(lock, flags) +#define _raw_read_unlock_irqrestore(lock, flags) \ + __UNLOCK_IRQRESTORE(lock, flags) +#define _raw_write_unlock_irqrestore(lock, flags) \ + __UNLOCK_IRQRESTORE(lock, flags) #endif /* __LINUX_SPINLOCK_API_UP_H */ diff --git a/kernel/spinlock.c b/kernel/spinlock.c index 795240b..be6517f 100644 --- a/kernel/spinlock.c +++ b/kernel/spinlock.c @@ -44,7 +44,7 @@ * towards that other CPU that it should break the lock ASAP. */ #define BUILD_LOCK_OPS(op, locktype) \ -void __lockfunc __##op##_lock(locktype##_t *lock) \ +void __lockfunc __raw_##op##_lock(locktype##_t *lock) \ { \ for (;;) { \ preempt_disable(); \ @@ -60,7 +60,7 @@ void __lockfunc __##op##_lock(locktype##_t *lock) \ (lock)->break_lock = 0; \ } \ \ -unsigned long __lockfunc __##op##_lock_irqsave(locktype##_t *lock) \ +unsigned long __lockfunc __raw_##op##_lock_irqsave(locktype##_t *lock) \ { \ unsigned long flags; \ \ @@ -81,12 +81,12 @@ unsigned long __lockfunc __##op##_lock_irqsave(locktype##_t *lock) \ return flags; \ } \ \ -void __lockfunc __##op##_lock_irq(locktype##_t *lock) \ +void __lockfunc __raw_##op##_lock_irq(locktype##_t *lock) \ { \ - _##op##_lock_irqsave(lock); \ + _raw_##op##_lock_irqsave(lock); \ } \ \ -void __lockfunc __##op##_lock_bh(locktype##_t *lock) \ +void __lockfunc __raw_##op##_lock_bh(locktype##_t *lock) \ { \ unsigned long flags; \ \ @@ -95,7 +95,7 @@ void __lockfunc __##op##_lock_bh(locktype##_t *lock) \ /* irq-disabling. We use the generic preemption-aware */ \ /* function: */ \ /**/ \ - flags = _##op##_lock_irqsave(lock); \ + flags = _raw_##op##_lock_irqsave(lock); \ local_bh_disable(); \ local_irq_restore(flags); \ } \ @@ -116,240 +116,240 @@ BUILD_LOCK_OPS(write, rwlock); #endif #ifndef CONFIG_INLINE_SPIN_TRYLOCK -int __lockfunc _spin_trylock(raw_spinlock_t *lock) +int __lockfunc _raw_spin_trylock(raw_spinlock_t *lock) { - return __spin_trylock(lock); + return __raw_spin_trylock(lock); } -EXPORT_SYMBOL(_spin_trylock); +EXPORT_SYMBOL(_raw_spin_trylock); #endif #ifndef CONFIG_INLINE_SPIN_TRYLOCK_BH -int __lockfunc _spin_trylock_bh(raw_spinlock_t *lock) +int __lockfunc _raw_spin_trylock_bh(raw_spinlock_t *lock) { - return __spin_trylock_bh(lock); + return __raw_spin_trylock_bh(lock); } -EXPORT_SYMBOL(_spin_trylock_bh); +EXPORT_SYMBOL(_raw_spin_trylock_bh); #endif #ifndef CONFIG_INLINE_SPIN_LOCK -void __lockfunc _spin_lock(raw_spinlock_t *lock) +void __lockfunc _raw_spin_lock(raw_spinlock_t *lock) { - __spin_lock(lock); + __raw_spin_lock(lock); } -EXPORT_SYMBOL(_spin_lock); +EXPORT_SYMBOL(_raw_spin_lock); #endif #ifndef CONFIG_INLINE_SPIN_LOCK_IRQSAVE -unsigned long __lockfunc _spin_lock_irqsave(raw_spinlock_t *lock) +unsigned long __lockfunc _raw_spin_lock_irqsave(raw_spinlock_t *lock) { - return __spin_lock_irqsave(lock); + return __raw_spin_lock_irqsave(lock); } -EXPORT_SYMBOL(_spin_lock_irqsave); +EXPORT_SYMBOL(_raw_spin_lock_irqsave); #endif #ifndef CONFIG_INLINE_SPIN_LOCK_IRQ -void __lockfunc _spin_lock_irq(raw_spinlock_t *lock) +void __lockfunc _raw_spin_lock_irq(raw_spinlock_t *lock) { - __spin_lock_irq(lock); + __raw_spin_lock_irq(lock); } -EXPORT_SYMBOL(_spin_lock_irq); +EXPORT_SYMBOL(_raw_spin_lock_irq); #endif #ifndef CONFIG_INLINE_SPIN_LOCK_BH -void __lockfunc _spin_lock_bh(raw_spinlock_t *lock) +void __lockfunc _raw_spin_lock_bh(raw_spinlock_t *lock) { - __spin_lock_bh(lock); + __raw_spin_lock_bh(lock); } -EXPORT_SYMBOL(_spin_lock_bh); +EXPORT_SYMBOL(_raw_spin_lock_bh); #endif #ifndef CONFIG_INLINE_SPIN_UNLOCK -void __lockfunc _spin_unlock(raw_spinlock_t *lock) +void __lockfunc _raw_spin_unlock(raw_spinlock_t *lock) { - __spin_unlock(lock); + __raw_spin_unlock(lock); } -EXPORT_SYMBOL(_spin_unlock); +EXPORT_SYMBOL(_raw_spin_unlock); #endif #ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE -void __lockfunc _spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) +void __lockfunc _raw_spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) { - __spin_unlock_irqrestore(lock, flags); + __raw_spin_unlock_irqrestore(lock, flags); } -EXPORT_SYMBOL(_spin_unlock_irqrestore); +EXPORT_SYMBOL(_raw_spin_unlock_irqrestore); #endif #ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQ -void __lockfunc _spin_unlock_irq(raw_spinlock_t *lock) +void __lockfunc _raw_spin_unlock_irq(raw_spinlock_t *lock) { - __spin_unlock_irq(lock); + __raw_spin_unlock_irq(lock); } -EXPORT_SYMBOL(_spin_unlock_irq); +EXPORT_SYMBOL(_raw_spin_unlock_irq); #endif #ifndef CONFIG_INLINE_SPIN_UNLOCK_BH -void __lockfunc _spin_unlock_bh(raw_spinlock_t *lock) +void __lockfunc _raw_spin_unlock_bh(raw_spinlock_t *lock) { - __spin_unlock_bh(lock); + __raw_spin_unlock_bh(lock); } -EXPORT_SYMBOL(_spin_unlock_bh); +EXPORT_SYMBOL(_raw_spin_unlock_bh); #endif #ifndef CONFIG_INLINE_READ_TRYLOCK -int __lockfunc _read_trylock(rwlock_t *lock) +int __lockfunc _raw_read_trylock(rwlock_t *lock) { - return __read_trylock(lock); + return __raw_read_trylock(lock); } -EXPORT_SYMBOL(_read_trylock); +EXPORT_SYMBOL(_raw_read_trylock); #endif #ifndef CONFIG_INLINE_READ_LOCK -void __lockfunc _read_lock(rwlock_t *lock) +void __lockfunc _raw_read_lock(rwlock_t *lock) { - __read_lock(lock); + __raw_read_lock(lock); } -EXPORT_SYMBOL(_read_lock); +EXPORT_SYMBOL(_raw_read_lock); #endif #ifndef CONFIG_INLINE_READ_LOCK_IRQSAVE -unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock) +unsigned long __lockfunc _raw_read_lock_irqsave(rwlock_t *lock) { - return __read_lock_irqsave(lock); + return __raw_read_lock_irqsave(lock); } -EXPORT_SYMBOL(_read_lock_irqsave); +EXPORT_SYMBOL(_raw_read_lock_irqsave); #endif #ifndef CONFIG_INLINE_READ_LOCK_IRQ -void __lockfunc _read_lock_irq(rwlock_t *lock) +void __lockfunc _raw_read_lock_irq(rwlock_t *lock) { - __read_lock_irq(lock); + __raw_read_lock_irq(lock); } -EXPORT_SYMBOL(_read_lock_irq); +EXPORT_SYMBOL(_raw_read_lock_irq); #endif #ifndef CONFIG_INLINE_READ_LOCK_BH -void __lockfunc _read_lock_bh(rwlock_t *lock) +void __lockfunc _raw_read_lock_bh(rwlock_t *lock) { - __read_lock_bh(lock); + __raw_read_lock_bh(lock); } -EXPORT_SYMBOL(_read_lock_bh); +EXPORT_SYMBOL(_raw_read_lock_bh); #endif #ifndef CONFIG_INLINE_READ_UNLOCK -void __lockfunc _read_unlock(rwlock_t *lock) +void __lockfunc _raw_read_unlock(rwlock_t *lock) { - __read_unlock(lock); + __raw_read_unlock(lock); } -EXPORT_SYMBOL(_read_unlock); +EXPORT_SYMBOL(_raw_read_unlock); #endif #ifndef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE -void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) +void __lockfunc _raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) { - __read_unlock_irqrestore(lock, flags); + __raw_read_unlock_irqrestore(lock, flags); } -EXPORT_SYMBOL(_read_unlock_irqrestore); +EXPORT_SYMBOL(_raw_read_unlock_irqrestore); #endif #ifndef CONFIG_INLINE_READ_UNLOCK_IRQ -void __lockfunc _read_unlock_irq(rwlock_t *lock) +void __lockfunc _raw_read_unlock_irq(rwlock_t *lock) { - __read_unlock_irq(lock); + __raw_read_unlock_irq(lock); } -EXPORT_SYMBOL(_read_unlock_irq); +EXPORT_SYMBOL(_raw_read_unlock_irq); #endif #ifndef CONFIG_INLINE_READ_UNLOCK_BH -void __lockfunc _read_unlock_bh(rwlock_t *lock) +void __lockfunc _raw_read_unlock_bh(rwlock_t *lock) { - __read_unlock_bh(lock); + __raw_read_unlock_bh(lock); } -EXPORT_SYMBOL(_read_unlock_bh); +EXPORT_SYMBOL(_raw_read_unlock_bh); #endif #ifndef CONFIG_INLINE_WRITE_TRYLOCK -int __lockfunc _write_trylock(rwlock_t *lock) +int __lockfunc _raw_write_trylock(rwlock_t *lock) { - return __write_trylock(lock); + return __raw_write_trylock(lock); } -EXPORT_SYMBOL(_write_trylock); +EXPORT_SYMBOL(_raw_write_trylock); #endif #ifndef CONFIG_INLINE_WRITE_LOCK -void __lockfunc _write_lock(rwlock_t *lock) +void __lockfunc _raw_write_lock(rwlock_t *lock) { - __write_lock(lock); + __raw_write_lock(lock); } -EXPORT_SYMBOL(_write_lock); +EXPORT_SYMBOL(_raw_write_lock); #endif #ifndef CONFIG_INLINE_WRITE_LOCK_IRQSAVE -unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock) +unsigned long __lockfunc _raw_write_lock_irqsave(rwlock_t *lock) { - return __write_lock_irqsave(lock); + return __raw_write_lock_irqsave(lock); } -EXPORT_SYMBOL(_write_lock_irqsave); +EXPORT_SYMBOL(_raw_write_lock_irqsave); #endif #ifndef CONFIG_INLINE_WRITE_LOCK_IRQ -void __lockfunc _write_lock_irq(rwlock_t *lock) +void __lockfunc _raw_write_lock_irq(rwlock_t *lock) { - __write_lock_irq(lock); + __raw_write_lock_irq(lock); } -EXPORT_SYMBOL(_write_lock_irq); +EXPORT_SYMBOL(_raw_write_lock_irq); #endif #ifndef CONFIG_INLINE_WRITE_LOCK_BH -void __lockfunc _write_lock_bh(rwlock_t *lock) +void __lockfunc _raw_write_lock_bh(rwlock_t *lock) { - __write_lock_bh(lock); + __raw_write_lock_bh(lock); } -EXPORT_SYMBOL(_write_lock_bh); +EXPORT_SYMBOL(_raw_write_lock_bh); #endif #ifndef CONFIG_INLINE_WRITE_UNLOCK -void __lockfunc _write_unlock(rwlock_t *lock) +void __lockfunc _raw_write_unlock(rwlock_t *lock) { - __write_unlock(lock); + __raw_write_unlock(lock); } -EXPORT_SYMBOL(_write_unlock); +EXPORT_SYMBOL(_raw_write_unlock); #endif #ifndef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE -void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) +void __lockfunc _raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) { - __write_unlock_irqrestore(lock, flags); + __raw_write_unlock_irqrestore(lock, flags); } -EXPORT_SYMBOL(_write_unlock_irqrestore); +EXPORT_SYMBOL(_raw_write_unlock_irqrestore); #endif #ifndef CONFIG_INLINE_WRITE_UNLOCK_IRQ -void __lockfunc _write_unlock_irq(rwlock_t *lock) +void __lockfunc _raw_write_unlock_irq(rwlock_t *lock) { - __write_unlock_irq(lock); + __raw_write_unlock_irq(lock); } -EXPORT_SYMBOL(_write_unlock_irq); +EXPORT_SYMBOL(_raw_write_unlock_irq); #endif #ifndef CONFIG_INLINE_WRITE_UNLOCK_BH -void __lockfunc _write_unlock_bh(rwlock_t *lock) +void __lockfunc _raw_write_unlock_bh(rwlock_t *lock) { - __write_unlock_bh(lock); + __raw_write_unlock_bh(lock); } -EXPORT_SYMBOL(_write_unlock_bh); +EXPORT_SYMBOL(_raw_write_unlock_bh); #endif #ifdef CONFIG_DEBUG_LOCK_ALLOC -void __lockfunc _spin_lock_nested(raw_spinlock_t *lock, int subclass) +void __lockfunc _raw_spin_lock_nested(raw_spinlock_t *lock, int subclass) { preempt_disable(); spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } -EXPORT_SYMBOL(_spin_lock_nested); +EXPORT_SYMBOL(_raw_spin_lock_nested); -unsigned long __lockfunc _spin_lock_irqsave_nested(raw_spinlock_t *lock, +unsigned long __lockfunc _raw_spin_lock_irqsave_nested(raw_spinlock_t *lock, int subclass) { unsigned long flags; @@ -361,16 +361,16 @@ unsigned long __lockfunc _spin_lock_irqsave_nested(raw_spinlock_t *lock, do_raw_spin_lock_flags, &flags); return flags; } -EXPORT_SYMBOL(_spin_lock_irqsave_nested); +EXPORT_SYMBOL(_raw_spin_lock_irqsave_nested); -void __lockfunc _spin_lock_nest_lock(raw_spinlock_t *lock, +void __lockfunc _raw_spin_lock_nest_lock(raw_spinlock_t *lock, struct lockdep_map *nest_lock) { preempt_disable(); spin_acquire_nest(&lock->dep_map, 0, 0, nest_lock, _RET_IP_); LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } -EXPORT_SYMBOL(_spin_lock_nest_lock); +EXPORT_SYMBOL(_raw_spin_lock_nest_lock); #endif -- cgit v0.10.2 From fa4062e7eae8f484c90b9cdd850b5df39ab0e5a0 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 17 Nov 2009 14:45:06 +0100 Subject: bkl: Fixup core_lock fallout kernel_lock.c emits a warning because a raw spinlock function is used with a spinlock. Convert BKL to raw_spinlock. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c index fdd23cd..b135d04a 100644 --- a/lib/kernel_lock.c +++ b/lib/kernel_lock.c @@ -23,7 +23,7 @@ * * Don't use in new code. */ -static __cacheline_aligned_in_smp DEFINE_SPINLOCK(kernel_flag); +static __cacheline_aligned_in_smp DEFINE_RAW_SPINLOCK(kernel_flag); /* @@ -82,7 +82,7 @@ static inline void __lock_kernel(void) */ do { preempt_enable(); - while (spin_is_locked(&kernel_flag)) + while (raw_spin_is_locked(&kernel_flag)) cpu_relax(); preempt_disable(); } while (!do_raw_spin_trylock(&kernel_flag)); -- cgit v0.10.2 From a26724591edba5acc528d41f3906a972590e8f54 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 17 Nov 2009 14:46:14 +0100 Subject: plist: Make plist debugging raw_spinlock aware plists are used with spinlocks and raw_spinlocks. Change the plist debugging to handle both types. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/include/linux/plist.h b/include/linux/plist.h index 45926d7..8227f71 100644 --- a/include/linux/plist.h +++ b/include/linux/plist.h @@ -81,7 +81,8 @@ struct plist_head { struct list_head prio_list; struct list_head node_list; #ifdef CONFIG_DEBUG_PI_LIST - spinlock_t *lock; + raw_spinlock_t *rawlock; + spinlock_t *spinlock; #endif }; @@ -91,9 +92,11 @@ struct plist_node { }; #ifdef CONFIG_DEBUG_PI_LIST -# define PLIST_HEAD_LOCK_INIT(_lock) .lock = _lock +# define PLIST_HEAD_LOCK_INIT(_lock) .spinlock = _lock +# define PLIST_HEAD_LOCK_INIT_RAW(_lock) .rawlock = _lock #else # define PLIST_HEAD_LOCK_INIT(_lock) +# define PLIST_HEAD_LOCK_INIT_RAW(_lock) #endif #define _PLIST_HEAD_INIT(head) \ @@ -107,11 +110,22 @@ struct plist_node { */ #define PLIST_HEAD_INIT(head, _lock) \ { \ - _PLIST_HEAD_INIT(head), \ + _PLIST_HEAD_INIT(head), \ PLIST_HEAD_LOCK_INIT(&(_lock)) \ } /** + * PLIST_HEAD_INIT_RAW - static struct plist_head initializer + * @head: struct plist_head variable name + * @_lock: lock to initialize for this list + */ +#define PLIST_HEAD_INIT_RAW(head, _lock) \ +{ \ + _PLIST_HEAD_INIT(head), \ + PLIST_HEAD_LOCK_INIT_RAW(&(_lock)) \ +} + +/** * PLIST_NODE_INIT - static struct plist_node initializer * @node: struct plist_node variable name * @__prio: initial node priority @@ -119,13 +133,13 @@ struct plist_node { #define PLIST_NODE_INIT(node, __prio) \ { \ .prio = (__prio), \ - .plist = { _PLIST_HEAD_INIT((node).plist) }, \ + .plist = { _PLIST_HEAD_INIT((node).plist) }, \ } /** * plist_head_init - dynamic struct plist_head initializer * @head: &struct plist_head pointer - * @lock: list spinlock, remembered for debugging + * @lock: spinlock protecting the list (debugging) */ static inline void plist_head_init(struct plist_head *head, spinlock_t *lock) @@ -133,7 +147,24 @@ plist_head_init(struct plist_head *head, spinlock_t *lock) INIT_LIST_HEAD(&head->prio_list); INIT_LIST_HEAD(&head->node_list); #ifdef CONFIG_DEBUG_PI_LIST - head->lock = lock; + head->spinlock = lock; + head->rawlock = NULL; +#endif +} + +/** + * plist_head_init_raw - dynamic struct plist_head initializer + * @head: &struct plist_head pointer + * @lock: raw_spinlock protecting the list (debugging) + */ +static inline void +plist_head_init_raw(struct plist_head *head, raw_spinlock_t *lock) +{ + INIT_LIST_HEAD(&head->prio_list); + INIT_LIST_HEAD(&head->node_list); +#ifdef CONFIG_DEBUG_PI_LIST + head->rawlock = lock; + head->spinlock = NULL; #endif } diff --git a/kernel/futex.c b/kernel/futex.c index d73ef1f..6af474d 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -1010,7 +1010,7 @@ void requeue_futex(struct futex_q *q, struct futex_hash_bucket *hb1, plist_add(&q->list, &hb2->chain); q->lock_ptr = &hb2->lock; #ifdef CONFIG_DEBUG_PI_LIST - q->list.plist.lock = &hb2->lock; + q->list.plist.spinlock = &hb2->lock; #endif } get_futex_key_refs(key2); @@ -1046,7 +1046,7 @@ void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key, q->lock_ptr = &hb->lock; #ifdef CONFIG_DEBUG_PI_LIST - q->list.plist.lock = &hb->lock; + q->list.plist.spinlock = &hb->lock; #endif wake_up_state(q->task, TASK_NORMAL); @@ -1394,7 +1394,7 @@ static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb) plist_node_init(&q->list, prio); #ifdef CONFIG_DEBUG_PI_LIST - q->list.plist.lock = &hb->lock; + q->list.plist.spinlock = &hb->lock; #endif plist_add(&q->list, &hb->chain); q->task = current; diff --git a/lib/plist.c b/lib/plist.c index d6c64a8..1471988 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -54,9 +54,11 @@ static void plist_check_list(struct list_head *top) static void plist_check_head(struct plist_head *head) { - WARN_ON(!head->lock); - if (head->lock) - WARN_ON_SMP(!spin_is_locked(head->lock)); + WARN_ON(!head->rawlock && !head->spinlock); + if (head->rawlock) + WARN_ON_SMP(!raw_spin_is_locked(head->rawlock)); + if (head->spinlock) + WARN_ON_SMP(!spin_is_locked(head->spinlock)); plist_check_list(&head->prio_list); plist_check_list(&head->node_list); } -- cgit v0.10.2 From 05fa785cf80c9b7c0254c3056037147aed3ea16b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 17 Nov 2009 14:28:38 +0100 Subject: sched: Convert rq->lock to raw_spinlock Convert locks which cannot be sleeping locks in preempt-rt to raw_spinlocks. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 91c65dd..3dbe617 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -525,7 +525,7 @@ static struct root_domain def_root_domain; */ struct rq { /* runqueue lock: */ - spinlock_t lock; + raw_spinlock_t lock; /* * nr_running and cpu_load should be in the same cacheline because @@ -685,7 +685,7 @@ inline void update_rq_clock(struct rq *rq) */ int runqueue_is_locked(int cpu) { - return spin_is_locked(&cpu_rq(cpu)->lock); + return raw_spin_is_locked(&cpu_rq(cpu)->lock); } /* @@ -884,7 +884,7 @@ static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev) { #ifdef CONFIG_DEBUG_SPINLOCK /* this is a valid case when another task releases the spinlock */ - rq->lock.rlock.owner = current; + rq->lock.owner = current; #endif /* * If we are tracking spinlock dependencies then we have to @@ -893,7 +893,7 @@ static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev) */ spin_acquire(&rq->lock.dep_map, 0, 0, _THIS_IP_); - spin_unlock_irq(&rq->lock); + raw_spin_unlock_irq(&rq->lock); } #else /* __ARCH_WANT_UNLOCKED_CTXSW */ @@ -917,9 +917,9 @@ static inline void prepare_lock_switch(struct rq *rq, struct task_struct *next) next->oncpu = 1; #endif #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW - spin_unlock_irq(&rq->lock); + raw_spin_unlock_irq(&rq->lock); #else - spin_unlock(&rq->lock); + raw_spin_unlock(&rq->lock); #endif } @@ -949,10 +949,10 @@ static inline struct rq *__task_rq_lock(struct task_struct *p) { for (;;) { struct rq *rq = task_rq(p); - spin_lock(&rq->lock); + raw_spin_lock(&rq->lock); if (likely(rq == task_rq(p))) return rq; - spin_unlock(&rq->lock); + raw_spin_unlock(&rq->lock); } } @@ -969,10 +969,10 @@ static struct rq *task_rq_lock(struct task_struct *p, unsigned long *flags) for (;;) { local_irq_save(*flags); rq = task_rq(p); - spin_lock(&rq->lock); + raw_spin_lock(&rq->lock); if (likely(rq == task_rq(p))) return rq; - spin_unlock_irqrestore(&rq->lock, *flags); + raw_spin_unlock_irqrestore(&rq->lock, *flags); } } @@ -981,19 +981,19 @@ void task_rq_unlock_wait(struct task_struct *p) struct rq *rq = task_rq(p); smp_mb(); /* spin-unlock-wait is not a full memory barrier */ - spin_unlock_wait(&rq->lock); + raw_spin_unlock_wait(&rq->lock); } static void __task_rq_unlock(struct rq *rq) __releases(rq->lock) { - spin_unlock(&rq->lock); + raw_spin_unlock(&rq->lock); } static inline void task_rq_unlock(struct rq *rq, unsigned long *flags) __releases(rq->lock) { - spin_unlock_irqrestore(&rq->lock, *flags); + raw_spin_unlock_irqrestore(&rq->lock, *flags); } /* @@ -1006,7 +1006,7 @@ static struct rq *this_rq_lock(void) local_irq_disable(); rq = this_rq(); - spin_lock(&rq->lock); + raw_spin_lock(&rq->lock); return rq; } @@ -1053,10 +1053,10 @@ static enum hrtimer_restart hrtick(struct hrtimer *timer) WARN_ON_ONCE(cpu_of(rq) != smp_processor_id()); - spin_lock(&rq->lock); + raw_spin_lock(&rq->lock); update_rq_clock(rq); rq->curr->sched_class->task_tick(rq, rq->curr, 1); - spin_unlock(&rq->lock); + raw_spin_unlock(&rq->lock); return HRTIMER_NORESTART; } @@ -1069,10 +1069,10 @@ static void __hrtick_start(void *arg) { struct rq *rq = arg; - spin_lock(&rq->lock); + raw_spin_lock(&rq->lock); hrtimer_restart(&rq->hrtick_timer); rq->hrtick_csd_pending = 0; - spin_unlock(&rq->lock); + raw_spin_unlock(&rq->lock); } /* @@ -1179,7 +1179,7 @@ static void resched_task(struct task_struct *p) { int cpu; - assert_spin_locked(&task_rq(p)->lock); + assert_raw_spin_locked(&task_rq(p)->lock); if (test_tsk_need_resched(p)) return; @@ -1201,10 +1201,10 @@ static void resched_cpu(int cpu) struct rq *rq = cpu_rq(cpu); unsigned long flags; - if (!spin_trylock_irqsave(&rq->lock, flags)) + if (!raw_spin_trylock_irqsave(&rq->lock, flags)) return; resched_task(cpu_curr(cpu)); - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); } #ifdef CONFIG_NO_HZ @@ -1273,7 +1273,7 @@ static void sched_rt_avg_update(struct rq *rq, u64 rt_delta) #else /* !CONFIG_SMP */ static void resched_task(struct task_struct *p) { - assert_spin_locked(&task_rq(p)->lock); + assert_raw_spin_locked(&task_rq(p)->lock); set_tsk_need_resched(p); } @@ -1600,11 +1600,11 @@ static void update_group_shares_cpu(struct task_group *tg, int cpu, struct rq *rq = cpu_rq(cpu); unsigned long flags; - spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock_irqsave(&rq->lock, flags); tg->cfs_rq[cpu]->rq_weight = boost ? 0 : rq_weight; tg->cfs_rq[cpu]->shares = boost ? 0 : shares; __set_se_shares(tg->se[cpu], shares); - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); } } @@ -1706,9 +1706,9 @@ static void update_shares_locked(struct rq *rq, struct sched_domain *sd) if (root_task_group_empty()) return; - spin_unlock(&rq->lock); + raw_spin_unlock(&rq->lock); update_shares(sd); - spin_lock(&rq->lock); + raw_spin_lock(&rq->lock); } static void update_h_load(long cpu) @@ -1748,7 +1748,7 @@ static inline int _double_lock_balance(struct rq *this_rq, struct rq *busiest) __acquires(busiest->lock) __acquires(this_rq->lock) { - spin_unlock(&this_rq->lock); + raw_spin_unlock(&this_rq->lock); double_rq_lock(this_rq, busiest); return 1; @@ -1769,14 +1769,16 @@ static int _double_lock_balance(struct rq *this_rq, struct rq *busiest) { int ret = 0; - if (unlikely(!spin_trylock(&busiest->lock))) { + if (unlikely(!raw_spin_trylock(&busiest->lock))) { if (busiest < this_rq) { - spin_unlock(&this_rq->lock); - spin_lock(&busiest->lock); - spin_lock_nested(&this_rq->lock, SINGLE_DEPTH_NESTING); + raw_spin_unlock(&this_rq->lock); + raw_spin_lock(&busiest->lock); + raw_spin_lock_nested(&this_rq->lock, + SINGLE_DEPTH_NESTING); ret = 1; } else - spin_lock_nested(&busiest->lock, SINGLE_DEPTH_NESTING); + raw_spin_lock_nested(&busiest->lock, + SINGLE_DEPTH_NESTING); } return ret; } @@ -1790,7 +1792,7 @@ static int double_lock_balance(struct rq *this_rq, struct rq *busiest) { if (unlikely(!irqs_disabled())) { /* printk() doesn't work good under rq->lock */ - spin_unlock(&this_rq->lock); + raw_spin_unlock(&this_rq->lock); BUG_ON(1); } @@ -1800,7 +1802,7 @@ static int double_lock_balance(struct rq *this_rq, struct rq *busiest) static inline void double_unlock_balance(struct rq *this_rq, struct rq *busiest) __releases(busiest->lock) { - spin_unlock(&busiest->lock); + raw_spin_unlock(&busiest->lock); lock_set_subclass(&this_rq->lock.dep_map, 0, _RET_IP_); } #endif @@ -2023,13 +2025,13 @@ void kthread_bind(struct task_struct *p, unsigned int cpu) return; } - spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock_irqsave(&rq->lock, flags); update_rq_clock(rq); set_task_cpu(p, cpu); p->cpus_allowed = cpumask_of_cpu(cpu); p->rt.nr_cpus_allowed = 1; p->flags |= PF_THREAD_BOUND; - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); } EXPORT_SYMBOL(kthread_bind); @@ -2781,10 +2783,10 @@ static inline void post_schedule(struct rq *rq) if (rq->post_schedule) { unsigned long flags; - spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock_irqsave(&rq->lock, flags); if (rq->curr->sched_class->post_schedule) rq->curr->sched_class->post_schedule(rq); - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); rq->post_schedule = 0; } @@ -3066,15 +3068,15 @@ static void double_rq_lock(struct rq *rq1, struct rq *rq2) { BUG_ON(!irqs_disabled()); if (rq1 == rq2) { - spin_lock(&rq1->lock); + raw_spin_lock(&rq1->lock); __acquire(rq2->lock); /* Fake it out ;) */ } else { if (rq1 < rq2) { - spin_lock(&rq1->lock); - spin_lock_nested(&rq2->lock, SINGLE_DEPTH_NESTING); + raw_spin_lock(&rq1->lock); + raw_spin_lock_nested(&rq2->lock, SINGLE_DEPTH_NESTING); } else { - spin_lock(&rq2->lock); - spin_lock_nested(&rq1->lock, SINGLE_DEPTH_NESTING); + raw_spin_lock(&rq2->lock); + raw_spin_lock_nested(&rq1->lock, SINGLE_DEPTH_NESTING); } } update_rq_clock(rq1); @@ -3091,9 +3093,9 @@ static void double_rq_unlock(struct rq *rq1, struct rq *rq2) __releases(rq1->lock) __releases(rq2->lock) { - spin_unlock(&rq1->lock); + raw_spin_unlock(&rq1->lock); if (rq1 != rq2) - spin_unlock(&rq2->lock); + raw_spin_unlock(&rq2->lock); else __release(rq2->lock); } @@ -4186,14 +4188,15 @@ redo: if (unlikely(sd->nr_balance_failed > sd->cache_nice_tries+2)) { - spin_lock_irqsave(&busiest->lock, flags); + raw_spin_lock_irqsave(&busiest->lock, flags); /* don't kick the migration_thread, if the curr * task on busiest cpu can't be moved to this_cpu */ if (!cpumask_test_cpu(this_cpu, &busiest->curr->cpus_allowed)) { - spin_unlock_irqrestore(&busiest->lock, flags); + raw_spin_unlock_irqrestore(&busiest->lock, + flags); all_pinned = 1; goto out_one_pinned; } @@ -4203,7 +4206,7 @@ redo: busiest->push_cpu = this_cpu; active_balance = 1; } - spin_unlock_irqrestore(&busiest->lock, flags); + raw_spin_unlock_irqrestore(&busiest->lock, flags); if (active_balance) wake_up_process(busiest->migration_thread); @@ -4385,10 +4388,10 @@ redo: /* * Should not call ttwu while holding a rq->lock */ - spin_unlock(&this_rq->lock); + raw_spin_unlock(&this_rq->lock); if (active_balance) wake_up_process(busiest->migration_thread); - spin_lock(&this_rq->lock); + raw_spin_lock(&this_rq->lock); } else sd->nr_balance_failed = 0; @@ -5257,11 +5260,11 @@ void scheduler_tick(void) sched_clock_tick(); - spin_lock(&rq->lock); + raw_spin_lock(&rq->lock); update_rq_clock(rq); update_cpu_load(rq); curr->sched_class->task_tick(rq, curr, 0); - spin_unlock(&rq->lock); + raw_spin_unlock(&rq->lock); perf_event_task_tick(curr, cpu); @@ -5455,7 +5458,7 @@ need_resched_nonpreemptible: if (sched_feat(HRTICK)) hrtick_clear(rq); - spin_lock_irq(&rq->lock); + raw_spin_lock_irq(&rq->lock); update_rq_clock(rq); clear_tsk_need_resched(prev); @@ -5491,7 +5494,7 @@ need_resched_nonpreemptible: cpu = smp_processor_id(); rq = cpu_rq(cpu); } else - spin_unlock_irq(&rq->lock); + raw_spin_unlock_irq(&rq->lock); post_schedule(rq); @@ -6980,7 +6983,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) struct rq *rq = cpu_rq(cpu); unsigned long flags; - spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock_irqsave(&rq->lock, flags); __sched_fork(idle); idle->se.exec_start = sched_clock(); @@ -6992,7 +6995,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) #if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) idle->oncpu = 1; #endif - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); /* Set the preempt count _outside_ the spinlocks! */ #if defined(CONFIG_PREEMPT) @@ -7209,10 +7212,10 @@ static int migration_thread(void *data) struct migration_req *req; struct list_head *head; - spin_lock_irq(&rq->lock); + raw_spin_lock_irq(&rq->lock); if (cpu_is_offline(cpu)) { - spin_unlock_irq(&rq->lock); + raw_spin_unlock_irq(&rq->lock); break; } @@ -7224,7 +7227,7 @@ static int migration_thread(void *data) head = &rq->migration_queue; if (list_empty(head)) { - spin_unlock_irq(&rq->lock); + raw_spin_unlock_irq(&rq->lock); schedule(); set_current_state(TASK_INTERRUPTIBLE); continue; @@ -7233,14 +7236,14 @@ static int migration_thread(void *data) list_del_init(head->next); if (req->task != NULL) { - spin_unlock(&rq->lock); + raw_spin_unlock(&rq->lock); __migrate_task(req->task, cpu, req->dest_cpu); } else if (likely(cpu == (badcpu = smp_processor_id()))) { req->dest_cpu = RCU_MIGRATION_GOT_QS; - spin_unlock(&rq->lock); + raw_spin_unlock(&rq->lock); } else { req->dest_cpu = RCU_MIGRATION_MUST_SYNC; - spin_unlock(&rq->lock); + raw_spin_unlock(&rq->lock); WARN_ONCE(1, "migration_thread() on CPU %d, expected %d\n", badcpu, cpu); } local_irq_enable(); @@ -7363,14 +7366,14 @@ void sched_idle_next(void) * Strictly not necessary since rest of the CPUs are stopped by now * and interrupts disabled on the current cpu. */ - spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock_irqsave(&rq->lock, flags); __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1); update_rq_clock(rq); activate_task(rq, p, 0); - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); } /* @@ -7406,9 +7409,9 @@ static void migrate_dead(unsigned int dead_cpu, struct task_struct *p) * that's OK. No task can be added to this CPU, so iteration is * fine. */ - spin_unlock_irq(&rq->lock); + raw_spin_unlock_irq(&rq->lock); move_task_off_dead_cpu(dead_cpu, p); - spin_lock_irq(&rq->lock); + raw_spin_lock_irq(&rq->lock); put_task_struct(p); } @@ -7674,13 +7677,13 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) /* Update our root-domain */ rq = cpu_rq(cpu); - spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock_irqsave(&rq->lock, flags); if (rq->rd) { BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span)); set_rq_online(rq); } - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); break; #ifdef CONFIG_HOTPLUG_CPU @@ -7705,13 +7708,13 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) put_task_struct(rq->migration_thread); rq->migration_thread = NULL; /* Idle task back to normal (off runqueue, low prio) */ - spin_lock_irq(&rq->lock); + raw_spin_lock_irq(&rq->lock); update_rq_clock(rq); deactivate_task(rq, rq->idle, 0); __setscheduler(rq, rq->idle, SCHED_NORMAL, 0); rq->idle->sched_class = &idle_sched_class; migrate_dead_tasks(cpu); - spin_unlock_irq(&rq->lock); + raw_spin_unlock_irq(&rq->lock); cpuset_unlock(); migrate_nr_uninterruptible(rq); BUG_ON(rq->nr_running != 0); @@ -7721,30 +7724,30 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) * they didn't take sched_hotcpu_mutex. Just wake up * the requestors. */ - spin_lock_irq(&rq->lock); + raw_spin_lock_irq(&rq->lock); while (!list_empty(&rq->migration_queue)) { struct migration_req *req; req = list_entry(rq->migration_queue.next, struct migration_req, list); list_del_init(&req->list); - spin_unlock_irq(&rq->lock); + raw_spin_unlock_irq(&rq->lock); complete(&req->done); - spin_lock_irq(&rq->lock); + raw_spin_lock_irq(&rq->lock); } - spin_unlock_irq(&rq->lock); + raw_spin_unlock_irq(&rq->lock); break; case CPU_DYING: case CPU_DYING_FROZEN: /* Update our root-domain */ rq = cpu_rq(cpu); - spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock_irqsave(&rq->lock, flags); if (rq->rd) { BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span)); set_rq_offline(rq); } - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); break; #endif } @@ -7974,7 +7977,7 @@ static void rq_attach_root(struct rq *rq, struct root_domain *rd) struct root_domain *old_rd = NULL; unsigned long flags; - spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock_irqsave(&rq->lock, flags); if (rq->rd) { old_rd = rq->rd; @@ -8000,7 +8003,7 @@ static void rq_attach_root(struct rq *rq, struct root_domain *rd) if (cpumask_test_cpu(rq->cpu, cpu_active_mask)) set_rq_online(rq); - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); if (old_rd) free_rootdomain(old_rd); @@ -9357,7 +9360,7 @@ static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq) #ifdef CONFIG_SMP rt_rq->rt_nr_migratory = 0; rt_rq->overloaded = 0; - plist_head_init(&rt_rq->pushable_tasks, &rq->lock); + plist_head_init_raw(&rt_rq->pushable_tasks, &rq->lock); #endif rt_rq->rt_time = 0; @@ -9523,7 +9526,7 @@ void __init sched_init(void) struct rq *rq; rq = cpu_rq(i); - spin_lock_init(&rq->lock); + raw_spin_lock_init(&rq->lock); rq->nr_running = 0; rq->calc_load_active = 0; rq->calc_load_update = jiffies + LOAD_FREQ; @@ -10115,9 +10118,9 @@ static void set_se_shares(struct sched_entity *se, unsigned long shares) struct rq *rq = cfs_rq->rq; unsigned long flags; - spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock_irqsave(&rq->lock, flags); __set_se_shares(se, shares); - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); } static DEFINE_MUTEX(shares_mutex); @@ -10717,9 +10720,9 @@ static u64 cpuacct_cpuusage_read(struct cpuacct *ca, int cpu) /* * Take rq->lock to make 64-bit read safe on 32-bit platforms. */ - spin_lock_irq(&cpu_rq(cpu)->lock); + raw_spin_lock_irq(&cpu_rq(cpu)->lock); data = *cpuusage; - spin_unlock_irq(&cpu_rq(cpu)->lock); + raw_spin_unlock_irq(&cpu_rq(cpu)->lock); #else data = *cpuusage; #endif @@ -10735,9 +10738,9 @@ static void cpuacct_cpuusage_write(struct cpuacct *ca, int cpu, u64 val) /* * Take rq->lock to make 64-bit write safe on 32-bit platforms. */ - spin_lock_irq(&cpu_rq(cpu)->lock); + raw_spin_lock_irq(&cpu_rq(cpu)->lock); *cpuusage = val; - spin_unlock_irq(&cpu_rq(cpu)->lock); + raw_spin_unlock_irq(&cpu_rq(cpu)->lock); #else *cpuusage = val; #endif @@ -10971,9 +10974,9 @@ void synchronize_sched_expedited(void) init_completion(&req->done); req->task = NULL; req->dest_cpu = RCU_MIGRATION_NEED_QS; - spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock_irqsave(&rq->lock, flags); list_add(&req->list, &rq->migration_queue); - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); wake_up_process(rq->migration_thread); } for_each_online_cpu(cpu) { @@ -10981,11 +10984,11 @@ void synchronize_sched_expedited(void) req = &per_cpu(rcu_migration_req, cpu); rq = cpu_rq(cpu); wait_for_completion(&req->done); - spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock_irqsave(&rq->lock, flags); if (unlikely(req->dest_cpu == RCU_MIGRATION_MUST_SYNC)) need_full_sync = 1; req->dest_cpu = RCU_MIGRATION_IDLE; - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); } rcu_expedited_state = RCU_EXPEDITED_STATE_IDLE; synchronize_sched_expedited_count++; diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c index 5ae24fc..67f95aa 100644 --- a/kernel/sched_debug.c +++ b/kernel/sched_debug.c @@ -184,7 +184,7 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) SEQ_printf(m, " .%-30s: %Ld.%06ld\n", "exec_clock", SPLIT_NS(cfs_rq->exec_clock)); - spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock_irqsave(&rq->lock, flags); if (cfs_rq->rb_leftmost) MIN_vruntime = (__pick_next_entity(cfs_rq))->vruntime; last = __pick_last_entity(cfs_rq); @@ -192,7 +192,7 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) max_vruntime = last->vruntime; min_vruntime = cfs_rq->min_vruntime; rq0_min_vruntime = cpu_rq(0)->cfs.min_vruntime; - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); SEQ_printf(m, " .%-30s: %Ld.%06ld\n", "MIN_vruntime", SPLIT_NS(MIN_vruntime)); SEQ_printf(m, " .%-30s: %Ld.%06ld\n", "min_vruntime", diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 804a411..5bedf6e 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -1955,7 +1955,7 @@ static void task_fork_fair(struct task_struct *p) struct rq *rq = this_rq(); unsigned long flags; - spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock_irqsave(&rq->lock, flags); if (unlikely(task_cpu(p) != this_cpu)) __set_task_cpu(p, this_cpu); @@ -1975,7 +1975,7 @@ static void task_fork_fair(struct task_struct *p) resched_task(rq->curr); } - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); } /* diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c index 33d5384..5f93b57 100644 --- a/kernel/sched_idletask.c +++ b/kernel/sched_idletask.c @@ -34,10 +34,10 @@ static struct task_struct *pick_next_task_idle(struct rq *rq) static void dequeue_task_idle(struct rq *rq, struct task_struct *p, int sleep) { - spin_unlock_irq(&rq->lock); + raw_spin_unlock_irq(&rq->lock); printk(KERN_ERR "bad: scheduling from the idle thread!\n"); dump_stack(); - spin_lock_irq(&rq->lock); + raw_spin_lock_irq(&rq->lock); } static void put_prev_task_idle(struct rq *rq, struct task_struct *prev) diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index aecbd9c..a8325a7 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -454,9 +454,9 @@ static void disable_runtime(struct rq *rq) { unsigned long flags; - spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock_irqsave(&rq->lock, flags); __disable_runtime(rq); - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); } static void __enable_runtime(struct rq *rq) @@ -486,9 +486,9 @@ static void enable_runtime(struct rq *rq) { unsigned long flags; - spin_lock_irqsave(&rq->lock, flags); + raw_spin_lock_irqsave(&rq->lock, flags); __enable_runtime(rq); - spin_unlock_irqrestore(&rq->lock, flags); + raw_spin_unlock_irqrestore(&rq->lock, flags); } static int balance_runtime(struct rt_rq *rt_rq) @@ -524,7 +524,7 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun) struct rt_rq *rt_rq = sched_rt_period_rt_rq(rt_b, i); struct rq *rq = rq_of_rt_rq(rt_rq); - spin_lock(&rq->lock); + raw_spin_lock(&rq->lock); if (rt_rq->rt_time) { u64 runtime; @@ -545,7 +545,7 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun) if (enqueue) sched_rt_rq_enqueue(rt_rq); - spin_unlock(&rq->lock); + raw_spin_unlock(&rq->lock); } return idle; @@ -1246,7 +1246,7 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq) task_running(rq, task) || !task->se.on_rq)) { - spin_unlock(&lowest_rq->lock); + raw_spin_unlock(&lowest_rq->lock); lowest_rq = NULL; break; } -- cgit v0.10.2 From 0986b11b12ad2baed338385f79fd0dec58a23fc6 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 17 Nov 2009 15:32:06 +0100 Subject: sched: Convert rt_runtime_lock to raw_spinlock Convert locks which cannot be sleeping locks in preempt-rt to raw_spinlocks. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 3dbe617..01c5016 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -141,7 +141,7 @@ struct rt_prio_array { struct rt_bandwidth { /* nests inside the rq lock: */ - spinlock_t rt_runtime_lock; + raw_spinlock_t rt_runtime_lock; ktime_t rt_period; u64 rt_runtime; struct hrtimer rt_period_timer; @@ -178,7 +178,7 @@ void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime) rt_b->rt_period = ns_to_ktime(period); rt_b->rt_runtime = runtime; - spin_lock_init(&rt_b->rt_runtime_lock); + raw_spin_lock_init(&rt_b->rt_runtime_lock); hrtimer_init(&rt_b->rt_period_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); @@ -200,7 +200,7 @@ static void start_rt_bandwidth(struct rt_bandwidth *rt_b) if (hrtimer_active(&rt_b->rt_period_timer)) return; - spin_lock(&rt_b->rt_runtime_lock); + raw_spin_lock(&rt_b->rt_runtime_lock); for (;;) { unsigned long delta; ktime_t soft, hard; @@ -217,7 +217,7 @@ static void start_rt_bandwidth(struct rt_bandwidth *rt_b) __hrtimer_start_range_ns(&rt_b->rt_period_timer, soft, delta, HRTIMER_MODE_ABS_PINNED, 0); } - spin_unlock(&rt_b->rt_runtime_lock); + raw_spin_unlock(&rt_b->rt_runtime_lock); } #ifdef CONFIG_RT_GROUP_SCHED @@ -470,7 +470,7 @@ struct rt_rq { u64 rt_time; u64 rt_runtime; /* Nests inside the rq lock: */ - spinlock_t rt_runtime_lock; + raw_spinlock_t rt_runtime_lock; #ifdef CONFIG_RT_GROUP_SCHED unsigned long rt_nr_boosted; @@ -9366,7 +9366,7 @@ static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq) rt_rq->rt_time = 0; rt_rq->rt_throttled = 0; rt_rq->rt_runtime = 0; - spin_lock_init(&rt_rq->rt_runtime_lock); + raw_spin_lock_init(&rt_rq->rt_runtime_lock); #ifdef CONFIG_RT_GROUP_SCHED rt_rq->rt_nr_boosted = 0; @@ -10305,18 +10305,18 @@ static int tg_set_bandwidth(struct task_group *tg, if (err) goto unlock; - spin_lock_irq(&tg->rt_bandwidth.rt_runtime_lock); + raw_spin_lock_irq(&tg->rt_bandwidth.rt_runtime_lock); tg->rt_bandwidth.rt_period = ns_to_ktime(rt_period); tg->rt_bandwidth.rt_runtime = rt_runtime; for_each_possible_cpu(i) { struct rt_rq *rt_rq = tg->rt_rq[i]; - spin_lock(&rt_rq->rt_runtime_lock); + raw_spin_lock(&rt_rq->rt_runtime_lock); rt_rq->rt_runtime = rt_runtime; - spin_unlock(&rt_rq->rt_runtime_lock); + raw_spin_unlock(&rt_rq->rt_runtime_lock); } - spin_unlock_irq(&tg->rt_bandwidth.rt_runtime_lock); + raw_spin_unlock_irq(&tg->rt_bandwidth.rt_runtime_lock); unlock: read_unlock(&tasklist_lock); mutex_unlock(&rt_constraints_mutex); @@ -10421,15 +10421,15 @@ static int sched_rt_global_constraints(void) if (sysctl_sched_rt_runtime == 0) return -EBUSY; - spin_lock_irqsave(&def_rt_bandwidth.rt_runtime_lock, flags); + raw_spin_lock_irqsave(&def_rt_bandwidth.rt_runtime_lock, flags); for_each_possible_cpu(i) { struct rt_rq *rt_rq = &cpu_rq(i)->rt; - spin_lock(&rt_rq->rt_runtime_lock); + raw_spin_lock(&rt_rq->rt_runtime_lock); rt_rq->rt_runtime = global_rt_runtime(); - spin_unlock(&rt_rq->rt_runtime_lock); + raw_spin_unlock(&rt_rq->rt_runtime_lock); } - spin_unlock_irqrestore(&def_rt_bandwidth.rt_runtime_lock, flags); + raw_spin_unlock_irqrestore(&def_rt_bandwidth.rt_runtime_lock, flags); return 0; } diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index a8325a7..d2ea282 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -327,7 +327,7 @@ static int do_balance_runtime(struct rt_rq *rt_rq) weight = cpumask_weight(rd->span); - spin_lock(&rt_b->rt_runtime_lock); + raw_spin_lock(&rt_b->rt_runtime_lock); rt_period = ktime_to_ns(rt_b->rt_period); for_each_cpu(i, rd->span) { struct rt_rq *iter = sched_rt_period_rt_rq(rt_b, i); @@ -336,7 +336,7 @@ static int do_balance_runtime(struct rt_rq *rt_rq) if (iter == rt_rq) continue; - spin_lock(&iter->rt_runtime_lock); + raw_spin_lock(&iter->rt_runtime_lock); /* * Either all rqs have inf runtime and there's nothing to steal * or __disable_runtime() below sets a specific rq to inf to @@ -358,14 +358,14 @@ static int do_balance_runtime(struct rt_rq *rt_rq) rt_rq->rt_runtime += diff; more = 1; if (rt_rq->rt_runtime == rt_period) { - spin_unlock(&iter->rt_runtime_lock); + raw_spin_unlock(&iter->rt_runtime_lock); break; } } next: - spin_unlock(&iter->rt_runtime_lock); + raw_spin_unlock(&iter->rt_runtime_lock); } - spin_unlock(&rt_b->rt_runtime_lock); + raw_spin_unlock(&rt_b->rt_runtime_lock); return more; } @@ -386,8 +386,8 @@ static void __disable_runtime(struct rq *rq) s64 want; int i; - spin_lock(&rt_b->rt_runtime_lock); - spin_lock(&rt_rq->rt_runtime_lock); + raw_spin_lock(&rt_b->rt_runtime_lock); + raw_spin_lock(&rt_rq->rt_runtime_lock); /* * Either we're all inf and nobody needs to borrow, or we're * already disabled and thus have nothing to do, or we have @@ -396,7 +396,7 @@ static void __disable_runtime(struct rq *rq) if (rt_rq->rt_runtime == RUNTIME_INF || rt_rq->rt_runtime == rt_b->rt_runtime) goto balanced; - spin_unlock(&rt_rq->rt_runtime_lock); + raw_spin_unlock(&rt_rq->rt_runtime_lock); /* * Calculate the difference between what we started out with @@ -418,7 +418,7 @@ static void __disable_runtime(struct rq *rq) if (iter == rt_rq || iter->rt_runtime == RUNTIME_INF) continue; - spin_lock(&iter->rt_runtime_lock); + raw_spin_lock(&iter->rt_runtime_lock); if (want > 0) { diff = min_t(s64, iter->rt_runtime, want); iter->rt_runtime -= diff; @@ -427,13 +427,13 @@ static void __disable_runtime(struct rq *rq) iter->rt_runtime -= want; want -= want; } - spin_unlock(&iter->rt_runtime_lock); + raw_spin_unlock(&iter->rt_runtime_lock); if (!want) break; } - spin_lock(&rt_rq->rt_runtime_lock); + raw_spin_lock(&rt_rq->rt_runtime_lock); /* * We cannot be left wanting - that would mean some runtime * leaked out of the system. @@ -445,8 +445,8 @@ balanced: * runtime - in which case borrowing doesn't make sense. */ rt_rq->rt_runtime = RUNTIME_INF; - spin_unlock(&rt_rq->rt_runtime_lock); - spin_unlock(&rt_b->rt_runtime_lock); + raw_spin_unlock(&rt_rq->rt_runtime_lock); + raw_spin_unlock(&rt_b->rt_runtime_lock); } } @@ -472,13 +472,13 @@ static void __enable_runtime(struct rq *rq) for_each_leaf_rt_rq(rt_rq, rq) { struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq); - spin_lock(&rt_b->rt_runtime_lock); - spin_lock(&rt_rq->rt_runtime_lock); + raw_spin_lock(&rt_b->rt_runtime_lock); + raw_spin_lock(&rt_rq->rt_runtime_lock); rt_rq->rt_runtime = rt_b->rt_runtime; rt_rq->rt_time = 0; rt_rq->rt_throttled = 0; - spin_unlock(&rt_rq->rt_runtime_lock); - spin_unlock(&rt_b->rt_runtime_lock); + raw_spin_unlock(&rt_rq->rt_runtime_lock); + raw_spin_unlock(&rt_b->rt_runtime_lock); } } @@ -496,9 +496,9 @@ static int balance_runtime(struct rt_rq *rt_rq) int more = 0; if (rt_rq->rt_time > rt_rq->rt_runtime) { - spin_unlock(&rt_rq->rt_runtime_lock); + raw_spin_unlock(&rt_rq->rt_runtime_lock); more = do_balance_runtime(rt_rq); - spin_lock(&rt_rq->rt_runtime_lock); + raw_spin_lock(&rt_rq->rt_runtime_lock); } return more; @@ -528,7 +528,7 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun) if (rt_rq->rt_time) { u64 runtime; - spin_lock(&rt_rq->rt_runtime_lock); + raw_spin_lock(&rt_rq->rt_runtime_lock); if (rt_rq->rt_throttled) balance_runtime(rt_rq); runtime = rt_rq->rt_runtime; @@ -539,7 +539,7 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun) } if (rt_rq->rt_time || rt_rq->rt_nr_running) idle = 0; - spin_unlock(&rt_rq->rt_runtime_lock); + raw_spin_unlock(&rt_rq->rt_runtime_lock); } else if (rt_rq->rt_nr_running) idle = 0; @@ -624,11 +624,11 @@ static void update_curr_rt(struct rq *rq) rt_rq = rt_rq_of_se(rt_se); if (sched_rt_runtime(rt_rq) != RUNTIME_INF) { - spin_lock(&rt_rq->rt_runtime_lock); + raw_spin_lock(&rt_rq->rt_runtime_lock); rt_rq->rt_time += delta_exec; if (sched_rt_runtime_exceeded(rt_rq)) resched_task(curr); - spin_unlock(&rt_rq->rt_runtime_lock); + raw_spin_unlock(&rt_rq->rt_runtime_lock); } } } -- cgit v0.10.2 From fe841226bd954fba4fd79f037a876053fe9c3217 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 17 Nov 2009 17:59:15 +0100 Subject: sched: Convert cpupri lock to raw_spinlock Convert locks which cannot be sleeping locks in preempt-rt to raw_spinlocks. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/kernel/sched_cpupri.c b/kernel/sched_cpupri.c index 0f052fc..597b330 100644 --- a/kernel/sched_cpupri.c +++ b/kernel/sched_cpupri.c @@ -135,26 +135,26 @@ void cpupri_set(struct cpupri *cp, int cpu, int newpri) if (likely(newpri != CPUPRI_INVALID)) { struct cpupri_vec *vec = &cp->pri_to_cpu[newpri]; - spin_lock_irqsave(&vec->lock, flags); + raw_spin_lock_irqsave(&vec->lock, flags); cpumask_set_cpu(cpu, vec->mask); vec->count++; if (vec->count == 1) set_bit(newpri, cp->pri_active); - spin_unlock_irqrestore(&vec->lock, flags); + raw_spin_unlock_irqrestore(&vec->lock, flags); } if (likely(oldpri != CPUPRI_INVALID)) { struct cpupri_vec *vec = &cp->pri_to_cpu[oldpri]; - spin_lock_irqsave(&vec->lock, flags); + raw_spin_lock_irqsave(&vec->lock, flags); vec->count--; if (!vec->count) clear_bit(oldpri, cp->pri_active); cpumask_clear_cpu(cpu, vec->mask); - spin_unlock_irqrestore(&vec->lock, flags); + raw_spin_unlock_irqrestore(&vec->lock, flags); } *currpri = newpri; @@ -180,7 +180,7 @@ int cpupri_init(struct cpupri *cp, bool bootmem) for (i = 0; i < CPUPRI_NR_PRIORITIES; i++) { struct cpupri_vec *vec = &cp->pri_to_cpu[i]; - spin_lock_init(&vec->lock); + raw_spin_lock_init(&vec->lock); vec->count = 0; if (!zalloc_cpumask_var(&vec->mask, gfp)) goto cleanup; diff --git a/kernel/sched_cpupri.h b/kernel/sched_cpupri.h index 9a7e859..7cb5bb6 100644 --- a/kernel/sched_cpupri.h +++ b/kernel/sched_cpupri.h @@ -12,7 +12,7 @@ /* values 2-101 are RT priorities 0-99 */ struct cpupri_vec { - spinlock_t lock; + raw_spinlock_t lock; int count; cpumask_var_t mask; }; -- cgit v0.10.2 From 1d615482547584b9a8bb6316a58fed6ce90dd9ff Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 17 Nov 2009 14:54:03 +0100 Subject: sched: Convert pi_lock to raw_spinlock Convert locks which cannot be sleeping locks in preempt-rt to raw_spinlocks. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 8d10aa7..abec69b 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -165,7 +165,7 @@ extern struct cred init_cred; .journal_info = NULL, \ .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ .fs_excl = ATOMIC_INIT(0), \ - .pi_lock = __SPIN_LOCK_UNLOCKED(tsk.pi_lock), \ + .pi_lock = __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock), \ .timer_slack_ns = 50000, /* 50 usec default slack */ \ .pids = { \ [PIDTYPE_PID] = INIT_PID_LINK(PIDTYPE_PID), \ diff --git a/include/linux/sched.h b/include/linux/sched.h index 294eb2f..41a9ea3 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1409,7 +1409,7 @@ struct task_struct { #endif /* Protection of the PI data structures: */ - spinlock_t pi_lock; + raw_spinlock_t pi_lock; #ifdef CONFIG_RT_MUTEXES /* PI waiters blocked on a rt_mutex held by this task */ diff --git a/kernel/exit.c b/kernel/exit.c index 6f50ef5..5962d7c 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -933,7 +933,7 @@ NORET_TYPE void do_exit(long code) * an exiting task cleaning up the robust pi futexes. */ smp_mb(); - spin_unlock_wait(&tsk->pi_lock); + raw_spin_unlock_wait(&tsk->pi_lock); if (unlikely(in_atomic())) printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n", diff --git a/kernel/fork.c b/kernel/fork.c index 1415dc4..9bd9144 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -939,9 +939,9 @@ SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr) static void rt_mutex_init_task(struct task_struct *p) { - spin_lock_init(&p->pi_lock); + raw_spin_lock_init(&p->pi_lock); #ifdef CONFIG_RT_MUTEXES - plist_head_init(&p->pi_waiters, &p->pi_lock); + plist_head_init_raw(&p->pi_waiters, &p->pi_lock); p->pi_blocked_on = NULL; #endif } diff --git a/kernel/futex.c b/kernel/futex.c index 6af474d..320b369 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -403,9 +403,9 @@ static void free_pi_state(struct futex_pi_state *pi_state) * and has cleaned up the pi_state already */ if (pi_state->owner) { - spin_lock_irq(&pi_state->owner->pi_lock); + raw_spin_lock_irq(&pi_state->owner->pi_lock); list_del_init(&pi_state->list); - spin_unlock_irq(&pi_state->owner->pi_lock); + raw_spin_unlock_irq(&pi_state->owner->pi_lock); rt_mutex_proxy_unlock(&pi_state->pi_mutex, pi_state->owner); } @@ -470,18 +470,18 @@ void exit_pi_state_list(struct task_struct *curr) * pi_state_list anymore, but we have to be careful * versus waiters unqueueing themselves: */ - spin_lock_irq(&curr->pi_lock); + raw_spin_lock_irq(&curr->pi_lock); while (!list_empty(head)) { next = head->next; pi_state = list_entry(next, struct futex_pi_state, list); key = pi_state->key; hb = hash_futex(&key); - spin_unlock_irq(&curr->pi_lock); + raw_spin_unlock_irq(&curr->pi_lock); spin_lock(&hb->lock); - spin_lock_irq(&curr->pi_lock); + raw_spin_lock_irq(&curr->pi_lock); /* * We dropped the pi-lock, so re-check whether this * task still owns the PI-state: @@ -495,15 +495,15 @@ void exit_pi_state_list(struct task_struct *curr) WARN_ON(list_empty(&pi_state->list)); list_del_init(&pi_state->list); pi_state->owner = NULL; - spin_unlock_irq(&curr->pi_lock); + raw_spin_unlock_irq(&curr->pi_lock); rt_mutex_unlock(&pi_state->pi_mutex); spin_unlock(&hb->lock); - spin_lock_irq(&curr->pi_lock); + raw_spin_lock_irq(&curr->pi_lock); } - spin_unlock_irq(&curr->pi_lock); + raw_spin_unlock_irq(&curr->pi_lock); } static int @@ -558,7 +558,7 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, * change of the task flags, we do this protected by * p->pi_lock: */ - spin_lock_irq(&p->pi_lock); + raw_spin_lock_irq(&p->pi_lock); if (unlikely(p->flags & PF_EXITING)) { /* * The task is on the way out. When PF_EXITPIDONE is @@ -567,7 +567,7 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, */ int ret = (p->flags & PF_EXITPIDONE) ? -ESRCH : -EAGAIN; - spin_unlock_irq(&p->pi_lock); + raw_spin_unlock_irq(&p->pi_lock); put_task_struct(p); return ret; } @@ -586,7 +586,7 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, WARN_ON(!list_empty(&pi_state->list)); list_add(&pi_state->list, &p->pi_state_list); pi_state->owner = p; - spin_unlock_irq(&p->pi_lock); + raw_spin_unlock_irq(&p->pi_lock); put_task_struct(p); @@ -794,16 +794,16 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) } } - spin_lock_irq(&pi_state->owner->pi_lock); + raw_spin_lock_irq(&pi_state->owner->pi_lock); WARN_ON(list_empty(&pi_state->list)); list_del_init(&pi_state->list); - spin_unlock_irq(&pi_state->owner->pi_lock); + raw_spin_unlock_irq(&pi_state->owner->pi_lock); - spin_lock_irq(&new_owner->pi_lock); + raw_spin_lock_irq(&new_owner->pi_lock); WARN_ON(!list_empty(&pi_state->list)); list_add(&pi_state->list, &new_owner->pi_state_list); pi_state->owner = new_owner; - spin_unlock_irq(&new_owner->pi_lock); + raw_spin_unlock_irq(&new_owner->pi_lock); spin_unlock(&pi_state->pi_mutex.wait_lock); rt_mutex_unlock(&pi_state->pi_mutex); @@ -1529,18 +1529,18 @@ retry: * itself. */ if (pi_state->owner != NULL) { - spin_lock_irq(&pi_state->owner->pi_lock); + raw_spin_lock_irq(&pi_state->owner->pi_lock); WARN_ON(list_empty(&pi_state->list)); list_del_init(&pi_state->list); - spin_unlock_irq(&pi_state->owner->pi_lock); + raw_spin_unlock_irq(&pi_state->owner->pi_lock); } pi_state->owner = newowner; - spin_lock_irq(&newowner->pi_lock); + raw_spin_lock_irq(&newowner->pi_lock); WARN_ON(!list_empty(&pi_state->list)); list_add(&pi_state->list, &newowner->pi_state_list); - spin_unlock_irq(&newowner->pi_lock); + raw_spin_unlock_irq(&newowner->pi_lock); return 0; /* diff --git a/kernel/rtmutex-debug.c b/kernel/rtmutex-debug.c index 5fcb4fe..ddabb54 100644 --- a/kernel/rtmutex-debug.c +++ b/kernel/rtmutex-debug.c @@ -37,8 +37,8 @@ do { \ if (rt_trace_on) { \ rt_trace_on = 0; \ console_verbose(); \ - if (spin_is_locked(¤t->pi_lock)) \ - spin_unlock(¤t->pi_lock); \ + if (raw_spin_is_locked(¤t->pi_lock)) \ + raw_spin_unlock(¤t->pi_lock); \ } \ } while (0) diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c index 29bd4ba..d33da47 100644 --- a/kernel/rtmutex.c +++ b/kernel/rtmutex.c @@ -138,9 +138,9 @@ static void rt_mutex_adjust_prio(struct task_struct *task) { unsigned long flags; - spin_lock_irqsave(&task->pi_lock, flags); + raw_spin_lock_irqsave(&task->pi_lock, flags); __rt_mutex_adjust_prio(task); - spin_unlock_irqrestore(&task->pi_lock, flags); + raw_spin_unlock_irqrestore(&task->pi_lock, flags); } /* @@ -195,7 +195,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, /* * Task can not go away as we did a get_task() before ! */ - spin_lock_irqsave(&task->pi_lock, flags); + raw_spin_lock_irqsave(&task->pi_lock, flags); waiter = task->pi_blocked_on; /* @@ -232,7 +232,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, lock = waiter->lock; if (!spin_trylock(&lock->wait_lock)) { - spin_unlock_irqrestore(&task->pi_lock, flags); + raw_spin_unlock_irqrestore(&task->pi_lock, flags); cpu_relax(); goto retry; } @@ -253,13 +253,13 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, plist_add(&waiter->list_entry, &lock->wait_list); /* Release the task */ - spin_unlock_irqrestore(&task->pi_lock, flags); + raw_spin_unlock_irqrestore(&task->pi_lock, flags); put_task_struct(task); /* Grab the next task */ task = rt_mutex_owner(lock); get_task_struct(task); - spin_lock_irqsave(&task->pi_lock, flags); + raw_spin_lock_irqsave(&task->pi_lock, flags); if (waiter == rt_mutex_top_waiter(lock)) { /* Boost the owner */ @@ -277,7 +277,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, __rt_mutex_adjust_prio(task); } - spin_unlock_irqrestore(&task->pi_lock, flags); + raw_spin_unlock_irqrestore(&task->pi_lock, flags); top_waiter = rt_mutex_top_waiter(lock); spin_unlock(&lock->wait_lock); @@ -288,7 +288,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, goto again; out_unlock_pi: - spin_unlock_irqrestore(&task->pi_lock, flags); + raw_spin_unlock_irqrestore(&task->pi_lock, flags); out_put_task: put_task_struct(task); @@ -313,9 +313,9 @@ static inline int try_to_steal_lock(struct rt_mutex *lock, if (pendowner == task) return 1; - spin_lock_irqsave(&pendowner->pi_lock, flags); + raw_spin_lock_irqsave(&pendowner->pi_lock, flags); if (task->prio >= pendowner->prio) { - spin_unlock_irqrestore(&pendowner->pi_lock, flags); + raw_spin_unlock_irqrestore(&pendowner->pi_lock, flags); return 0; } @@ -325,7 +325,7 @@ static inline int try_to_steal_lock(struct rt_mutex *lock, * priority. */ if (likely(!rt_mutex_has_waiters(lock))) { - spin_unlock_irqrestore(&pendowner->pi_lock, flags); + raw_spin_unlock_irqrestore(&pendowner->pi_lock, flags); return 1; } @@ -333,7 +333,7 @@ static inline int try_to_steal_lock(struct rt_mutex *lock, next = rt_mutex_top_waiter(lock); plist_del(&next->pi_list_entry, &pendowner->pi_waiters); __rt_mutex_adjust_prio(pendowner); - spin_unlock_irqrestore(&pendowner->pi_lock, flags); + raw_spin_unlock_irqrestore(&pendowner->pi_lock, flags); /* * We are going to steal the lock and a waiter was @@ -350,10 +350,10 @@ static inline int try_to_steal_lock(struct rt_mutex *lock, * might be task: */ if (likely(next->task != task)) { - spin_lock_irqsave(&task->pi_lock, flags); + raw_spin_lock_irqsave(&task->pi_lock, flags); plist_add(&next->pi_list_entry, &task->pi_waiters); __rt_mutex_adjust_prio(task); - spin_unlock_irqrestore(&task->pi_lock, flags); + raw_spin_unlock_irqrestore(&task->pi_lock, flags); } return 1; } @@ -420,7 +420,7 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock, unsigned long flags; int chain_walk = 0, res; - spin_lock_irqsave(&task->pi_lock, flags); + raw_spin_lock_irqsave(&task->pi_lock, flags); __rt_mutex_adjust_prio(task); waiter->task = task; waiter->lock = lock; @@ -434,17 +434,17 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock, task->pi_blocked_on = waiter; - spin_unlock_irqrestore(&task->pi_lock, flags); + raw_spin_unlock_irqrestore(&task->pi_lock, flags); if (waiter == rt_mutex_top_waiter(lock)) { - spin_lock_irqsave(&owner->pi_lock, flags); + raw_spin_lock_irqsave(&owner->pi_lock, flags); plist_del(&top_waiter->pi_list_entry, &owner->pi_waiters); plist_add(&waiter->pi_list_entry, &owner->pi_waiters); __rt_mutex_adjust_prio(owner); if (owner->pi_blocked_on) chain_walk = 1; - spin_unlock_irqrestore(&owner->pi_lock, flags); + raw_spin_unlock_irqrestore(&owner->pi_lock, flags); } else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock)) chain_walk = 1; @@ -483,7 +483,7 @@ static void wakeup_next_waiter(struct rt_mutex *lock) struct task_struct *pendowner; unsigned long flags; - spin_lock_irqsave(¤t->pi_lock, flags); + raw_spin_lock_irqsave(¤t->pi_lock, flags); waiter = rt_mutex_top_waiter(lock); plist_del(&waiter->list_entry, &lock->wait_list); @@ -500,7 +500,7 @@ static void wakeup_next_waiter(struct rt_mutex *lock) rt_mutex_set_owner(lock, pendowner, RT_MUTEX_OWNER_PENDING); - spin_unlock_irqrestore(¤t->pi_lock, flags); + raw_spin_unlock_irqrestore(¤t->pi_lock, flags); /* * Clear the pi_blocked_on variable and enqueue a possible @@ -509,7 +509,7 @@ static void wakeup_next_waiter(struct rt_mutex *lock) * waiter with higher priority than pending-owner->normal_prio * is blocked on the unboosted (pending) owner. */ - spin_lock_irqsave(&pendowner->pi_lock, flags); + raw_spin_lock_irqsave(&pendowner->pi_lock, flags); WARN_ON(!pendowner->pi_blocked_on); WARN_ON(pendowner->pi_blocked_on != waiter); @@ -523,7 +523,7 @@ static void wakeup_next_waiter(struct rt_mutex *lock) next = rt_mutex_top_waiter(lock); plist_add(&next->pi_list_entry, &pendowner->pi_waiters); } - spin_unlock_irqrestore(&pendowner->pi_lock, flags); + raw_spin_unlock_irqrestore(&pendowner->pi_lock, flags); wake_up_process(pendowner); } @@ -541,15 +541,15 @@ static void remove_waiter(struct rt_mutex *lock, unsigned long flags; int chain_walk = 0; - spin_lock_irqsave(¤t->pi_lock, flags); + raw_spin_lock_irqsave(¤t->pi_lock, flags); plist_del(&waiter->list_entry, &lock->wait_list); waiter->task = NULL; current->pi_blocked_on = NULL; - spin_unlock_irqrestore(¤t->pi_lock, flags); + raw_spin_unlock_irqrestore(¤t->pi_lock, flags); if (first && owner != current) { - spin_lock_irqsave(&owner->pi_lock, flags); + raw_spin_lock_irqsave(&owner->pi_lock, flags); plist_del(&waiter->pi_list_entry, &owner->pi_waiters); @@ -564,7 +564,7 @@ static void remove_waiter(struct rt_mutex *lock, if (owner->pi_blocked_on) chain_walk = 1; - spin_unlock_irqrestore(&owner->pi_lock, flags); + raw_spin_unlock_irqrestore(&owner->pi_lock, flags); } WARN_ON(!plist_node_empty(&waiter->pi_list_entry)); @@ -592,15 +592,15 @@ void rt_mutex_adjust_pi(struct task_struct *task) struct rt_mutex_waiter *waiter; unsigned long flags; - spin_lock_irqsave(&task->pi_lock, flags); + raw_spin_lock_irqsave(&task->pi_lock, flags); waiter = task->pi_blocked_on; if (!waiter || waiter->list_entry.prio == task->prio) { - spin_unlock_irqrestore(&task->pi_lock, flags); + raw_spin_unlock_irqrestore(&task->pi_lock, flags); return; } - spin_unlock_irqrestore(&task->pi_lock, flags); + raw_spin_unlock_irqrestore(&task->pi_lock, flags); /* gets dropped in rt_mutex_adjust_prio_chain()! */ get_task_struct(task); diff --git a/kernel/sched.c b/kernel/sched.c index 01c5016..18cceee 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6323,7 +6323,7 @@ recheck: * make sure no PI-waiters arrive (or leave) while we are * changing the priority of the task: */ - spin_lock_irqsave(&p->pi_lock, flags); + raw_spin_lock_irqsave(&p->pi_lock, flags); /* * To be able to change p->policy safely, the apropriate * runqueue lock must be held. @@ -6333,7 +6333,7 @@ recheck: if (unlikely(oldpolicy != -1 && oldpolicy != p->policy)) { policy = oldpolicy = -1; __task_rq_unlock(rq); - spin_unlock_irqrestore(&p->pi_lock, flags); + raw_spin_unlock_irqrestore(&p->pi_lock, flags); goto recheck; } update_rq_clock(rq); @@ -6357,7 +6357,7 @@ recheck: check_class_changed(rq, p, prev_class, oldprio, running); } __task_rq_unlock(rq); - spin_unlock_irqrestore(&p->pi_lock, flags); + raw_spin_unlock_irqrestore(&p->pi_lock, flags); rt_mutex_adjust_pi(p); @@ -9624,7 +9624,7 @@ void __init sched_init(void) #endif #ifdef CONFIG_RT_MUTEXES - plist_head_init(&init_task.pi_waiters, &init_task.pi_lock); + plist_head_init_raw(&init_task.pi_waiters, &init_task.pi_lock); #endif /* @@ -9749,13 +9749,13 @@ void normalize_rt_tasks(void) continue; } - spin_lock(&p->pi_lock); + raw_spin_lock(&p->pi_lock); rq = __task_rq_lock(p); normalize_task(rq, p); __task_rq_unlock(rq); - spin_unlock(&p->pi_lock); + raw_spin_unlock(&p->pi_lock); } while_each_thread(g, p); read_unlock_irqrestore(&tasklist_lock, flags); -- cgit v0.10.2 From d209d74d52ab39dc071656533cac095294f70de7 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 17 Nov 2009 18:22:11 +0100 Subject: rtmutes: Convert rtmutex.lock to raw_spinlock Convert locks which cannot be sleeping locks in preempt-rt to raw_spinlocks. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h index f19b00b..281d8fd 100644 --- a/include/linux/rtmutex.h +++ b/include/linux/rtmutex.h @@ -24,7 +24,7 @@ * @owner: the mutex owner */ struct rt_mutex { - spinlock_t wait_lock; + raw_spinlock_t wait_lock; struct plist_head wait_list; struct task_struct *owner; #ifdef CONFIG_DEBUG_RT_MUTEXES @@ -63,8 +63,8 @@ struct hrtimer_sleeper; #endif #define __RT_MUTEX_INITIALIZER(mutexname) \ - { .wait_lock = __SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ - , .wait_list = PLIST_HEAD_INIT(mutexname.wait_list, mutexname.wait_lock) \ + { .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ + , .wait_list = PLIST_HEAD_INIT_RAW(mutexname.wait_list, mutexname.wait_lock) \ , .owner = NULL \ __DEBUG_RT_MUTEX_INITIALIZER(mutexname)} diff --git a/kernel/futex.c b/kernel/futex.c index 320b369..8e3c3ff 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -760,7 +760,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) if (!pi_state) return -EINVAL; - spin_lock(&pi_state->pi_mutex.wait_lock); + raw_spin_lock(&pi_state->pi_mutex.wait_lock); new_owner = rt_mutex_next_owner(&pi_state->pi_mutex); /* @@ -789,7 +789,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) else if (curval != uval) ret = -EINVAL; if (ret) { - spin_unlock(&pi_state->pi_mutex.wait_lock); + raw_spin_unlock(&pi_state->pi_mutex.wait_lock); return ret; } } @@ -805,7 +805,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) pi_state->owner = new_owner; raw_spin_unlock_irq(&new_owner->pi_lock); - spin_unlock(&pi_state->pi_mutex.wait_lock); + raw_spin_unlock(&pi_state->pi_mutex.wait_lock); rt_mutex_unlock(&pi_state->pi_mutex); return 0; diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c index d33da47..a960481 100644 --- a/kernel/rtmutex.c +++ b/kernel/rtmutex.c @@ -231,7 +231,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, goto out_unlock_pi; lock = waiter->lock; - if (!spin_trylock(&lock->wait_lock)) { + if (!raw_spin_trylock(&lock->wait_lock)) { raw_spin_unlock_irqrestore(&task->pi_lock, flags); cpu_relax(); goto retry; @@ -240,7 +240,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, /* Deadlock detection */ if (lock == orig_lock || rt_mutex_owner(lock) == top_task) { debug_rt_mutex_deadlock(deadlock_detect, orig_waiter, lock); - spin_unlock(&lock->wait_lock); + raw_spin_unlock(&lock->wait_lock); ret = deadlock_detect ? -EDEADLK : 0; goto out_unlock_pi; } @@ -280,7 +280,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, raw_spin_unlock_irqrestore(&task->pi_lock, flags); top_waiter = rt_mutex_top_waiter(lock); - spin_unlock(&lock->wait_lock); + raw_spin_unlock(&lock->wait_lock); if (!detect_deadlock && waiter != top_waiter) goto out_put_task; @@ -459,12 +459,12 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock, */ get_task_struct(owner); - spin_unlock(&lock->wait_lock); + raw_spin_unlock(&lock->wait_lock); res = rt_mutex_adjust_prio_chain(owner, detect_deadlock, lock, waiter, task); - spin_lock(&lock->wait_lock); + raw_spin_lock(&lock->wait_lock); return res; } @@ -575,11 +575,11 @@ static void remove_waiter(struct rt_mutex *lock, /* gets dropped in rt_mutex_adjust_prio_chain()! */ get_task_struct(owner); - spin_unlock(&lock->wait_lock); + raw_spin_unlock(&lock->wait_lock); rt_mutex_adjust_prio_chain(owner, 0, lock, NULL, current); - spin_lock(&lock->wait_lock); + raw_spin_lock(&lock->wait_lock); } /* @@ -672,14 +672,14 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state, break; } - spin_unlock(&lock->wait_lock); + raw_spin_unlock(&lock->wait_lock); debug_rt_mutex_print_deadlock(waiter); if (waiter->task) schedule_rt_mutex(lock); - spin_lock(&lock->wait_lock); + raw_spin_lock(&lock->wait_lock); set_current_state(state); } @@ -700,11 +700,11 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, debug_rt_mutex_init_waiter(&waiter); waiter.task = NULL; - spin_lock(&lock->wait_lock); + raw_spin_lock(&lock->wait_lock); /* Try to acquire the lock again: */ if (try_to_take_rt_mutex(lock)) { - spin_unlock(&lock->wait_lock); + raw_spin_unlock(&lock->wait_lock); return 0; } @@ -731,7 +731,7 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, */ fixup_rt_mutex_waiters(lock); - spin_unlock(&lock->wait_lock); + raw_spin_unlock(&lock->wait_lock); /* Remove pending timer: */ if (unlikely(timeout)) @@ -758,7 +758,7 @@ rt_mutex_slowtrylock(struct rt_mutex *lock) { int ret = 0; - spin_lock(&lock->wait_lock); + raw_spin_lock(&lock->wait_lock); if (likely(rt_mutex_owner(lock) != current)) { @@ -770,7 +770,7 @@ rt_mutex_slowtrylock(struct rt_mutex *lock) fixup_rt_mutex_waiters(lock); } - spin_unlock(&lock->wait_lock); + raw_spin_unlock(&lock->wait_lock); return ret; } @@ -781,7 +781,7 @@ rt_mutex_slowtrylock(struct rt_mutex *lock) static void __sched rt_mutex_slowunlock(struct rt_mutex *lock) { - spin_lock(&lock->wait_lock); + raw_spin_lock(&lock->wait_lock); debug_rt_mutex_unlock(lock); @@ -789,13 +789,13 @@ rt_mutex_slowunlock(struct rt_mutex *lock) if (!rt_mutex_has_waiters(lock)) { lock->owner = NULL; - spin_unlock(&lock->wait_lock); + raw_spin_unlock(&lock->wait_lock); return; } wakeup_next_waiter(lock); - spin_unlock(&lock->wait_lock); + raw_spin_unlock(&lock->wait_lock); /* Undo pi boosting if necessary: */ rt_mutex_adjust_prio(current); @@ -970,8 +970,8 @@ EXPORT_SYMBOL_GPL(rt_mutex_destroy); void __rt_mutex_init(struct rt_mutex *lock, const char *name) { lock->owner = NULL; - spin_lock_init(&lock->wait_lock); - plist_head_init(&lock->wait_list, &lock->wait_lock); + raw_spin_lock_init(&lock->wait_lock); + plist_head_init_raw(&lock->wait_list, &lock->wait_lock); debug_rt_mutex_init(lock, name); } @@ -1032,7 +1032,7 @@ int rt_mutex_start_proxy_lock(struct rt_mutex *lock, { int ret; - spin_lock(&lock->wait_lock); + raw_spin_lock(&lock->wait_lock); mark_rt_mutex_waiters(lock); @@ -1040,7 +1040,7 @@ int rt_mutex_start_proxy_lock(struct rt_mutex *lock, /* We got the lock for task. */ debug_rt_mutex_lock(lock); rt_mutex_set_owner(lock, task, 0); - spin_unlock(&lock->wait_lock); + raw_spin_unlock(&lock->wait_lock); rt_mutex_deadlock_account_lock(lock, task); return 1; } @@ -1056,7 +1056,7 @@ int rt_mutex_start_proxy_lock(struct rt_mutex *lock, */ ret = 0; } - spin_unlock(&lock->wait_lock); + raw_spin_unlock(&lock->wait_lock); debug_rt_mutex_print_deadlock(waiter); @@ -1106,7 +1106,7 @@ int rt_mutex_finish_proxy_lock(struct rt_mutex *lock, { int ret; - spin_lock(&lock->wait_lock); + raw_spin_lock(&lock->wait_lock); set_current_state(TASK_INTERRUPTIBLE); @@ -1124,7 +1124,7 @@ int rt_mutex_finish_proxy_lock(struct rt_mutex *lock, */ fixup_rt_mutex_waiters(lock); - spin_unlock(&lock->wait_lock); + raw_spin_unlock(&lock->wait_lock); /* * Readjust priority, when we did not get the lock. We might have been -- cgit v0.10.2 From 9f5a5621e78cf48d86682a71ceb3fcdbde38b222 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 17 Nov 2009 15:40:01 +0100 Subject: smp: Convert smplocks to raw_spinlocks Convert locks which cannot be sleeping locks in preempt-rt to raw_spinlocks. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/kernel/smp.c b/kernel/smp.c index a8c7606..6e7c7fd 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -16,11 +16,11 @@ static DEFINE_PER_CPU(struct call_single_queue, call_single_queue); static struct { struct list_head queue; - spinlock_t lock; + raw_spinlock_t lock; } call_function __cacheline_aligned_in_smp = { .queue = LIST_HEAD_INIT(call_function.queue), - .lock = __SPIN_LOCK_UNLOCKED(call_function.lock), + .lock = __RAW_SPIN_LOCK_UNLOCKED(call_function.lock), }; enum { @@ -35,7 +35,7 @@ struct call_function_data { struct call_single_queue { struct list_head list; - spinlock_t lock; + raw_spinlock_t lock; }; static DEFINE_PER_CPU(struct call_function_data, cfd_data); @@ -80,7 +80,7 @@ static int __cpuinit init_call_single_data(void) for_each_possible_cpu(i) { struct call_single_queue *q = &per_cpu(call_single_queue, i); - spin_lock_init(&q->lock); + raw_spin_lock_init(&q->lock); INIT_LIST_HEAD(&q->list); } @@ -141,10 +141,10 @@ void generic_exec_single(int cpu, struct call_single_data *data, int wait) unsigned long flags; int ipi; - spin_lock_irqsave(&dst->lock, flags); + raw_spin_lock_irqsave(&dst->lock, flags); ipi = list_empty(&dst->list); list_add_tail(&data->list, &dst->list); - spin_unlock_irqrestore(&dst->lock, flags); + raw_spin_unlock_irqrestore(&dst->lock, flags); /* * The list addition should be visible before sending the IPI @@ -201,9 +201,9 @@ void generic_smp_call_function_interrupt(void) refs = atomic_dec_return(&data->refs); WARN_ON(refs < 0); if (!refs) { - spin_lock(&call_function.lock); + raw_spin_lock(&call_function.lock); list_del_rcu(&data->csd.list); - spin_unlock(&call_function.lock); + raw_spin_unlock(&call_function.lock); } if (refs) @@ -230,9 +230,9 @@ void generic_smp_call_function_single_interrupt(void) */ WARN_ON_ONCE(!cpu_online(smp_processor_id())); - spin_lock(&q->lock); + raw_spin_lock(&q->lock); list_replace_init(&q->list, &list); - spin_unlock(&q->lock); + raw_spin_unlock(&q->lock); while (!list_empty(&list)) { struct call_single_data *data; @@ -449,14 +449,14 @@ void smp_call_function_many(const struct cpumask *mask, cpumask_clear_cpu(this_cpu, data->cpumask); atomic_set(&data->refs, cpumask_weight(data->cpumask)); - spin_lock_irqsave(&call_function.lock, flags); + raw_spin_lock_irqsave(&call_function.lock, flags); /* * Place entry at the _HEAD_ of the list, so that any cpu still * observing the entry in generic_smp_call_function_interrupt() * will not miss any other list entries: */ list_add_rcu(&data->csd.list, &call_function.queue); - spin_unlock_irqrestore(&call_function.lock, flags); + raw_spin_unlock_irqrestore(&call_function.lock, flags); /* * Make the list addition visible before sending the ipi. @@ -501,20 +501,20 @@ EXPORT_SYMBOL(smp_call_function); void ipi_call_lock(void) { - spin_lock(&call_function.lock); + raw_spin_lock(&call_function.lock); } void ipi_call_unlock(void) { - spin_unlock(&call_function.lock); + raw_spin_unlock(&call_function.lock); } void ipi_call_lock_irq(void) { - spin_lock_irq(&call_function.lock); + raw_spin_lock_irq(&call_function.lock); } void ipi_call_unlock_irq(void) { - spin_unlock_irq(&call_function.lock); + raw_spin_unlock_irq(&call_function.lock); } -- cgit v0.10.2 From 239007b8440abff689632f50cdf0f2b9e895b534 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 17 Nov 2009 16:46:45 +0100 Subject: genirq: Convert irq_desc.lock to raw_spinlock Convert locks which cannot be sleeping locks in preempt-rt to raw_spinlocks. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index c0de072..5f2cf23 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -81,7 +81,7 @@ show_interrupts(struct seq_file *p, void *v) #endif if (irq < ACTUAL_NR_IRQS) { - spin_lock_irqsave(&irq_desc[irq].lock, flags); + raw_spin_lock_irqsave(&irq_desc[irq].lock, flags); action = irq_desc[irq].action; if (!action) goto unlock; @@ -105,7 +105,7 @@ show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); unlock: - spin_unlock_irqrestore(&irq_desc[irq].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags); } else if (irq == ACTUAL_NR_IRQS) { #ifdef CONFIG_SMP seq_puts(p, "IPI: "); diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h index acac530..8920b2d6 100644 --- a/arch/arm/include/asm/mach/irq.h +++ b/arch/arm/include/asm/mach/irq.h @@ -26,9 +26,9 @@ extern int show_fiq_list(struct seq_file *, void *); */ #define do_bad_IRQ(irq,desc) \ do { \ - spin_lock(&desc->lock); \ + raw_spin_lock(&desc->lock); \ handle_bad_irq(irq, desc); \ - spin_unlock(&desc->lock); \ + raw_spin_unlock(&desc->lock); \ } while(0) #endif diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index c9a8619..b7cb45b 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -69,7 +69,7 @@ int show_interrupts(struct seq_file *p, void *v) } if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) goto unlock; @@ -84,7 +84,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); unlock: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } else if (i == NR_IRQS) { #ifdef CONFIG_FIQ show_fiq_list(p, v); @@ -139,7 +139,7 @@ void set_irq_flags(unsigned int irq, unsigned int iflags) } desc = irq_desc + irq; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; if (iflags & IRQF_VALID) desc->status &= ~IRQ_NOREQUEST; @@ -147,7 +147,7 @@ void set_irq_flags(unsigned int irq, unsigned int iflags) desc->status &= ~IRQ_NOPROBE; if (!(iflags & IRQF_NOAUTOEN)) desc->status &= ~IRQ_NOAUTOEN; - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } void __init init_IRQ(void) @@ -166,9 +166,9 @@ static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu) { pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->node, cpu); - spin_lock_irq(&desc->lock); + raw_spin_lock_irq(&desc->lock); desc->chip->set_affinity(irq, cpumask_of(cpu)); - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); } /* diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c index feb0e54..038f24d 100644 --- a/arch/arm/mach-ns9xxx/irq.c +++ b/arch/arm/mach-ns9xxx/irq.c @@ -66,7 +66,7 @@ static void handle_prio_irq(unsigned int irq, struct irq_desc *desc) struct irqaction *action; irqreturn_t action_ret; - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); BUG_ON(desc->status & IRQ_INPROGRESS); @@ -78,7 +78,7 @@ static void handle_prio_irq(unsigned int irq, struct irq_desc *desc) goto out_mask; desc->status |= IRQ_INPROGRESS; - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); action_ret = handle_IRQ_event(irq, action); @@ -87,7 +87,7 @@ static void handle_prio_irq(unsigned int irq, struct irq_desc *desc) * Maybe this function should go to kernel/irq/chip.c? */ note_interrupt(irq, desc, action_ret); - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); desc->status &= ~IRQ_INPROGRESS; if (desc->status & IRQ_DISABLED) @@ -97,7 +97,7 @@ out_mask: /* ack unconditionally to unmask lower prio irqs */ desc->chip->ack(irq); - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); } #define handle_irq handle_prio_irq #endif diff --git a/arch/avr32/kernel/irq.c b/arch/avr32/kernel/irq.c index 9f57222..c8ab63e 100644 --- a/arch/avr32/kernel/irq.c +++ b/arch/avr32/kernel/irq.c @@ -51,7 +51,7 @@ int show_interrupts(struct seq_file *p, void *v) } if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) goto unlock; @@ -66,7 +66,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); unlock: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } return 0; diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c index db9f9c9..64cff54 100644 --- a/arch/blackfin/kernel/irqchip.c +++ b/arch/blackfin/kernel/irqchip.c @@ -23,7 +23,7 @@ void ack_bad_irq(unsigned int irq) static struct irq_desc bad_irq_desc = { .handle_irq = handle_bad_irq, - .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock), + .lock = __RAW_SPIN_LOCK_UNLOCKED(bad_irq_desc.lock), }; #ifdef CONFIG_CPUMASK_OFFSTACK @@ -39,7 +39,7 @@ int show_interrupts(struct seq_file *p, void *v) unsigned long flags; if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) goto skip; @@ -53,7 +53,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } else if (i == NR_IRQS) { seq_printf(p, "NMI: "); for_each_online_cpu(j) diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 78cb3d3..9636bac 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -1140,7 +1140,7 @@ void show_regs(struct pt_regs *fp) if (fp->ipend & ~0x3F) { for (i = 0; i < (NR_IRQS - 1); i++) { if (!in_atomic) - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) @@ -1155,7 +1155,7 @@ void show_regs(struct pt_regs *fp) verbose_printk("\n"); unlock: if (!in_atomic) - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } } diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c index 0ca7d98..b5ce072 100644 --- a/arch/cris/kernel/irq.c +++ b/arch/cris/kernel/irq.c @@ -52,7 +52,7 @@ int show_interrupts(struct seq_file *p, void *v) } if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) goto skip; @@ -71,7 +71,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } return 0; } diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c index af3e824..62d1aba 100644 --- a/arch/frv/kernel/irq.c +++ b/arch/frv/kernel/irq.c @@ -69,7 +69,7 @@ int show_interrupts(struct seq_file *p, void *v) } if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (action) { seq_printf(p, "%3d: ", i); @@ -85,7 +85,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); } - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } else if (i == NR_IRQS) { seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count)); } diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c index 5c913d4..c25dc2c 100644 --- a/arch/h8300/kernel/irq.c +++ b/arch/h8300/kernel/irq.c @@ -186,7 +186,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_puts(p, " CPU0"); if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) goto unlock; @@ -200,7 +200,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, ", %s", action->name); seq_putc(p, '\n'); unlock: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } return 0; } diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index dab4d39..95ac77a 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -793,12 +793,12 @@ iosapic_register_intr (unsigned int gsi, goto unlock_iosapic_lock; } - spin_lock(&irq_desc[irq].lock); + raw_spin_lock(&irq_desc[irq].lock); dest = get_target_cpu(gsi, irq); dmode = choose_dmode(); err = register_intr(gsi, irq, dmode, polarity, trigger); if (err < 0) { - spin_unlock(&irq_desc[irq].lock); + raw_spin_unlock(&irq_desc[irq].lock); irq = err; goto unlock_iosapic_lock; } @@ -817,7 +817,7 @@ iosapic_register_intr (unsigned int gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), cpu_logical_id(dest), dest, irq_to_vector(irq)); - spin_unlock(&irq_desc[irq].lock); + raw_spin_unlock(&irq_desc[irq].lock); unlock_iosapic_lock: spin_unlock_irqrestore(&iosapic_lock, flags); return irq; diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index 7d89512..94ee9d0 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c @@ -71,7 +71,7 @@ int show_interrupts(struct seq_file *p, void *v) } if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) goto skip; @@ -91,7 +91,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } else if (i == NR_IRQS) seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); return 0; diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index dd9d7b5..70e4bad 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -345,7 +345,7 @@ static irqreturn_t smp_irq_move_cleanup_interrupt(int irq, void *dev_id) desc = irq_desc + irq; cfg = irq_cfg + irq; - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); if (!cfg->move_cleanup_count) goto unlock; @@ -358,7 +358,7 @@ static irqreturn_t smp_irq_move_cleanup_interrupt(int irq, void *dev_id) spin_unlock_irqrestore(&vector_lock, flags); cfg->move_cleanup_count--; unlock: - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); } return IRQ_HANDLED; } diff --git a/arch/m32r/kernel/irq.c b/arch/m32r/kernel/irq.c index 8dfd31e..3c71f77 100644 --- a/arch/m32r/kernel/irq.c +++ b/arch/m32r/kernel/irq.c @@ -40,7 +40,7 @@ int show_interrupts(struct seq_file *p, void *v) } if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) goto skip; @@ -59,7 +59,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } return 0; } diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c index 7d5ddd6..0f06034 100644 --- a/arch/microblaze/kernel/irq.c +++ b/arch/microblaze/kernel/irq.c @@ -68,7 +68,7 @@ int show_interrupts(struct seq_file *p, void *v) } if (i < nr_irq) { - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) goto skip; @@ -89,7 +89,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } return 0; } diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 7b845ba..8b0b418 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -99,7 +99,7 @@ int show_interrupts(struct seq_file *p, void *v) } if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) goto skip; @@ -118,7 +118,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } else if (i == NR_IRQS) { seq_putc(p, '\n'); seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c index 6d39e22..6153b6a 100644 --- a/arch/mips/vr41xx/common/icu.c +++ b/arch/mips/vr41xx/common/icu.c @@ -159,9 +159,9 @@ void vr41xx_enable_piuint(uint16_t mask) if (current_cpu_type() == CPU_VR4111 || current_cpu_type() == CPU_VR4121) { - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu1_set(MPIUINTREG, mask); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } @@ -174,9 +174,9 @@ void vr41xx_disable_piuint(uint16_t mask) if (current_cpu_type() == CPU_VR4111 || current_cpu_type() == CPU_VR4121) { - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu1_clear(MPIUINTREG, mask); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } @@ -189,9 +189,9 @@ void vr41xx_enable_aiuint(uint16_t mask) if (current_cpu_type() == CPU_VR4111 || current_cpu_type() == CPU_VR4121) { - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu1_set(MAIUINTREG, mask); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } @@ -204,9 +204,9 @@ void vr41xx_disable_aiuint(uint16_t mask) if (current_cpu_type() == CPU_VR4111 || current_cpu_type() == CPU_VR4121) { - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu1_clear(MAIUINTREG, mask); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } @@ -219,9 +219,9 @@ void vr41xx_enable_kiuint(uint16_t mask) if (current_cpu_type() == CPU_VR4111 || current_cpu_type() == CPU_VR4121) { - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu1_set(MKIUINTREG, mask); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } @@ -234,9 +234,9 @@ void vr41xx_disable_kiuint(uint16_t mask) if (current_cpu_type() == CPU_VR4111 || current_cpu_type() == CPU_VR4121) { - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu1_clear(MKIUINTREG, mask); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } @@ -247,9 +247,9 @@ void vr41xx_enable_macint(uint16_t mask) struct irq_desc *desc = irq_desc + ETHERNET_IRQ; unsigned long flags; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu1_set(MMACINTREG, mask); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } EXPORT_SYMBOL(vr41xx_enable_macint); @@ -259,9 +259,9 @@ void vr41xx_disable_macint(uint16_t mask) struct irq_desc *desc = irq_desc + ETHERNET_IRQ; unsigned long flags; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu1_clear(MMACINTREG, mask); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } EXPORT_SYMBOL(vr41xx_disable_macint); @@ -271,9 +271,9 @@ void vr41xx_enable_dsiuint(uint16_t mask) struct irq_desc *desc = irq_desc + DSIU_IRQ; unsigned long flags; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu1_set(MDSIUINTREG, mask); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } EXPORT_SYMBOL(vr41xx_enable_dsiuint); @@ -283,9 +283,9 @@ void vr41xx_disable_dsiuint(uint16_t mask) struct irq_desc *desc = irq_desc + DSIU_IRQ; unsigned long flags; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu1_clear(MDSIUINTREG, mask); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } EXPORT_SYMBOL(vr41xx_disable_dsiuint); @@ -295,9 +295,9 @@ void vr41xx_enable_firint(uint16_t mask) struct irq_desc *desc = irq_desc + FIR_IRQ; unsigned long flags; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu2_set(MFIRINTREG, mask); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } EXPORT_SYMBOL(vr41xx_enable_firint); @@ -307,9 +307,9 @@ void vr41xx_disable_firint(uint16_t mask) struct irq_desc *desc = irq_desc + FIR_IRQ; unsigned long flags; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu2_clear(MFIRINTREG, mask); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } EXPORT_SYMBOL(vr41xx_disable_firint); @@ -322,9 +322,9 @@ void vr41xx_enable_pciint(void) if (current_cpu_type() == CPU_VR4122 || current_cpu_type() == CPU_VR4131 || current_cpu_type() == CPU_VR4133) { - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu2_write(MPCIINTREG, PCIINT0); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } @@ -338,9 +338,9 @@ void vr41xx_disable_pciint(void) if (current_cpu_type() == CPU_VR4122 || current_cpu_type() == CPU_VR4131 || current_cpu_type() == CPU_VR4133) { - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu2_write(MPCIINTREG, 0); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } @@ -354,9 +354,9 @@ void vr41xx_enable_scuint(void) if (current_cpu_type() == CPU_VR4122 || current_cpu_type() == CPU_VR4131 || current_cpu_type() == CPU_VR4133) { - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu2_write(MSCUINTREG, SCUINT0); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } @@ -370,9 +370,9 @@ void vr41xx_disable_scuint(void) if (current_cpu_type() == CPU_VR4122 || current_cpu_type() == CPU_VR4131 || current_cpu_type() == CPU_VR4133) { - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu2_write(MSCUINTREG, 0); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } @@ -386,9 +386,9 @@ void vr41xx_enable_csiint(uint16_t mask) if (current_cpu_type() == CPU_VR4122 || current_cpu_type() == CPU_VR4131 || current_cpu_type() == CPU_VR4133) { - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu2_set(MCSIINTREG, mask); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } @@ -402,9 +402,9 @@ void vr41xx_disable_csiint(uint16_t mask) if (current_cpu_type() == CPU_VR4122 || current_cpu_type() == CPU_VR4131 || current_cpu_type() == CPU_VR4133) { - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu2_clear(MCSIINTREG, mask); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } @@ -418,9 +418,9 @@ void vr41xx_enable_bcuint(void) if (current_cpu_type() == CPU_VR4122 || current_cpu_type() == CPU_VR4131 || current_cpu_type() == CPU_VR4133) { - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu2_write(MBCUINTREG, BCUINTR); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } @@ -434,9 +434,9 @@ void vr41xx_disable_bcuint(void) if (current_cpu_type() == CPU_VR4122 || current_cpu_type() == CPU_VR4131 || current_cpu_type() == CPU_VR4133) { - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); icu2_write(MBCUINTREG, 0); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } @@ -486,7 +486,7 @@ static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) pin = SYSINT1_IRQ_TO_PIN(irq); - spin_lock_irq(&desc->lock); + raw_spin_lock_irq(&desc->lock); intassign0 = icu1_read(INTASSIGN0); intassign1 = icu1_read(INTASSIGN1); @@ -525,7 +525,7 @@ static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) intassign1 |= (uint16_t)assign << 9; break; default: - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); return -EINVAL; } @@ -533,7 +533,7 @@ static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) icu1_write(INTASSIGN0, intassign0); icu1_write(INTASSIGN1, intassign1); - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); return 0; } @@ -546,7 +546,7 @@ static inline int set_sysint2_assign(unsigned int irq, unsigned char assign) pin = SYSINT2_IRQ_TO_PIN(irq); - spin_lock_irq(&desc->lock); + raw_spin_lock_irq(&desc->lock); intassign2 = icu1_read(INTASSIGN2); intassign3 = icu1_read(INTASSIGN3); @@ -593,7 +593,7 @@ static inline int set_sysint2_assign(unsigned int irq, unsigned char assign) intassign3 |= (uint16_t)assign << 12; break; default: - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); return -EINVAL; } @@ -601,7 +601,7 @@ static inline int set_sysint2_assign(unsigned int irq, unsigned char assign) icu1_write(INTASSIGN2, intassign2); icu1_write(INTASSIGN3, intassign3); - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); return 0; } diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c index 4c3c58e..e2d5ed8 100644 --- a/arch/mn10300/kernel/irq.c +++ b/arch/mn10300/kernel/irq.c @@ -215,7 +215,7 @@ int show_interrupts(struct seq_file *p, void *v) /* display information rows, one per active CPU */ case 1 ... NR_IRQS - 1: - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (action) { @@ -235,7 +235,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); } - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); break; /* polish off with NMI and error counters */ diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 2e7610c..f47465e 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -180,7 +180,7 @@ int show_interrupts(struct seq_file *p, void *v) if (i < NR_IRQS) { struct irqaction *action; - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) goto skip; @@ -224,7 +224,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } return 0; diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index f6dca4f..9040330 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -210,7 +210,7 @@ int show_interrupts(struct seq_file *p, void *v) if (!desc) return 0; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); action = desc->action; if (!action || !action->handler) @@ -237,7 +237,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); return 0; } @@ -1112,7 +1112,7 @@ static int virq_debug_show(struct seq_file *m, void *private) if (!desc) continue; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); if (desc->action && desc->action->handler) { seq_printf(m, "%5d ", i); @@ -1131,7 +1131,7 @@ static int virq_debug_show(struct seq_file *m, void *private) seq_printf(m, "%s\n", p); } - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } return 0; diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c index cc0c854..0bac3a3 100644 --- a/arch/powerpc/platforms/52xx/media5200.c +++ b/arch/powerpc/platforms/52xx/media5200.c @@ -86,9 +86,9 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc) u32 status, enable; /* Mask off the cascaded IRQ */ - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); desc->chip->mask(virq); - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); /* Ask the FPGA for IRQ status. If 'val' is 0, then no irqs * are pending. 'ffs()' is 1 based */ @@ -104,11 +104,11 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc) } /* Processing done; can reenable the cascade now */ - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); desc->chip->ack(virq); if (!(desc->status & IRQ_DISABLED)) desc->chip->unmask(virq); - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); } static int media5200_irq_map(struct irq_host *h, unsigned int virq, diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 7267eff..6829cf7 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -237,7 +237,7 @@ extern int noirqdebug; static void handle_iic_irq(unsigned int irq, struct irq_desc *desc) { - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); @@ -265,18 +265,18 @@ static void handle_iic_irq(unsigned int irq, struct irq_desc *desc) goto out_eoi; desc->status &= ~IRQ_PENDING; - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); action_ret = handle_IRQ_event(irq, action); if (!noirqdebug) note_interrupt(irq, desc, action_ret); - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING); desc->status &= ~IRQ_INPROGRESS; out_eoi: desc->chip->eoi(irq); - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); } static int iic_host_map(struct irq_host *h, unsigned int virq, diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c index 0776225..86c4b29 100644 --- a/arch/powerpc/platforms/iseries/irq.c +++ b/arch/powerpc/platforms/iseries/irq.c @@ -217,9 +217,9 @@ void __init iSeries_activate_IRQs() struct irq_desc *desc = irq_to_desc(irq); if (desc && desc->chip && desc->chip->startup) { - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); desc->chip->startup(irq); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } } diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 7d01b58..b9b9e11 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c @@ -906,7 +906,7 @@ void xics_migrate_irqs_away(void) || desc->chip->set_affinity == NULL) continue; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); if (status) { @@ -930,7 +930,7 @@ void xics_migrate_irqs_away(void) cpumask_setall(irq_to_desc(virq)->affinity); desc->chip->set_affinity(virq, cpu_all_mask); unlock: - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } #endif diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 62e5025..c6e11b0 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -173,7 +173,7 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) u32 intr_index; u32 have_shift = 0; - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) { if (desc->chip->mask_ack) desc->chip->mask_ack(irq); @@ -225,7 +225,7 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) break; } unlock: - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); } static int __devinit fsl_of_msi_probe(struct of_device *dev, diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c index 7d10074..6f220a9 100644 --- a/arch/powerpc/sysdev/uic.c +++ b/arch/powerpc/sysdev/uic.c @@ -225,12 +225,12 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc) int src; int subvirq; - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); if (desc->status & IRQ_LEVEL) desc->chip->mask(virq); else desc->chip->mask_ack(virq); - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); msr = mfdcr(uic->dcrbase + UIC_MSR); if (!msr) /* spurious interrupt */ @@ -242,12 +242,12 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc) generic_handle_irq(subvirq); uic_irq_ret: - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); if (desc->status & IRQ_LEVEL) desc->chip->ack(virq); if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) desc->chip->unmask(virq); - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); } static struct uic * __init uic_init_one(struct device_node *node) diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index e1913f2..d2d41d0 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -76,7 +76,7 @@ int show_interrupts(struct seq_file *p, void *v) if (!desc) return 0; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); for_each_online_cpu(j) any_count |= kstat_irqs_cpu(i, j); action = desc->action; @@ -97,7 +97,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); out: - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); return 0; } #endif diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index ce996f9..8d6882b 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -176,7 +176,7 @@ int show_interrupts(struct seq_file *p, void *v) } if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) goto skip; @@ -195,7 +195,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } else if (i == NR_IRQS) { seq_printf(p, "NMI: "); for_each_online_cpu(j) @@ -785,14 +785,14 @@ void fixup_irqs(void) for (irq = 0; irq < NR_IRQS; irq++) { unsigned long flags; - spin_lock_irqsave(&irq_desc[irq].lock, flags); + raw_spin_lock_irqsave(&irq_desc[irq].lock, flags); if (irq_desc[irq].action && !(irq_desc[irq].status & IRQ_PER_CPU)) { if (irq_desc[irq].chip->set_affinity) irq_desc[irq].chip->set_affinity(irq, irq_desc[irq].affinity); } - spin_unlock_irqrestore(&irq_desc[irq].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags); } tick_ops->disable_irq(); diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 039270b..89474ba 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -34,7 +34,7 @@ int show_interrupts(struct seq_file *p, void *v) } if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) goto skip; @@ -53,7 +53,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } else if (i == NR_IRQS) seq_putc(p, '\n'); diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index d5d498f..11a5851 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2431,7 +2431,7 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) continue; cfg = irq_cfg(irq); - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) goto unlock; @@ -2450,7 +2450,7 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) } __get_cpu_var(vector_irq)[vector] = -1; unlock: - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); } irq_exit(); diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 664bcb7..91fd0c7 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -149,7 +149,7 @@ int show_interrupts(struct seq_file *p, void *v) if (!desc) return 0; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); for_each_online_cpu(j) any_count |= kstat_irqs_cpu(i, j); action = desc->action; @@ -170,7 +170,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); out: - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); return 0; } @@ -294,12 +294,12 @@ void fixup_irqs(void) continue; /* interrupt's are disabled at this point */ - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); affinity = desc->affinity; if (!irq_has_action(irq) || cpumask_equal(affinity, cpu_online_mask)) { - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); continue; } @@ -326,7 +326,7 @@ void fixup_irqs(void) if (!(desc->status & IRQ_MOVE_PCNTXT) && desc->chip->unmask) desc->chip->unmask(irq); - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); if (break_affinity && set_affinity) printk("Broke affinity for irq %i\n", irq); @@ -356,10 +356,10 @@ void fixup_irqs(void) irq = __get_cpu_var(vector_irq)[vector]; desc = irq_to_desc(irq); - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); if (desc->chip->retrigger) desc->chip->retrigger(irq); - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); } } } diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index a1badb3..8cd3848 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c @@ -90,7 +90,7 @@ int show_interrupts(struct seq_file *p, void *v) } if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); + raw_spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) goto skip; @@ -109,7 +109,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); } else if (i == NR_IRQS) { seq_printf(p, "NMI: "); for_each_online_cpu(j) diff --git a/include/linux/irq.h b/include/linux/irq.h index a287cfc..451481c 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -192,7 +192,7 @@ struct irq_desc { unsigned int irq_count; /* For detecting broken IRQs */ unsigned long last_unhandled; /* Aging timer for unhandled count */ unsigned int irqs_unhandled; - spinlock_t lock; + raw_spinlock_t lock; #ifdef CONFIG_SMP cpumask_var_t affinity; unsigned int node; diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c index 1de9700..2295a31 100644 --- a/kernel/irq/autoprobe.c +++ b/kernel/irq/autoprobe.c @@ -45,7 +45,7 @@ unsigned long probe_irq_on(void) * flush such a longstanding irq before considering it as spurious. */ for_each_irq_desc_reverse(i, desc) { - spin_lock_irq(&desc->lock); + raw_spin_lock_irq(&desc->lock); if (!desc->action && !(desc->status & IRQ_NOPROBE)) { /* * An old-style architecture might still have @@ -61,7 +61,7 @@ unsigned long probe_irq_on(void) desc->chip->set_type(i, IRQ_TYPE_PROBE); desc->chip->startup(i); } - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); } /* Wait for longstanding interrupts to trigger. */ @@ -73,13 +73,13 @@ unsigned long probe_irq_on(void) * happened in the previous stage, it may have masked itself) */ for_each_irq_desc_reverse(i, desc) { - spin_lock_irq(&desc->lock); + raw_spin_lock_irq(&desc->lock); if (!desc->action && !(desc->status & IRQ_NOPROBE)) { desc->status |= IRQ_AUTODETECT | IRQ_WAITING; if (desc->chip->startup(i)) desc->status |= IRQ_PENDING; } - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); } /* @@ -91,7 +91,7 @@ unsigned long probe_irq_on(void) * Now filter out any obviously spurious interrupts */ for_each_irq_desc(i, desc) { - spin_lock_irq(&desc->lock); + raw_spin_lock_irq(&desc->lock); status = desc->status; if (status & IRQ_AUTODETECT) { @@ -103,7 +103,7 @@ unsigned long probe_irq_on(void) if (i < 32) mask |= 1 << i; } - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); } return mask; @@ -129,7 +129,7 @@ unsigned int probe_irq_mask(unsigned long val) int i; for_each_irq_desc(i, desc) { - spin_lock_irq(&desc->lock); + raw_spin_lock_irq(&desc->lock); status = desc->status; if (status & IRQ_AUTODETECT) { @@ -139,7 +139,7 @@ unsigned int probe_irq_mask(unsigned long val) desc->status = status & ~IRQ_AUTODETECT; desc->chip->shutdown(i); } - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); } mutex_unlock(&probing_active); @@ -171,7 +171,7 @@ int probe_irq_off(unsigned long val) unsigned int status; for_each_irq_desc(i, desc) { - spin_lock_irq(&desc->lock); + raw_spin_lock_irq(&desc->lock); status = desc->status; if (status & IRQ_AUTODETECT) { @@ -183,7 +183,7 @@ int probe_irq_off(unsigned long val) desc->status = status & ~IRQ_AUTODETECT; desc->chip->shutdown(i); } - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); } mutex_unlock(&probing_active); diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index ba566c2..ecc3fa2 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -34,7 +34,7 @@ void dynamic_irq_init(unsigned int irq) } /* Ensure we don't have left over values from a previous use of this irq */ - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); desc->status = IRQ_DISABLED; desc->chip = &no_irq_chip; desc->handle_irq = handle_bad_irq; @@ -51,7 +51,7 @@ void dynamic_irq_init(unsigned int irq) cpumask_clear(desc->pending_mask); #endif #endif - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } /** @@ -68,9 +68,9 @@ void dynamic_irq_cleanup(unsigned int irq) return; } - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); if (desc->action) { - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); WARN(1, KERN_ERR "Destroying IRQ%d without calling free_irq\n", irq); return; @@ -82,7 +82,7 @@ void dynamic_irq_cleanup(unsigned int irq) desc->chip = &no_irq_chip; desc->name = NULL; clear_kstat_irqs(desc); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } @@ -104,10 +104,10 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip) if (!chip) chip = &no_irq_chip; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); irq_chip_set_defaults(chip); desc->chip = chip; - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); return 0; } @@ -133,9 +133,9 @@ int set_irq_type(unsigned int irq, unsigned int type) if (type == IRQ_TYPE_NONE) return 0; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); ret = __irq_set_trigger(desc, irq, type); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); return ret; } EXPORT_SYMBOL(set_irq_type); @@ -158,9 +158,9 @@ int set_irq_data(unsigned int irq, void *data) return -EINVAL; } - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); desc->handler_data = data; - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); return 0; } EXPORT_SYMBOL(set_irq_data); @@ -183,11 +183,11 @@ int set_irq_msi(unsigned int irq, struct msi_desc *entry) return -EINVAL; } - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); desc->msi_desc = entry; if (entry) entry->irq = irq; - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); return 0; } @@ -214,9 +214,9 @@ int set_irq_chip_data(unsigned int irq, void *data) return -EINVAL; } - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); desc->chip_data = data; - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); return 0; } @@ -241,12 +241,12 @@ void set_irq_nested_thread(unsigned int irq, int nest) if (!desc) return; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); if (nest) desc->status |= IRQ_NESTED_THREAD; else desc->status &= ~IRQ_NESTED_THREAD; - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } EXPORT_SYMBOL_GPL(set_irq_nested_thread); @@ -343,7 +343,7 @@ void handle_nested_irq(unsigned int irq) might_sleep(); - spin_lock_irq(&desc->lock); + raw_spin_lock_irq(&desc->lock); kstat_incr_irqs_this_cpu(irq, desc); @@ -352,17 +352,17 @@ void handle_nested_irq(unsigned int irq) goto out_unlock; desc->status |= IRQ_INPROGRESS; - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); action_ret = action->thread_fn(action->irq, action->dev_id); if (!noirqdebug) note_interrupt(irq, desc, action_ret); - spin_lock_irq(&desc->lock); + raw_spin_lock_irq(&desc->lock); desc->status &= ~IRQ_INPROGRESS; out_unlock: - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); } EXPORT_SYMBOL_GPL(handle_nested_irq); @@ -384,7 +384,7 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc) struct irqaction *action; irqreturn_t action_ret; - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); if (unlikely(desc->status & IRQ_INPROGRESS)) goto out_unlock; @@ -396,16 +396,16 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc) goto out_unlock; desc->status |= IRQ_INPROGRESS; - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); action_ret = handle_IRQ_event(irq, action); if (!noirqdebug) note_interrupt(irq, desc, action_ret); - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); desc->status &= ~IRQ_INPROGRESS; out_unlock: - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); } /** @@ -424,7 +424,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) struct irqaction *action; irqreturn_t action_ret; - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); mask_ack_irq(desc, irq); if (unlikely(desc->status & IRQ_INPROGRESS)) @@ -441,13 +441,13 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) goto out_unlock; desc->status |= IRQ_INPROGRESS; - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); action_ret = handle_IRQ_event(irq, action); if (!noirqdebug) note_interrupt(irq, desc, action_ret); - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); desc->status &= ~IRQ_INPROGRESS; if (unlikely(desc->status & IRQ_ONESHOT)) @@ -455,7 +455,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) else if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) desc->chip->unmask(irq); out_unlock: - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); } EXPORT_SYMBOL_GPL(handle_level_irq); @@ -475,7 +475,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) struct irqaction *action; irqreturn_t action_ret; - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); if (unlikely(desc->status & IRQ_INPROGRESS)) goto out; @@ -497,18 +497,18 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) desc->status |= IRQ_INPROGRESS; desc->status &= ~IRQ_PENDING; - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); action_ret = handle_IRQ_event(irq, action); if (!noirqdebug) note_interrupt(irq, desc, action_ret); - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); desc->status &= ~IRQ_INPROGRESS; out: desc->chip->eoi(irq); - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); } /** @@ -530,7 +530,7 @@ out: void handle_edge_irq(unsigned int irq, struct irq_desc *desc) { - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); @@ -576,17 +576,17 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc) } desc->status &= ~IRQ_PENDING; - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); action_ret = handle_IRQ_event(irq, action); if (!noirqdebug) note_interrupt(irq, desc, action_ret); - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING); desc->status &= ~IRQ_INPROGRESS; out_unlock: - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); } /** @@ -643,7 +643,7 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, } chip_bus_lock(irq, desc); - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); /* Uninstall? */ if (handle == handle_bad_irq) { @@ -661,7 +661,7 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, desc->depth = 0; desc->chip->startup(irq); } - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); chip_bus_sync_unlock(irq, desc); } EXPORT_SYMBOL_GPL(__set_irq_handler); @@ -692,9 +692,9 @@ void __init set_irq_noprobe(unsigned int irq) return; } - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); desc->status |= IRQ_NOPROBE; - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } void __init set_irq_probe(unsigned int irq) @@ -707,7 +707,7 @@ void __init set_irq_probe(unsigned int irq) return; } - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); desc->status &= ~IRQ_NOPROBE; - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 17c71bb..814940e 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c @@ -80,7 +80,7 @@ static struct irq_desc irq_desc_init = { .chip = &no_irq_chip, .handle_irq = handle_bad_irq, .depth = 1, - .lock = __SPIN_LOCK_UNLOCKED(irq_desc_init.lock), + .lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock), }; void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr) @@ -108,7 +108,7 @@ static void init_one_irq_desc(int irq, struct irq_desc *desc, int node) { memcpy(desc, &irq_desc_init, sizeof(struct irq_desc)); - spin_lock_init(&desc->lock); + raw_spin_lock_init(&desc->lock); desc->irq = irq; #ifdef CONFIG_SMP desc->node = node; @@ -130,7 +130,7 @@ static void init_one_irq_desc(int irq, struct irq_desc *desc, int node) /* * Protect the sparse_irqs: */ -DEFINE_SPINLOCK(sparse_irq_lock); +DEFINE_RAW_SPINLOCK(sparse_irq_lock); struct irq_desc **irq_desc_ptrs __read_mostly; @@ -141,7 +141,7 @@ static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_sm .chip = &no_irq_chip, .handle_irq = handle_bad_irq, .depth = 1, - .lock = __SPIN_LOCK_UNLOCKED(irq_desc_init.lock), + .lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock), } }; @@ -212,7 +212,7 @@ struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node) if (desc) return desc; - spin_lock_irqsave(&sparse_irq_lock, flags); + raw_spin_lock_irqsave(&sparse_irq_lock, flags); /* We have to check it to avoid races with another CPU */ desc = irq_desc_ptrs[irq]; @@ -234,7 +234,7 @@ struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node) irq_desc_ptrs[irq] = desc; out_unlock: - spin_unlock_irqrestore(&sparse_irq_lock, flags); + raw_spin_unlock_irqrestore(&sparse_irq_lock, flags); return desc; } @@ -247,7 +247,7 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = { .chip = &no_irq_chip, .handle_irq = handle_bad_irq, .depth = 1, - .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock), + .lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock), } }; @@ -473,7 +473,7 @@ unsigned int __do_IRQ(unsigned int irq) return 1; } - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); if (desc->chip->ack) desc->chip->ack(irq); /* @@ -517,13 +517,13 @@ unsigned int __do_IRQ(unsigned int irq) for (;;) { irqreturn_t action_ret; - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); action_ret = handle_IRQ_event(irq, action); if (!noirqdebug) note_interrupt(irq, desc, action_ret); - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); if (likely(!(desc->status & IRQ_PENDING))) break; desc->status &= ~IRQ_PENDING; @@ -536,7 +536,7 @@ out: * disabled while the handler was running. */ desc->chip->end(irq); - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); return 1; } diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index 1b5d742..b2821f0 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h @@ -18,7 +18,7 @@ extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume); extern struct lock_class_key irq_desc_lock_class; extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr); extern void clear_kstat_irqs(struct irq_desc *desc); -extern spinlock_t sparse_irq_lock; +extern raw_spinlock_t sparse_irq_lock; #ifdef CONFIG_SPARSE_IRQ /* irq_desc_ptrs allocated at boot time */ diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 7305b29..eb6078c 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -46,9 +46,9 @@ void synchronize_irq(unsigned int irq) cpu_relax(); /* Ok, that indicated we're done: double-check carefully. */ - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); status = desc->status; - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); /* Oops, that failed? */ } while (status & IRQ_INPROGRESS); @@ -114,7 +114,7 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask) if (!desc->chip->set_affinity) return -EINVAL; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); #ifdef CONFIG_GENERIC_PENDING_IRQ if (desc->status & IRQ_MOVE_PCNTXT) { @@ -134,7 +134,7 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask) } #endif desc->status |= IRQ_AFFINITY_SET; - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); return 0; } @@ -181,11 +181,11 @@ int irq_select_affinity_usr(unsigned int irq) unsigned long flags; int ret; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); ret = setup_affinity(irq, desc); if (!ret) irq_set_thread_affinity(desc); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); return ret; } @@ -231,9 +231,9 @@ void disable_irq_nosync(unsigned int irq) return; chip_bus_lock(irq, desc); - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); __disable_irq(desc, irq, false); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); chip_bus_sync_unlock(irq, desc); } EXPORT_SYMBOL(disable_irq_nosync); @@ -308,9 +308,9 @@ void enable_irq(unsigned int irq) return; chip_bus_lock(irq, desc); - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); __enable_irq(desc, irq, false); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); chip_bus_sync_unlock(irq, desc); } EXPORT_SYMBOL(enable_irq); @@ -347,7 +347,7 @@ int set_irq_wake(unsigned int irq, unsigned int on) /* wakeup-capable irqs can be shared between drivers that * don't need to have the same sleep mode behaviors. */ - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); if (on) { if (desc->wake_depth++ == 0) { ret = set_irq_wake_real(irq, on); @@ -368,7 +368,7 @@ int set_irq_wake(unsigned int irq, unsigned int on) } } - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); return ret; } EXPORT_SYMBOL(set_irq_wake); @@ -484,12 +484,12 @@ static int irq_wait_for_interrupt(struct irqaction *action) static void irq_finalize_oneshot(unsigned int irq, struct irq_desc *desc) { chip_bus_lock(irq, desc); - spin_lock_irq(&desc->lock); + raw_spin_lock_irq(&desc->lock); if (!(desc->status & IRQ_DISABLED) && (desc->status & IRQ_MASKED)) { desc->status &= ~IRQ_MASKED; desc->chip->unmask(irq); } - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); chip_bus_sync_unlock(irq, desc); } @@ -514,9 +514,9 @@ irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action) return; } - spin_lock_irq(&desc->lock); + raw_spin_lock_irq(&desc->lock); cpumask_copy(mask, desc->affinity); - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); set_cpus_allowed_ptr(current, mask); free_cpumask_var(mask); @@ -545,7 +545,7 @@ static int irq_thread(void *data) atomic_inc(&desc->threads_active); - spin_lock_irq(&desc->lock); + raw_spin_lock_irq(&desc->lock); if (unlikely(desc->status & IRQ_DISABLED)) { /* * CHECKME: We might need a dedicated @@ -555,9 +555,9 @@ static int irq_thread(void *data) * retriggers the interrupt itself --- tglx */ desc->status |= IRQ_PENDING; - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); } else { - spin_unlock_irq(&desc->lock); + raw_spin_unlock_irq(&desc->lock); action->thread_fn(action->irq, action->dev_id); @@ -679,7 +679,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) /* * The following block of code has to be executed atomically */ - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); old_ptr = &desc->action; old = *old_ptr; if (old) { @@ -775,7 +775,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) __enable_irq(desc, irq, false); } - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); /* * Strictly no need to wake it up, but hung_task complains @@ -802,7 +802,7 @@ mismatch: ret = -EBUSY; out_thread: - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); if (new->thread) { struct task_struct *t = new->thread; @@ -844,7 +844,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id) if (!desc) return NULL; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); /* * There can be multiple actions per IRQ descriptor, find the right @@ -856,7 +856,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id) if (!action) { WARN(1, "Trying to free already-free IRQ %d\n", irq); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); return NULL; } @@ -884,7 +884,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id) desc->chip->disable(irq); } - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); unregister_handler_proc(irq, action); diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c index fcb6c96..2419622 100644 --- a/kernel/irq/migration.c +++ b/kernel/irq/migration.c @@ -27,7 +27,7 @@ void move_masked_irq(int irq) if (!desc->chip->set_affinity) return; - assert_spin_locked(&desc->lock); + assert_raw_spin_locked(&desc->lock); /* * If there was a valid mask to work with, please diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c index 3fd3019..26bac9d 100644 --- a/kernel/irq/numa_migrate.c +++ b/kernel/irq/numa_migrate.c @@ -42,7 +42,7 @@ static bool init_copy_one_irq_desc(int irq, struct irq_desc *old_desc, "for migration.\n", irq); return false; } - spin_lock_init(&desc->lock); + raw_spin_lock_init(&desc->lock); desc->node = node; lockdep_set_class(&desc->lock, &irq_desc_lock_class); init_copy_kstat_irqs(old_desc, desc, node, nr_cpu_ids); @@ -67,7 +67,7 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc, irq = old_desc->irq; - spin_lock_irqsave(&sparse_irq_lock, flags); + raw_spin_lock_irqsave(&sparse_irq_lock, flags); /* We have to check it to avoid races with another CPU */ desc = irq_desc_ptrs[irq]; @@ -91,7 +91,7 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc, } irq_desc_ptrs[irq] = desc; - spin_unlock_irqrestore(&sparse_irq_lock, flags); + raw_spin_unlock_irqrestore(&sparse_irq_lock, flags); /* free the old one */ free_one_irq_desc(old_desc, desc); @@ -100,7 +100,7 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc, return desc; out_unlock: - spin_unlock_irqrestore(&sparse_irq_lock, flags); + raw_spin_unlock_irqrestore(&sparse_irq_lock, flags); return desc; } diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c index a0bb09e..0d4005d8 100644 --- a/kernel/irq/pm.c +++ b/kernel/irq/pm.c @@ -28,9 +28,9 @@ void suspend_device_irqs(void) for_each_irq_desc(irq, desc) { unsigned long flags; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); __disable_irq(desc, irq, true); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } for_each_irq_desc(irq, desc) @@ -56,9 +56,9 @@ void resume_device_irqs(void) if (!(desc->status & IRQ_SUSPENDED)) continue; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); __enable_irq(desc, irq, true); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); } } EXPORT_SYMBOL_GPL(resume_device_irqs); diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index 0832145..6f50ecc 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -179,7 +179,7 @@ static int name_unique(unsigned int irq, struct irqaction *new_action) unsigned long flags; int ret = 1; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); for (action = desc->action ; action; action = action->next) { if ((action != new_action) && action->name && !strcmp(new_action->name, action->name)) { @@ -187,7 +187,7 @@ static int name_unique(unsigned int irq, struct irqaction *new_action) break; } } - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); return ret; } diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index e49ea1c..89fb90a 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c @@ -28,7 +28,7 @@ static int try_one_irq(int irq, struct irq_desc *desc) struct irqaction *action; int ok = 0, work = 0; - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); /* Already running on another processor */ if (desc->status & IRQ_INPROGRESS) { /* @@ -37,13 +37,13 @@ static int try_one_irq(int irq, struct irq_desc *desc) */ if (desc->action && (desc->action->flags & IRQF_SHARED)) desc->status |= IRQ_PENDING; - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); return ok; } /* Honour the normal IRQ locking */ desc->status |= IRQ_INPROGRESS; action = desc->action; - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); while (action) { /* Only shared IRQ handlers are safe to call */ @@ -56,7 +56,7 @@ static int try_one_irq(int irq, struct irq_desc *desc) } local_irq_disable(); /* Now clean up the flags */ - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); action = desc->action; /* @@ -68,9 +68,9 @@ static int try_one_irq(int irq, struct irq_desc *desc) * Perform real IRQ processing for the IRQ we deferred */ work = 1; - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); handle_IRQ_event(irq, action); - spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); desc->status &= ~IRQ_PENDING; } desc->status &= ~IRQ_INPROGRESS; @@ -80,7 +80,7 @@ static int try_one_irq(int irq, struct irq_desc *desc) */ if (work && desc->chip && desc->chip->end) desc->chip->end(irq); - spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); return ok; } -- cgit v0.10.2 From ecb49d1a639acbacfc3771cae5ec07bed5df3847 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 17 Nov 2009 16:36:54 +0100 Subject: hrtimers: Convert to raw_spinlocks Convert locks which cannot be sleeping locks in preempt-rt to raw_spinlocks. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index af634e9..5d86fb2 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -169,7 +169,7 @@ struct hrtimer_clock_base { * @max_hang_time: Maximum time spent in hrtimer_interrupt */ struct hrtimer_cpu_base { - spinlock_t lock; + raw_spinlock_t lock; struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; #ifdef CONFIG_HIGH_RES_TIMERS ktime_t expires_next; diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index d2f9239..0086628 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -127,11 +127,11 @@ struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer, for (;;) { base = timer->base; if (likely(base != NULL)) { - spin_lock_irqsave(&base->cpu_base->lock, *flags); + raw_spin_lock_irqsave(&base->cpu_base->lock, *flags); if (likely(base == timer->base)) return base; /* The timer has migrated to another CPU: */ - spin_unlock_irqrestore(&base->cpu_base->lock, *flags); + raw_spin_unlock_irqrestore(&base->cpu_base->lock, *flags); } cpu_relax(); } @@ -208,13 +208,13 @@ again: /* See the comment in lock_timer_base() */ timer->base = NULL; - spin_unlock(&base->cpu_base->lock); - spin_lock(&new_base->cpu_base->lock); + raw_spin_unlock(&base->cpu_base->lock); + raw_spin_lock(&new_base->cpu_base->lock); if (cpu != this_cpu && hrtimer_check_target(timer, new_base)) { cpu = this_cpu; - spin_unlock(&new_base->cpu_base->lock); - spin_lock(&base->cpu_base->lock); + raw_spin_unlock(&new_base->cpu_base->lock); + raw_spin_lock(&base->cpu_base->lock); timer->base = base; goto again; } @@ -230,7 +230,7 @@ lock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags) { struct hrtimer_clock_base *base = timer->base; - spin_lock_irqsave(&base->cpu_base->lock, *flags); + raw_spin_lock_irqsave(&base->cpu_base->lock, *flags); return base; } @@ -628,12 +628,12 @@ static void retrigger_next_event(void *arg) base = &__get_cpu_var(hrtimer_bases); /* Adjust CLOCK_REALTIME offset */ - spin_lock(&base->lock); + raw_spin_lock(&base->lock); base->clock_base[CLOCK_REALTIME].offset = timespec_to_ktime(realtime_offset); hrtimer_force_reprogram(base, 0); - spin_unlock(&base->lock); + raw_spin_unlock(&base->lock); } /* @@ -694,9 +694,9 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, { if (base->cpu_base->hres_active && hrtimer_reprogram(timer, base)) { if (wakeup) { - spin_unlock(&base->cpu_base->lock); + raw_spin_unlock(&base->cpu_base->lock); raise_softirq_irqoff(HRTIMER_SOFTIRQ); - spin_lock(&base->cpu_base->lock); + raw_spin_lock(&base->cpu_base->lock); } else __raise_softirq_irqoff(HRTIMER_SOFTIRQ); @@ -790,7 +790,7 @@ static inline void timer_stats_account_hrtimer(struct hrtimer *timer) static inline void unlock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags) { - spin_unlock_irqrestore(&timer->base->cpu_base->lock, *flags); + raw_spin_unlock_irqrestore(&timer->base->cpu_base->lock, *flags); } /** @@ -1123,7 +1123,7 @@ ktime_t hrtimer_get_next_event(void) unsigned long flags; int i; - spin_lock_irqsave(&cpu_base->lock, flags); + raw_spin_lock_irqsave(&cpu_base->lock, flags); if (!hrtimer_hres_active()) { for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++, base++) { @@ -1140,7 +1140,7 @@ ktime_t hrtimer_get_next_event(void) } } - spin_unlock_irqrestore(&cpu_base->lock, flags); + raw_spin_unlock_irqrestore(&cpu_base->lock, flags); if (mindelta.tv64 < 0) mindelta.tv64 = 0; @@ -1222,11 +1222,11 @@ static void __run_hrtimer(struct hrtimer *timer, ktime_t *now) * they get migrated to another cpu, therefore its safe to unlock * the timer base. */ - spin_unlock(&cpu_base->lock); + raw_spin_unlock(&cpu_base->lock); trace_hrtimer_expire_entry(timer, now); restart = fn(timer); trace_hrtimer_expire_exit(timer); - spin_lock(&cpu_base->lock); + raw_spin_lock(&cpu_base->lock); /* * Note: We clear the CALLBACK bit after enqueue_hrtimer and @@ -1261,7 +1261,7 @@ void hrtimer_interrupt(struct clock_event_device *dev) retry: expires_next.tv64 = KTIME_MAX; - spin_lock(&cpu_base->lock); + raw_spin_lock(&cpu_base->lock); /* * We set expires_next to KTIME_MAX here with cpu_base->lock * held to prevent that a timer is enqueued in our queue via @@ -1317,7 +1317,7 @@ retry: * against it. */ cpu_base->expires_next = expires_next; - spin_unlock(&cpu_base->lock); + raw_spin_unlock(&cpu_base->lock); /* Reprogramming necessary ? */ if (expires_next.tv64 == KTIME_MAX || @@ -1457,7 +1457,7 @@ void hrtimer_run_queues(void) gettime = 0; } - spin_lock(&cpu_base->lock); + raw_spin_lock(&cpu_base->lock); while ((node = base->first)) { struct hrtimer *timer; @@ -1469,7 +1469,7 @@ void hrtimer_run_queues(void) __run_hrtimer(timer, &base->softirq_time); } - spin_unlock(&cpu_base->lock); + raw_spin_unlock(&cpu_base->lock); } } @@ -1625,7 +1625,7 @@ static void __cpuinit init_hrtimers_cpu(int cpu) struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu); int i; - spin_lock_init(&cpu_base->lock); + raw_spin_lock_init(&cpu_base->lock); for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) cpu_base->clock_base[i].cpu_base = cpu_base; @@ -1683,16 +1683,16 @@ static void migrate_hrtimers(int scpu) * The caller is globally serialized and nobody else * takes two locks at once, deadlock is not possible. */ - spin_lock(&new_base->lock); - spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING); + raw_spin_lock(&new_base->lock); + raw_spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING); for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { migrate_hrtimer_list(&old_base->clock_base[i], &new_base->clock_base[i]); } - spin_unlock(&old_base->lock); - spin_unlock(&new_base->lock); + raw_spin_unlock(&old_base->lock); + raw_spin_unlock(&new_base->lock); /* Check, if we got expired work to do */ __hrtimer_peek_ahead_timers(); diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c index 9d80db4..2826563 100644 --- a/kernel/time/timer_list.c +++ b/kernel/time/timer_list.c @@ -84,7 +84,7 @@ print_active_timers(struct seq_file *m, struct hrtimer_clock_base *base, next_one: i = 0; - spin_lock_irqsave(&base->cpu_base->lock, flags); + raw_spin_lock_irqsave(&base->cpu_base->lock, flags); curr = base->first; /* @@ -100,13 +100,13 @@ next_one: timer = rb_entry(curr, struct hrtimer, node); tmp = *timer; - spin_unlock_irqrestore(&base->cpu_base->lock, flags); + raw_spin_unlock_irqrestore(&base->cpu_base->lock, flags); print_timer(m, timer, &tmp, i, now); next++; goto next_one; } - spin_unlock_irqrestore(&base->cpu_base->lock, flags); + raw_spin_unlock_irqrestore(&base->cpu_base->lock, flags); } static void diff --git a/kernel/time/timer_stats.c b/kernel/time/timer_stats.c index 63b117e..2f3b585 100644 --- a/kernel/time/timer_stats.c +++ b/kernel/time/timer_stats.c @@ -86,7 +86,7 @@ static DEFINE_SPINLOCK(table_lock); /* * Per-CPU lookup locks for fast hash lookup: */ -static DEFINE_PER_CPU(spinlock_t, tstats_lookup_lock); +static DEFINE_PER_CPU(raw_spinlock_t, tstats_lookup_lock); /* * Mutex to serialize state changes with show-stats activities: @@ -238,7 +238,7 @@ void timer_stats_update_stats(void *timer, pid_t pid, void *startf, /* * It doesnt matter which lock we take: */ - spinlock_t *lock; + raw_spinlock_t *lock; struct entry *entry, input; unsigned long flags; @@ -253,7 +253,7 @@ void timer_stats_update_stats(void *timer, pid_t pid, void *startf, input.pid = pid; input.timer_flag = timer_flag; - spin_lock_irqsave(lock, flags); + raw_spin_lock_irqsave(lock, flags); if (!timer_stats_active) goto out_unlock; @@ -264,7 +264,7 @@ void timer_stats_update_stats(void *timer, pid_t pid, void *startf, atomic_inc(&overflow_count); out_unlock: - spin_unlock_irqrestore(lock, flags); + raw_spin_unlock_irqrestore(lock, flags); } static void print_name_offset(struct seq_file *m, unsigned long addr) @@ -348,10 +348,11 @@ static void sync_access(void) int cpu; for_each_online_cpu(cpu) { - spinlock_t *lock = &per_cpu(tstats_lookup_lock, cpu); - spin_lock_irqsave(lock, flags); + raw_spinlock_t *lock = &per_cpu(tstats_lookup_lock, cpu); + + raw_spin_lock_irqsave(lock, flags); /* nothing */ - spin_unlock_irqrestore(lock, flags); + raw_spin_unlock_irqrestore(lock, flags); } } @@ -409,7 +410,7 @@ void __init init_timer_stats(void) int cpu; for_each_possible_cpu(cpu) - spin_lock_init(&per_cpu(tstats_lookup_lock, cpu)); + raw_spin_lock_init(&per_cpu(tstats_lookup_lock, cpu)); } static int __init init_tstats_procfs(void) -- cgit v0.10.2 From e625cce1b73fb38b74e5387226534f7bcbfc36fe Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 17 Nov 2009 18:02:06 +0100 Subject: perf_event: Convert to raw_spinlock Convert locks which cannot be sleeping locks in preempt-rt to raw_spinlocks. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 64a53f7..da7bdc2 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -681,7 +681,7 @@ struct perf_event_context { * Protect the states of the events in the list, * nr_active, and the list: */ - spinlock_t lock; + raw_spinlock_t lock; /* * Protect the list of events. Locking either mutex or lock * is sufficient to ensure the list doesn't change; to change diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c index 366eedf..dbcbf6a 100644 --- a/kernel/hw_breakpoint.c +++ b/kernel/hw_breakpoint.c @@ -96,7 +96,7 @@ static int task_bp_pinned(struct task_struct *tsk) list = &ctx->event_list; - spin_lock_irqsave(&ctx->lock, flags); + raw_spin_lock_irqsave(&ctx->lock, flags); /* * The current breakpoint counter is not included in the list @@ -107,7 +107,7 @@ static int task_bp_pinned(struct task_struct *tsk) count++; } - spin_unlock_irqrestore(&ctx->lock, flags); + raw_spin_unlock_irqrestore(&ctx->lock, flags); return count; } diff --git a/kernel/perf_event.c b/kernel/perf_event.c index e73e53c..9052d6c 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -203,14 +203,14 @@ perf_lock_task_context(struct task_struct *task, unsigned long *flags) * if so. If we locked the right context, then it * can't get swapped on us any more. */ - spin_lock_irqsave(&ctx->lock, *flags); + raw_spin_lock_irqsave(&ctx->lock, *flags); if (ctx != rcu_dereference(task->perf_event_ctxp)) { - spin_unlock_irqrestore(&ctx->lock, *flags); + raw_spin_unlock_irqrestore(&ctx->lock, *flags); goto retry; } if (!atomic_inc_not_zero(&ctx->refcount)) { - spin_unlock_irqrestore(&ctx->lock, *flags); + raw_spin_unlock_irqrestore(&ctx->lock, *flags); ctx = NULL; } } @@ -231,7 +231,7 @@ static struct perf_event_context *perf_pin_task_context(struct task_struct *task ctx = perf_lock_task_context(task, &flags); if (ctx) { ++ctx->pin_count; - spin_unlock_irqrestore(&ctx->lock, flags); + raw_spin_unlock_irqrestore(&ctx->lock, flags); } return ctx; } @@ -240,9 +240,9 @@ static void perf_unpin_context(struct perf_event_context *ctx) { unsigned long flags; - spin_lock_irqsave(&ctx->lock, flags); + raw_spin_lock_irqsave(&ctx->lock, flags); --ctx->pin_count; - spin_unlock_irqrestore(&ctx->lock, flags); + raw_spin_unlock_irqrestore(&ctx->lock, flags); put_ctx(ctx); } @@ -427,7 +427,7 @@ static void __perf_event_remove_from_context(void *info) if (ctx->task && cpuctx->task_ctx != ctx) return; - spin_lock(&ctx->lock); + raw_spin_lock(&ctx->lock); /* * Protect the list operation against NMI by disabling the * events on a global level. @@ -449,7 +449,7 @@ static void __perf_event_remove_from_context(void *info) } perf_enable(); - spin_unlock(&ctx->lock); + raw_spin_unlock(&ctx->lock); } @@ -488,12 +488,12 @@ retry: task_oncpu_function_call(task, __perf_event_remove_from_context, event); - spin_lock_irq(&ctx->lock); + raw_spin_lock_irq(&ctx->lock); /* * If the context is active we need to retry the smp call. */ if (ctx->nr_active && !list_empty(&event->group_entry)) { - spin_unlock_irq(&ctx->lock); + raw_spin_unlock_irq(&ctx->lock); goto retry; } @@ -504,7 +504,7 @@ retry: */ if (!list_empty(&event->group_entry)) list_del_event(event, ctx); - spin_unlock_irq(&ctx->lock); + raw_spin_unlock_irq(&ctx->lock); } /* @@ -535,7 +535,7 @@ static void __perf_event_disable(void *info) if (ctx->task && cpuctx->task_ctx != ctx) return; - spin_lock(&ctx->lock); + raw_spin_lock(&ctx->lock); /* * If the event is on, turn it off. @@ -551,7 +551,7 @@ static void __perf_event_disable(void *info) event->state = PERF_EVENT_STATE_OFF; } - spin_unlock(&ctx->lock); + raw_spin_unlock(&ctx->lock); } /* @@ -584,12 +584,12 @@ void perf_event_disable(struct perf_event *event) retry: task_oncpu_function_call(task, __perf_event_disable, event); - spin_lock_irq(&ctx->lock); + raw_spin_lock_irq(&ctx->lock); /* * If the event is still active, we need to retry the cross-call. */ if (event->state == PERF_EVENT_STATE_ACTIVE) { - spin_unlock_irq(&ctx->lock); + raw_spin_unlock_irq(&ctx->lock); goto retry; } @@ -602,7 +602,7 @@ void perf_event_disable(struct perf_event *event) event->state = PERF_EVENT_STATE_OFF; } - spin_unlock_irq(&ctx->lock); + raw_spin_unlock_irq(&ctx->lock); } static int @@ -770,7 +770,7 @@ static void __perf_install_in_context(void *info) cpuctx->task_ctx = ctx; } - spin_lock(&ctx->lock); + raw_spin_lock(&ctx->lock); ctx->is_active = 1; update_context_time(ctx); @@ -820,7 +820,7 @@ static void __perf_install_in_context(void *info) unlock: perf_enable(); - spin_unlock(&ctx->lock); + raw_spin_unlock(&ctx->lock); } /* @@ -856,12 +856,12 @@ retry: task_oncpu_function_call(task, __perf_install_in_context, event); - spin_lock_irq(&ctx->lock); + raw_spin_lock_irq(&ctx->lock); /* * we need to retry the smp call. */ if (ctx->is_active && list_empty(&event->group_entry)) { - spin_unlock_irq(&ctx->lock); + raw_spin_unlock_irq(&ctx->lock); goto retry; } @@ -872,7 +872,7 @@ retry: */ if (list_empty(&event->group_entry)) add_event_to_ctx(event, ctx); - spin_unlock_irq(&ctx->lock); + raw_spin_unlock_irq(&ctx->lock); } /* @@ -917,7 +917,7 @@ static void __perf_event_enable(void *info) cpuctx->task_ctx = ctx; } - spin_lock(&ctx->lock); + raw_spin_lock(&ctx->lock); ctx->is_active = 1; update_context_time(ctx); @@ -959,7 +959,7 @@ static void __perf_event_enable(void *info) } unlock: - spin_unlock(&ctx->lock); + raw_spin_unlock(&ctx->lock); } /* @@ -985,7 +985,7 @@ void perf_event_enable(struct perf_event *event) return; } - spin_lock_irq(&ctx->lock); + raw_spin_lock_irq(&ctx->lock); if (event->state >= PERF_EVENT_STATE_INACTIVE) goto out; @@ -1000,10 +1000,10 @@ void perf_event_enable(struct perf_event *event) event->state = PERF_EVENT_STATE_OFF; retry: - spin_unlock_irq(&ctx->lock); + raw_spin_unlock_irq(&ctx->lock); task_oncpu_function_call(task, __perf_event_enable, event); - spin_lock_irq(&ctx->lock); + raw_spin_lock_irq(&ctx->lock); /* * If the context is active and the event is still off, @@ -1020,7 +1020,7 @@ void perf_event_enable(struct perf_event *event) __perf_event_mark_enabled(event, ctx); out: - spin_unlock_irq(&ctx->lock); + raw_spin_unlock_irq(&ctx->lock); } static int perf_event_refresh(struct perf_event *event, int refresh) @@ -1042,7 +1042,7 @@ void __perf_event_sched_out(struct perf_event_context *ctx, { struct perf_event *event; - spin_lock(&ctx->lock); + raw_spin_lock(&ctx->lock); ctx->is_active = 0; if (likely(!ctx->nr_events)) goto out; @@ -1055,7 +1055,7 @@ void __perf_event_sched_out(struct perf_event_context *ctx, } perf_enable(); out: - spin_unlock(&ctx->lock); + raw_spin_unlock(&ctx->lock); } /* @@ -1193,8 +1193,8 @@ void perf_event_task_sched_out(struct task_struct *task, * order we take the locks because no other cpu could * be trying to lock both of these tasks. */ - spin_lock(&ctx->lock); - spin_lock_nested(&next_ctx->lock, SINGLE_DEPTH_NESTING); + raw_spin_lock(&ctx->lock); + raw_spin_lock_nested(&next_ctx->lock, SINGLE_DEPTH_NESTING); if (context_equiv(ctx, next_ctx)) { /* * XXX do we need a memory barrier of sorts @@ -1208,8 +1208,8 @@ void perf_event_task_sched_out(struct task_struct *task, perf_event_sync_stat(ctx, next_ctx); } - spin_unlock(&next_ctx->lock); - spin_unlock(&ctx->lock); + raw_spin_unlock(&next_ctx->lock); + raw_spin_unlock(&ctx->lock); } rcu_read_unlock(); @@ -1251,7 +1251,7 @@ __perf_event_sched_in(struct perf_event_context *ctx, struct perf_event *event; int can_add_hw = 1; - spin_lock(&ctx->lock); + raw_spin_lock(&ctx->lock); ctx->is_active = 1; if (likely(!ctx->nr_events)) goto out; @@ -1306,7 +1306,7 @@ __perf_event_sched_in(struct perf_event_context *ctx, } perf_enable(); out: - spin_unlock(&ctx->lock); + raw_spin_unlock(&ctx->lock); } /* @@ -1370,7 +1370,7 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx) struct hw_perf_event *hwc; u64 interrupts, freq; - spin_lock(&ctx->lock); + raw_spin_lock(&ctx->lock); list_for_each_entry_rcu(event, &ctx->event_list, event_entry) { if (event->state != PERF_EVENT_STATE_ACTIVE) continue; @@ -1425,7 +1425,7 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx) perf_enable(); } } - spin_unlock(&ctx->lock); + raw_spin_unlock(&ctx->lock); } /* @@ -1438,7 +1438,7 @@ static void rotate_ctx(struct perf_event_context *ctx) if (!ctx->nr_events) return; - spin_lock(&ctx->lock); + raw_spin_lock(&ctx->lock); /* * Rotate the first entry last (works just fine for group events too): */ @@ -1449,7 +1449,7 @@ static void rotate_ctx(struct perf_event_context *ctx) } perf_enable(); - spin_unlock(&ctx->lock); + raw_spin_unlock(&ctx->lock); } void perf_event_task_tick(struct task_struct *curr, int cpu) @@ -1498,7 +1498,7 @@ static void perf_event_enable_on_exec(struct task_struct *task) __perf_event_task_sched_out(ctx); - spin_lock(&ctx->lock); + raw_spin_lock(&ctx->lock); list_for_each_entry(event, &ctx->group_list, group_entry) { if (!event->attr.enable_on_exec) @@ -1516,7 +1516,7 @@ static void perf_event_enable_on_exec(struct task_struct *task) if (enabled) unclone_ctx(ctx); - spin_unlock(&ctx->lock); + raw_spin_unlock(&ctx->lock); perf_event_task_sched_in(task, smp_processor_id()); out: @@ -1542,10 +1542,10 @@ static void __perf_event_read(void *info) if (ctx->task && cpuctx->task_ctx != ctx) return; - spin_lock(&ctx->lock); + raw_spin_lock(&ctx->lock); update_context_time(ctx); update_event_times(event); - spin_unlock(&ctx->lock); + raw_spin_unlock(&ctx->lock); event->pmu->read(event); } @@ -1563,10 +1563,10 @@ static u64 perf_event_read(struct perf_event *event) struct perf_event_context *ctx = event->ctx; unsigned long flags; - spin_lock_irqsave(&ctx->lock, flags); + raw_spin_lock_irqsave(&ctx->lock, flags); update_context_time(ctx); update_event_times(event); - spin_unlock_irqrestore(&ctx->lock, flags); + raw_spin_unlock_irqrestore(&ctx->lock, flags); } return atomic64_read(&event->count); @@ -1579,7 +1579,7 @@ static void __perf_event_init_context(struct perf_event_context *ctx, struct task_struct *task) { - spin_lock_init(&ctx->lock); + raw_spin_lock_init(&ctx->lock); mutex_init(&ctx->mutex); INIT_LIST_HEAD(&ctx->group_list); INIT_LIST_HEAD(&ctx->event_list); @@ -1649,7 +1649,7 @@ static struct perf_event_context *find_get_context(pid_t pid, int cpu) ctx = perf_lock_task_context(task, &flags); if (ctx) { unclone_ctx(ctx); - spin_unlock_irqrestore(&ctx->lock, flags); + raw_spin_unlock_irqrestore(&ctx->lock, flags); } if (!ctx) { @@ -1987,7 +1987,7 @@ static int perf_event_period(struct perf_event *event, u64 __user *arg) if (!value) return -EINVAL; - spin_lock_irq(&ctx->lock); + raw_spin_lock_irq(&ctx->lock); if (event->attr.freq) { if (value > sysctl_perf_event_sample_rate) { ret = -EINVAL; @@ -2000,7 +2000,7 @@ static int perf_event_period(struct perf_event *event, u64 __user *arg) event->hw.sample_period = value; } unlock: - spin_unlock_irq(&ctx->lock); + raw_spin_unlock_irq(&ctx->lock); return ret; } @@ -4992,7 +4992,7 @@ void perf_event_exit_task(struct task_struct *child) * reading child->perf_event_ctxp, we wait until it has * incremented the context's refcount before we do put_ctx below. */ - spin_lock(&child_ctx->lock); + raw_spin_lock(&child_ctx->lock); child->perf_event_ctxp = NULL; /* * If this context is a clone; unclone it so it can't get @@ -5001,7 +5001,7 @@ void perf_event_exit_task(struct task_struct *child) */ unclone_ctx(child_ctx); update_context_time(child_ctx); - spin_unlock_irqrestore(&child_ctx->lock, flags); + raw_spin_unlock_irqrestore(&child_ctx->lock, flags); /* * Report the task dead after unscheduling the events so that we @@ -5292,11 +5292,11 @@ perf_set_reserve_percpu(struct sysdev_class *class, perf_reserved_percpu = val; for_each_online_cpu(cpu) { cpuctx = &per_cpu(perf_cpu_context, cpu); - spin_lock_irq(&cpuctx->ctx.lock); + raw_spin_lock_irq(&cpuctx->ctx.lock); mpt = min(perf_max_events - cpuctx->ctx.nr_events, perf_max_events - perf_reserved_percpu); cpuctx->max_pertask = mpt; - spin_unlock_irq(&cpuctx->ctx.lock); + raw_spin_unlock_irq(&cpuctx->ctx.lock); } spin_unlock(&perf_resource_lock); -- cgit v0.10.2 From aef9cb05247df3d7615773737beb4f83d78577bb Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 17 Nov 2009 18:11:28 +0100 Subject: debugobjects: Convert to raw_spinlocks Convert locks which cannot be sleeping locks in preempt-rt to raw_spinlocks. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/lib/debugobjects.c b/lib/debugobjects.c index eae56fd..a9a8996 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -26,14 +26,14 @@ struct debug_bucket { struct hlist_head list; - spinlock_t lock; + raw_spinlock_t lock; }; static struct debug_bucket obj_hash[ODEBUG_HASH_SIZE]; static struct debug_obj obj_static_pool[ODEBUG_POOL_SIZE] __initdata; -static DEFINE_SPINLOCK(pool_lock); +static DEFINE_RAW_SPINLOCK(pool_lock); static HLIST_HEAD(obj_pool); @@ -96,10 +96,10 @@ static int fill_pool(void) if (!new) return obj_pool_free; - spin_lock_irqsave(&pool_lock, flags); + raw_spin_lock_irqsave(&pool_lock, flags); hlist_add_head(&new->node, &obj_pool); obj_pool_free++; - spin_unlock_irqrestore(&pool_lock, flags); + raw_spin_unlock_irqrestore(&pool_lock, flags); } return obj_pool_free; } @@ -133,7 +133,7 @@ alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr) { struct debug_obj *obj = NULL; - spin_lock(&pool_lock); + raw_spin_lock(&pool_lock); if (obj_pool.first) { obj = hlist_entry(obj_pool.first, typeof(*obj), node); @@ -152,7 +152,7 @@ alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr) if (obj_pool_free < obj_pool_min_free) obj_pool_min_free = obj_pool_free; } - spin_unlock(&pool_lock); + raw_spin_unlock(&pool_lock); return obj; } @@ -165,7 +165,7 @@ static void free_obj_work(struct work_struct *work) struct debug_obj *obj; unsigned long flags; - spin_lock_irqsave(&pool_lock, flags); + raw_spin_lock_irqsave(&pool_lock, flags); while (obj_pool_free > ODEBUG_POOL_SIZE) { obj = hlist_entry(obj_pool.first, typeof(*obj), node); hlist_del(&obj->node); @@ -174,11 +174,11 @@ static void free_obj_work(struct work_struct *work) * We release pool_lock across kmem_cache_free() to * avoid contention on pool_lock. */ - spin_unlock_irqrestore(&pool_lock, flags); + raw_spin_unlock_irqrestore(&pool_lock, flags); kmem_cache_free(obj_cache, obj); - spin_lock_irqsave(&pool_lock, flags); + raw_spin_lock_irqsave(&pool_lock, flags); } - spin_unlock_irqrestore(&pool_lock, flags); + raw_spin_unlock_irqrestore(&pool_lock, flags); } /* @@ -190,7 +190,7 @@ static void free_object(struct debug_obj *obj) unsigned long flags; int sched = 0; - spin_lock_irqsave(&pool_lock, flags); + raw_spin_lock_irqsave(&pool_lock, flags); /* * schedule work when the pool is filled and the cache is * initialized: @@ -200,7 +200,7 @@ static void free_object(struct debug_obj *obj) hlist_add_head(&obj->node, &obj_pool); obj_pool_free++; obj_pool_used--; - spin_unlock_irqrestore(&pool_lock, flags); + raw_spin_unlock_irqrestore(&pool_lock, flags); if (sched) schedule_work(&debug_obj_work); } @@ -221,9 +221,9 @@ static void debug_objects_oom(void) printk(KERN_WARNING "ODEBUG: Out of memory. ODEBUG disabled\n"); for (i = 0; i < ODEBUG_HASH_SIZE; i++, db++) { - spin_lock_irqsave(&db->lock, flags); + raw_spin_lock_irqsave(&db->lock, flags); hlist_move_list(&db->list, &freelist); - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); /* Now free them */ hlist_for_each_entry_safe(obj, node, tmp, &freelist, node) { @@ -303,14 +303,14 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) db = get_bucket((unsigned long) addr); - spin_lock_irqsave(&db->lock, flags); + raw_spin_lock_irqsave(&db->lock, flags); obj = lookup_object(addr, db); if (!obj) { obj = alloc_object(addr, db, descr); if (!obj) { debug_objects_enabled = 0; - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); debug_objects_oom(); return; } @@ -327,7 +327,7 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) case ODEBUG_STATE_ACTIVE: debug_print_object(obj, "init"); state = obj->state; - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); debug_object_fixup(descr->fixup_init, addr, state); return; @@ -338,7 +338,7 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) break; } - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); } /** @@ -385,7 +385,7 @@ void debug_object_activate(void *addr, struct debug_obj_descr *descr) db = get_bucket((unsigned long) addr); - spin_lock_irqsave(&db->lock, flags); + raw_spin_lock_irqsave(&db->lock, flags); obj = lookup_object(addr, db); if (obj) { @@ -398,7 +398,7 @@ void debug_object_activate(void *addr, struct debug_obj_descr *descr) case ODEBUG_STATE_ACTIVE: debug_print_object(obj, "activate"); state = obj->state; - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); debug_object_fixup(descr->fixup_activate, addr, state); return; @@ -408,11 +408,11 @@ void debug_object_activate(void *addr, struct debug_obj_descr *descr) default: break; } - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); return; } - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); /* * This happens when a static object is activated. We * let the type specific code decide whether this is @@ -438,7 +438,7 @@ void debug_object_deactivate(void *addr, struct debug_obj_descr *descr) db = get_bucket((unsigned long) addr); - spin_lock_irqsave(&db->lock, flags); + raw_spin_lock_irqsave(&db->lock, flags); obj = lookup_object(addr, db); if (obj) { @@ -463,7 +463,7 @@ void debug_object_deactivate(void *addr, struct debug_obj_descr *descr) debug_print_object(&o, "deactivate"); } - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); } /** @@ -483,7 +483,7 @@ void debug_object_destroy(void *addr, struct debug_obj_descr *descr) db = get_bucket((unsigned long) addr); - spin_lock_irqsave(&db->lock, flags); + raw_spin_lock_irqsave(&db->lock, flags); obj = lookup_object(addr, db); if (!obj) @@ -498,7 +498,7 @@ void debug_object_destroy(void *addr, struct debug_obj_descr *descr) case ODEBUG_STATE_ACTIVE: debug_print_object(obj, "destroy"); state = obj->state; - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); debug_object_fixup(descr->fixup_destroy, addr, state); return; @@ -509,7 +509,7 @@ void debug_object_destroy(void *addr, struct debug_obj_descr *descr) break; } out_unlock: - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); } /** @@ -529,7 +529,7 @@ void debug_object_free(void *addr, struct debug_obj_descr *descr) db = get_bucket((unsigned long) addr); - spin_lock_irqsave(&db->lock, flags); + raw_spin_lock_irqsave(&db->lock, flags); obj = lookup_object(addr, db); if (!obj) @@ -539,17 +539,17 @@ void debug_object_free(void *addr, struct debug_obj_descr *descr) case ODEBUG_STATE_ACTIVE: debug_print_object(obj, "free"); state = obj->state; - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); debug_object_fixup(descr->fixup_free, addr, state); return; default: hlist_del(&obj->node); - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); free_object(obj); return; } out_unlock: - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); } #ifdef CONFIG_DEBUG_OBJECTS_FREE @@ -575,7 +575,7 @@ static void __debug_check_no_obj_freed(const void *address, unsigned long size) repeat: cnt = 0; - spin_lock_irqsave(&db->lock, flags); + raw_spin_lock_irqsave(&db->lock, flags); hlist_for_each_entry_safe(obj, node, tmp, &db->list, node) { cnt++; oaddr = (unsigned long) obj->object; @@ -587,7 +587,7 @@ repeat: debug_print_object(obj, "free"); descr = obj->descr; state = obj->state; - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); debug_object_fixup(descr->fixup_free, (void *) oaddr, state); goto repeat; @@ -597,7 +597,7 @@ repeat: break; } } - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); /* Now free them */ hlist_for_each_entry_safe(obj, node, tmp, &freelist, node) { @@ -783,7 +783,7 @@ check_results(void *addr, enum debug_obj_state state, int fixups, int warnings) db = get_bucket((unsigned long) addr); - spin_lock_irqsave(&db->lock, flags); + raw_spin_lock_irqsave(&db->lock, flags); obj = lookup_object(addr, db); if (!obj && state != ODEBUG_STATE_NONE) { @@ -807,7 +807,7 @@ check_results(void *addr, enum debug_obj_state state, int fixups, int warnings) } res = 0; out: - spin_unlock_irqrestore(&db->lock, flags); + raw_spin_unlock_irqrestore(&db->lock, flags); if (res) debug_objects_enabled = 0; return res; @@ -907,7 +907,7 @@ void __init debug_objects_early_init(void) int i; for (i = 0; i < ODEBUG_HASH_SIZE; i++) - spin_lock_init(&obj_hash[i].lock); + raw_spin_lock_init(&obj_hash[i].lock); for (i = 0; i < ODEBUG_POOL_SIZE; i++) hlist_add_head(&obj_static_pool[i].node, &obj_pool); -- cgit v0.10.2 From d192c47f25daa98996c7eae543d8a27e41247ec2 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 8 Dec 2009 12:49:26 +0100 Subject: clockevents: Make tick_device_lock static Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index 83c4417..af39cf1 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -34,7 +34,7 @@ DEFINE_PER_CPU(struct tick_device, tick_cpu_device); ktime_t tick_next_period; ktime_t tick_period; int tick_do_timer_cpu __read_mostly = TICK_DO_TIMER_BOOT; -DEFINE_SPINLOCK(tick_device_lock); +static DEFINE_SPINLOCK(tick_device_lock); /* * Debugging: see timer_list.c diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h index b1c05bf..290eefb 100644 --- a/kernel/time/tick-internal.h +++ b/kernel/time/tick-internal.h @@ -6,7 +6,6 @@ #define TICK_DO_TIMER_BOOT -2 DECLARE_PER_CPU(struct tick_device, tick_cpu_device); -extern spinlock_t tick_device_lock; extern ktime_t tick_next_period; extern ktime_t tick_period; extern int tick_do_timer_cpu __read_mostly; -- cgit v0.10.2 From b5f91da0a6973bb6f9ff3b91b0e92c0773a458f3 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 8 Dec 2009 12:40:31 +0100 Subject: clockevents: Convert to raw_spinlock Convert locks which cannot be sleeping locks in preempt-rt to raw_spinlocks. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra Acked-by: Ingo Molnar diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 20a8920..3d5fc0f 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -30,7 +30,7 @@ static LIST_HEAD(clockevents_released); static RAW_NOTIFIER_HEAD(clockevents_chain); /* Protection for the above */ -static DEFINE_SPINLOCK(clockevents_lock); +static DEFINE_RAW_SPINLOCK(clockevents_lock); /** * clockevents_delta2ns - Convert a latch value (device ticks) to nanoseconds @@ -141,9 +141,9 @@ int clockevents_register_notifier(struct notifier_block *nb) unsigned long flags; int ret; - spin_lock_irqsave(&clockevents_lock, flags); + raw_spin_lock_irqsave(&clockevents_lock, flags); ret = raw_notifier_chain_register(&clockevents_chain, nb); - spin_unlock_irqrestore(&clockevents_lock, flags); + raw_spin_unlock_irqrestore(&clockevents_lock, flags); return ret; } @@ -185,13 +185,13 @@ void clockevents_register_device(struct clock_event_device *dev) BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED); BUG_ON(!dev->cpumask); - spin_lock_irqsave(&clockevents_lock, flags); + raw_spin_lock_irqsave(&clockevents_lock, flags); list_add(&dev->list, &clockevent_devices); clockevents_do_notify(CLOCK_EVT_NOTIFY_ADD, dev); clockevents_notify_released(); - spin_unlock_irqrestore(&clockevents_lock, flags); + raw_spin_unlock_irqrestore(&clockevents_lock, flags); } EXPORT_SYMBOL_GPL(clockevents_register_device); @@ -241,7 +241,7 @@ void clockevents_notify(unsigned long reason, void *arg) struct list_head *node, *tmp; unsigned long flags; - spin_lock_irqsave(&clockevents_lock, flags); + raw_spin_lock_irqsave(&clockevents_lock, flags); clockevents_do_notify(reason, arg); switch (reason) { @@ -256,7 +256,7 @@ void clockevents_notify(unsigned long reason, void *arg) default: break; } - spin_unlock_irqrestore(&clockevents_lock, flags); + raw_spin_unlock_irqrestore(&clockevents_lock, flags); } EXPORT_SYMBOL_GPL(clockevents_notify); #endif diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index c2ec250..b3bafd5 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -31,7 +31,7 @@ static struct tick_device tick_broadcast_device; /* FIXME: Use cpumask_var_t. */ static DECLARE_BITMAP(tick_broadcast_mask, NR_CPUS); static DECLARE_BITMAP(tmpmask, NR_CPUS); -static DEFINE_SPINLOCK(tick_broadcast_lock); +static DEFINE_RAW_SPINLOCK(tick_broadcast_lock); static int tick_broadcast_force; #ifdef CONFIG_TICK_ONESHOT @@ -96,7 +96,7 @@ int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu) unsigned long flags; int ret = 0; - spin_lock_irqsave(&tick_broadcast_lock, flags); + raw_spin_lock_irqsave(&tick_broadcast_lock, flags); /* * Devices might be registered with both periodic and oneshot @@ -122,7 +122,7 @@ int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu) tick_broadcast_clear_oneshot(cpu); } } - spin_unlock_irqrestore(&tick_broadcast_lock, flags); + raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); return ret; } @@ -161,13 +161,13 @@ static void tick_do_broadcast(struct cpumask *mask) */ static void tick_do_periodic_broadcast(void) { - spin_lock(&tick_broadcast_lock); + raw_spin_lock(&tick_broadcast_lock); cpumask_and(to_cpumask(tmpmask), cpu_online_mask, tick_get_broadcast_mask()); tick_do_broadcast(to_cpumask(tmpmask)); - spin_unlock(&tick_broadcast_lock); + raw_spin_unlock(&tick_broadcast_lock); } /* @@ -212,7 +212,7 @@ static void tick_do_broadcast_on_off(unsigned long *reason) unsigned long flags; int cpu, bc_stopped; - spin_lock_irqsave(&tick_broadcast_lock, flags); + raw_spin_lock_irqsave(&tick_broadcast_lock, flags); cpu = smp_processor_id(); td = &per_cpu(tick_cpu_device, cpu); @@ -263,7 +263,7 @@ static void tick_do_broadcast_on_off(unsigned long *reason) tick_broadcast_setup_oneshot(bc); } out: - spin_unlock_irqrestore(&tick_broadcast_lock, flags); + raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); } /* @@ -299,7 +299,7 @@ void tick_shutdown_broadcast(unsigned int *cpup) unsigned long flags; unsigned int cpu = *cpup; - spin_lock_irqsave(&tick_broadcast_lock, flags); + raw_spin_lock_irqsave(&tick_broadcast_lock, flags); bc = tick_broadcast_device.evtdev; cpumask_clear_cpu(cpu, tick_get_broadcast_mask()); @@ -309,7 +309,7 @@ void tick_shutdown_broadcast(unsigned int *cpup) clockevents_shutdown(bc); } - spin_unlock_irqrestore(&tick_broadcast_lock, flags); + raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); } void tick_suspend_broadcast(void) @@ -317,13 +317,13 @@ void tick_suspend_broadcast(void) struct clock_event_device *bc; unsigned long flags; - spin_lock_irqsave(&tick_broadcast_lock, flags); + raw_spin_lock_irqsave(&tick_broadcast_lock, flags); bc = tick_broadcast_device.evtdev; if (bc) clockevents_shutdown(bc); - spin_unlock_irqrestore(&tick_broadcast_lock, flags); + raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); } int tick_resume_broadcast(void) @@ -332,7 +332,7 @@ int tick_resume_broadcast(void) unsigned long flags; int broadcast = 0; - spin_lock_irqsave(&tick_broadcast_lock, flags); + raw_spin_lock_irqsave(&tick_broadcast_lock, flags); bc = tick_broadcast_device.evtdev; @@ -351,7 +351,7 @@ int tick_resume_broadcast(void) break; } } - spin_unlock_irqrestore(&tick_broadcast_lock, flags); + raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); return broadcast; } @@ -405,7 +405,7 @@ static void tick_handle_oneshot_broadcast(struct clock_event_device *dev) ktime_t now, next_event; int cpu; - spin_lock(&tick_broadcast_lock); + raw_spin_lock(&tick_broadcast_lock); again: dev->next_event.tv64 = KTIME_MAX; next_event.tv64 = KTIME_MAX; @@ -443,7 +443,7 @@ again: if (tick_broadcast_set_event(next_event, 0)) goto again; } - spin_unlock(&tick_broadcast_lock); + raw_spin_unlock(&tick_broadcast_lock); } /* @@ -457,7 +457,7 @@ void tick_broadcast_oneshot_control(unsigned long reason) unsigned long flags; int cpu; - spin_lock_irqsave(&tick_broadcast_lock, flags); + raw_spin_lock_irqsave(&tick_broadcast_lock, flags); /* * Periodic mode does not care about the enter/exit of power @@ -492,7 +492,7 @@ void tick_broadcast_oneshot_control(unsigned long reason) } out: - spin_unlock_irqrestore(&tick_broadcast_lock, flags); + raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); } /* @@ -563,13 +563,13 @@ void tick_broadcast_switch_to_oneshot(void) struct clock_event_device *bc; unsigned long flags; - spin_lock_irqsave(&tick_broadcast_lock, flags); + raw_spin_lock_irqsave(&tick_broadcast_lock, flags); tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT; bc = tick_broadcast_device.evtdev; if (bc) tick_broadcast_setup_oneshot(bc); - spin_unlock_irqrestore(&tick_broadcast_lock, flags); + raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); } @@ -581,7 +581,7 @@ void tick_shutdown_broadcast_oneshot(unsigned int *cpup) unsigned long flags; unsigned int cpu = *cpup; - spin_lock_irqsave(&tick_broadcast_lock, flags); + raw_spin_lock_irqsave(&tick_broadcast_lock, flags); /* * Clear the broadcast mask flag for the dead cpu, but do not @@ -589,7 +589,7 @@ void tick_shutdown_broadcast_oneshot(unsigned int *cpup) */ cpumask_clear_cpu(cpu, tick_get_broadcast_oneshot_mask()); - spin_unlock_irqrestore(&tick_broadcast_lock, flags); + raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); } /* diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index af39cf1..b6b898d 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -34,7 +34,7 @@ DEFINE_PER_CPU(struct tick_device, tick_cpu_device); ktime_t tick_next_period; ktime_t tick_period; int tick_do_timer_cpu __read_mostly = TICK_DO_TIMER_BOOT; -static DEFINE_SPINLOCK(tick_device_lock); +static DEFINE_RAW_SPINLOCK(tick_device_lock); /* * Debugging: see timer_list.c @@ -209,7 +209,7 @@ static int tick_check_new_device(struct clock_event_device *newdev) int cpu, ret = NOTIFY_OK; unsigned long flags; - spin_lock_irqsave(&tick_device_lock, flags); + raw_spin_lock_irqsave(&tick_device_lock, flags); cpu = smp_processor_id(); if (!cpumask_test_cpu(cpu, newdev->cpumask)) @@ -268,7 +268,7 @@ static int tick_check_new_device(struct clock_event_device *newdev) if (newdev->features & CLOCK_EVT_FEAT_ONESHOT) tick_oneshot_notify(); - spin_unlock_irqrestore(&tick_device_lock, flags); + raw_spin_unlock_irqrestore(&tick_device_lock, flags); return NOTIFY_STOP; out_bc: @@ -278,7 +278,7 @@ out_bc: if (tick_check_broadcast_device(newdev)) ret = NOTIFY_STOP; - spin_unlock_irqrestore(&tick_device_lock, flags); + raw_spin_unlock_irqrestore(&tick_device_lock, flags); return ret; } @@ -311,7 +311,7 @@ static void tick_shutdown(unsigned int *cpup) struct clock_event_device *dev = td->evtdev; unsigned long flags; - spin_lock_irqsave(&tick_device_lock, flags); + raw_spin_lock_irqsave(&tick_device_lock, flags); td->mode = TICKDEV_MODE_PERIODIC; if (dev) { /* @@ -322,7 +322,7 @@ static void tick_shutdown(unsigned int *cpup) clockevents_exchange_device(dev, NULL); td->evtdev = NULL; } - spin_unlock_irqrestore(&tick_device_lock, flags); + raw_spin_unlock_irqrestore(&tick_device_lock, flags); } static void tick_suspend(void) @@ -330,9 +330,9 @@ static void tick_suspend(void) struct tick_device *td = &__get_cpu_var(tick_cpu_device); unsigned long flags; - spin_lock_irqsave(&tick_device_lock, flags); + raw_spin_lock_irqsave(&tick_device_lock, flags); clockevents_shutdown(td->evtdev); - spin_unlock_irqrestore(&tick_device_lock, flags); + raw_spin_unlock_irqrestore(&tick_device_lock, flags); } static void tick_resume(void) @@ -341,7 +341,7 @@ static void tick_resume(void) unsigned long flags; int broadcast = tick_resume_broadcast(); - spin_lock_irqsave(&tick_device_lock, flags); + raw_spin_lock_irqsave(&tick_device_lock, flags); clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_RESUME); if (!broadcast) { @@ -350,7 +350,7 @@ static void tick_resume(void) else tick_resume_oneshot(); } - spin_unlock_irqrestore(&tick_device_lock, flags); + raw_spin_unlock_irqrestore(&tick_device_lock, flags); } /* -- cgit v0.10.2 From 57ecb34febc4c133ca0ccc7817796605a78a01d3 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Tue, 1 Dec 2009 19:42:57 -0500 Subject: nfsd4: fix share mode permissions NFSv4 opens may function as locks denying other NFSv4 users the rights to open a file. We're requiring a user to have write permissions before they can deny write. We're *not* requiring a user to have write permissions to deny read, which is if anything a more drastic denial. What was intended was to require write permissions for DENY_READ. Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 60a93cd..a468224 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -171,7 +171,7 @@ do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs accmode |= NFSD_MAY_READ; if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) accmode |= (NFSD_MAY_WRITE | NFSD_MAY_TRUNC); - if (open->op_share_deny & NFS4_SHARE_DENY_WRITE) + if (open->op_share_deny & NFS4_SHARE_DENY_READ) accmode |= NFSD_MAY_WRITE; status = fh_verify(rqstp, current_fh, S_IFREG, accmode); -- cgit v0.10.2 From 4056c9a344d60ee96471a5f3b0a3c8a90371c8fd Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Thu, 3 Dec 2009 20:28:04 +0200 Subject: nfsd: Remove unused dprintk This doesn't appear to be useful. Signed-off-by: Boaz Harrosh Signed-off-by: J. Bruce Fields diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h index 8f641c9..2973e11 100644 --- a/include/linux/nfsd/nfsfh.h +++ b/include/linux/nfsd/nfsfh.h @@ -20,7 +20,6 @@ # include #endif #include -#include /* * This is the old "dentry style" Linux NFSv2 file handle. @@ -329,9 +328,6 @@ fh_lock_nested(struct svc_fh *fhp, unsigned int subclass) struct dentry *dentry = fhp->fh_dentry; struct inode *inode; - dfprintk(FILEOP, "nfsd: fh_lock(%s) locked = %d\n", - SVCFH_fmt(fhp), fhp->fh_locked); - BUG_ON(!dentry); if (fhp->fh_locked) { -- cgit v0.10.2 From a600ffcbb3743cf1296bee2a41d4824c719d7181 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Thu, 3 Dec 2009 20:28:35 +0200 Subject: sunrpc: Clean never used include files Remove include of two headers never used by this file. Doing so exposed a missing #include in include/linux/sunrpc/rpc_rdma.h. I did not see any other users dependency but if exist they should be fixed since these headers are totally irrelevant to here. Signed-off-by: Boaz Harrosh Signed-off-by: J. Bruce Fields diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h index 10709cb..c2786f2 100644 --- a/include/linux/sunrpc/debug.h +++ b/include/linux/sunrpc/debug.h @@ -28,9 +28,6 @@ #ifdef __KERNEL__ -#include -#include - /* * Enable RPC debugging/profiling. */ diff --git a/include/linux/sunrpc/rpc_rdma.h b/include/linux/sunrpc/rpc_rdma.h index 87b895d..b78f16b 100644 --- a/include/linux/sunrpc/rpc_rdma.h +++ b/include/linux/sunrpc/rpc_rdma.h @@ -40,6 +40,8 @@ #ifndef _LINUX_SUNRPC_RPC_RDMA_H #define _LINUX_SUNRPC_RPC_RDMA_H +#include + struct rpcrdma_segment { __be32 rs_handle; /* Registered memory handle */ __be32 rs_length; /* Length of the chunk in bytes */ -- cgit v0.10.2 From d703158229329af7152d159753f849aa7bd55ee6 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Thu, 3 Dec 2009 20:28:47 +0200 Subject: nfsd: Fix independence of a few nfsd related headers An header should be compilation independent, .i.e pull in any header who's declarations are directly used by this header. And not let users re-include all it's dependencies all over again. [At the end of the day what's the use of a header if it does not have more then one user?] Signed-off-by: Boaz Harrosh Signed-off-by: J. Bruce Fields diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 62f63fb..00a0c81 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -2,6 +2,7 @@ #define _LINUX_NFS_XDR_H #include +#include /* * To change the maximum rsize and wsize supported by the NFS client, adjust diff --git a/include/linux/nfsacl.h b/include/linux/nfsacl.h index 43011b6..f321b57 100644 --- a/include/linux/nfsacl.h +++ b/include/linux/nfsacl.h @@ -29,6 +29,7 @@ #ifdef __KERNEL__ #include +#include /* Maximum number of ACL entries over NFS */ #define NFS_ACL_MAX_ENTRIES 1024 -- cgit v0.10.2 From 72579ac9cd68081108277c31781b127d0f420d61 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Thu, 3 Dec 2009 20:28:59 +0200 Subject: nfsd: Headers Independence and include cleanups * Add includes that are directly used by headers * Remove includes that are not needed These are the changes made: [xdr.h] struct nfsd_readdirres has an embedded struct readdir_cd from nfsd.h fixing that we can drop other includes [xdr4.h] embedded types defined both at state.h and nfsd.h [syscall.h] After export.h fix none of these stuff is needed. fix extra space in # include <> statement [stats.h] does not need but was export to user-mode so I don't touch it [state.h] embedded types from nfsfh.h like struct knfsd_fh. bringing that eliminates the need for all other includes [nfsfh.h] directly manipulating types from sunrpc/svc.h. Removed Other unused headers. [nfsd.h] removed unused headers include [export.h] lots of sunrpc/svc.h types and a single prototype declaration with pointer from nfsfh.h, but all users of export.h do need nfsfh.h any way. remove now un-needed include. [const.h] Unfixed (not independent) [cache.h] could do with a forward declaration of "struct svc_rqst;" from sunrpc/svc.h but all users absolutely will need sunrpc/svc.h it is easier overall this way. Signed-off-by: Boaz Harrosh Signed-off-by: J. Bruce Fields diff --git a/include/linux/nfsd/cache.h b/include/linux/nfsd/cache.h index 3a3f589..a165425 100644 --- a/include/linux/nfsd/cache.h +++ b/include/linux/nfsd/cache.h @@ -10,8 +10,7 @@ #ifndef NFSCACHE_H #define NFSCACHE_H -#include -#include +#include /* * Representation of a reply cache entry. diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h index a6d9ef2..ef3d416 100644 --- a/include/linux/nfsd/export.h +++ b/include/linux/nfsd/export.h @@ -12,7 +12,7 @@ # include #ifdef __KERNEL__ -# include +# include #endif /* diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h index e4518d0..74f67c2 100644 --- a/include/linux/nfsd/nfsd.h +++ b/include/linux/nfsd/nfsd.h @@ -11,13 +11,9 @@ #define LINUX_NFSD_NFSD_H #include -#include -#include -#include #include #include -#include #include #include /* diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h index 2973e11..49523ed 100644 --- a/include/linux/nfsd/nfsfh.h +++ b/include/linux/nfsd/nfsfh.h @@ -16,8 +16,7 @@ # include #ifdef __KERNEL__ -# include -# include +# include #endif #include diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h index 5aadf8a..2af7568 100644 --- a/include/linux/nfsd/state.h +++ b/include/linux/nfsd/state.h @@ -37,9 +37,7 @@ #ifndef _NFSD4_STATE_H #define _NFSD4_STATE_H -#include -#include -#include +#include typedef struct { u32 cl_boot; diff --git a/include/linux/nfsd/syscall.h b/include/linux/nfsd/syscall.h index 7a3b565..812bc1e 100644 --- a/include/linux/nfsd/syscall.h +++ b/include/linux/nfsd/syscall.h @@ -9,14 +9,8 @@ #ifndef NFSD_SYSCALL_H #define NFSD_SYSCALL_H -# include -#ifdef __KERNEL__ -# include -#endif -#include -#include +#include #include -#include /* * Version of the syscall interface diff --git a/include/linux/nfsd/xdr.h b/include/linux/nfsd/xdr.h index a0132ef..58f824d 100644 --- a/include/linux/nfsd/xdr.h +++ b/include/linux/nfsd/xdr.h @@ -7,9 +7,8 @@ #ifndef LINUX_NFSD_H #define LINUX_NFSD_H -#include #include -#include +#include struct nfsd_fhandle { struct svc_fh fh; diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h index 73164c2..1bf2662 100644 --- a/include/linux/nfsd/xdr4.h +++ b/include/linux/nfsd/xdr4.h @@ -39,7 +39,8 @@ #ifndef _LINUX_NFSD_XDR4_H #define _LINUX_NFSD_XDR4_H -#include +#include +#include #define NFSD4_MAX_TAGLEN 128 #define XDR_LEN(n) (((n) + 3) & ~3) -- cgit v0.10.2 From 341eb184469f8e4a6841fc49a57ad4a27e51c335 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Thu, 3 Dec 2009 20:29:12 +0200 Subject: nfsd: Source files #include cleanups Now that the headers are fixed and carry their own wait, all fs/nfsd/ source files can include a minimal set of headers. and still compile just fine. This patch should improve the compilation speed of the nfsd module. Signed-off-by: Boaz Harrosh Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c index 36fcabbf..ad354d2 100644 --- a/fs/nfsd/auth.c +++ b/fs/nfsd/auth.c @@ -4,12 +4,8 @@ * Copyright (C) 1995, 1996 Olaf Kirch */ -#include #include -#include -#include #include -#include #include "auth.h" int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp) diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index b73baba..68e63f4 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -14,27 +14,12 @@ * Copyright (C) 1995, 1996 Olaf Kirch, */ -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include #include #include -#include #include -#include #include -#include -#include -#include #include #define NFSDDBG_FACILITY NFSDDBG_EXPORT diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c index 812bc64..801ef71 100644 --- a/fs/nfsd/lockd.c +++ b/fs/nfsd/lockd.c @@ -8,12 +8,7 @@ * Copyright (C) 1996, Olaf Kirch */ -#include -#include #include -#include -#include -#include #include #include #include "vfs.h" diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c index 38c883d..a54628d 100644 --- a/fs/nfsd/nfs2acl.c +++ b/fs/nfsd/nfs2acl.c @@ -6,13 +6,9 @@ * Copyright (C) 2002-2003 Andreas Gruenbacher */ -#include -#include #include #include -#include #include -#include #include #include "vfs.h" diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c index 526d85a..2f5c61b 100644 --- a/fs/nfsd/nfs3acl.c +++ b/fs/nfsd/nfs3acl.c @@ -6,12 +6,9 @@ * Copyright (C) 2002-2003 Andreas Gruenbacher */ -#include -#include #include #include #include -#include #include #include "vfs.h" diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 1a259d3..b694b43 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -6,25 +6,12 @@ * Copyright (C) 1996, 1997, 1998 Olaf Kirch */ -#include -#include -#include #include #include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include #include #include -#include #include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_PROC diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index d0a2ce1..623e13a 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -8,18 +8,7 @@ * 2003-08-09 Jamie Lokier: Use htonl() for nanoseconds, not htons()! */ -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include #include #include "auth.h" diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 6d9c6aa..d6f0cea 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -36,15 +36,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include -#include -#include #include -#include -#include #include diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 24e8d78..4fe3960 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -33,22 +33,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include #include -#include -#include -#include #define NFSDDBG_FACILITY NFSDDBG_PROC diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index ba2c199..8e518cd 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c @@ -35,22 +35,9 @@ */ #include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include #include -#include +#include /* * Cache entry diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index a468224..61f682c 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -34,20 +34,10 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -#include -#include -#include #include -#include -#include #include -#include -#include #include -#include -#include #include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_PROC diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index c7a6b24..48742f2 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -33,20 +33,12 @@ * */ -#include -#include #include -#include #include -#include -#include #include #include -#include -#include #include #include -#include #include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_PROC diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 850960e..1fe6e29 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -34,26 +34,11 @@ * */ -#include -#include -#include - -#include -#include -#include #include -#include -#include #include -#include -#include -#include #include #include #include -#include -#include -#include #include #include #include "vfs.h" diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index db0fc55..2fa9682 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -40,22 +40,12 @@ * at the end of nfs4svc_decode_compoundargs. */ -#include -#include -#include #include -#include +#include #include -#include -#include -#include -#include -#include #include #include -#include #include -#include #include #include "vfs.h" diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index 4638635..96694b8 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -10,14 +10,6 @@ * Copyright (C) 1995, 1996 Olaf Kirch */ -#include -#include -#include -#include -#include -#include - -#include #include #include diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 5c01fc1..e4f49fd 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -6,42 +6,17 @@ * Copyright (C) 1995, 1996 Olaf Kirch */ -#include - -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include -#include -#include #include #include #include -#include #include #include #include -#include -#include - /* * We have a single directory with 9 nodes in it. */ diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index a77efb8..7399481 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -9,17 +9,8 @@ * ... and again Southern-Winter 2001 to support export_operations */ -#include -#include -#include -#include -#include -#include #include -#include -#include -#include #include #include #include "vfs.h" diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index 6c967e1..b6bd9e0 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -7,21 +7,8 @@ * Copyright (C) 1995-1997 Olaf Kirch */ -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include #include #include #include "vfs.h" diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 2944b31..b2d7ffa 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -8,30 +8,15 @@ * Copyright (C) 1995, 1996, 1997 Olaf Kirch */ -#include #include -#include -#include -#include -#include -#include -#include -#include -#include #include #include -#include #include -#include #include -#include #include -#include #include -#include #include -#include #include #include #include diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index afd08e2..5e0603d 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c @@ -6,15 +6,7 @@ * Copyright (C) 1995, 1996 Olaf Kirch */ -#include -#include -#include -#include -#include -#include -#include #include -#include #include "auth.h" #define NFSDDBG_FACILITY NFSDDBG_XDR diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c index 71944cd..e3e411e 100644 --- a/fs/nfsd/stats.c +++ b/fs/nfsd/stats.c @@ -23,14 +23,9 @@ * Copyright (C) 1995, 1996, 1997 Olaf Kirch */ -#include -#include -#include #include -#include #include -#include #include #include #include diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index a7038ed..81ce108 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -16,43 +16,23 @@ * Zerocpy NFS support (C) 2002 Hirokazu Takahashi */ -#include -#include -#include #include #include -#include -#include #include -#include -#include #include -#include -#include -#include -#include -#include -#include #include -#include #include -#include #include #ifdef CONFIG_NFSD_V3 -#include #include #endif /* CONFIG_NFSD_V3 */ -#include #include #include -#include #include #include #ifdef CONFIG_NFSD_V4 -#include #include #include -#include #endif /* CONFIG_NFSD_V4 */ #include #include -- cgit v0.10.2 From 370d560017c9c269a1351ba19e91b206bd5816c8 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Thu, 3 Dec 2009 20:29:27 +0200 Subject: compat.c: Remove dependence on nfsd private headers Two nfsd related headers where included but never actually used. The linux/nfsd/nfsd.h file will eventually be moved to fs/nfsd directory as it is only needed by nfsd itself. There are 3 more compat.c files in the Kernel at other ARCHs that wrongly #include nfsd headers. Once these are fixed the headers can be moved. Signed-off-by: Boaz Harrosh Signed-off-by: J. Bruce Fields diff --git a/fs/compat.c b/fs/compat.c index 6c19040..00d90c2 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -38,8 +38,6 @@ #include #include #include -#include -#include #include #include #include -- cgit v0.10.2 From ec346449eb75474df27db945377c7a5b56b7c8cc Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Thu, 3 Dec 2009 20:29:39 +0200 Subject: parsic: remove un-used nfsd #includes Some un-used includes removed. This patch is in an effort to cleanup nfsd headers and move private definitions to source directory. Signed-off-by: Boaz Harrosh Tested-by: Grant Grundler Acked-by: Helge Deller Signed-off-by: J. Bruce Fields diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index 561388b..4a8ca63 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c @@ -26,13 +26,7 @@ #include #include #include -#include #include -#include -#include -#include -#include -#include #include #include #include -- cgit v0.10.2 From 40ede4a8cf8af6faac23462ba1b48bc4d074f0bb Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Thu, 3 Dec 2009 20:29:54 +0200 Subject: sparc: remove un-used nfsd #includes Some un-used includes removed. In an effort to cleanup nfsd headers and move private definitions to source directory. Signed-off-by: Boaz Harrosh Signed-off-by: J. Bruce Fields diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index 04e28b2..0a68fdf 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c @@ -26,11 +26,6 @@ #include #include #include -#include -#include -#include -#include -#include #include #include #include -- cgit v0.10.2 From 399643f25eb93374e27e06ec85f0e8958298af2e Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Thu, 3 Dec 2009 20:30:05 +0200 Subject: s390: remove un-used nfsd #includes Some un-used includes removed. This patch is in an effort to cleanup nfsd headers and move private definitions to source directory. Signed-off-by: Boaz Harrosh Signed-off-by: J. Bruce Fields diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 0debcec..29a2f34 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -31,14 +31,8 @@ #include #include #include -#include #include #include -#include -#include -#include -#include -#include #include #include #include diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index c07f9ca..81d6ee8 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h @@ -4,10 +4,6 @@ #include #include #include -#include -#include -#include -#include /* Macro that masks the high order bit of an 32 bit pointer and converts it*/ /* to a 64 bit pointer */ -- cgit v0.10.2 From 0296f55f98368219af772f54d3bf18a9ad859399 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Thu, 3 Dec 2009 20:30:27 +0200 Subject: lockd: Remove un-used nfsd headers #includes In what history where these ever needed? Well not any more. Signed-off-by: Boaz Harrosh Signed-off-by: J. Bruce Fields diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index bd173a6..a7966ee 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c @@ -11,10 +11,6 @@ #include #include #include -#include -#include -#include -#include #include #include diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index e1d28dd..56c9519 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -11,10 +11,6 @@ #include #include #include -#include -#include -#include -#include #include #include -- cgit v0.10.2 From 68590c382b875cc9a76b06097f3dff6730d787c1 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Thu, 3 Dec 2009 20:30:43 +0200 Subject: vfs: nfsctl.c un-used nfsd #includes Only linux/nfsd/syscall.h is actually used. Remove the other nfsd #includes, so they can be moved to source directory. Signed-off-by: Boaz Harrosh Signed-off-by: J. Bruce Fields diff --git a/fs/nfsctl.c b/fs/nfsctl.c index 8f9a205..d3854d9 100644 --- a/fs/nfsctl.c +++ b/fs/nfsctl.c @@ -7,8 +7,6 @@ #include #include #include -#include -#include #include #include #include -- cgit v0.10.2 From 9a74af21330c8d46efa977d088a62cc1bfa954e9 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Thu, 3 Dec 2009 20:30:56 +0200 Subject: nfsd: Move private headers to source directory Lots of include/linux/nfsd/* headers are only used by nfsd module. Move them to the source directory Signed-off-by: Boaz Harrosh Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c index ad354d2..71209d4 100644 --- a/fs/nfsd/auth.c +++ b/fs/nfsd/auth.c @@ -5,7 +5,7 @@ */ #include -#include +#include "nfsd.h" #include "auth.h" int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp) diff --git a/fs/nfsd/cache.h b/fs/nfsd/cache.h new file mode 100644 index 0000000..a165425 --- /dev/null +++ b/fs/nfsd/cache.h @@ -0,0 +1,85 @@ +/* + * include/linux/nfsd/cache.h + * + * Request reply cache. This was heavily inspired by the + * implementation in 4.3BSD/4.4BSD. + * + * Copyright (C) 1995, 1996 Olaf Kirch + */ + +#ifndef NFSCACHE_H +#define NFSCACHE_H + +#include + +/* + * Representation of a reply cache entry. + */ +struct svc_cacherep { + struct hlist_node c_hash; + struct list_head c_lru; + + unsigned char c_state, /* unused, inprog, done */ + c_type, /* status, buffer */ + c_secure : 1; /* req came from port < 1024 */ + struct sockaddr_in c_addr; + __be32 c_xid; + u32 c_prot; + u32 c_proc; + u32 c_vers; + unsigned long c_timestamp; + union { + struct kvec u_vec; + __be32 u_status; + } c_u; +}; + +#define c_replvec c_u.u_vec +#define c_replstat c_u.u_status + +/* cache entry states */ +enum { + RC_UNUSED, + RC_INPROG, + RC_DONE +}; + +/* return values */ +enum { + RC_DROPIT, + RC_REPLY, + RC_DOIT, + RC_INTR +}; + +/* + * Cache types. + * We may want to add more types one day, e.g. for diropres and + * attrstat replies. Using cache entries with fixed length instead + * of buffer pointers may be more efficient. + */ +enum { + RC_NOCACHE, + RC_REPLSTAT, + RC_REPLBUFF, +}; + +/* + * If requests are retransmitted within this interval, they're dropped. + */ +#define RC_DELAY (HZ/5) + +int nfsd_reply_cache_init(void); +void nfsd_reply_cache_shutdown(void); +int nfsd_cache_lookup(struct svc_rqst *, int); +void nfsd_cache_update(struct svc_rqst *, int, __be32 *); + +#ifdef CONFIG_NFSD_V4 +void nfsd4_set_statp(struct svc_rqst *rqstp, __be32 *statp); +#else /* CONFIG_NFSD_V4 */ +static inline void nfsd4_set_statp(struct svc_rqst *rqstp, __be32 *statp) +{ +} +#endif /* CONFIG_NFSD_V4 */ + +#endif /* NFSCACHE_H */ diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 68e63f4..cb3dae2 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -18,10 +18,11 @@ #include #include -#include #include #include +#include "nfsd.h" + #define NFSDDBG_FACILITY NFSDDBG_EXPORT typedef struct auth_domain svc_client; diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c index 801ef71..6f12777 100644 --- a/fs/nfsd/lockd.c +++ b/fs/nfsd/lockd.c @@ -9,8 +9,8 @@ */ #include -#include #include +#include "nfsd.h" #include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_LOCKD diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c index a54628d..874e2a9 100644 --- a/fs/nfsd/nfs2acl.c +++ b/fs/nfsd/nfs2acl.c @@ -6,10 +6,11 @@ * Copyright (C) 2002-2003 Andreas Gruenbacher */ -#include -#include -#include +#include "nfsd.h" +/* FIXME: nfsacl.h is a broken header */ #include +#include "cache.h" +#include "xdr3.h" #include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_PROC diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c index 2f5c61b..c6011dd 100644 --- a/fs/nfsd/nfs3acl.c +++ b/fs/nfsd/nfs3acl.c @@ -6,10 +6,11 @@ * Copyright (C) 2002-2003 Andreas Gruenbacher */ -#include -#include -#include +#include "nfsd.h" +/* FIXME: nfsacl.h is a broken header */ #include +#include "cache.h" +#include "xdr3.h" #include "vfs.h" #define RETURN_STATUS(st) { resp->status = (st); return (st); } diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index b694b43..90b19ca 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -10,8 +10,8 @@ #include #include -#include -#include +#include "cache.h" +#include "xdr3.h" #include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_PROC diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 623e13a..c523bb8 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -9,7 +9,7 @@ */ #include -#include +#include "xdr3.h" #include "auth.h" #define NFSDDBG_FACILITY NFSDDBG_XDR diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 4fe3960..f7a3158 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -34,8 +34,8 @@ */ #include -#include -#include +#include "nfsd.h" +#include "state.h" #define NFSDDBG_FACILITY NFSDDBG_PROC diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 61f682c..e2b5666 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -36,8 +36,8 @@ */ #include -#include -#include +#include "cache.h" +#include "xdr4.h" #include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_PROC diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 48742f2..6744e7f 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -33,12 +33,13 @@ * */ -#include -#include #include #include #include #include + +#include "nfsd.h" +#include "state.h" #include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_PROC diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 1fe6e29..2923e6c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -36,11 +36,11 @@ #include #include -#include #include #include #include #include +#include "xdr4.h" #include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_PROC diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 2fa9682..cab9780 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -43,10 +43,11 @@ #include #include #include -#include #include #include #include + +#include "xdr4.h" #include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_XDR diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index 96694b8..18aa972 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -10,8 +10,8 @@ * Copyright (C) 1995, 1996 Olaf Kirch */ -#include -#include +#include "nfsd.h" +#include "cache.h" /* Size of reply cache. Common values are: * 4.3BSD: 128 diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index e4f49fd..0415680 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -11,12 +11,13 @@ #include #include -#include -#include #include #include #include +#include "nfsd.h" +#include "cache.h" + /* * We have a single directory with 9 nodes in it. */ diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h new file mode 100644 index 0000000..74f67c2 --- /dev/null +++ b/fs/nfsd/nfsd.h @@ -0,0 +1,335 @@ +/* + * linux/include/linux/nfsd/nfsd.h + * + * Hodge-podge collection of knfsd-related stuff. + * I will sort this out later. + * + * Copyright (C) 1995-1997 Olaf Kirch + */ + +#ifndef LINUX_NFSD_NFSD_H +#define LINUX_NFSD_NFSD_H + +#include +#include + +#include +#include +#include +/* + * nfsd version + */ +#define NFSD_SUPPORTED_MINOR_VERSION 1 + +struct readdir_cd { + __be32 err; /* 0, nfserr, or nfserr_eof */ +}; + + +extern struct svc_program nfsd_program; +extern struct svc_version nfsd_version2, nfsd_version3, + nfsd_version4; +extern u32 nfsd_supported_minorversion; +extern struct mutex nfsd_mutex; +extern struct svc_serv *nfsd_serv; +extern spinlock_t nfsd_drc_lock; +extern unsigned int nfsd_drc_max_mem; +extern unsigned int nfsd_drc_mem_used; + +extern const struct seq_operations nfs_exports_op; + +/* + * Function prototypes. + */ +int nfsd_svc(unsigned short port, int nrservs); +int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp); + +int nfsd_nrthreads(void); +int nfsd_nrpools(void); +int nfsd_get_nrthreads(int n, int *); +int nfsd_set_nrthreads(int n, int *); + +#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) +#ifdef CONFIG_NFSD_V2_ACL +extern struct svc_version nfsd_acl_version2; +#else +#define nfsd_acl_version2 NULL +#endif +#ifdef CONFIG_NFSD_V3_ACL +extern struct svc_version nfsd_acl_version3; +#else +#define nfsd_acl_version3 NULL +#endif +#endif + +enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL }; +int nfsd_vers(int vers, enum vers_op change); +int nfsd_minorversion(u32 minorversion, enum vers_op change); +void nfsd_reset_versions(void); +int nfsd_create_serv(void); + +extern int nfsd_max_blksize; + +/* + * NFSv4 State + */ +#ifdef CONFIG_NFSD_V4 +extern unsigned int max_delegations; +int nfs4_state_init(void); +void nfsd4_free_slabs(void); +int nfs4_state_start(void); +void nfs4_state_shutdown(void); +time_t nfs4_lease_time(void); +void nfs4_reset_lease(time_t leasetime); +int nfs4_reset_recoverydir(char *recdir); +#else +static inline int nfs4_state_init(void) { return 0; } +static inline void nfsd4_free_slabs(void) { } +static inline int nfs4_state_start(void) { return 0; } +static inline void nfs4_state_shutdown(void) { } +static inline time_t nfs4_lease_time(void) { return 0; } +static inline void nfs4_reset_lease(time_t leasetime) { } +static inline int nfs4_reset_recoverydir(char *recdir) { return 0; } +#endif + +/* + * lockd binding + */ +void nfsd_lockd_init(void); +void nfsd_lockd_shutdown(void); + + +/* + * These macros provide pre-xdr'ed values for faster operation. + */ +#define nfs_ok cpu_to_be32(NFS_OK) +#define nfserr_perm cpu_to_be32(NFSERR_PERM) +#define nfserr_noent cpu_to_be32(NFSERR_NOENT) +#define nfserr_io cpu_to_be32(NFSERR_IO) +#define nfserr_nxio cpu_to_be32(NFSERR_NXIO) +#define nfserr_eagain cpu_to_be32(NFSERR_EAGAIN) +#define nfserr_acces cpu_to_be32(NFSERR_ACCES) +#define nfserr_exist cpu_to_be32(NFSERR_EXIST) +#define nfserr_xdev cpu_to_be32(NFSERR_XDEV) +#define nfserr_nodev cpu_to_be32(NFSERR_NODEV) +#define nfserr_notdir cpu_to_be32(NFSERR_NOTDIR) +#define nfserr_isdir cpu_to_be32(NFSERR_ISDIR) +#define nfserr_inval cpu_to_be32(NFSERR_INVAL) +#define nfserr_fbig cpu_to_be32(NFSERR_FBIG) +#define nfserr_nospc cpu_to_be32(NFSERR_NOSPC) +#define nfserr_rofs cpu_to_be32(NFSERR_ROFS) +#define nfserr_mlink cpu_to_be32(NFSERR_MLINK) +#define nfserr_opnotsupp cpu_to_be32(NFSERR_OPNOTSUPP) +#define nfserr_nametoolong cpu_to_be32(NFSERR_NAMETOOLONG) +#define nfserr_notempty cpu_to_be32(NFSERR_NOTEMPTY) +#define nfserr_dquot cpu_to_be32(NFSERR_DQUOT) +#define nfserr_stale cpu_to_be32(NFSERR_STALE) +#define nfserr_remote cpu_to_be32(NFSERR_REMOTE) +#define nfserr_wflush cpu_to_be32(NFSERR_WFLUSH) +#define nfserr_badhandle cpu_to_be32(NFSERR_BADHANDLE) +#define nfserr_notsync cpu_to_be32(NFSERR_NOT_SYNC) +#define nfserr_badcookie cpu_to_be32(NFSERR_BAD_COOKIE) +#define nfserr_notsupp cpu_to_be32(NFSERR_NOTSUPP) +#define nfserr_toosmall cpu_to_be32(NFSERR_TOOSMALL) +#define nfserr_serverfault cpu_to_be32(NFSERR_SERVERFAULT) +#define nfserr_badtype cpu_to_be32(NFSERR_BADTYPE) +#define nfserr_jukebox cpu_to_be32(NFSERR_JUKEBOX) +#define nfserr_denied cpu_to_be32(NFSERR_DENIED) +#define nfserr_deadlock cpu_to_be32(NFSERR_DEADLOCK) +#define nfserr_expired cpu_to_be32(NFSERR_EXPIRED) +#define nfserr_bad_cookie cpu_to_be32(NFSERR_BAD_COOKIE) +#define nfserr_same cpu_to_be32(NFSERR_SAME) +#define nfserr_clid_inuse cpu_to_be32(NFSERR_CLID_INUSE) +#define nfserr_stale_clientid cpu_to_be32(NFSERR_STALE_CLIENTID) +#define nfserr_resource cpu_to_be32(NFSERR_RESOURCE) +#define nfserr_moved cpu_to_be32(NFSERR_MOVED) +#define nfserr_nofilehandle cpu_to_be32(NFSERR_NOFILEHANDLE) +#define nfserr_minor_vers_mismatch cpu_to_be32(NFSERR_MINOR_VERS_MISMATCH) +#define nfserr_share_denied cpu_to_be32(NFSERR_SHARE_DENIED) +#define nfserr_stale_stateid cpu_to_be32(NFSERR_STALE_STATEID) +#define nfserr_old_stateid cpu_to_be32(NFSERR_OLD_STATEID) +#define nfserr_bad_stateid cpu_to_be32(NFSERR_BAD_STATEID) +#define nfserr_bad_seqid cpu_to_be32(NFSERR_BAD_SEQID) +#define nfserr_symlink cpu_to_be32(NFSERR_SYMLINK) +#define nfserr_not_same cpu_to_be32(NFSERR_NOT_SAME) +#define nfserr_restorefh cpu_to_be32(NFSERR_RESTOREFH) +#define nfserr_attrnotsupp cpu_to_be32(NFSERR_ATTRNOTSUPP) +#define nfserr_bad_xdr cpu_to_be32(NFSERR_BAD_XDR) +#define nfserr_openmode cpu_to_be32(NFSERR_OPENMODE) +#define nfserr_locks_held cpu_to_be32(NFSERR_LOCKS_HELD) +#define nfserr_op_illegal cpu_to_be32(NFSERR_OP_ILLEGAL) +#define nfserr_grace cpu_to_be32(NFSERR_GRACE) +#define nfserr_no_grace cpu_to_be32(NFSERR_NO_GRACE) +#define nfserr_reclaim_bad cpu_to_be32(NFSERR_RECLAIM_BAD) +#define nfserr_badname cpu_to_be32(NFSERR_BADNAME) +#define nfserr_cb_path_down cpu_to_be32(NFSERR_CB_PATH_DOWN) +#define nfserr_locked cpu_to_be32(NFSERR_LOCKED) +#define nfserr_wrongsec cpu_to_be32(NFSERR_WRONGSEC) +#define nfserr_badiomode cpu_to_be32(NFS4ERR_BADIOMODE) +#define nfserr_badlayout cpu_to_be32(NFS4ERR_BADLAYOUT) +#define nfserr_bad_session_digest cpu_to_be32(NFS4ERR_BAD_SESSION_DIGEST) +#define nfserr_badsession cpu_to_be32(NFS4ERR_BADSESSION) +#define nfserr_badslot cpu_to_be32(NFS4ERR_BADSLOT) +#define nfserr_complete_already cpu_to_be32(NFS4ERR_COMPLETE_ALREADY) +#define nfserr_conn_not_bound_to_session cpu_to_be32(NFS4ERR_CONN_NOT_BOUND_TO_SESSION) +#define nfserr_deleg_already_wanted cpu_to_be32(NFS4ERR_DELEG_ALREADY_WANTED) +#define nfserr_back_chan_busy cpu_to_be32(NFS4ERR_BACK_CHAN_BUSY) +#define nfserr_layouttrylater cpu_to_be32(NFS4ERR_LAYOUTTRYLATER) +#define nfserr_layoutunavailable cpu_to_be32(NFS4ERR_LAYOUTUNAVAILABLE) +#define nfserr_nomatching_layout cpu_to_be32(NFS4ERR_NOMATCHING_LAYOUT) +#define nfserr_recallconflict cpu_to_be32(NFS4ERR_RECALLCONFLICT) +#define nfserr_unknown_layouttype cpu_to_be32(NFS4ERR_UNKNOWN_LAYOUTTYPE) +#define nfserr_seq_misordered cpu_to_be32(NFS4ERR_SEQ_MISORDERED) +#define nfserr_sequence_pos cpu_to_be32(NFS4ERR_SEQUENCE_POS) +#define nfserr_req_too_big cpu_to_be32(NFS4ERR_REQ_TOO_BIG) +#define nfserr_rep_too_big cpu_to_be32(NFS4ERR_REP_TOO_BIG) +#define nfserr_rep_too_big_to_cache cpu_to_be32(NFS4ERR_REP_TOO_BIG_TO_CACHE) +#define nfserr_retry_uncached_rep cpu_to_be32(NFS4ERR_RETRY_UNCACHED_REP) +#define nfserr_unsafe_compound cpu_to_be32(NFS4ERR_UNSAFE_COMPOUND) +#define nfserr_too_many_ops cpu_to_be32(NFS4ERR_TOO_MANY_OPS) +#define nfserr_op_not_in_session cpu_to_be32(NFS4ERR_OP_NOT_IN_SESSION) +#define nfserr_hash_alg_unsupp cpu_to_be32(NFS4ERR_HASH_ALG_UNSUPP) +#define nfserr_clientid_busy cpu_to_be32(NFS4ERR_CLIENTID_BUSY) +#define nfserr_pnfs_io_hole cpu_to_be32(NFS4ERR_PNFS_IO_HOLE) +#define nfserr_seq_false_retry cpu_to_be32(NFS4ERR_SEQ_FALSE_RETRY) +#define nfserr_bad_high_slot cpu_to_be32(NFS4ERR_BAD_HIGH_SLOT) +#define nfserr_deadsession cpu_to_be32(NFS4ERR_DEADSESSION) +#define nfserr_encr_alg_unsupp cpu_to_be32(NFS4ERR_ENCR_ALG_UNSUPP) +#define nfserr_pnfs_no_layout cpu_to_be32(NFS4ERR_PNFS_NO_LAYOUT) +#define nfserr_not_only_op cpu_to_be32(NFS4ERR_NOT_ONLY_OP) +#define nfserr_wrong_cred cpu_to_be32(NFS4ERR_WRONG_CRED) +#define nfserr_wrong_type cpu_to_be32(NFS4ERR_WRONG_TYPE) +#define nfserr_dirdeleg_unavail cpu_to_be32(NFS4ERR_DIRDELEG_UNAVAIL) +#define nfserr_reject_deleg cpu_to_be32(NFS4ERR_REJECT_DELEG) +#define nfserr_returnconflict cpu_to_be32(NFS4ERR_RETURNCONFLICT) +#define nfserr_deleg_revoked cpu_to_be32(NFS4ERR_DELEG_REVOKED) + +/* error codes for internal use */ +/* if a request fails due to kmalloc failure, it gets dropped. + * Client should resend eventually + */ +#define nfserr_dropit cpu_to_be32(30000) +/* end-of-file indicator in readdir */ +#define nfserr_eof cpu_to_be32(30001) +/* replay detected */ +#define nfserr_replay_me cpu_to_be32(11001) +/* nfs41 replay detected */ +#define nfserr_replay_cache cpu_to_be32(11002) + +/* Check for dir entries '.' and '..' */ +#define isdotent(n, l) (l < 3 && n[0] == '.' && (l == 1 || n[1] == '.')) + +/* + * Time of server startup + */ +extern struct timeval nfssvc_boot; + +#ifdef CONFIG_NFSD_V4 + +/* before processing a COMPOUND operation, we have to check that there + * is enough space in the buffer for XDR encode to succeed. otherwise, + * we might process an operation with side effects, and be unable to + * tell the client that the operation succeeded. + * + * COMPOUND_SLACK_SPACE - this is the minimum bytes of buffer space + * needed to encode an "ordinary" _successful_ operation. (GETATTR, + * READ, READDIR, and READLINK have their own buffer checks.) if we + * fall below this level, we fail the next operation with NFS4ERR_RESOURCE. + * + * COMPOUND_ERR_SLACK_SPACE - this is the minimum bytes of buffer space + * needed to encode an operation which has failed with NFS4ERR_RESOURCE. + * care is taken to ensure that we never fall below this level for any + * reason. + */ +#define COMPOUND_SLACK_SPACE 140 /* OP_GETFH */ +#define COMPOUND_ERR_SLACK_SPACE 12 /* OP_SETATTR */ + +#define NFSD_LEASE_TIME (nfs4_lease_time()) +#define NFSD_LAUNDROMAT_MINTIMEOUT 10 /* seconds */ + +/* + * The following attributes are currently not supported by the NFSv4 server: + * ARCHIVE (deprecated anyway) + * HIDDEN (unlikely to be supported any time soon) + * MIMETYPE (unlikely to be supported any time soon) + * QUOTA_* (will be supported in a forthcoming patch) + * SYSTEM (unlikely to be supported any time soon) + * TIME_BACKUP (unlikely to be supported any time soon) + * TIME_CREATE (unlikely to be supported any time soon) + */ +#define NFSD4_SUPPORTED_ATTRS_WORD0 \ +(FATTR4_WORD0_SUPPORTED_ATTRS | FATTR4_WORD0_TYPE | FATTR4_WORD0_FH_EXPIRE_TYPE \ + | FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE | FATTR4_WORD0_LINK_SUPPORT \ + | FATTR4_WORD0_SYMLINK_SUPPORT | FATTR4_WORD0_NAMED_ATTR | FATTR4_WORD0_FSID \ + | FATTR4_WORD0_UNIQUE_HANDLES | FATTR4_WORD0_LEASE_TIME | FATTR4_WORD0_RDATTR_ERROR \ + | FATTR4_WORD0_ACLSUPPORT | FATTR4_WORD0_CANSETTIME | FATTR4_WORD0_CASE_INSENSITIVE \ + | FATTR4_WORD0_CASE_PRESERVING | FATTR4_WORD0_CHOWN_RESTRICTED \ + | FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FILEID | FATTR4_WORD0_FILES_AVAIL \ + | FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_HOMOGENEOUS \ + | FATTR4_WORD0_MAXFILESIZE | FATTR4_WORD0_MAXLINK | FATTR4_WORD0_MAXNAME \ + | FATTR4_WORD0_MAXREAD | FATTR4_WORD0_MAXWRITE | FATTR4_WORD0_ACL) + +#define NFSD4_SUPPORTED_ATTRS_WORD1 \ +(FATTR4_WORD1_MODE | FATTR4_WORD1_NO_TRUNC | FATTR4_WORD1_NUMLINKS \ + | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP | FATTR4_WORD1_RAWDEV \ + | FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | FATTR4_WORD1_SPACE_TOTAL \ + | FATTR4_WORD1_SPACE_USED | FATTR4_WORD1_TIME_ACCESS | FATTR4_WORD1_TIME_ACCESS_SET \ + | FATTR4_WORD1_TIME_DELTA | FATTR4_WORD1_TIME_METADATA \ + | FATTR4_WORD1_TIME_MODIFY | FATTR4_WORD1_TIME_MODIFY_SET | FATTR4_WORD1_MOUNTED_ON_FILEID) + +#define NFSD4_SUPPORTED_ATTRS_WORD2 0 + +#define NFSD4_1_SUPPORTED_ATTRS_WORD0 \ + NFSD4_SUPPORTED_ATTRS_WORD0 + +#define NFSD4_1_SUPPORTED_ATTRS_WORD1 \ + NFSD4_SUPPORTED_ATTRS_WORD1 + +#define NFSD4_1_SUPPORTED_ATTRS_WORD2 \ + (NFSD4_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SUPPATTR_EXCLCREAT) + +static inline u32 nfsd_suppattrs0(u32 minorversion) +{ + return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0 + : NFSD4_SUPPORTED_ATTRS_WORD0; +} + +static inline u32 nfsd_suppattrs1(u32 minorversion) +{ + return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD1 + : NFSD4_SUPPORTED_ATTRS_WORD1; +} + +static inline u32 nfsd_suppattrs2(u32 minorversion) +{ + return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD2 + : NFSD4_SUPPORTED_ATTRS_WORD2; +} + +/* These will return ERR_INVAL if specified in GETATTR or READDIR. */ +#define NFSD_WRITEONLY_ATTRS_WORD1 \ +(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) + +/* These are the only attrs allowed in CREATE/OPEN/SETATTR. */ +#define NFSD_WRITEABLE_ATTRS_WORD0 \ +(FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL ) +#define NFSD_WRITEABLE_ATTRS_WORD1 \ +(FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ + | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) +#define NFSD_WRITEABLE_ATTRS_WORD2 0 + +#define NFSD_SUPPATTR_EXCLCREAT_WORD0 \ + NFSD_WRITEABLE_ATTRS_WORD0 +/* + * we currently store the exclusive create verifier in the v_{a,m}time + * attributes so the client can't set these at create time using EXCLUSIVE4_1 + */ +#define NFSD_SUPPATTR_EXCLCREAT_WORD1 \ + (NFSD_WRITEABLE_ATTRS_WORD1 & \ + ~(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)) +#define NFSD_SUPPATTR_EXCLCREAT_WORD2 \ + NFSD_WRITEABLE_ATTRS_WORD2 + +#endif /* CONFIG_NFSD_V4 */ + +#endif /* LINUX_NFSD_NFSD_H */ diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 7399481..0eb1c59 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -12,7 +12,7 @@ #include #include -#include +#include "nfsd.h" #include "vfs.h" #include "auth.h" diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index b6bd9e0..21a5f79 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -9,8 +9,8 @@ #include -#include -#include +#include "cache.h" +#include "xdr.h" #include "vfs.h" typedef struct svc_rqst svc_rqst; diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index b2d7ffa..b520ce1 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -15,11 +15,11 @@ #include #include -#include -#include #include #include #include +#include "nfsd.h" +#include "cache.h" #include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_SVC diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index 5e0603d..3bec831 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c @@ -6,7 +6,7 @@ * Copyright (C) 1995, 1996 Olaf Kirch */ -#include +#include "xdr.h" #include "auth.h" #define NFSDDBG_FACILITY NFSDDBG_XDR diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h new file mode 100644 index 0000000..2af7568 --- /dev/null +++ b/fs/nfsd/state.h @@ -0,0 +1,409 @@ +/* + * linux/include/nfsd/state.h + * + * Copyright (c) 2001 The Regents of the University of Michigan. + * All rights reserved. + * + * Kendrick Smith + * Andy Adamson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _NFSD4_STATE_H +#define _NFSD4_STATE_H + +#include + +typedef struct { + u32 cl_boot; + u32 cl_id; +} clientid_t; + +typedef struct { + u32 so_boot; + u32 so_stateownerid; + u32 so_fileid; +} stateid_opaque_t; + +typedef struct { + u32 si_generation; + stateid_opaque_t si_opaque; +} stateid_t; +#define si_boot si_opaque.so_boot +#define si_stateownerid si_opaque.so_stateownerid +#define si_fileid si_opaque.so_fileid + +#define STATEID_FMT "(%08x/%08x/%08x/%08x)" +#define STATEID_VAL(s) \ + (s)->si_boot, \ + (s)->si_stateownerid, \ + (s)->si_fileid, \ + (s)->si_generation + +struct nfsd4_cb_sequence { + /* args/res */ + u32 cbs_minorversion; + struct nfs4_client *cbs_clp; +}; + +struct nfs4_delegation { + struct list_head dl_perfile; + struct list_head dl_perclnt; + struct list_head dl_recall_lru; /* delegation recalled */ + atomic_t dl_count; /* ref count */ + struct nfs4_client *dl_client; + struct nfs4_file *dl_file; + struct file_lock *dl_flock; + struct file *dl_vfs_file; + u32 dl_type; + time_t dl_time; +/* For recall: */ + u32 dl_ident; + stateid_t dl_stateid; + struct knfsd_fh dl_fh; + int dl_retries; +}; + +/* client delegation callback info */ +struct nfs4_cb_conn { + /* SETCLIENTID info */ + struct sockaddr_storage cb_addr; + size_t cb_addrlen; + u32 cb_prog; + u32 cb_minorversion; + u32 cb_ident; /* minorversion 0 only */ + /* RPC client info */ + atomic_t cb_set; /* successful CB_NULL call */ + struct rpc_clnt * cb_client; +}; + +/* Maximum number of slots per session. 160 is useful for long haul TCP */ +#define NFSD_MAX_SLOTS_PER_SESSION 160 +/* Maximum number of operations per session compound */ +#define NFSD_MAX_OPS_PER_COMPOUND 16 +/* Maximum session per slot cache size */ +#define NFSD_SLOT_CACHE_SIZE 1024 +/* Maximum number of NFSD_SLOT_CACHE_SIZE slots per session */ +#define NFSD_CACHE_SIZE_SLOTS_PER_SESSION 32 +#define NFSD_MAX_MEM_PER_SESSION \ + (NFSD_CACHE_SIZE_SLOTS_PER_SESSION * NFSD_SLOT_CACHE_SIZE) + +struct nfsd4_slot { + bool sl_inuse; + bool sl_cachethis; + u16 sl_opcnt; + u32 sl_seqid; + __be32 sl_status; + u32 sl_datalen; + char sl_data[]; +}; + +struct nfsd4_channel_attrs { + u32 headerpadsz; + u32 maxreq_sz; + u32 maxresp_sz; + u32 maxresp_cached; + u32 maxops; + u32 maxreqs; + u32 nr_rdma_attrs; + u32 rdma_attrs; +}; + +struct nfsd4_create_session { + clientid_t clientid; + struct nfs4_sessionid sessionid; + u32 seqid; + u32 flags; + struct nfsd4_channel_attrs fore_channel; + struct nfsd4_channel_attrs back_channel; + u32 callback_prog; + u32 uid; + u32 gid; +}; + +/* The single slot clientid cache structure */ +struct nfsd4_clid_slot { + u32 sl_seqid; + __be32 sl_status; + struct nfsd4_create_session sl_cr_ses; +}; + +struct nfsd4_session { + struct kref se_ref; + struct list_head se_hash; /* hash by sessionid */ + struct list_head se_perclnt; + u32 se_flags; + struct nfs4_client *se_client; /* for expire_client */ + struct nfs4_sessionid se_sessionid; + struct nfsd4_channel_attrs se_fchannel; + struct nfsd4_channel_attrs se_bchannel; + struct nfsd4_slot *se_slots[]; /* forward channel slots */ +}; + +static inline void +nfsd4_put_session(struct nfsd4_session *ses) +{ + extern void free_session(struct kref *kref); + kref_put(&ses->se_ref, free_session); +} + +static inline void +nfsd4_get_session(struct nfsd4_session *ses) +{ + kref_get(&ses->se_ref); +} + +/* formatted contents of nfs4_sessionid */ +struct nfsd4_sessionid { + clientid_t clientid; + u32 sequence; + u32 reserved; +}; + +#define HEXDIR_LEN 33 /* hex version of 16 byte md5 of cl_name plus '\0' */ + +/* + * struct nfs4_client - one per client. Clientids live here. + * o Each nfs4_client is hashed by clientid. + * + * o Each nfs4_clients is also hashed by name + * (the opaque quantity initially sent by the client to identify itself). + * + * o cl_perclient list is used to ensure no dangling stateowner references + * when we expire the nfs4_client + */ +struct nfs4_client { + struct list_head cl_idhash; /* hash by cl_clientid.id */ + struct list_head cl_strhash; /* hash by cl_name */ + struct list_head cl_openowners; + struct list_head cl_delegations; + struct list_head cl_lru; /* tail queue */ + struct xdr_netobj cl_name; /* id generated by client */ + char cl_recdir[HEXDIR_LEN]; /* recovery dir */ + nfs4_verifier cl_verifier; /* generated by client */ + time_t cl_time; /* time of last lease renewal */ + struct sockaddr_storage cl_addr; /* client ipaddress */ + u32 cl_flavor; /* setclientid pseudoflavor */ + char *cl_principal; /* setclientid principal name */ + struct svc_cred cl_cred; /* setclientid principal */ + clientid_t cl_clientid; /* generated by server */ + nfs4_verifier cl_confirm; /* generated by server */ + struct nfs4_cb_conn cl_cb_conn; /* callback info */ + atomic_t cl_count; /* ref count */ + u32 cl_firststate; /* recovery dir creation */ + + /* for nfs41 */ + struct list_head cl_sessions; + struct nfsd4_clid_slot cl_cs_slot; /* create_session slot */ + u32 cl_exchange_flags; + struct nfs4_sessionid cl_sessionid; + + /* for nfs41 callbacks */ + /* We currently support a single back channel with a single slot */ + unsigned long cl_cb_slot_busy; + u32 cl_cb_seq_nr; + struct svc_xprt *cl_cb_xprt; /* 4.1 callback transport */ + struct rpc_wait_queue cl_cb_waitq; /* backchannel callers may */ + /* wait here for slots */ +}; + +/* struct nfs4_client_reset + * one per old client. Populates reset_str_hashtbl. Filled from conf_id_hashtbl + * upon lease reset, or from upcall to state_daemon (to read in state + * from non-volitile storage) upon reboot. + */ +struct nfs4_client_reclaim { + struct list_head cr_strhash; /* hash by cr_name */ + char cr_recdir[HEXDIR_LEN]; /* recover dir */ +}; + +static inline void +update_stateid(stateid_t *stateid) +{ + stateid->si_generation++; +} + +/* A reasonable value for REPLAY_ISIZE was estimated as follows: + * The OPEN response, typically the largest, requires + * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) + 8(verifier) + + * 4(deleg. type) + 8(deleg. stateid) + 4(deleg. recall flag) + + * 20(deleg. space limit) + ~32(deleg. ace) = 112 bytes + */ + +#define NFSD4_REPLAY_ISIZE 112 + +/* + * Replay buffer, where the result of the last seqid-mutating operation + * is cached. + */ +struct nfs4_replay { + __be32 rp_status; + unsigned int rp_buflen; + char *rp_buf; + unsigned intrp_allocated; + struct knfsd_fh rp_openfh; + char rp_ibuf[NFSD4_REPLAY_ISIZE]; +}; + +/* +* nfs4_stateowner can either be an open_owner, or a lock_owner +* +* so_idhash: stateid_hashtbl[] for open owner, lockstateid_hashtbl[] +* for lock_owner +* so_strhash: ownerstr_hashtbl[] for open_owner, lock_ownerstr_hashtbl[] +* for lock_owner +* so_perclient: nfs4_client->cl_perclient entry - used when nfs4_client +* struct is reaped. +* so_perfilestate: heads the list of nfs4_stateid (either open or lock) +* and is used to ensure no dangling nfs4_stateid references when we +* release a stateowner. +* so_perlockowner: (open) nfs4_stateid->st_perlockowner entry - used when +* close is called to reap associated byte-range locks +* so_close_lru: (open) stateowner is placed on this list instead of being +* reaped (when so_perfilestate is empty) to hold the last close replay. +* reaped by laundramat thread after lease period. +*/ +struct nfs4_stateowner { + struct kref so_ref; + struct list_head so_idhash; /* hash by so_id */ + struct list_head so_strhash; /* hash by op_name */ + struct list_head so_perclient; + struct list_head so_stateids; + struct list_head so_perstateid; /* for lockowners only */ + struct list_head so_close_lru; /* tail queue */ + time_t so_time; /* time of placement on so_close_lru */ + int so_is_open_owner; /* 1=openowner,0=lockowner */ + u32 so_id; + struct nfs4_client * so_client; + /* after increment in ENCODE_SEQID_OP_TAIL, represents the next + * sequence id expected from the client: */ + u32 so_seqid; + struct xdr_netobj so_owner; /* open owner name */ + int so_confirmed; /* successful OPEN_CONFIRM? */ + struct nfs4_replay so_replay; +}; + +/* +* nfs4_file: a file opened by some number of (open) nfs4_stateowners. +* o fi_perfile list is used to search for conflicting +* share_acces, share_deny on the file. +*/ +struct nfs4_file { + atomic_t fi_ref; + struct list_head fi_hash; /* hash by "struct inode *" */ + struct list_head fi_stateids; + struct list_head fi_delegations; + struct inode *fi_inode; + u32 fi_id; /* used with stateowner->so_id + * for stateid_hashtbl hash */ + bool fi_had_conflict; +}; + +/* +* nfs4_stateid can either be an open stateid or (eventually) a lock stateid +* +* (open)nfs4_stateid: one per (open)nfs4_stateowner, nfs4_file +* +* st_hash: stateid_hashtbl[] entry or lockstateid_hashtbl entry +* st_perfile: file_hashtbl[] entry. +* st_perfile_state: nfs4_stateowner->so_perfilestate +* st_perlockowner: (open stateid) list of lock nfs4_stateowners +* st_access_bmap: used only for open stateid +* st_deny_bmap: used only for open stateid +* st_openstp: open stateid lock stateid was derived from +* +* XXX: open stateids and lock stateids have diverged sufficiently that +* we should consider defining separate structs for the two cases. +*/ + +struct nfs4_stateid { + struct list_head st_hash; + struct list_head st_perfile; + struct list_head st_perstateowner; + struct list_head st_lockowners; + struct nfs4_stateowner * st_stateowner; + struct nfs4_file * st_file; + stateid_t st_stateid; + struct file * st_vfs_file; + unsigned long st_access_bmap; + unsigned long st_deny_bmap; + struct nfs4_stateid * st_openstp; +}; + +/* flags for preprocess_seqid_op() */ +#define HAS_SESSION 0x00000001 +#define CONFIRM 0x00000002 +#define OPEN_STATE 0x00000004 +#define LOCK_STATE 0x00000008 +#define RD_STATE 0x00000010 +#define WR_STATE 0x00000020 +#define CLOSE_STATE 0x00000040 + +#define seqid_mutating_err(err) \ + (((err) != nfserr_stale_clientid) && \ + ((err) != nfserr_bad_seqid) && \ + ((err) != nfserr_stale_stateid) && \ + ((err) != nfserr_bad_stateid)) + +struct nfsd4_compound_state; + +extern __be32 nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, + stateid_t *stateid, int flags, struct file **filp); +extern void nfs4_lock_state(void); +extern void nfs4_unlock_state(void); +extern int nfs4_in_grace(void); +extern __be32 nfs4_check_open_reclaim(clientid_t *clid); +extern void put_nfs4_client(struct nfs4_client *clp); +extern void nfs4_free_stateowner(struct kref *kref); +extern int set_callback_cred(void); +extern void nfsd4_probe_callback(struct nfs4_client *clp); +extern void nfsd4_cb_recall(struct nfs4_delegation *dp); +extern void nfs4_put_delegation(struct nfs4_delegation *dp); +extern __be32 nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname); +extern void nfsd4_init_recdir(char *recdir_name); +extern int nfsd4_recdir_load(void); +extern void nfsd4_shutdown_recdir(void); +extern int nfs4_client_to_reclaim(const char *name); +extern int nfs4_has_reclaimed_state(const char *name, bool use_exchange_id); +extern void nfsd4_recdir_purge_old(void); +extern int nfsd4_create_clid_dir(struct nfs4_client *clp); +extern void nfsd4_remove_clid_dir(struct nfs4_client *clp); + +static inline void +nfs4_put_stateowner(struct nfs4_stateowner *so) +{ + kref_put(&so->so_ref, nfs4_free_stateowner); +} + +static inline void +nfs4_get_stateowner(struct nfs4_stateowner *so) +{ + kref_get(&so->so_ref); +} + +#endif /* NFSD4_STATE_H */ diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c index e3e411e..3fc69df 100644 --- a/fs/nfsd/stats.c +++ b/fs/nfsd/stats.c @@ -25,11 +25,11 @@ #include #include - #include -#include #include +#include "nfsd.h" + struct nfsd_stats nfsdstats; struct svc_stat nfsd_svcstats = { .program = &nfsd_program, diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 81ce108..04bdba1 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -22,23 +22,25 @@ #include #include #include -#include -#ifdef CONFIG_NFSD_V3 -#include -#endif /* CONFIG_NFSD_V3 */ #include #include #include #include +#include +#include +#include + +#ifdef CONFIG_NFSD_V3 +#include "xdr3.h" +#endif /* CONFIG_NFSD_V3 */ + #ifdef CONFIG_NFSD_V4 #include #include #endif /* CONFIG_NFSD_V4 */ -#include -#include -#include "vfs.h" -#include +#include "nfsd.h" +#include "vfs.h" #define NFSDDBG_FACILITY NFSDDBG_FILEOP diff --git a/fs/nfsd/xdr.h b/fs/nfsd/xdr.h new file mode 100644 index 0000000..235ee5c --- /dev/null +++ b/fs/nfsd/xdr.h @@ -0,0 +1,176 @@ +/* + * linux/include/linux/nfsd/xdr.h + * + * XDR types for nfsd. This is mainly a typing exercise. + */ + +#ifndef LINUX_NFSD_H +#define LINUX_NFSD_H + +#include +#include "nfsd.h" + +struct nfsd_fhandle { + struct svc_fh fh; +}; + +struct nfsd_sattrargs { + struct svc_fh fh; + struct iattr attrs; +}; + +struct nfsd_diropargs { + struct svc_fh fh; + char * name; + unsigned int len; +}; + +struct nfsd_readargs { + struct svc_fh fh; + __u32 offset; + __u32 count; + int vlen; +}; + +struct nfsd_writeargs { + svc_fh fh; + __u32 offset; + int len; + int vlen; +}; + +struct nfsd_createargs { + struct svc_fh fh; + char * name; + unsigned int len; + struct iattr attrs; +}; + +struct nfsd_renameargs { + struct svc_fh ffh; + char * fname; + unsigned int flen; + struct svc_fh tfh; + char * tname; + unsigned int tlen; +}; + +struct nfsd_readlinkargs { + struct svc_fh fh; + char * buffer; +}; + +struct nfsd_linkargs { + struct svc_fh ffh; + struct svc_fh tfh; + char * tname; + unsigned int tlen; +}; + +struct nfsd_symlinkargs { + struct svc_fh ffh; + char * fname; + unsigned int flen; + char * tname; + unsigned int tlen; + struct iattr attrs; +}; + +struct nfsd_readdirargs { + struct svc_fh fh; + __u32 cookie; + __u32 count; + __be32 * buffer; +}; + +struct nfsd_attrstat { + struct svc_fh fh; + struct kstat stat; +}; + +struct nfsd_diropres { + struct svc_fh fh; + struct kstat stat; +}; + +struct nfsd_readlinkres { + int len; +}; + +struct nfsd_readres { + struct svc_fh fh; + unsigned long count; + struct kstat stat; +}; + +struct nfsd_readdirres { + int count; + + struct readdir_cd common; + __be32 * buffer; + int buflen; + __be32 * offset; +}; + +struct nfsd_statfsres { + struct kstatfs stats; +}; + +/* + * Storage requirements for XDR arguments and results. + */ +union nfsd_xdrstore { + struct nfsd_sattrargs sattr; + struct nfsd_diropargs dirop; + struct nfsd_readargs read; + struct nfsd_writeargs write; + struct nfsd_createargs create; + struct nfsd_renameargs rename; + struct nfsd_linkargs link; + struct nfsd_symlinkargs symlink; + struct nfsd_readdirargs readdir; +}; + +#define NFS2_SVC_XDRSIZE sizeof(union nfsd_xdrstore) + + +int nfssvc_decode_void(struct svc_rqst *, __be32 *, void *); +int nfssvc_decode_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); +int nfssvc_decode_sattrargs(struct svc_rqst *, __be32 *, + struct nfsd_sattrargs *); +int nfssvc_decode_diropargs(struct svc_rqst *, __be32 *, + struct nfsd_diropargs *); +int nfssvc_decode_readargs(struct svc_rqst *, __be32 *, + struct nfsd_readargs *); +int nfssvc_decode_writeargs(struct svc_rqst *, __be32 *, + struct nfsd_writeargs *); +int nfssvc_decode_createargs(struct svc_rqst *, __be32 *, + struct nfsd_createargs *); +int nfssvc_decode_renameargs(struct svc_rqst *, __be32 *, + struct nfsd_renameargs *); +int nfssvc_decode_readlinkargs(struct svc_rqst *, __be32 *, + struct nfsd_readlinkargs *); +int nfssvc_decode_linkargs(struct svc_rqst *, __be32 *, + struct nfsd_linkargs *); +int nfssvc_decode_symlinkargs(struct svc_rqst *, __be32 *, + struct nfsd_symlinkargs *); +int nfssvc_decode_readdirargs(struct svc_rqst *, __be32 *, + struct nfsd_readdirargs *); +int nfssvc_encode_void(struct svc_rqst *, __be32 *, void *); +int nfssvc_encode_attrstat(struct svc_rqst *, __be32 *, struct nfsd_attrstat *); +int nfssvc_encode_diropres(struct svc_rqst *, __be32 *, struct nfsd_diropres *); +int nfssvc_encode_readlinkres(struct svc_rqst *, __be32 *, struct nfsd_readlinkres *); +int nfssvc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd_readres *); +int nfssvc_encode_statfsres(struct svc_rqst *, __be32 *, struct nfsd_statfsres *); +int nfssvc_encode_readdirres(struct svc_rqst *, __be32 *, struct nfsd_readdirres *); + +int nfssvc_encode_entry(void *, const char *name, + int namlen, loff_t offset, u64 ino, unsigned int); + +int nfssvc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); + +/* Helper functions for NFSv2 ACL code */ +__be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp); +__be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp); + +#endif /* LINUX_NFSD_H */ diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h new file mode 100644 index 0000000..b330756 --- /dev/null +++ b/fs/nfsd/xdr3.h @@ -0,0 +1,346 @@ +/* + * linux/include/linux/nfsd/xdr3.h + * + * XDR types for NFSv3 in nfsd. + * + * Copyright (C) 1996-1998, Olaf Kirch + */ + +#ifndef _LINUX_NFSD_XDR3_H +#define _LINUX_NFSD_XDR3_H + +#include "xdr.h" + +struct nfsd3_sattrargs { + struct svc_fh fh; + struct iattr attrs; + int check_guard; + time_t guardtime; +}; + +struct nfsd3_diropargs { + struct svc_fh fh; + char * name; + unsigned int len; +}; + +struct nfsd3_accessargs { + struct svc_fh fh; + unsigned int access; +}; + +struct nfsd3_readargs { + struct svc_fh fh; + __u64 offset; + __u32 count; + int vlen; +}; + +struct nfsd3_writeargs { + svc_fh fh; + __u64 offset; + __u32 count; + int stable; + __u32 len; + int vlen; +}; + +struct nfsd3_createargs { + struct svc_fh fh; + char * name; + unsigned int len; + int createmode; + struct iattr attrs; + __be32 * verf; +}; + +struct nfsd3_mknodargs { + struct svc_fh fh; + char * name; + unsigned int len; + __u32 ftype; + __u32 major, minor; + struct iattr attrs; +}; + +struct nfsd3_renameargs { + struct svc_fh ffh; + char * fname; + unsigned int flen; + struct svc_fh tfh; + char * tname; + unsigned int tlen; +}; + +struct nfsd3_readlinkargs { + struct svc_fh fh; + char * buffer; +}; + +struct nfsd3_linkargs { + struct svc_fh ffh; + struct svc_fh tfh; + char * tname; + unsigned int tlen; +}; + +struct nfsd3_symlinkargs { + struct svc_fh ffh; + char * fname; + unsigned int flen; + char * tname; + unsigned int tlen; + struct iattr attrs; +}; + +struct nfsd3_readdirargs { + struct svc_fh fh; + __u64 cookie; + __u32 dircount; + __u32 count; + __be32 * verf; + __be32 * buffer; +}; + +struct nfsd3_commitargs { + struct svc_fh fh; + __u64 offset; + __u32 count; +}; + +struct nfsd3_getaclargs { + struct svc_fh fh; + int mask; +}; + +struct posix_acl; +struct nfsd3_setaclargs { + struct svc_fh fh; + int mask; + struct posix_acl *acl_access; + struct posix_acl *acl_default; +}; + +struct nfsd3_attrstat { + __be32 status; + struct svc_fh fh; + struct kstat stat; +}; + +/* LOOKUP, CREATE, MKDIR, SYMLINK, MKNOD */ +struct nfsd3_diropres { + __be32 status; + struct svc_fh dirfh; + struct svc_fh fh; +}; + +struct nfsd3_accessres { + __be32 status; + struct svc_fh fh; + __u32 access; +}; + +struct nfsd3_readlinkres { + __be32 status; + struct svc_fh fh; + __u32 len; +}; + +struct nfsd3_readres { + __be32 status; + struct svc_fh fh; + unsigned long count; + int eof; +}; + +struct nfsd3_writeres { + __be32 status; + struct svc_fh fh; + unsigned long count; + int committed; +}; + +struct nfsd3_renameres { + __be32 status; + struct svc_fh ffh; + struct svc_fh tfh; +}; + +struct nfsd3_linkres { + __be32 status; + struct svc_fh tfh; + struct svc_fh fh; +}; + +struct nfsd3_readdirres { + __be32 status; + struct svc_fh fh; + int count; + __be32 verf[2]; + + struct readdir_cd common; + __be32 * buffer; + int buflen; + __be32 * offset; + __be32 * offset1; + struct svc_rqst * rqstp; + +}; + +struct nfsd3_fsstatres { + __be32 status; + struct kstatfs stats; + __u32 invarsec; +}; + +struct nfsd3_fsinfores { + __be32 status; + __u32 f_rtmax; + __u32 f_rtpref; + __u32 f_rtmult; + __u32 f_wtmax; + __u32 f_wtpref; + __u32 f_wtmult; + __u32 f_dtpref; + __u64 f_maxfilesize; + __u32 f_properties; +}; + +struct nfsd3_pathconfres { + __be32 status; + __u32 p_link_max; + __u32 p_name_max; + __u32 p_no_trunc; + __u32 p_chown_restricted; + __u32 p_case_insensitive; + __u32 p_case_preserving; +}; + +struct nfsd3_commitres { + __be32 status; + struct svc_fh fh; +}; + +struct nfsd3_getaclres { + __be32 status; + struct svc_fh fh; + int mask; + struct posix_acl *acl_access; + struct posix_acl *acl_default; +}; + +/* dummy type for release */ +struct nfsd3_fhandle_pair { + __u32 dummy; + struct svc_fh fh1; + struct svc_fh fh2; +}; + +/* + * Storage requirements for XDR arguments and results. + */ +union nfsd3_xdrstore { + struct nfsd3_sattrargs sattrargs; + struct nfsd3_diropargs diropargs; + struct nfsd3_readargs readargs; + struct nfsd3_writeargs writeargs; + struct nfsd3_createargs createargs; + struct nfsd3_renameargs renameargs; + struct nfsd3_linkargs linkargs; + struct nfsd3_symlinkargs symlinkargs; + struct nfsd3_readdirargs readdirargs; + struct nfsd3_diropres diropres; + struct nfsd3_accessres accessres; + struct nfsd3_readlinkres readlinkres; + struct nfsd3_readres readres; + struct nfsd3_writeres writeres; + struct nfsd3_renameres renameres; + struct nfsd3_linkres linkres; + struct nfsd3_readdirres readdirres; + struct nfsd3_fsstatres fsstatres; + struct nfsd3_fsinfores fsinfores; + struct nfsd3_pathconfres pathconfres; + struct nfsd3_commitres commitres; + struct nfsd3_getaclres getaclres; +}; + +#define NFS3_SVC_XDRSIZE sizeof(union nfsd3_xdrstore) + +int nfs3svc_decode_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); +int nfs3svc_decode_sattrargs(struct svc_rqst *, __be32 *, + struct nfsd3_sattrargs *); +int nfs3svc_decode_diropargs(struct svc_rqst *, __be32 *, + struct nfsd3_diropargs *); +int nfs3svc_decode_accessargs(struct svc_rqst *, __be32 *, + struct nfsd3_accessargs *); +int nfs3svc_decode_readargs(struct svc_rqst *, __be32 *, + struct nfsd3_readargs *); +int nfs3svc_decode_writeargs(struct svc_rqst *, __be32 *, + struct nfsd3_writeargs *); +int nfs3svc_decode_createargs(struct svc_rqst *, __be32 *, + struct nfsd3_createargs *); +int nfs3svc_decode_mkdirargs(struct svc_rqst *, __be32 *, + struct nfsd3_createargs *); +int nfs3svc_decode_mknodargs(struct svc_rqst *, __be32 *, + struct nfsd3_mknodargs *); +int nfs3svc_decode_renameargs(struct svc_rqst *, __be32 *, + struct nfsd3_renameargs *); +int nfs3svc_decode_readlinkargs(struct svc_rqst *, __be32 *, + struct nfsd3_readlinkargs *); +int nfs3svc_decode_linkargs(struct svc_rqst *, __be32 *, + struct nfsd3_linkargs *); +int nfs3svc_decode_symlinkargs(struct svc_rqst *, __be32 *, + struct nfsd3_symlinkargs *); +int nfs3svc_decode_readdirargs(struct svc_rqst *, __be32 *, + struct nfsd3_readdirargs *); +int nfs3svc_decode_readdirplusargs(struct svc_rqst *, __be32 *, + struct nfsd3_readdirargs *); +int nfs3svc_decode_commitargs(struct svc_rqst *, __be32 *, + struct nfsd3_commitargs *); +int nfs3svc_encode_voidres(struct svc_rqst *, __be32 *, void *); +int nfs3svc_encode_attrstat(struct svc_rqst *, __be32 *, + struct nfsd3_attrstat *); +int nfs3svc_encode_wccstat(struct svc_rqst *, __be32 *, + struct nfsd3_attrstat *); +int nfs3svc_encode_diropres(struct svc_rqst *, __be32 *, + struct nfsd3_diropres *); +int nfs3svc_encode_accessres(struct svc_rqst *, __be32 *, + struct nfsd3_accessres *); +int nfs3svc_encode_readlinkres(struct svc_rqst *, __be32 *, + struct nfsd3_readlinkres *); +int nfs3svc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd3_readres *); +int nfs3svc_encode_writeres(struct svc_rqst *, __be32 *, struct nfsd3_writeres *); +int nfs3svc_encode_createres(struct svc_rqst *, __be32 *, + struct nfsd3_diropres *); +int nfs3svc_encode_renameres(struct svc_rqst *, __be32 *, + struct nfsd3_renameres *); +int nfs3svc_encode_linkres(struct svc_rqst *, __be32 *, + struct nfsd3_linkres *); +int nfs3svc_encode_readdirres(struct svc_rqst *, __be32 *, + struct nfsd3_readdirres *); +int nfs3svc_encode_fsstatres(struct svc_rqst *, __be32 *, + struct nfsd3_fsstatres *); +int nfs3svc_encode_fsinfores(struct svc_rqst *, __be32 *, + struct nfsd3_fsinfores *); +int nfs3svc_encode_pathconfres(struct svc_rqst *, __be32 *, + struct nfsd3_pathconfres *); +int nfs3svc_encode_commitres(struct svc_rqst *, __be32 *, + struct nfsd3_commitres *); + +int nfs3svc_release_fhandle(struct svc_rqst *, __be32 *, + struct nfsd3_attrstat *); +int nfs3svc_release_fhandle2(struct svc_rqst *, __be32 *, + struct nfsd3_fhandle_pair *); +int nfs3svc_encode_entry(void *, const char *name, + int namlen, loff_t offset, u64 ino, + unsigned int); +int nfs3svc_encode_entry_plus(void *, const char *name, + int namlen, loff_t offset, u64 ino, + unsigned int); +/* Helper functions for NFSv3 ACL code */ +__be32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, + struct svc_fh *fhp); +__be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp); + + +#endif /* _LINUX_NFSD_XDR3_H */ diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h new file mode 100644 index 0000000..83202a1 --- /dev/null +++ b/fs/nfsd/xdr4.h @@ -0,0 +1,564 @@ +/* + * include/linux/nfsd/xdr4.h + * + * Server-side types for NFSv4. + * + * Copyright (c) 2002 The Regents of the University of Michigan. + * All rights reserved. + * + * Kendrick Smith + * Andy Adamson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _LINUX_NFSD_XDR4_H +#define _LINUX_NFSD_XDR4_H + +#include "state.h" +#include "nfsd.h" + +#define NFSD4_MAX_TAGLEN 128 +#define XDR_LEN(n) (((n) + 3) & ~3) + +struct nfsd4_compound_state { + struct svc_fh current_fh; + struct svc_fh save_fh; + struct nfs4_stateowner *replay_owner; + /* For sessions DRC */ + struct nfsd4_session *session; + struct nfsd4_slot *slot; + __be32 *datap; + size_t iovlen; + u32 minorversion; + u32 status; +}; + +static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs) +{ + return cs->slot != NULL; +} + +struct nfsd4_change_info { + u32 atomic; + bool change_supported; + u32 before_ctime_sec; + u32 before_ctime_nsec; + u64 before_change; + u32 after_ctime_sec; + u32 after_ctime_nsec; + u64 after_change; +}; + +struct nfsd4_access { + u32 ac_req_access; /* request */ + u32 ac_supported; /* response */ + u32 ac_resp_access; /* response */ +}; + +struct nfsd4_close { + u32 cl_seqid; /* request */ + stateid_t cl_stateid; /* request+response */ + struct nfs4_stateowner * cl_stateowner; /* response */ +}; + +struct nfsd4_commit { + u64 co_offset; /* request */ + u32 co_count; /* request */ + nfs4_verifier co_verf; /* response */ +}; + +struct nfsd4_create { + u32 cr_namelen; /* request */ + char * cr_name; /* request */ + u32 cr_type; /* request */ + union { /* request */ + struct { + u32 namelen; + char *name; + } link; /* NF4LNK */ + struct { + u32 specdata1; + u32 specdata2; + } dev; /* NF4BLK, NF4CHR */ + } u; + u32 cr_bmval[3]; /* request */ + struct iattr cr_iattr; /* request */ + struct nfsd4_change_info cr_cinfo; /* response */ + struct nfs4_acl *cr_acl; +}; +#define cr_linklen u.link.namelen +#define cr_linkname u.link.name +#define cr_specdata1 u.dev.specdata1 +#define cr_specdata2 u.dev.specdata2 + +struct nfsd4_delegreturn { + stateid_t dr_stateid; +}; + +struct nfsd4_getattr { + u32 ga_bmval[3]; /* request */ + struct svc_fh *ga_fhp; /* response */ +}; + +struct nfsd4_link { + u32 li_namelen; /* request */ + char * li_name; /* request */ + struct nfsd4_change_info li_cinfo; /* response */ +}; + +struct nfsd4_lock_denied { + clientid_t ld_clientid; + struct nfs4_stateowner *ld_sop; + u64 ld_start; + u64 ld_length; + u32 ld_type; +}; + +struct nfsd4_lock { + /* request */ + u32 lk_type; + u32 lk_reclaim; /* boolean */ + u64 lk_offset; + u64 lk_length; + u32 lk_is_new; + union { + struct { + u32 open_seqid; + stateid_t open_stateid; + u32 lock_seqid; + clientid_t clientid; + struct xdr_netobj owner; + } new; + struct { + stateid_t lock_stateid; + u32 lock_seqid; + } old; + } v; + + /* response */ + union { + struct { + stateid_t stateid; + } ok; + struct nfsd4_lock_denied denied; + } u; + /* The lk_replay_owner is the open owner in the open_to_lock_owner + * case and the lock owner otherwise: */ + struct nfs4_stateowner *lk_replay_owner; +}; +#define lk_new_open_seqid v.new.open_seqid +#define lk_new_open_stateid v.new.open_stateid +#define lk_new_lock_seqid v.new.lock_seqid +#define lk_new_clientid v.new.clientid +#define lk_new_owner v.new.owner +#define lk_old_lock_stateid v.old.lock_stateid +#define lk_old_lock_seqid v.old.lock_seqid + +#define lk_rflags u.ok.rflags +#define lk_resp_stateid u.ok.stateid +#define lk_denied u.denied + + +struct nfsd4_lockt { + u32 lt_type; + clientid_t lt_clientid; + struct xdr_netobj lt_owner; + u64 lt_offset; + u64 lt_length; + struct nfs4_stateowner * lt_stateowner; + struct nfsd4_lock_denied lt_denied; +}; + + +struct nfsd4_locku { + u32 lu_type; + u32 lu_seqid; + stateid_t lu_stateid; + u64 lu_offset; + u64 lu_length; + struct nfs4_stateowner *lu_stateowner; +}; + + +struct nfsd4_lookup { + u32 lo_len; /* request */ + char * lo_name; /* request */ +}; + +struct nfsd4_putfh { + u32 pf_fhlen; /* request */ + char *pf_fhval; /* request */ +}; + +struct nfsd4_open { + u32 op_claim_type; /* request */ + struct xdr_netobj op_fname; /* request - everything but CLAIM_PREV */ + u32 op_delegate_type; /* request - CLAIM_PREV only */ + stateid_t op_delegate_stateid; /* request - response */ + u32 op_create; /* request */ + u32 op_createmode; /* request */ + u32 op_bmval[3]; /* request */ + struct iattr iattr; /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */ + nfs4_verifier verf; /* EXCLUSIVE4 */ + clientid_t op_clientid; /* request */ + struct xdr_netobj op_owner; /* request */ + u32 op_seqid; /* request */ + u32 op_share_access; /* request */ + u32 op_share_deny; /* request */ + stateid_t op_stateid; /* response */ + u32 op_recall; /* recall */ + struct nfsd4_change_info op_cinfo; /* response */ + u32 op_rflags; /* response */ + int op_truncate; /* used during processing */ + struct nfs4_stateowner *op_stateowner; /* used during processing */ + struct nfs4_acl *op_acl; +}; +#define op_iattr iattr +#define op_verf verf + +struct nfsd4_open_confirm { + stateid_t oc_req_stateid /* request */; + u32 oc_seqid /* request */; + stateid_t oc_resp_stateid /* response */; + struct nfs4_stateowner * oc_stateowner; /* response */ +}; + +struct nfsd4_open_downgrade { + stateid_t od_stateid; + u32 od_seqid; + u32 od_share_access; + u32 od_share_deny; + struct nfs4_stateowner *od_stateowner; +}; + + +struct nfsd4_read { + stateid_t rd_stateid; /* request */ + u64 rd_offset; /* request */ + u32 rd_length; /* request */ + int rd_vlen; + struct file *rd_filp; + + struct svc_rqst *rd_rqstp; /* response */ + struct svc_fh * rd_fhp; /* response */ +}; + +struct nfsd4_readdir { + u64 rd_cookie; /* request */ + nfs4_verifier rd_verf; /* request */ + u32 rd_dircount; /* request */ + u32 rd_maxcount; /* request */ + u32 rd_bmval[3]; /* request */ + struct svc_rqst *rd_rqstp; /* response */ + struct svc_fh * rd_fhp; /* response */ + + struct readdir_cd common; + __be32 * buffer; + int buflen; + __be32 * offset; +}; + +struct nfsd4_release_lockowner { + clientid_t rl_clientid; + struct xdr_netobj rl_owner; +}; +struct nfsd4_readlink { + struct svc_rqst *rl_rqstp; /* request */ + struct svc_fh * rl_fhp; /* request */ +}; + +struct nfsd4_remove { + u32 rm_namelen; /* request */ + char * rm_name; /* request */ + struct nfsd4_change_info rm_cinfo; /* response */ +}; + +struct nfsd4_rename { + u32 rn_snamelen; /* request */ + char * rn_sname; /* request */ + u32 rn_tnamelen; /* request */ + char * rn_tname; /* request */ + struct nfsd4_change_info rn_sinfo; /* response */ + struct nfsd4_change_info rn_tinfo; /* response */ +}; + +struct nfsd4_secinfo { + u32 si_namelen; /* request */ + char *si_name; /* request */ + struct svc_export *si_exp; /* response */ +}; + +struct nfsd4_setattr { + stateid_t sa_stateid; /* request */ + u32 sa_bmval[3]; /* request */ + struct iattr sa_iattr; /* request */ + struct nfs4_acl *sa_acl; +}; + +struct nfsd4_setclientid { + nfs4_verifier se_verf; /* request */ + u32 se_namelen; /* request */ + char * se_name; /* request */ + u32 se_callback_prog; /* request */ + u32 se_callback_netid_len; /* request */ + char * se_callback_netid_val; /* request */ + u32 se_callback_addr_len; /* request */ + char * se_callback_addr_val; /* request */ + u32 se_callback_ident; /* request */ + clientid_t se_clientid; /* response */ + nfs4_verifier se_confirm; /* response */ +}; + +struct nfsd4_setclientid_confirm { + clientid_t sc_clientid; + nfs4_verifier sc_confirm; +}; + +/* also used for NVERIFY */ +struct nfsd4_verify { + u32 ve_bmval[3]; /* request */ + u32 ve_attrlen; /* request */ + char * ve_attrval; /* request */ +}; + +struct nfsd4_write { + stateid_t wr_stateid; /* request */ + u64 wr_offset; /* request */ + u32 wr_stable_how; /* request */ + u32 wr_buflen; /* request */ + int wr_vlen; + + u32 wr_bytes_written; /* response */ + u32 wr_how_written; /* response */ + nfs4_verifier wr_verifier; /* response */ +}; + +struct nfsd4_exchange_id { + nfs4_verifier verifier; + struct xdr_netobj clname; + u32 flags; + clientid_t clientid; + u32 seqid; + int spa_how; +}; + +struct nfsd4_sequence { + struct nfs4_sessionid sessionid; /* request/response */ + u32 seqid; /* request/response */ + u32 slotid; /* request/response */ + u32 maxslots; /* request/response */ + u32 cachethis; /* request */ +#if 0 + u32 target_maxslots; /* response */ + u32 status_flags; /* response */ +#endif /* not yet */ +}; + +struct nfsd4_destroy_session { + struct nfs4_sessionid sessionid; +}; + +struct nfsd4_op { + int opnum; + __be32 status; + union { + struct nfsd4_access access; + struct nfsd4_close close; + struct nfsd4_commit commit; + struct nfsd4_create create; + struct nfsd4_delegreturn delegreturn; + struct nfsd4_getattr getattr; + struct svc_fh * getfh; + struct nfsd4_link link; + struct nfsd4_lock lock; + struct nfsd4_lockt lockt; + struct nfsd4_locku locku; + struct nfsd4_lookup lookup; + struct nfsd4_verify nverify; + struct nfsd4_open open; + struct nfsd4_open_confirm open_confirm; + struct nfsd4_open_downgrade open_downgrade; + struct nfsd4_putfh putfh; + struct nfsd4_read read; + struct nfsd4_readdir readdir; + struct nfsd4_readlink readlink; + struct nfsd4_remove remove; + struct nfsd4_rename rename; + clientid_t renew; + struct nfsd4_secinfo secinfo; + struct nfsd4_setattr setattr; + struct nfsd4_setclientid setclientid; + struct nfsd4_setclientid_confirm setclientid_confirm; + struct nfsd4_verify verify; + struct nfsd4_write write; + struct nfsd4_release_lockowner release_lockowner; + + /* NFSv4.1 */ + struct nfsd4_exchange_id exchange_id; + struct nfsd4_create_session create_session; + struct nfsd4_destroy_session destroy_session; + struct nfsd4_sequence sequence; + } u; + struct nfs4_replay * replay; +}; + +struct nfsd4_compoundargs { + /* scratch variables for XDR decode */ + __be32 * p; + __be32 * end; + struct page ** pagelist; + int pagelen; + __be32 tmp[8]; + __be32 * tmpp; + struct tmpbuf { + struct tmpbuf *next; + void (*release)(const void *); + void *buf; + } *to_free; + + struct svc_rqst *rqstp; + + u32 taglen; + char * tag; + u32 minorversion; + u32 opcnt; + struct nfsd4_op *ops; + struct nfsd4_op iops[8]; +}; + +struct nfsd4_compoundres { + /* scratch variables for XDR encode */ + __be32 * p; + __be32 * end; + struct xdr_buf * xbuf; + struct svc_rqst * rqstp; + + u32 taglen; + char * tag; + u32 opcnt; + __be32 * tagp; /* tag, opcount encode location */ + struct nfsd4_compound_state cstate; +}; + +static inline bool nfsd4_is_solo_sequence(struct nfsd4_compoundres *resp) +{ + struct nfsd4_compoundargs *args = resp->rqstp->rq_argp; + return resp->opcnt == 1 && args->ops[0].opnum == OP_SEQUENCE; +} + +static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp) +{ + return !resp->cstate.slot->sl_cachethis || nfsd4_is_solo_sequence(resp); +} + +#define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs) + +static inline void +set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) +{ + BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved); + cinfo->atomic = 1; + cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode); + if (cinfo->change_supported) { + cinfo->before_change = fhp->fh_pre_change; + cinfo->after_change = fhp->fh_post_change; + } else { + cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec; + cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec; + cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec; + cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec; + } +} + +int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); +int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *, + struct nfsd4_compoundargs *); +int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *, + struct nfsd4_compoundres *); +void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *); +void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op); +__be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, + struct dentry *dentry, __be32 *buffer, int *countp, + u32 *bmval, struct svc_rqst *, int ignore_crossmnt); +extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, + struct nfsd4_setclientid *setclid); +extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, + struct nfsd4_setclientid_confirm *setclientid_confirm); +extern void nfsd4_store_cache_entry(struct nfsd4_compoundres *resp); +extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, + struct nfsd4_sequence *seq); +extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, +struct nfsd4_exchange_id *); + extern __be32 nfsd4_create_session(struct svc_rqst *, + struct nfsd4_compound_state *, + struct nfsd4_create_session *); +extern __be32 nfsd4_sequence(struct svc_rqst *, + struct nfsd4_compound_state *, + struct nfsd4_sequence *); +extern __be32 nfsd4_destroy_session(struct svc_rqst *, + struct nfsd4_compound_state *, + struct nfsd4_destroy_session *); +extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *, + struct nfsd4_open *open); +extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp, + struct svc_fh *current_fh, struct nfsd4_open *open); +extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc); +extern __be32 nfsd4_close(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, + struct nfsd4_close *close); +extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, + struct nfsd4_open_downgrade *od); +extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *, + struct nfsd4_lock *lock); +extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, + struct nfsd4_lockt *lockt); +extern __be32 nfsd4_locku(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, + struct nfsd4_locku *locku); +extern __be32 +nfsd4_release_lockowner(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, + struct nfsd4_release_lockowner *rlockowner); +extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *); +extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, struct nfsd4_delegreturn *dr); +extern __be32 nfsd4_renew(struct svc_rqst *rqstp, + struct nfsd4_compound_state *, clientid_t *clid); +#endif + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/include/linux/nfsd/cache.h b/include/linux/nfsd/cache.h deleted file mode 100644 index a165425..0000000 --- a/include/linux/nfsd/cache.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * include/linux/nfsd/cache.h - * - * Request reply cache. This was heavily inspired by the - * implementation in 4.3BSD/4.4BSD. - * - * Copyright (C) 1995, 1996 Olaf Kirch - */ - -#ifndef NFSCACHE_H -#define NFSCACHE_H - -#include - -/* - * Representation of a reply cache entry. - */ -struct svc_cacherep { - struct hlist_node c_hash; - struct list_head c_lru; - - unsigned char c_state, /* unused, inprog, done */ - c_type, /* status, buffer */ - c_secure : 1; /* req came from port < 1024 */ - struct sockaddr_in c_addr; - __be32 c_xid; - u32 c_prot; - u32 c_proc; - u32 c_vers; - unsigned long c_timestamp; - union { - struct kvec u_vec; - __be32 u_status; - } c_u; -}; - -#define c_replvec c_u.u_vec -#define c_replstat c_u.u_status - -/* cache entry states */ -enum { - RC_UNUSED, - RC_INPROG, - RC_DONE -}; - -/* return values */ -enum { - RC_DROPIT, - RC_REPLY, - RC_DOIT, - RC_INTR -}; - -/* - * Cache types. - * We may want to add more types one day, e.g. for diropres and - * attrstat replies. Using cache entries with fixed length instead - * of buffer pointers may be more efficient. - */ -enum { - RC_NOCACHE, - RC_REPLSTAT, - RC_REPLBUFF, -}; - -/* - * If requests are retransmitted within this interval, they're dropped. - */ -#define RC_DELAY (HZ/5) - -int nfsd_reply_cache_init(void); -void nfsd_reply_cache_shutdown(void); -int nfsd_cache_lookup(struct svc_rqst *, int); -void nfsd_cache_update(struct svc_rqst *, int, __be32 *); - -#ifdef CONFIG_NFSD_V4 -void nfsd4_set_statp(struct svc_rqst *rqstp, __be32 *statp); -#else /* CONFIG_NFSD_V4 */ -static inline void nfsd4_set_statp(struct svc_rqst *rqstp, __be32 *statp) -{ -} -#endif /* CONFIG_NFSD_V4 */ - -#endif /* NFSCACHE_H */ diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h deleted file mode 100644 index 74f67c2..0000000 --- a/include/linux/nfsd/nfsd.h +++ /dev/null @@ -1,335 +0,0 @@ -/* - * linux/include/linux/nfsd/nfsd.h - * - * Hodge-podge collection of knfsd-related stuff. - * I will sort this out later. - * - * Copyright (C) 1995-1997 Olaf Kirch - */ - -#ifndef LINUX_NFSD_NFSD_H -#define LINUX_NFSD_NFSD_H - -#include -#include - -#include -#include -#include -/* - * nfsd version - */ -#define NFSD_SUPPORTED_MINOR_VERSION 1 - -struct readdir_cd { - __be32 err; /* 0, nfserr, or nfserr_eof */ -}; - - -extern struct svc_program nfsd_program; -extern struct svc_version nfsd_version2, nfsd_version3, - nfsd_version4; -extern u32 nfsd_supported_minorversion; -extern struct mutex nfsd_mutex; -extern struct svc_serv *nfsd_serv; -extern spinlock_t nfsd_drc_lock; -extern unsigned int nfsd_drc_max_mem; -extern unsigned int nfsd_drc_mem_used; - -extern const struct seq_operations nfs_exports_op; - -/* - * Function prototypes. - */ -int nfsd_svc(unsigned short port, int nrservs); -int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp); - -int nfsd_nrthreads(void); -int nfsd_nrpools(void); -int nfsd_get_nrthreads(int n, int *); -int nfsd_set_nrthreads(int n, int *); - -#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) -#ifdef CONFIG_NFSD_V2_ACL -extern struct svc_version nfsd_acl_version2; -#else -#define nfsd_acl_version2 NULL -#endif -#ifdef CONFIG_NFSD_V3_ACL -extern struct svc_version nfsd_acl_version3; -#else -#define nfsd_acl_version3 NULL -#endif -#endif - -enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL }; -int nfsd_vers(int vers, enum vers_op change); -int nfsd_minorversion(u32 minorversion, enum vers_op change); -void nfsd_reset_versions(void); -int nfsd_create_serv(void); - -extern int nfsd_max_blksize; - -/* - * NFSv4 State - */ -#ifdef CONFIG_NFSD_V4 -extern unsigned int max_delegations; -int nfs4_state_init(void); -void nfsd4_free_slabs(void); -int nfs4_state_start(void); -void nfs4_state_shutdown(void); -time_t nfs4_lease_time(void); -void nfs4_reset_lease(time_t leasetime); -int nfs4_reset_recoverydir(char *recdir); -#else -static inline int nfs4_state_init(void) { return 0; } -static inline void nfsd4_free_slabs(void) { } -static inline int nfs4_state_start(void) { return 0; } -static inline void nfs4_state_shutdown(void) { } -static inline time_t nfs4_lease_time(void) { return 0; } -static inline void nfs4_reset_lease(time_t leasetime) { } -static inline int nfs4_reset_recoverydir(char *recdir) { return 0; } -#endif - -/* - * lockd binding - */ -void nfsd_lockd_init(void); -void nfsd_lockd_shutdown(void); - - -/* - * These macros provide pre-xdr'ed values for faster operation. - */ -#define nfs_ok cpu_to_be32(NFS_OK) -#define nfserr_perm cpu_to_be32(NFSERR_PERM) -#define nfserr_noent cpu_to_be32(NFSERR_NOENT) -#define nfserr_io cpu_to_be32(NFSERR_IO) -#define nfserr_nxio cpu_to_be32(NFSERR_NXIO) -#define nfserr_eagain cpu_to_be32(NFSERR_EAGAIN) -#define nfserr_acces cpu_to_be32(NFSERR_ACCES) -#define nfserr_exist cpu_to_be32(NFSERR_EXIST) -#define nfserr_xdev cpu_to_be32(NFSERR_XDEV) -#define nfserr_nodev cpu_to_be32(NFSERR_NODEV) -#define nfserr_notdir cpu_to_be32(NFSERR_NOTDIR) -#define nfserr_isdir cpu_to_be32(NFSERR_ISDIR) -#define nfserr_inval cpu_to_be32(NFSERR_INVAL) -#define nfserr_fbig cpu_to_be32(NFSERR_FBIG) -#define nfserr_nospc cpu_to_be32(NFSERR_NOSPC) -#define nfserr_rofs cpu_to_be32(NFSERR_ROFS) -#define nfserr_mlink cpu_to_be32(NFSERR_MLINK) -#define nfserr_opnotsupp cpu_to_be32(NFSERR_OPNOTSUPP) -#define nfserr_nametoolong cpu_to_be32(NFSERR_NAMETOOLONG) -#define nfserr_notempty cpu_to_be32(NFSERR_NOTEMPTY) -#define nfserr_dquot cpu_to_be32(NFSERR_DQUOT) -#define nfserr_stale cpu_to_be32(NFSERR_STALE) -#define nfserr_remote cpu_to_be32(NFSERR_REMOTE) -#define nfserr_wflush cpu_to_be32(NFSERR_WFLUSH) -#define nfserr_badhandle cpu_to_be32(NFSERR_BADHANDLE) -#define nfserr_notsync cpu_to_be32(NFSERR_NOT_SYNC) -#define nfserr_badcookie cpu_to_be32(NFSERR_BAD_COOKIE) -#define nfserr_notsupp cpu_to_be32(NFSERR_NOTSUPP) -#define nfserr_toosmall cpu_to_be32(NFSERR_TOOSMALL) -#define nfserr_serverfault cpu_to_be32(NFSERR_SERVERFAULT) -#define nfserr_badtype cpu_to_be32(NFSERR_BADTYPE) -#define nfserr_jukebox cpu_to_be32(NFSERR_JUKEBOX) -#define nfserr_denied cpu_to_be32(NFSERR_DENIED) -#define nfserr_deadlock cpu_to_be32(NFSERR_DEADLOCK) -#define nfserr_expired cpu_to_be32(NFSERR_EXPIRED) -#define nfserr_bad_cookie cpu_to_be32(NFSERR_BAD_COOKIE) -#define nfserr_same cpu_to_be32(NFSERR_SAME) -#define nfserr_clid_inuse cpu_to_be32(NFSERR_CLID_INUSE) -#define nfserr_stale_clientid cpu_to_be32(NFSERR_STALE_CLIENTID) -#define nfserr_resource cpu_to_be32(NFSERR_RESOURCE) -#define nfserr_moved cpu_to_be32(NFSERR_MOVED) -#define nfserr_nofilehandle cpu_to_be32(NFSERR_NOFILEHANDLE) -#define nfserr_minor_vers_mismatch cpu_to_be32(NFSERR_MINOR_VERS_MISMATCH) -#define nfserr_share_denied cpu_to_be32(NFSERR_SHARE_DENIED) -#define nfserr_stale_stateid cpu_to_be32(NFSERR_STALE_STATEID) -#define nfserr_old_stateid cpu_to_be32(NFSERR_OLD_STATEID) -#define nfserr_bad_stateid cpu_to_be32(NFSERR_BAD_STATEID) -#define nfserr_bad_seqid cpu_to_be32(NFSERR_BAD_SEQID) -#define nfserr_symlink cpu_to_be32(NFSERR_SYMLINK) -#define nfserr_not_same cpu_to_be32(NFSERR_NOT_SAME) -#define nfserr_restorefh cpu_to_be32(NFSERR_RESTOREFH) -#define nfserr_attrnotsupp cpu_to_be32(NFSERR_ATTRNOTSUPP) -#define nfserr_bad_xdr cpu_to_be32(NFSERR_BAD_XDR) -#define nfserr_openmode cpu_to_be32(NFSERR_OPENMODE) -#define nfserr_locks_held cpu_to_be32(NFSERR_LOCKS_HELD) -#define nfserr_op_illegal cpu_to_be32(NFSERR_OP_ILLEGAL) -#define nfserr_grace cpu_to_be32(NFSERR_GRACE) -#define nfserr_no_grace cpu_to_be32(NFSERR_NO_GRACE) -#define nfserr_reclaim_bad cpu_to_be32(NFSERR_RECLAIM_BAD) -#define nfserr_badname cpu_to_be32(NFSERR_BADNAME) -#define nfserr_cb_path_down cpu_to_be32(NFSERR_CB_PATH_DOWN) -#define nfserr_locked cpu_to_be32(NFSERR_LOCKED) -#define nfserr_wrongsec cpu_to_be32(NFSERR_WRONGSEC) -#define nfserr_badiomode cpu_to_be32(NFS4ERR_BADIOMODE) -#define nfserr_badlayout cpu_to_be32(NFS4ERR_BADLAYOUT) -#define nfserr_bad_session_digest cpu_to_be32(NFS4ERR_BAD_SESSION_DIGEST) -#define nfserr_badsession cpu_to_be32(NFS4ERR_BADSESSION) -#define nfserr_badslot cpu_to_be32(NFS4ERR_BADSLOT) -#define nfserr_complete_already cpu_to_be32(NFS4ERR_COMPLETE_ALREADY) -#define nfserr_conn_not_bound_to_session cpu_to_be32(NFS4ERR_CONN_NOT_BOUND_TO_SESSION) -#define nfserr_deleg_already_wanted cpu_to_be32(NFS4ERR_DELEG_ALREADY_WANTED) -#define nfserr_back_chan_busy cpu_to_be32(NFS4ERR_BACK_CHAN_BUSY) -#define nfserr_layouttrylater cpu_to_be32(NFS4ERR_LAYOUTTRYLATER) -#define nfserr_layoutunavailable cpu_to_be32(NFS4ERR_LAYOUTUNAVAILABLE) -#define nfserr_nomatching_layout cpu_to_be32(NFS4ERR_NOMATCHING_LAYOUT) -#define nfserr_recallconflict cpu_to_be32(NFS4ERR_RECALLCONFLICT) -#define nfserr_unknown_layouttype cpu_to_be32(NFS4ERR_UNKNOWN_LAYOUTTYPE) -#define nfserr_seq_misordered cpu_to_be32(NFS4ERR_SEQ_MISORDERED) -#define nfserr_sequence_pos cpu_to_be32(NFS4ERR_SEQUENCE_POS) -#define nfserr_req_too_big cpu_to_be32(NFS4ERR_REQ_TOO_BIG) -#define nfserr_rep_too_big cpu_to_be32(NFS4ERR_REP_TOO_BIG) -#define nfserr_rep_too_big_to_cache cpu_to_be32(NFS4ERR_REP_TOO_BIG_TO_CACHE) -#define nfserr_retry_uncached_rep cpu_to_be32(NFS4ERR_RETRY_UNCACHED_REP) -#define nfserr_unsafe_compound cpu_to_be32(NFS4ERR_UNSAFE_COMPOUND) -#define nfserr_too_many_ops cpu_to_be32(NFS4ERR_TOO_MANY_OPS) -#define nfserr_op_not_in_session cpu_to_be32(NFS4ERR_OP_NOT_IN_SESSION) -#define nfserr_hash_alg_unsupp cpu_to_be32(NFS4ERR_HASH_ALG_UNSUPP) -#define nfserr_clientid_busy cpu_to_be32(NFS4ERR_CLIENTID_BUSY) -#define nfserr_pnfs_io_hole cpu_to_be32(NFS4ERR_PNFS_IO_HOLE) -#define nfserr_seq_false_retry cpu_to_be32(NFS4ERR_SEQ_FALSE_RETRY) -#define nfserr_bad_high_slot cpu_to_be32(NFS4ERR_BAD_HIGH_SLOT) -#define nfserr_deadsession cpu_to_be32(NFS4ERR_DEADSESSION) -#define nfserr_encr_alg_unsupp cpu_to_be32(NFS4ERR_ENCR_ALG_UNSUPP) -#define nfserr_pnfs_no_layout cpu_to_be32(NFS4ERR_PNFS_NO_LAYOUT) -#define nfserr_not_only_op cpu_to_be32(NFS4ERR_NOT_ONLY_OP) -#define nfserr_wrong_cred cpu_to_be32(NFS4ERR_WRONG_CRED) -#define nfserr_wrong_type cpu_to_be32(NFS4ERR_WRONG_TYPE) -#define nfserr_dirdeleg_unavail cpu_to_be32(NFS4ERR_DIRDELEG_UNAVAIL) -#define nfserr_reject_deleg cpu_to_be32(NFS4ERR_REJECT_DELEG) -#define nfserr_returnconflict cpu_to_be32(NFS4ERR_RETURNCONFLICT) -#define nfserr_deleg_revoked cpu_to_be32(NFS4ERR_DELEG_REVOKED) - -/* error codes for internal use */ -/* if a request fails due to kmalloc failure, it gets dropped. - * Client should resend eventually - */ -#define nfserr_dropit cpu_to_be32(30000) -/* end-of-file indicator in readdir */ -#define nfserr_eof cpu_to_be32(30001) -/* replay detected */ -#define nfserr_replay_me cpu_to_be32(11001) -/* nfs41 replay detected */ -#define nfserr_replay_cache cpu_to_be32(11002) - -/* Check for dir entries '.' and '..' */ -#define isdotent(n, l) (l < 3 && n[0] == '.' && (l == 1 || n[1] == '.')) - -/* - * Time of server startup - */ -extern struct timeval nfssvc_boot; - -#ifdef CONFIG_NFSD_V4 - -/* before processing a COMPOUND operation, we have to check that there - * is enough space in the buffer for XDR encode to succeed. otherwise, - * we might process an operation with side effects, and be unable to - * tell the client that the operation succeeded. - * - * COMPOUND_SLACK_SPACE - this is the minimum bytes of buffer space - * needed to encode an "ordinary" _successful_ operation. (GETATTR, - * READ, READDIR, and READLINK have their own buffer checks.) if we - * fall below this level, we fail the next operation with NFS4ERR_RESOURCE. - * - * COMPOUND_ERR_SLACK_SPACE - this is the minimum bytes of buffer space - * needed to encode an operation which has failed with NFS4ERR_RESOURCE. - * care is taken to ensure that we never fall below this level for any - * reason. - */ -#define COMPOUND_SLACK_SPACE 140 /* OP_GETFH */ -#define COMPOUND_ERR_SLACK_SPACE 12 /* OP_SETATTR */ - -#define NFSD_LEASE_TIME (nfs4_lease_time()) -#define NFSD_LAUNDROMAT_MINTIMEOUT 10 /* seconds */ - -/* - * The following attributes are currently not supported by the NFSv4 server: - * ARCHIVE (deprecated anyway) - * HIDDEN (unlikely to be supported any time soon) - * MIMETYPE (unlikely to be supported any time soon) - * QUOTA_* (will be supported in a forthcoming patch) - * SYSTEM (unlikely to be supported any time soon) - * TIME_BACKUP (unlikely to be supported any time soon) - * TIME_CREATE (unlikely to be supported any time soon) - */ -#define NFSD4_SUPPORTED_ATTRS_WORD0 \ -(FATTR4_WORD0_SUPPORTED_ATTRS | FATTR4_WORD0_TYPE | FATTR4_WORD0_FH_EXPIRE_TYPE \ - | FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE | FATTR4_WORD0_LINK_SUPPORT \ - | FATTR4_WORD0_SYMLINK_SUPPORT | FATTR4_WORD0_NAMED_ATTR | FATTR4_WORD0_FSID \ - | FATTR4_WORD0_UNIQUE_HANDLES | FATTR4_WORD0_LEASE_TIME | FATTR4_WORD0_RDATTR_ERROR \ - | FATTR4_WORD0_ACLSUPPORT | FATTR4_WORD0_CANSETTIME | FATTR4_WORD0_CASE_INSENSITIVE \ - | FATTR4_WORD0_CASE_PRESERVING | FATTR4_WORD0_CHOWN_RESTRICTED \ - | FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FILEID | FATTR4_WORD0_FILES_AVAIL \ - | FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_HOMOGENEOUS \ - | FATTR4_WORD0_MAXFILESIZE | FATTR4_WORD0_MAXLINK | FATTR4_WORD0_MAXNAME \ - | FATTR4_WORD0_MAXREAD | FATTR4_WORD0_MAXWRITE | FATTR4_WORD0_ACL) - -#define NFSD4_SUPPORTED_ATTRS_WORD1 \ -(FATTR4_WORD1_MODE | FATTR4_WORD1_NO_TRUNC | FATTR4_WORD1_NUMLINKS \ - | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP | FATTR4_WORD1_RAWDEV \ - | FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | FATTR4_WORD1_SPACE_TOTAL \ - | FATTR4_WORD1_SPACE_USED | FATTR4_WORD1_TIME_ACCESS | FATTR4_WORD1_TIME_ACCESS_SET \ - | FATTR4_WORD1_TIME_DELTA | FATTR4_WORD1_TIME_METADATA \ - | FATTR4_WORD1_TIME_MODIFY | FATTR4_WORD1_TIME_MODIFY_SET | FATTR4_WORD1_MOUNTED_ON_FILEID) - -#define NFSD4_SUPPORTED_ATTRS_WORD2 0 - -#define NFSD4_1_SUPPORTED_ATTRS_WORD0 \ - NFSD4_SUPPORTED_ATTRS_WORD0 - -#define NFSD4_1_SUPPORTED_ATTRS_WORD1 \ - NFSD4_SUPPORTED_ATTRS_WORD1 - -#define NFSD4_1_SUPPORTED_ATTRS_WORD2 \ - (NFSD4_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SUPPATTR_EXCLCREAT) - -static inline u32 nfsd_suppattrs0(u32 minorversion) -{ - return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0 - : NFSD4_SUPPORTED_ATTRS_WORD0; -} - -static inline u32 nfsd_suppattrs1(u32 minorversion) -{ - return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD1 - : NFSD4_SUPPORTED_ATTRS_WORD1; -} - -static inline u32 nfsd_suppattrs2(u32 minorversion) -{ - return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD2 - : NFSD4_SUPPORTED_ATTRS_WORD2; -} - -/* These will return ERR_INVAL if specified in GETATTR or READDIR. */ -#define NFSD_WRITEONLY_ATTRS_WORD1 \ -(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) - -/* These are the only attrs allowed in CREATE/OPEN/SETATTR. */ -#define NFSD_WRITEABLE_ATTRS_WORD0 \ -(FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL ) -#define NFSD_WRITEABLE_ATTRS_WORD1 \ -(FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ - | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) -#define NFSD_WRITEABLE_ATTRS_WORD2 0 - -#define NFSD_SUPPATTR_EXCLCREAT_WORD0 \ - NFSD_WRITEABLE_ATTRS_WORD0 -/* - * we currently store the exclusive create verifier in the v_{a,m}time - * attributes so the client can't set these at create time using EXCLUSIVE4_1 - */ -#define NFSD_SUPPATTR_EXCLCREAT_WORD1 \ - (NFSD_WRITEABLE_ATTRS_WORD1 & \ - ~(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)) -#define NFSD_SUPPATTR_EXCLCREAT_WORD2 \ - NFSD_WRITEABLE_ATTRS_WORD2 - -#endif /* CONFIG_NFSD_V4 */ - -#endif /* LINUX_NFSD_NFSD_H */ diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h deleted file mode 100644 index 2af7568..0000000 --- a/include/linux/nfsd/state.h +++ /dev/null @@ -1,409 +0,0 @@ -/* - * linux/include/nfsd/state.h - * - * Copyright (c) 2001 The Regents of the University of Michigan. - * All rights reserved. - * - * Kendrick Smith - * Andy Adamson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef _NFSD4_STATE_H -#define _NFSD4_STATE_H - -#include - -typedef struct { - u32 cl_boot; - u32 cl_id; -} clientid_t; - -typedef struct { - u32 so_boot; - u32 so_stateownerid; - u32 so_fileid; -} stateid_opaque_t; - -typedef struct { - u32 si_generation; - stateid_opaque_t si_opaque; -} stateid_t; -#define si_boot si_opaque.so_boot -#define si_stateownerid si_opaque.so_stateownerid -#define si_fileid si_opaque.so_fileid - -#define STATEID_FMT "(%08x/%08x/%08x/%08x)" -#define STATEID_VAL(s) \ - (s)->si_boot, \ - (s)->si_stateownerid, \ - (s)->si_fileid, \ - (s)->si_generation - -struct nfsd4_cb_sequence { - /* args/res */ - u32 cbs_minorversion; - struct nfs4_client *cbs_clp; -}; - -struct nfs4_delegation { - struct list_head dl_perfile; - struct list_head dl_perclnt; - struct list_head dl_recall_lru; /* delegation recalled */ - atomic_t dl_count; /* ref count */ - struct nfs4_client *dl_client; - struct nfs4_file *dl_file; - struct file_lock *dl_flock; - struct file *dl_vfs_file; - u32 dl_type; - time_t dl_time; -/* For recall: */ - u32 dl_ident; - stateid_t dl_stateid; - struct knfsd_fh dl_fh; - int dl_retries; -}; - -/* client delegation callback info */ -struct nfs4_cb_conn { - /* SETCLIENTID info */ - struct sockaddr_storage cb_addr; - size_t cb_addrlen; - u32 cb_prog; - u32 cb_minorversion; - u32 cb_ident; /* minorversion 0 only */ - /* RPC client info */ - atomic_t cb_set; /* successful CB_NULL call */ - struct rpc_clnt * cb_client; -}; - -/* Maximum number of slots per session. 160 is useful for long haul TCP */ -#define NFSD_MAX_SLOTS_PER_SESSION 160 -/* Maximum number of operations per session compound */ -#define NFSD_MAX_OPS_PER_COMPOUND 16 -/* Maximum session per slot cache size */ -#define NFSD_SLOT_CACHE_SIZE 1024 -/* Maximum number of NFSD_SLOT_CACHE_SIZE slots per session */ -#define NFSD_CACHE_SIZE_SLOTS_PER_SESSION 32 -#define NFSD_MAX_MEM_PER_SESSION \ - (NFSD_CACHE_SIZE_SLOTS_PER_SESSION * NFSD_SLOT_CACHE_SIZE) - -struct nfsd4_slot { - bool sl_inuse; - bool sl_cachethis; - u16 sl_opcnt; - u32 sl_seqid; - __be32 sl_status; - u32 sl_datalen; - char sl_data[]; -}; - -struct nfsd4_channel_attrs { - u32 headerpadsz; - u32 maxreq_sz; - u32 maxresp_sz; - u32 maxresp_cached; - u32 maxops; - u32 maxreqs; - u32 nr_rdma_attrs; - u32 rdma_attrs; -}; - -struct nfsd4_create_session { - clientid_t clientid; - struct nfs4_sessionid sessionid; - u32 seqid; - u32 flags; - struct nfsd4_channel_attrs fore_channel; - struct nfsd4_channel_attrs back_channel; - u32 callback_prog; - u32 uid; - u32 gid; -}; - -/* The single slot clientid cache structure */ -struct nfsd4_clid_slot { - u32 sl_seqid; - __be32 sl_status; - struct nfsd4_create_session sl_cr_ses; -}; - -struct nfsd4_session { - struct kref se_ref; - struct list_head se_hash; /* hash by sessionid */ - struct list_head se_perclnt; - u32 se_flags; - struct nfs4_client *se_client; /* for expire_client */ - struct nfs4_sessionid se_sessionid; - struct nfsd4_channel_attrs se_fchannel; - struct nfsd4_channel_attrs se_bchannel; - struct nfsd4_slot *se_slots[]; /* forward channel slots */ -}; - -static inline void -nfsd4_put_session(struct nfsd4_session *ses) -{ - extern void free_session(struct kref *kref); - kref_put(&ses->se_ref, free_session); -} - -static inline void -nfsd4_get_session(struct nfsd4_session *ses) -{ - kref_get(&ses->se_ref); -} - -/* formatted contents of nfs4_sessionid */ -struct nfsd4_sessionid { - clientid_t clientid; - u32 sequence; - u32 reserved; -}; - -#define HEXDIR_LEN 33 /* hex version of 16 byte md5 of cl_name plus '\0' */ - -/* - * struct nfs4_client - one per client. Clientids live here. - * o Each nfs4_client is hashed by clientid. - * - * o Each nfs4_clients is also hashed by name - * (the opaque quantity initially sent by the client to identify itself). - * - * o cl_perclient list is used to ensure no dangling stateowner references - * when we expire the nfs4_client - */ -struct nfs4_client { - struct list_head cl_idhash; /* hash by cl_clientid.id */ - struct list_head cl_strhash; /* hash by cl_name */ - struct list_head cl_openowners; - struct list_head cl_delegations; - struct list_head cl_lru; /* tail queue */ - struct xdr_netobj cl_name; /* id generated by client */ - char cl_recdir[HEXDIR_LEN]; /* recovery dir */ - nfs4_verifier cl_verifier; /* generated by client */ - time_t cl_time; /* time of last lease renewal */ - struct sockaddr_storage cl_addr; /* client ipaddress */ - u32 cl_flavor; /* setclientid pseudoflavor */ - char *cl_principal; /* setclientid principal name */ - struct svc_cred cl_cred; /* setclientid principal */ - clientid_t cl_clientid; /* generated by server */ - nfs4_verifier cl_confirm; /* generated by server */ - struct nfs4_cb_conn cl_cb_conn; /* callback info */ - atomic_t cl_count; /* ref count */ - u32 cl_firststate; /* recovery dir creation */ - - /* for nfs41 */ - struct list_head cl_sessions; - struct nfsd4_clid_slot cl_cs_slot; /* create_session slot */ - u32 cl_exchange_flags; - struct nfs4_sessionid cl_sessionid; - - /* for nfs41 callbacks */ - /* We currently support a single back channel with a single slot */ - unsigned long cl_cb_slot_busy; - u32 cl_cb_seq_nr; - struct svc_xprt *cl_cb_xprt; /* 4.1 callback transport */ - struct rpc_wait_queue cl_cb_waitq; /* backchannel callers may */ - /* wait here for slots */ -}; - -/* struct nfs4_client_reset - * one per old client. Populates reset_str_hashtbl. Filled from conf_id_hashtbl - * upon lease reset, or from upcall to state_daemon (to read in state - * from non-volitile storage) upon reboot. - */ -struct nfs4_client_reclaim { - struct list_head cr_strhash; /* hash by cr_name */ - char cr_recdir[HEXDIR_LEN]; /* recover dir */ -}; - -static inline void -update_stateid(stateid_t *stateid) -{ - stateid->si_generation++; -} - -/* A reasonable value for REPLAY_ISIZE was estimated as follows: - * The OPEN response, typically the largest, requires - * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) + 8(verifier) + - * 4(deleg. type) + 8(deleg. stateid) + 4(deleg. recall flag) + - * 20(deleg. space limit) + ~32(deleg. ace) = 112 bytes - */ - -#define NFSD4_REPLAY_ISIZE 112 - -/* - * Replay buffer, where the result of the last seqid-mutating operation - * is cached. - */ -struct nfs4_replay { - __be32 rp_status; - unsigned int rp_buflen; - char *rp_buf; - unsigned intrp_allocated; - struct knfsd_fh rp_openfh; - char rp_ibuf[NFSD4_REPLAY_ISIZE]; -}; - -/* -* nfs4_stateowner can either be an open_owner, or a lock_owner -* -* so_idhash: stateid_hashtbl[] for open owner, lockstateid_hashtbl[] -* for lock_owner -* so_strhash: ownerstr_hashtbl[] for open_owner, lock_ownerstr_hashtbl[] -* for lock_owner -* so_perclient: nfs4_client->cl_perclient entry - used when nfs4_client -* struct is reaped. -* so_perfilestate: heads the list of nfs4_stateid (either open or lock) -* and is used to ensure no dangling nfs4_stateid references when we -* release a stateowner. -* so_perlockowner: (open) nfs4_stateid->st_perlockowner entry - used when -* close is called to reap associated byte-range locks -* so_close_lru: (open) stateowner is placed on this list instead of being -* reaped (when so_perfilestate is empty) to hold the last close replay. -* reaped by laundramat thread after lease period. -*/ -struct nfs4_stateowner { - struct kref so_ref; - struct list_head so_idhash; /* hash by so_id */ - struct list_head so_strhash; /* hash by op_name */ - struct list_head so_perclient; - struct list_head so_stateids; - struct list_head so_perstateid; /* for lockowners only */ - struct list_head so_close_lru; /* tail queue */ - time_t so_time; /* time of placement on so_close_lru */ - int so_is_open_owner; /* 1=openowner,0=lockowner */ - u32 so_id; - struct nfs4_client * so_client; - /* after increment in ENCODE_SEQID_OP_TAIL, represents the next - * sequence id expected from the client: */ - u32 so_seqid; - struct xdr_netobj so_owner; /* open owner name */ - int so_confirmed; /* successful OPEN_CONFIRM? */ - struct nfs4_replay so_replay; -}; - -/* -* nfs4_file: a file opened by some number of (open) nfs4_stateowners. -* o fi_perfile list is used to search for conflicting -* share_acces, share_deny on the file. -*/ -struct nfs4_file { - atomic_t fi_ref; - struct list_head fi_hash; /* hash by "struct inode *" */ - struct list_head fi_stateids; - struct list_head fi_delegations; - struct inode *fi_inode; - u32 fi_id; /* used with stateowner->so_id - * for stateid_hashtbl hash */ - bool fi_had_conflict; -}; - -/* -* nfs4_stateid can either be an open stateid or (eventually) a lock stateid -* -* (open)nfs4_stateid: one per (open)nfs4_stateowner, nfs4_file -* -* st_hash: stateid_hashtbl[] entry or lockstateid_hashtbl entry -* st_perfile: file_hashtbl[] entry. -* st_perfile_state: nfs4_stateowner->so_perfilestate -* st_perlockowner: (open stateid) list of lock nfs4_stateowners -* st_access_bmap: used only for open stateid -* st_deny_bmap: used only for open stateid -* st_openstp: open stateid lock stateid was derived from -* -* XXX: open stateids and lock stateids have diverged sufficiently that -* we should consider defining separate structs for the two cases. -*/ - -struct nfs4_stateid { - struct list_head st_hash; - struct list_head st_perfile; - struct list_head st_perstateowner; - struct list_head st_lockowners; - struct nfs4_stateowner * st_stateowner; - struct nfs4_file * st_file; - stateid_t st_stateid; - struct file * st_vfs_file; - unsigned long st_access_bmap; - unsigned long st_deny_bmap; - struct nfs4_stateid * st_openstp; -}; - -/* flags for preprocess_seqid_op() */ -#define HAS_SESSION 0x00000001 -#define CONFIRM 0x00000002 -#define OPEN_STATE 0x00000004 -#define LOCK_STATE 0x00000008 -#define RD_STATE 0x00000010 -#define WR_STATE 0x00000020 -#define CLOSE_STATE 0x00000040 - -#define seqid_mutating_err(err) \ - (((err) != nfserr_stale_clientid) && \ - ((err) != nfserr_bad_seqid) && \ - ((err) != nfserr_stale_stateid) && \ - ((err) != nfserr_bad_stateid)) - -struct nfsd4_compound_state; - -extern __be32 nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, - stateid_t *stateid, int flags, struct file **filp); -extern void nfs4_lock_state(void); -extern void nfs4_unlock_state(void); -extern int nfs4_in_grace(void); -extern __be32 nfs4_check_open_reclaim(clientid_t *clid); -extern void put_nfs4_client(struct nfs4_client *clp); -extern void nfs4_free_stateowner(struct kref *kref); -extern int set_callback_cred(void); -extern void nfsd4_probe_callback(struct nfs4_client *clp); -extern void nfsd4_cb_recall(struct nfs4_delegation *dp); -extern void nfs4_put_delegation(struct nfs4_delegation *dp); -extern __be32 nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname); -extern void nfsd4_init_recdir(char *recdir_name); -extern int nfsd4_recdir_load(void); -extern void nfsd4_shutdown_recdir(void); -extern int nfs4_client_to_reclaim(const char *name); -extern int nfs4_has_reclaimed_state(const char *name, bool use_exchange_id); -extern void nfsd4_recdir_purge_old(void); -extern int nfsd4_create_clid_dir(struct nfs4_client *clp); -extern void nfsd4_remove_clid_dir(struct nfs4_client *clp); - -static inline void -nfs4_put_stateowner(struct nfs4_stateowner *so) -{ - kref_put(&so->so_ref, nfs4_free_stateowner); -} - -static inline void -nfs4_get_stateowner(struct nfs4_stateowner *so) -{ - kref_get(&so->so_ref); -} - -#endif /* NFSD4_STATE_H */ diff --git a/include/linux/nfsd/xdr.h b/include/linux/nfsd/xdr.h deleted file mode 100644 index 58f824d..0000000 --- a/include/linux/nfsd/xdr.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - * linux/include/linux/nfsd/xdr.h - * - * XDR types for nfsd. This is mainly a typing exercise. - */ - -#ifndef LINUX_NFSD_H -#define LINUX_NFSD_H - -#include -#include - -struct nfsd_fhandle { - struct svc_fh fh; -}; - -struct nfsd_sattrargs { - struct svc_fh fh; - struct iattr attrs; -}; - -struct nfsd_diropargs { - struct svc_fh fh; - char * name; - unsigned int len; -}; - -struct nfsd_readargs { - struct svc_fh fh; - __u32 offset; - __u32 count; - int vlen; -}; - -struct nfsd_writeargs { - svc_fh fh; - __u32 offset; - int len; - int vlen; -}; - -struct nfsd_createargs { - struct svc_fh fh; - char * name; - unsigned int len; - struct iattr attrs; -}; - -struct nfsd_renameargs { - struct svc_fh ffh; - char * fname; - unsigned int flen; - struct svc_fh tfh; - char * tname; - unsigned int tlen; -}; - -struct nfsd_readlinkargs { - struct svc_fh fh; - char * buffer; -}; - -struct nfsd_linkargs { - struct svc_fh ffh; - struct svc_fh tfh; - char * tname; - unsigned int tlen; -}; - -struct nfsd_symlinkargs { - struct svc_fh ffh; - char * fname; - unsigned int flen; - char * tname; - unsigned int tlen; - struct iattr attrs; -}; - -struct nfsd_readdirargs { - struct svc_fh fh; - __u32 cookie; - __u32 count; - __be32 * buffer; -}; - -struct nfsd_attrstat { - struct svc_fh fh; - struct kstat stat; -}; - -struct nfsd_diropres { - struct svc_fh fh; - struct kstat stat; -}; - -struct nfsd_readlinkres { - int len; -}; - -struct nfsd_readres { - struct svc_fh fh; - unsigned long count; - struct kstat stat; -}; - -struct nfsd_readdirres { - int count; - - struct readdir_cd common; - __be32 * buffer; - int buflen; - __be32 * offset; -}; - -struct nfsd_statfsres { - struct kstatfs stats; -}; - -/* - * Storage requirements for XDR arguments and results. - */ -union nfsd_xdrstore { - struct nfsd_sattrargs sattr; - struct nfsd_diropargs dirop; - struct nfsd_readargs read; - struct nfsd_writeargs write; - struct nfsd_createargs create; - struct nfsd_renameargs rename; - struct nfsd_linkargs link; - struct nfsd_symlinkargs symlink; - struct nfsd_readdirargs readdir; -}; - -#define NFS2_SVC_XDRSIZE sizeof(union nfsd_xdrstore) - - -int nfssvc_decode_void(struct svc_rqst *, __be32 *, void *); -int nfssvc_decode_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); -int nfssvc_decode_sattrargs(struct svc_rqst *, __be32 *, - struct nfsd_sattrargs *); -int nfssvc_decode_diropargs(struct svc_rqst *, __be32 *, - struct nfsd_diropargs *); -int nfssvc_decode_readargs(struct svc_rqst *, __be32 *, - struct nfsd_readargs *); -int nfssvc_decode_writeargs(struct svc_rqst *, __be32 *, - struct nfsd_writeargs *); -int nfssvc_decode_createargs(struct svc_rqst *, __be32 *, - struct nfsd_createargs *); -int nfssvc_decode_renameargs(struct svc_rqst *, __be32 *, - struct nfsd_renameargs *); -int nfssvc_decode_readlinkargs(struct svc_rqst *, __be32 *, - struct nfsd_readlinkargs *); -int nfssvc_decode_linkargs(struct svc_rqst *, __be32 *, - struct nfsd_linkargs *); -int nfssvc_decode_symlinkargs(struct svc_rqst *, __be32 *, - struct nfsd_symlinkargs *); -int nfssvc_decode_readdirargs(struct svc_rqst *, __be32 *, - struct nfsd_readdirargs *); -int nfssvc_encode_void(struct svc_rqst *, __be32 *, void *); -int nfssvc_encode_attrstat(struct svc_rqst *, __be32 *, struct nfsd_attrstat *); -int nfssvc_encode_diropres(struct svc_rqst *, __be32 *, struct nfsd_diropres *); -int nfssvc_encode_readlinkres(struct svc_rqst *, __be32 *, struct nfsd_readlinkres *); -int nfssvc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd_readres *); -int nfssvc_encode_statfsres(struct svc_rqst *, __be32 *, struct nfsd_statfsres *); -int nfssvc_encode_readdirres(struct svc_rqst *, __be32 *, struct nfsd_readdirres *); - -int nfssvc_encode_entry(void *, const char *name, - int namlen, loff_t offset, u64 ino, unsigned int); - -int nfssvc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); - -/* Helper functions for NFSv2 ACL code */ -__be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp); -__be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp); - -#endif /* LINUX_NFSD_H */ diff --git a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h deleted file mode 100644 index 421eddd..0000000 --- a/include/linux/nfsd/xdr3.h +++ /dev/null @@ -1,346 +0,0 @@ -/* - * linux/include/linux/nfsd/xdr3.h - * - * XDR types for NFSv3 in nfsd. - * - * Copyright (C) 1996-1998, Olaf Kirch - */ - -#ifndef _LINUX_NFSD_XDR3_H -#define _LINUX_NFSD_XDR3_H - -#include - -struct nfsd3_sattrargs { - struct svc_fh fh; - struct iattr attrs; - int check_guard; - time_t guardtime; -}; - -struct nfsd3_diropargs { - struct svc_fh fh; - char * name; - unsigned int len; -}; - -struct nfsd3_accessargs { - struct svc_fh fh; - unsigned int access; -}; - -struct nfsd3_readargs { - struct svc_fh fh; - __u64 offset; - __u32 count; - int vlen; -}; - -struct nfsd3_writeargs { - svc_fh fh; - __u64 offset; - __u32 count; - int stable; - __u32 len; - int vlen; -}; - -struct nfsd3_createargs { - struct svc_fh fh; - char * name; - unsigned int len; - int createmode; - struct iattr attrs; - __be32 * verf; -}; - -struct nfsd3_mknodargs { - struct svc_fh fh; - char * name; - unsigned int len; - __u32 ftype; - __u32 major, minor; - struct iattr attrs; -}; - -struct nfsd3_renameargs { - struct svc_fh ffh; - char * fname; - unsigned int flen; - struct svc_fh tfh; - char * tname; - unsigned int tlen; -}; - -struct nfsd3_readlinkargs { - struct svc_fh fh; - char * buffer; -}; - -struct nfsd3_linkargs { - struct svc_fh ffh; - struct svc_fh tfh; - char * tname; - unsigned int tlen; -}; - -struct nfsd3_symlinkargs { - struct svc_fh ffh; - char * fname; - unsigned int flen; - char * tname; - unsigned int tlen; - struct iattr attrs; -}; - -struct nfsd3_readdirargs { - struct svc_fh fh; - __u64 cookie; - __u32 dircount; - __u32 count; - __be32 * verf; - __be32 * buffer; -}; - -struct nfsd3_commitargs { - struct svc_fh fh; - __u64 offset; - __u32 count; -}; - -struct nfsd3_getaclargs { - struct svc_fh fh; - int mask; -}; - -struct posix_acl; -struct nfsd3_setaclargs { - struct svc_fh fh; - int mask; - struct posix_acl *acl_access; - struct posix_acl *acl_default; -}; - -struct nfsd3_attrstat { - __be32 status; - struct svc_fh fh; - struct kstat stat; -}; - -/* LOOKUP, CREATE, MKDIR, SYMLINK, MKNOD */ -struct nfsd3_diropres { - __be32 status; - struct svc_fh dirfh; - struct svc_fh fh; -}; - -struct nfsd3_accessres { - __be32 status; - struct svc_fh fh; - __u32 access; -}; - -struct nfsd3_readlinkres { - __be32 status; - struct svc_fh fh; - __u32 len; -}; - -struct nfsd3_readres { - __be32 status; - struct svc_fh fh; - unsigned long count; - int eof; -}; - -struct nfsd3_writeres { - __be32 status; - struct svc_fh fh; - unsigned long count; - int committed; -}; - -struct nfsd3_renameres { - __be32 status; - struct svc_fh ffh; - struct svc_fh tfh; -}; - -struct nfsd3_linkres { - __be32 status; - struct svc_fh tfh; - struct svc_fh fh; -}; - -struct nfsd3_readdirres { - __be32 status; - struct svc_fh fh; - int count; - __be32 verf[2]; - - struct readdir_cd common; - __be32 * buffer; - int buflen; - __be32 * offset; - __be32 * offset1; - struct svc_rqst * rqstp; - -}; - -struct nfsd3_fsstatres { - __be32 status; - struct kstatfs stats; - __u32 invarsec; -}; - -struct nfsd3_fsinfores { - __be32 status; - __u32 f_rtmax; - __u32 f_rtpref; - __u32 f_rtmult; - __u32 f_wtmax; - __u32 f_wtpref; - __u32 f_wtmult; - __u32 f_dtpref; - __u64 f_maxfilesize; - __u32 f_properties; -}; - -struct nfsd3_pathconfres { - __be32 status; - __u32 p_link_max; - __u32 p_name_max; - __u32 p_no_trunc; - __u32 p_chown_restricted; - __u32 p_case_insensitive; - __u32 p_case_preserving; -}; - -struct nfsd3_commitres { - __be32 status; - struct svc_fh fh; -}; - -struct nfsd3_getaclres { - __be32 status; - struct svc_fh fh; - int mask; - struct posix_acl *acl_access; - struct posix_acl *acl_default; -}; - -/* dummy type for release */ -struct nfsd3_fhandle_pair { - __u32 dummy; - struct svc_fh fh1; - struct svc_fh fh2; -}; - -/* - * Storage requirements for XDR arguments and results. - */ -union nfsd3_xdrstore { - struct nfsd3_sattrargs sattrargs; - struct nfsd3_diropargs diropargs; - struct nfsd3_readargs readargs; - struct nfsd3_writeargs writeargs; - struct nfsd3_createargs createargs; - struct nfsd3_renameargs renameargs; - struct nfsd3_linkargs linkargs; - struct nfsd3_symlinkargs symlinkargs; - struct nfsd3_readdirargs readdirargs; - struct nfsd3_diropres diropres; - struct nfsd3_accessres accessres; - struct nfsd3_readlinkres readlinkres; - struct nfsd3_readres readres; - struct nfsd3_writeres writeres; - struct nfsd3_renameres renameres; - struct nfsd3_linkres linkres; - struct nfsd3_readdirres readdirres; - struct nfsd3_fsstatres fsstatres; - struct nfsd3_fsinfores fsinfores; - struct nfsd3_pathconfres pathconfres; - struct nfsd3_commitres commitres; - struct nfsd3_getaclres getaclres; -}; - -#define NFS3_SVC_XDRSIZE sizeof(union nfsd3_xdrstore) - -int nfs3svc_decode_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); -int nfs3svc_decode_sattrargs(struct svc_rqst *, __be32 *, - struct nfsd3_sattrargs *); -int nfs3svc_decode_diropargs(struct svc_rqst *, __be32 *, - struct nfsd3_diropargs *); -int nfs3svc_decode_accessargs(struct svc_rqst *, __be32 *, - struct nfsd3_accessargs *); -int nfs3svc_decode_readargs(struct svc_rqst *, __be32 *, - struct nfsd3_readargs *); -int nfs3svc_decode_writeargs(struct svc_rqst *, __be32 *, - struct nfsd3_writeargs *); -int nfs3svc_decode_createargs(struct svc_rqst *, __be32 *, - struct nfsd3_createargs *); -int nfs3svc_decode_mkdirargs(struct svc_rqst *, __be32 *, - struct nfsd3_createargs *); -int nfs3svc_decode_mknodargs(struct svc_rqst *, __be32 *, - struct nfsd3_mknodargs *); -int nfs3svc_decode_renameargs(struct svc_rqst *, __be32 *, - struct nfsd3_renameargs *); -int nfs3svc_decode_readlinkargs(struct svc_rqst *, __be32 *, - struct nfsd3_readlinkargs *); -int nfs3svc_decode_linkargs(struct svc_rqst *, __be32 *, - struct nfsd3_linkargs *); -int nfs3svc_decode_symlinkargs(struct svc_rqst *, __be32 *, - struct nfsd3_symlinkargs *); -int nfs3svc_decode_readdirargs(struct svc_rqst *, __be32 *, - struct nfsd3_readdirargs *); -int nfs3svc_decode_readdirplusargs(struct svc_rqst *, __be32 *, - struct nfsd3_readdirargs *); -int nfs3svc_decode_commitargs(struct svc_rqst *, __be32 *, - struct nfsd3_commitargs *); -int nfs3svc_encode_voidres(struct svc_rqst *, __be32 *, void *); -int nfs3svc_encode_attrstat(struct svc_rqst *, __be32 *, - struct nfsd3_attrstat *); -int nfs3svc_encode_wccstat(struct svc_rqst *, __be32 *, - struct nfsd3_attrstat *); -int nfs3svc_encode_diropres(struct svc_rqst *, __be32 *, - struct nfsd3_diropres *); -int nfs3svc_encode_accessres(struct svc_rqst *, __be32 *, - struct nfsd3_accessres *); -int nfs3svc_encode_readlinkres(struct svc_rqst *, __be32 *, - struct nfsd3_readlinkres *); -int nfs3svc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd3_readres *); -int nfs3svc_encode_writeres(struct svc_rqst *, __be32 *, struct nfsd3_writeres *); -int nfs3svc_encode_createres(struct svc_rqst *, __be32 *, - struct nfsd3_diropres *); -int nfs3svc_encode_renameres(struct svc_rqst *, __be32 *, - struct nfsd3_renameres *); -int nfs3svc_encode_linkres(struct svc_rqst *, __be32 *, - struct nfsd3_linkres *); -int nfs3svc_encode_readdirres(struct svc_rqst *, __be32 *, - struct nfsd3_readdirres *); -int nfs3svc_encode_fsstatres(struct svc_rqst *, __be32 *, - struct nfsd3_fsstatres *); -int nfs3svc_encode_fsinfores(struct svc_rqst *, __be32 *, - struct nfsd3_fsinfores *); -int nfs3svc_encode_pathconfres(struct svc_rqst *, __be32 *, - struct nfsd3_pathconfres *); -int nfs3svc_encode_commitres(struct svc_rqst *, __be32 *, - struct nfsd3_commitres *); - -int nfs3svc_release_fhandle(struct svc_rqst *, __be32 *, - struct nfsd3_attrstat *); -int nfs3svc_release_fhandle2(struct svc_rqst *, __be32 *, - struct nfsd3_fhandle_pair *); -int nfs3svc_encode_entry(void *, const char *name, - int namlen, loff_t offset, u64 ino, - unsigned int); -int nfs3svc_encode_entry_plus(void *, const char *name, - int namlen, loff_t offset, u64 ino, - unsigned int); -/* Helper functions for NFSv3 ACL code */ -__be32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, - struct svc_fh *fhp); -__be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp); - - -#endif /* _LINUX_NFSD_XDR3_H */ diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h deleted file mode 100644 index 1bf2662..0000000 --- a/include/linux/nfsd/xdr4.h +++ /dev/null @@ -1,564 +0,0 @@ -/* - * include/linux/nfsd/xdr4.h - * - * Server-side types for NFSv4. - * - * Copyright (c) 2002 The Regents of the University of Michigan. - * All rights reserved. - * - * Kendrick Smith - * Andy Adamson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef _LINUX_NFSD_XDR4_H -#define _LINUX_NFSD_XDR4_H - -#include -#include - -#define NFSD4_MAX_TAGLEN 128 -#define XDR_LEN(n) (((n) + 3) & ~3) - -struct nfsd4_compound_state { - struct svc_fh current_fh; - struct svc_fh save_fh; - struct nfs4_stateowner *replay_owner; - /* For sessions DRC */ - struct nfsd4_session *session; - struct nfsd4_slot *slot; - __be32 *datap; - size_t iovlen; - u32 minorversion; - u32 status; -}; - -static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs) -{ - return cs->slot != NULL; -} - -struct nfsd4_change_info { - u32 atomic; - bool change_supported; - u32 before_ctime_sec; - u32 before_ctime_nsec; - u64 before_change; - u32 after_ctime_sec; - u32 after_ctime_nsec; - u64 after_change; -}; - -struct nfsd4_access { - u32 ac_req_access; /* request */ - u32 ac_supported; /* response */ - u32 ac_resp_access; /* response */ -}; - -struct nfsd4_close { - u32 cl_seqid; /* request */ - stateid_t cl_stateid; /* request+response */ - struct nfs4_stateowner * cl_stateowner; /* response */ -}; - -struct nfsd4_commit { - u64 co_offset; /* request */ - u32 co_count; /* request */ - nfs4_verifier co_verf; /* response */ -}; - -struct nfsd4_create { - u32 cr_namelen; /* request */ - char * cr_name; /* request */ - u32 cr_type; /* request */ - union { /* request */ - struct { - u32 namelen; - char *name; - } link; /* NF4LNK */ - struct { - u32 specdata1; - u32 specdata2; - } dev; /* NF4BLK, NF4CHR */ - } u; - u32 cr_bmval[3]; /* request */ - struct iattr cr_iattr; /* request */ - struct nfsd4_change_info cr_cinfo; /* response */ - struct nfs4_acl *cr_acl; -}; -#define cr_linklen u.link.namelen -#define cr_linkname u.link.name -#define cr_specdata1 u.dev.specdata1 -#define cr_specdata2 u.dev.specdata2 - -struct nfsd4_delegreturn { - stateid_t dr_stateid; -}; - -struct nfsd4_getattr { - u32 ga_bmval[3]; /* request */ - struct svc_fh *ga_fhp; /* response */ -}; - -struct nfsd4_link { - u32 li_namelen; /* request */ - char * li_name; /* request */ - struct nfsd4_change_info li_cinfo; /* response */ -}; - -struct nfsd4_lock_denied { - clientid_t ld_clientid; - struct nfs4_stateowner *ld_sop; - u64 ld_start; - u64 ld_length; - u32 ld_type; -}; - -struct nfsd4_lock { - /* request */ - u32 lk_type; - u32 lk_reclaim; /* boolean */ - u64 lk_offset; - u64 lk_length; - u32 lk_is_new; - union { - struct { - u32 open_seqid; - stateid_t open_stateid; - u32 lock_seqid; - clientid_t clientid; - struct xdr_netobj owner; - } new; - struct { - stateid_t lock_stateid; - u32 lock_seqid; - } old; - } v; - - /* response */ - union { - struct { - stateid_t stateid; - } ok; - struct nfsd4_lock_denied denied; - } u; - /* The lk_replay_owner is the open owner in the open_to_lock_owner - * case and the lock owner otherwise: */ - struct nfs4_stateowner *lk_replay_owner; -}; -#define lk_new_open_seqid v.new.open_seqid -#define lk_new_open_stateid v.new.open_stateid -#define lk_new_lock_seqid v.new.lock_seqid -#define lk_new_clientid v.new.clientid -#define lk_new_owner v.new.owner -#define lk_old_lock_stateid v.old.lock_stateid -#define lk_old_lock_seqid v.old.lock_seqid - -#define lk_rflags u.ok.rflags -#define lk_resp_stateid u.ok.stateid -#define lk_denied u.denied - - -struct nfsd4_lockt { - u32 lt_type; - clientid_t lt_clientid; - struct xdr_netobj lt_owner; - u64 lt_offset; - u64 lt_length; - struct nfs4_stateowner * lt_stateowner; - struct nfsd4_lock_denied lt_denied; -}; - - -struct nfsd4_locku { - u32 lu_type; - u32 lu_seqid; - stateid_t lu_stateid; - u64 lu_offset; - u64 lu_length; - struct nfs4_stateowner *lu_stateowner; -}; - - -struct nfsd4_lookup { - u32 lo_len; /* request */ - char * lo_name; /* request */ -}; - -struct nfsd4_putfh { - u32 pf_fhlen; /* request */ - char *pf_fhval; /* request */ -}; - -struct nfsd4_open { - u32 op_claim_type; /* request */ - struct xdr_netobj op_fname; /* request - everything but CLAIM_PREV */ - u32 op_delegate_type; /* request - CLAIM_PREV only */ - stateid_t op_delegate_stateid; /* request - response */ - u32 op_create; /* request */ - u32 op_createmode; /* request */ - u32 op_bmval[3]; /* request */ - struct iattr iattr; /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */ - nfs4_verifier verf; /* EXCLUSIVE4 */ - clientid_t op_clientid; /* request */ - struct xdr_netobj op_owner; /* request */ - u32 op_seqid; /* request */ - u32 op_share_access; /* request */ - u32 op_share_deny; /* request */ - stateid_t op_stateid; /* response */ - u32 op_recall; /* recall */ - struct nfsd4_change_info op_cinfo; /* response */ - u32 op_rflags; /* response */ - int op_truncate; /* used during processing */ - struct nfs4_stateowner *op_stateowner; /* used during processing */ - struct nfs4_acl *op_acl; -}; -#define op_iattr iattr -#define op_verf verf - -struct nfsd4_open_confirm { - stateid_t oc_req_stateid /* request */; - u32 oc_seqid /* request */; - stateid_t oc_resp_stateid /* response */; - struct nfs4_stateowner * oc_stateowner; /* response */ -}; - -struct nfsd4_open_downgrade { - stateid_t od_stateid; - u32 od_seqid; - u32 od_share_access; - u32 od_share_deny; - struct nfs4_stateowner *od_stateowner; -}; - - -struct nfsd4_read { - stateid_t rd_stateid; /* request */ - u64 rd_offset; /* request */ - u32 rd_length; /* request */ - int rd_vlen; - struct file *rd_filp; - - struct svc_rqst *rd_rqstp; /* response */ - struct svc_fh * rd_fhp; /* response */ -}; - -struct nfsd4_readdir { - u64 rd_cookie; /* request */ - nfs4_verifier rd_verf; /* request */ - u32 rd_dircount; /* request */ - u32 rd_maxcount; /* request */ - u32 rd_bmval[3]; /* request */ - struct svc_rqst *rd_rqstp; /* response */ - struct svc_fh * rd_fhp; /* response */ - - struct readdir_cd common; - __be32 * buffer; - int buflen; - __be32 * offset; -}; - -struct nfsd4_release_lockowner { - clientid_t rl_clientid; - struct xdr_netobj rl_owner; -}; -struct nfsd4_readlink { - struct svc_rqst *rl_rqstp; /* request */ - struct svc_fh * rl_fhp; /* request */ -}; - -struct nfsd4_remove { - u32 rm_namelen; /* request */ - char * rm_name; /* request */ - struct nfsd4_change_info rm_cinfo; /* response */ -}; - -struct nfsd4_rename { - u32 rn_snamelen; /* request */ - char * rn_sname; /* request */ - u32 rn_tnamelen; /* request */ - char * rn_tname; /* request */ - struct nfsd4_change_info rn_sinfo; /* response */ - struct nfsd4_change_info rn_tinfo; /* response */ -}; - -struct nfsd4_secinfo { - u32 si_namelen; /* request */ - char *si_name; /* request */ - struct svc_export *si_exp; /* response */ -}; - -struct nfsd4_setattr { - stateid_t sa_stateid; /* request */ - u32 sa_bmval[3]; /* request */ - struct iattr sa_iattr; /* request */ - struct nfs4_acl *sa_acl; -}; - -struct nfsd4_setclientid { - nfs4_verifier se_verf; /* request */ - u32 se_namelen; /* request */ - char * se_name; /* request */ - u32 se_callback_prog; /* request */ - u32 se_callback_netid_len; /* request */ - char * se_callback_netid_val; /* request */ - u32 se_callback_addr_len; /* request */ - char * se_callback_addr_val; /* request */ - u32 se_callback_ident; /* request */ - clientid_t se_clientid; /* response */ - nfs4_verifier se_confirm; /* response */ -}; - -struct nfsd4_setclientid_confirm { - clientid_t sc_clientid; - nfs4_verifier sc_confirm; -}; - -/* also used for NVERIFY */ -struct nfsd4_verify { - u32 ve_bmval[3]; /* request */ - u32 ve_attrlen; /* request */ - char * ve_attrval; /* request */ -}; - -struct nfsd4_write { - stateid_t wr_stateid; /* request */ - u64 wr_offset; /* request */ - u32 wr_stable_how; /* request */ - u32 wr_buflen; /* request */ - int wr_vlen; - - u32 wr_bytes_written; /* response */ - u32 wr_how_written; /* response */ - nfs4_verifier wr_verifier; /* response */ -}; - -struct nfsd4_exchange_id { - nfs4_verifier verifier; - struct xdr_netobj clname; - u32 flags; - clientid_t clientid; - u32 seqid; - int spa_how; -}; - -struct nfsd4_sequence { - struct nfs4_sessionid sessionid; /* request/response */ - u32 seqid; /* request/response */ - u32 slotid; /* request/response */ - u32 maxslots; /* request/response */ - u32 cachethis; /* request */ -#if 0 - u32 target_maxslots; /* response */ - u32 status_flags; /* response */ -#endif /* not yet */ -}; - -struct nfsd4_destroy_session { - struct nfs4_sessionid sessionid; -}; - -struct nfsd4_op { - int opnum; - __be32 status; - union { - struct nfsd4_access access; - struct nfsd4_close close; - struct nfsd4_commit commit; - struct nfsd4_create create; - struct nfsd4_delegreturn delegreturn; - struct nfsd4_getattr getattr; - struct svc_fh * getfh; - struct nfsd4_link link; - struct nfsd4_lock lock; - struct nfsd4_lockt lockt; - struct nfsd4_locku locku; - struct nfsd4_lookup lookup; - struct nfsd4_verify nverify; - struct nfsd4_open open; - struct nfsd4_open_confirm open_confirm; - struct nfsd4_open_downgrade open_downgrade; - struct nfsd4_putfh putfh; - struct nfsd4_read read; - struct nfsd4_readdir readdir; - struct nfsd4_readlink readlink; - struct nfsd4_remove remove; - struct nfsd4_rename rename; - clientid_t renew; - struct nfsd4_secinfo secinfo; - struct nfsd4_setattr setattr; - struct nfsd4_setclientid setclientid; - struct nfsd4_setclientid_confirm setclientid_confirm; - struct nfsd4_verify verify; - struct nfsd4_write write; - struct nfsd4_release_lockowner release_lockowner; - - /* NFSv4.1 */ - struct nfsd4_exchange_id exchange_id; - struct nfsd4_create_session create_session; - struct nfsd4_destroy_session destroy_session; - struct nfsd4_sequence sequence; - } u; - struct nfs4_replay * replay; -}; - -struct nfsd4_compoundargs { - /* scratch variables for XDR decode */ - __be32 * p; - __be32 * end; - struct page ** pagelist; - int pagelen; - __be32 tmp[8]; - __be32 * tmpp; - struct tmpbuf { - struct tmpbuf *next; - void (*release)(const void *); - void *buf; - } *to_free; - - struct svc_rqst *rqstp; - - u32 taglen; - char * tag; - u32 minorversion; - u32 opcnt; - struct nfsd4_op *ops; - struct nfsd4_op iops[8]; -}; - -struct nfsd4_compoundres { - /* scratch variables for XDR encode */ - __be32 * p; - __be32 * end; - struct xdr_buf * xbuf; - struct svc_rqst * rqstp; - - u32 taglen; - char * tag; - u32 opcnt; - __be32 * tagp; /* tag, opcount encode location */ - struct nfsd4_compound_state cstate; -}; - -static inline bool nfsd4_is_solo_sequence(struct nfsd4_compoundres *resp) -{ - struct nfsd4_compoundargs *args = resp->rqstp->rq_argp; - return resp->opcnt == 1 && args->ops[0].opnum == OP_SEQUENCE; -} - -static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp) -{ - return !resp->cstate.slot->sl_cachethis || nfsd4_is_solo_sequence(resp); -} - -#define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs) - -static inline void -set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) -{ - BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved); - cinfo->atomic = 1; - cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode); - if (cinfo->change_supported) { - cinfo->before_change = fhp->fh_pre_change; - cinfo->after_change = fhp->fh_post_change; - } else { - cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec; - cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec; - cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec; - cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec; - } -} - -int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); -int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *, - struct nfsd4_compoundargs *); -int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *, - struct nfsd4_compoundres *); -void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *); -void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op); -__be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, - struct dentry *dentry, __be32 *buffer, int *countp, - u32 *bmval, struct svc_rqst *, int ignore_crossmnt); -extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, - struct nfsd4_setclientid *setclid); -extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, - struct nfsd4_setclientid_confirm *setclientid_confirm); -extern void nfsd4_store_cache_entry(struct nfsd4_compoundres *resp); -extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, - struct nfsd4_sequence *seq); -extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, -struct nfsd4_exchange_id *); - extern __be32 nfsd4_create_session(struct svc_rqst *, - struct nfsd4_compound_state *, - struct nfsd4_create_session *); -extern __be32 nfsd4_sequence(struct svc_rqst *, - struct nfsd4_compound_state *, - struct nfsd4_sequence *); -extern __be32 nfsd4_destroy_session(struct svc_rqst *, - struct nfsd4_compound_state *, - struct nfsd4_destroy_session *); -extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *, - struct nfsd4_open *open); -extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp, - struct svc_fh *current_fh, struct nfsd4_open *open); -extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc); -extern __be32 nfsd4_close(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, - struct nfsd4_close *close); -extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, - struct nfsd4_open_downgrade *od); -extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *, - struct nfsd4_lock *lock); -extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, - struct nfsd4_lockt *lockt); -extern __be32 nfsd4_locku(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, - struct nfsd4_locku *locku); -extern __be32 -nfsd4_release_lockowner(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, - struct nfsd4_release_lockowner *rlockowner); -extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *); -extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, struct nfsd4_delegreturn *dr); -extern __be32 nfsd4_renew(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, clientid_t *clid); -#endif - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ -- cgit v0.10.2 From 61c2bb45697a56e96313a5f85f609b0c12ae26ff Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 14 Dec 2009 11:51:40 -0800 Subject: drm/nouveau: fix ch7006 build The ch7006 driver could be built even when nouveau was not enabled, but the build fails in that case, so make it depend on DRM_NOUVEUA. Also make the I2c encoder/helper chips menu depend on I2C (no build error, just visual inspection). ERROR: "drm_helper_probe_single_connector_modes" [drivers/gpu/drm/i2c/ch7006.ko] undefined! Signed-off-by: Randy Dunlap Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index d823e63..b1bc1ea 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -30,11 +30,12 @@ config DRM_NOUVEAU_DEBUG via debugfs. menu "I2C encoder or helper chips" - depends on DRM + depends on DRM && I2C config DRM_I2C_CH7006 tristate "Chrontel ch7006 TV encoder" - default m if DRM_NOUVEAU + depends on DRM_NOUVEAU + default m help Support for Chrontel ch7006 and similar TV encoders, found on some nVidia video cards. -- cgit v0.10.2 From e8e8753f7a32ce4f636771126fc8eba0dc4ad817 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 14 Dec 2009 12:53:32 -0500 Subject: nfsd: new interface to advertise export features Soon we will add the new V4ROOT flag, and allow the INSECURE flag to vary by pseudoflavor. It would be useful for nfs-utils (for example, for improved exportfs error reporting) to be able to know when this happens. Use this new interface for that purpose. Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 0415680..e7051ac 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -31,6 +31,7 @@ enum { NFSD_Getfd, NFSD_Getfs, NFSD_List, + NFSD_Export_features, NFSD_Fh, NFSD_FO_UnlockIP, NFSD_FO_UnlockFS, @@ -149,6 +150,24 @@ static const struct file_operations exports_operations = { .owner = THIS_MODULE, }; +static int export_features_show(struct seq_file *m, void *v) +{ + seq_printf(m, "0x%x 0x%x\n", NFSEXP_ALLFLAGS, NFSEXP_SECINFO_FLAGS); + return 0; +} + +static int export_features_open(struct inode *inode, struct file *file) +{ + return single_open(file, export_features_show, NULL); +} + +static struct file_operations export_features_operations = { + .open = export_features_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + extern int nfsd_pool_stats_open(struct inode *inode, struct file *file); extern int nfsd_pool_stats_release(struct inode *inode, struct file *file); @@ -1306,6 +1325,8 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) [NFSD_Getfd] = {".getfd", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_Getfs] = {".getfs", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_List] = {"exports", &exports_operations, S_IRUGO}, + [NFSD_Export_features] = {"export_features", + &export_features_operations, S_IRUGO}, [NFSD_FO_UnlockIP] = {"unlock_ip", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_FO_UnlockFS] = {"unlock_filesystem", diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h index ef3d416..4f1df1d 100644 --- a/include/linux/nfsd/export.h +++ b/include/linux/nfsd/export.h @@ -39,7 +39,8 @@ #define NFSEXP_FSID 0x2000 #define NFSEXP_CROSSMOUNT 0x4000 #define NFSEXP_NOACL 0x8000 /* reserved for possible ACL related use */ -#define NFSEXP_ALLFLAGS 0xFE3F +/* All flags that we claim to support. (Note we don't support NOACL.) */ +#define NFSEXP_ALLFLAGS 0x7E3F /* The flags that may vary depending on security flavor: */ #define NFSEXP_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH \ -- cgit v0.10.2 From 09b366b78c9602f53344c269eac608fd6e24d670 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Wed, 9 Dec 2009 10:56:41 +0900 Subject: [IA64] preallocate IA64_IRQ_MOVE_VECTOR Previously, we tried to use IA64_DEF_FIRST_DEVICE_VECTOR (0x30) as the IA64_IRQ_MOVE_VECTOR. However, we allocate other IRQs from the device vector range, so there's no guarantee that IA64_DEF_FIRST_DEVICE_VECTOR will still be available when we register IA64_IRQ_MOVE_VECTOR. This patch statically allocates 0x30 for IA64_IRQ_MOVE_VECTOR and removes it from the device vector range. Without this patch, we crash on machines like the HP rx3600 that use vector 48 (0x30) as the ACPI SCI interrupt: kernel BUG at arch/ia64/kernel/irq_ia64.c:647! swapper[0]: bugcheck! 0 [1] Modules linked in: Pid: 0, CPU 0, comm: swapper psr : 00001010084a2018 ifs : 800000000000030e ip : [] Not tainted (2.6.32-rc8-00184-gd5d4ec8) ip is at ia64_native_register_percpu_irq+0x110/0x1e0 Signed-off-by: Bjorn Helgaas Signed-off-by: Kenji Kaneshige Tested-by: Kenji Kaneshige Tested-by: Bjorn Helgaas Signed-off-by: Tony Luck diff --git a/arch/ia64/include/asm/hw_irq.h b/arch/ia64/include/asm/hw_irq.h index 91619b3..bf2e374 100644 --- a/arch/ia64/include/asm/hw_irq.h +++ b/arch/ia64/include/asm/hw_irq.h @@ -59,7 +59,13 @@ typedef u16 ia64_vector; extern int ia64_first_device_vector; extern int ia64_last_device_vector; +#if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined (CONFIG_IA64_DIG)) +/* Reserve the lower priority vector than device vectors for "move IRQ" IPI */ +#define IA64_IRQ_MOVE_VECTOR 0x30 /* "move IRQ" IPI */ +#define IA64_DEF_FIRST_DEVICE_VECTOR 0x31 +#else #define IA64_DEF_FIRST_DEVICE_VECTOR 0x30 +#endif #define IA64_DEF_LAST_DEVICE_VECTOR 0xe7 #define IA64_FIRST_DEVICE_VECTOR ia64_first_device_vector #define IA64_LAST_DEVICE_VECTOR ia64_last_device_vector diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index dd9d7b5..181a934 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -260,7 +260,6 @@ void __setup_vector_irq(int cpu) } #if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG)) -#define IA64_IRQ_MOVE_VECTOR IA64_DEF_FIRST_DEVICE_VECTOR static enum vector_domain_type { VECTOR_DOMAIN_NONE, @@ -659,11 +658,8 @@ init_IRQ (void) register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL); #ifdef CONFIG_SMP #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG) - if (vector_domain_type != VECTOR_DOMAIN_NONE) { - BUG_ON(IA64_FIRST_DEVICE_VECTOR != IA64_IRQ_MOVE_VECTOR); - IA64_FIRST_DEVICE_VECTOR++; + if (vector_domain_type != VECTOR_DOMAIN_NONE) register_percpu_irq(IA64_IRQ_MOVE_VECTOR, &irq_move_irqaction); - } #endif #endif #ifdef CONFIG_PERFMON -- cgit v0.10.2 From 12045a6ee9908b38b6d286530c7d816e39071346 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Tue, 8 Dec 2009 18:15:52 -0500 Subject: nfsd: let "insecure" flag vary by pseudoflavor This was an oversight; it should be among the export flags that can be allowed to vary by pseudoflavor. This allows an administrator to (for example) allow auth_sys mounts only from low ports, but allow auth_krb5 mounts to use any port. Signed-off-by: J. Bruce Fields diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 0eb1c59..951938d 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -88,8 +88,10 @@ nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type) static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, struct svc_export *exp) { + int flags = nfsexp_flags(rqstp, exp); + /* Check if the request originated from a secure port. */ - if (!rqstp->rq_secure && EX_SECURE(exp)) { + if (!rqstp->rq_secure && (flags & NFSEXP_INSECURE_PORT)) { RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); dprintk(KERN_WARNING "nfsd: request from insecure port %s!\n", diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h index 4f1df1d..4cafbe1 100644 --- a/include/linux/nfsd/export.h +++ b/include/linux/nfsd/export.h @@ -44,7 +44,8 @@ /* The flags that may vary depending on security flavor: */ #define NFSEXP_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH \ - | NFSEXP_ALLSQUASH) + | NFSEXP_ALLSQUASH \ + | NFSEXP_INSECURE_PORT) #ifdef __KERNEL__ @@ -109,7 +110,6 @@ struct svc_expkey { struct path ek_path; }; -#define EX_SECURE(exp) (!((exp)->ex_flags & NFSEXP_INSECURE_PORT)) #define EX_ISSYNC(exp) (!((exp)->ex_flags & NFSEXP_ASYNC)) #define EX_NOHIDE(exp) ((exp)->ex_flags & NFSEXP_NOHIDE) #define EX_WGATHER(exp) ((exp)->ex_flags & NFSEXP_GATHERED_WRITES) -- cgit v0.10.2 From 9ee27c76393394c7fb1ddeca3f1622d4537185a0 Mon Sep 17 00:00:00 2001 From: Takao Indoh Date: Thu, 19 Nov 2009 16:39:22 -0500 Subject: [IA64] Save I-resources to ia64_sal_os_state This is a patch related to this discussion. http://www.spinics.net/lists/linux-ia64/msg07605.html When INIT is sent, ip/psr/pfs register is stored to the I-resources (iip/ipsr/ifs registers), and they are copied in the min-state save area(pmsa_{iip,ipsr,ifs}). Therefore, in creating pt_regs at ia64_mca_modify_original_stack(), cr_{iip,ipsr,ifs} should be derived from pmsa_{iip,ipsr,ifs}. But current code copies pmsa_{xip,xpsr,xfs} to cr_{iip,ipsr,ifs} when PSR.ic is 0. finish_pt_regs(struct pt_regs *regs, const pal_min_state_area_t *ms, unsigned long *nat) { (snip) if (ia64_psr(regs)->ic) { regs->cr_iip = ms->pmsa_iip; regs->cr_ipsr = ms->pmsa_ipsr; regs->cr_ifs = ms->pmsa_ifs; } else { regs->cr_iip = ms->pmsa_xip; regs->cr_ipsr = ms->pmsa_xpsr; regs->cr_ifs = ms->pmsa_xfs; } It's ok when PSR.ic is not 0. But when PSR.ic is 0, this could be a problem when we investigate kernel as the value of regs->cr_iip does not point to where INIT really interrupted. At first I tried to change finish_pt_regs() so that it uses always pmsa_{iip,ipsr,ifs} for cr_{iip,ipsr,ifs}, but Keith Owens pointed out it could cause another problem if I change it. >The only problem I can think of is an MCA/INIT >arriving while code like SAVE_MIN or SAVE_REST is executing. Back >tracing at that point using pmsa_iip is going to be a problem, you have >no idea what state the registers or stack are in. I confirmed he was right, so I decided to keep it as-is and to save pmsa_{iip,ipsr,ifs} to ia64_sal_os_state for debugging. An attached patch is just adding new members into ia64_sal_os_state to save pmsa_{iip,ipsr,ifs}. Signed-off-by: Takao Indoh Signed-off-by: Tony Luck diff --git a/arch/ia64/include/asm/mca.h b/arch/ia64/include/asm/mca.h index c171cdf..43f96ab 100644 --- a/arch/ia64/include/asm/mca.h +++ b/arch/ia64/include/asm/mca.h @@ -106,6 +106,11 @@ struct ia64_sal_os_state { unsigned long os_status; /* OS status to SAL, enum below */ unsigned long context; /* 0 if return to same context 1 if return to new context */ + + /* I-resources */ + unsigned long iip; + unsigned long ipsr; + unsigned long ifs; }; enum { diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 496ac7a..32f2639 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -888,9 +888,10 @@ ia64_mca_modify_comm(const struct task_struct *previous_current) } static void -finish_pt_regs(struct pt_regs *regs, const pal_min_state_area_t *ms, +finish_pt_regs(struct pt_regs *regs, struct ia64_sal_os_state *sos, unsigned long *nat) { + const pal_min_state_area_t *ms = sos->pal_min_state; const u64 *bank; /* If ipsr.ic then use pmsa_{iip,ipsr,ifs}, else use @@ -904,6 +905,10 @@ finish_pt_regs(struct pt_regs *regs, const pal_min_state_area_t *ms, regs->cr_iip = ms->pmsa_xip; regs->cr_ipsr = ms->pmsa_xpsr; regs->cr_ifs = ms->pmsa_xfs; + + sos->iip = ms->pmsa_iip; + sos->ipsr = ms->pmsa_ipsr; + sos->ifs = ms->pmsa_ifs; } regs->pr = ms->pmsa_pr; regs->b0 = ms->pmsa_br0; @@ -1079,7 +1084,7 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, memcpy(old_regs, regs, sizeof(*regs)); old_regs->loadrs = loadrs; old_unat = old_regs->ar_unat; - finish_pt_regs(old_regs, ms, &old_unat); + finish_pt_regs(old_regs, sos, &old_unat); /* Next stack a struct switch_stack. mca_asm.S built a partial * switch_stack, copy it and fill in the blanks using pt_regs and @@ -1150,7 +1155,7 @@ no_mod: mprintk(KERN_INFO "cpu %d, %s %s, original stack not modified\n", smp_processor_id(), type, msg); old_unat = regs->ar_unat; - finish_pt_regs(regs, ms, &old_unat); + finish_pt_regs(regs, sos, &old_unat); return previous_current; } -- cgit v0.10.2 From e2a465675dc089e9a56ba2fa2a5fbd9bd8844d18 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 17 Nov 2009 14:44:35 -0800 Subject: [IA64] fix SBA IOMMU to handle allocation failure properly It's possible that SBA IOMMU might fail to find I/O space under heavy I/Os. SBA IOMMU panics on allocation failure but it shouldn't; drivers can handle the failure. The majority of other IOMMU drivers don't panic on allocation failure. This patch fixes SBA IOMMU path to handle allocation failure properly. Signed-off-by: FUJITA Tomonori Cc: Fenghua Yu Signed-off-by: Andrew Morton Signed-off-by: Tony Luck diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index f332e3f..e14c492 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -677,12 +677,19 @@ sba_alloc_range(struct ioc *ioc, struct device *dev, size_t size) spin_unlock_irqrestore(&ioc->saved_lock, flags); pide = sba_search_bitmap(ioc, dev, pages_needed, 0); - if (unlikely(pide >= (ioc->res_size << 3))) - panic(__FILE__ ": I/O MMU @ %p is out of mapping resources\n", - ioc->ioc_hpa); + if (unlikely(pide >= (ioc->res_size << 3))) { + printk(KERN_WARNING "%s: I/O MMU @ %p is" + "out of mapping resources, %u %u %lx\n", + __func__, ioc->ioc_hpa, ioc->res_size, + pages_needed, dma_get_seg_boundary(dev)); + return -1; + } #else - panic(__FILE__ ": I/O MMU @ %p is out of mapping resources\n", - ioc->ioc_hpa); + printk(KERN_WARNING "%s: I/O MMU @ %p is" + "out of mapping resources, %u %u %lx\n", + __func__, ioc->ioc_hpa, ioc->res_size, + pages_needed, dma_get_seg_boundary(dev)); + return -1; #endif } } @@ -965,6 +972,8 @@ static dma_addr_t sba_map_page(struct device *dev, struct page *page, #endif pide = sba_alloc_range(ioc, dev, size); + if (pide < 0) + return 0; iovp = (dma_addr_t) pide << iovp_shift; @@ -1320,6 +1329,7 @@ sba_coalesce_chunks(struct ioc *ioc, struct device *dev, unsigned long dma_offset, dma_len; /* start/len of DMA stream */ int n_mappings = 0; unsigned int max_seg_size = dma_get_max_seg_size(dev); + int idx; while (nents > 0) { unsigned long vaddr = (unsigned long) sba_sg_address(startsg); @@ -1418,16 +1428,22 @@ sba_coalesce_chunks(struct ioc *ioc, struct device *dev, vcontig_sg->dma_length = vcontig_len; dma_len = (dma_len + dma_offset + ~iovp_mask) & iovp_mask; ASSERT(dma_len <= DMA_CHUNK_SIZE); - dma_sg->dma_address = (dma_addr_t) (PIDE_FLAG - | (sba_alloc_range(ioc, dev, dma_len) << iovp_shift) - | dma_offset); + idx = sba_alloc_range(ioc, dev, dma_len); + if (idx < 0) { + dma_sg->dma_length = 0; + return -1; + } + dma_sg->dma_address = (dma_addr_t)(PIDE_FLAG | (idx << iovp_shift) + | dma_offset); n_mappings++; } return n_mappings; } - +static void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs); /** * sba_map_sg - map Scatter/Gather list * @dev: instance of PCI owned by the driver that's asking. @@ -1493,6 +1509,10 @@ static int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, ** Access to the virtual address is what forces a two pass algorithm. */ coalesced = sba_coalesce_chunks(ioc, dev, sglist, nents); + if (coalesced < 0) { + sba_unmap_sg_attrs(dev, sglist, nents, dir, attrs); + return 0; + } /* ** Program the I/O Pdir -- cgit v0.10.2 From 21fc3fded7095f6018e770412b6881ced4c09d6f Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 6 Nov 2009 22:42:01 +0000 Subject: [IA64] Replace old style lock initializer SPIN_LOCK_UNLOCKED is deprecated. Use __SPIN_LOCK_UNLOCKED instead. Signed-off-by: Thomas Gleixner Cc: linux-ia64@vger.kernel.org Signed-off-by: Tony Luck diff --git a/arch/ia64/include/asm/rwsem.h b/arch/ia64/include/asm/rwsem.h index fbee74b..e876268 100644 --- a/arch/ia64/include/asm/rwsem.h +++ b/arch/ia64/include/asm/rwsem.h @@ -47,7 +47,7 @@ struct rw_semaphore { #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) #define __RWSEM_INITIALIZER(name) \ - { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \ + { RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \ LIST_HEAD_INIT((name).wait_list) } #define DECLARE_RWSEM(name) \ -- cgit v0.10.2 From 430677133fd5a2033222b3b5016bb461fe8fabf2 Mon Sep 17 00:00:00 2001 From: "Luck, Tony" Date: Mon, 14 Dec 2009 15:00:37 -0500 Subject: [IA64] implement early_io{re,un}map for ia64 drivers/pci/dmar.c uses these functions, so provide them for ia64 Signed-off-by: Tony Luck diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h index 0d9d16e..cc8335e 100644 --- a/arch/ia64/include/asm/io.h +++ b/arch/ia64/include/asm/io.h @@ -424,6 +424,8 @@ __writeq (unsigned long val, volatile void __iomem *addr) extern void __iomem * ioremap(unsigned long offset, unsigned long size); extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size); extern void iounmap (volatile void __iomem *addr); +extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size); +extern void early_iounmap (volatile void __iomem *addr, unsigned long size); /* * String version of IO memory access ops: diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c index 2a14062..3dccdd8 100644 --- a/arch/ia64/mm/ioremap.c +++ b/arch/ia64/mm/ioremap.c @@ -22,6 +22,12 @@ __ioremap (unsigned long phys_addr) } void __iomem * +early_ioremap (unsigned long phys_addr, unsigned long size) +{ + return __ioremap(phys_addr); +} + +void __iomem * ioremap (unsigned long phys_addr, unsigned long size) { void __iomem *addr; @@ -102,6 +108,11 @@ ioremap_nocache (unsigned long phys_addr, unsigned long size) EXPORT_SYMBOL(ioremap_nocache); void +early_iounmap (volatile void __iomem *addr, unsigned long size) +{ +} + +void iounmap (volatile void __iomem *addr) { if (REGION_NUMBER(addr) == RGN_GATE) -- cgit v0.10.2 From b694dfb25a8de4ffbc14c9092ab8f88344ca86b1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 15 Dec 2009 10:38:32 +1000 Subject: drm/nouveau: fix build with CONFIG_AGP=n Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 320a14b..aa2dfbc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -311,8 +311,10 @@ nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device *bdev) struct drm_device *dev = dev_priv->dev; switch (dev_priv->gart_info.type) { +#if __OS_HAS_AGP case NOUVEAU_GART_AGP: return ttm_agp_backend_init(bdev, dev->agp->bridge); +#endif case NOUVEAU_GART_SGDMA: return nouveau_sgdma_init_ttm(dev); default: diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 0275571..5158a12 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -407,6 +407,7 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) return 0; } +#if __OS_HAS_AGP static void nouveau_mem_reset_agp(struct drm_device *dev) { uint32_t saved_pci_nv_1, saved_pci_nv_19, pmc_enable; @@ -432,10 +433,12 @@ static void nouveau_mem_reset_agp(struct drm_device *dev) nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19); nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1); } +#endif int nouveau_mem_init_agp(struct drm_device *dev) { +#if __OS_HAS_AGP struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_agp_info info; struct drm_agp_mode mode; @@ -471,6 +474,7 @@ nouveau_mem_init_agp(struct drm_device *dev) dev_priv->gart_info.type = NOUVEAU_GART_AGP; dev_priv->gart_info.aper_base = info.aperture_base; dev_priv->gart_info.aper_size = info.aperture_size; +#endif return 0; } -- cgit v0.10.2 From 81a5487756573b43458073969bc36b1e19124c24 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 14 Dec 2009 14:31:40 +1100 Subject: nouveau: Fix endianness with new context program loader When switching to request_firmware() to load the context programs, some endian fixes need to be applied. This makes it work again on my quad g5 nvidia 6600. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index d3e0a2a..7e8547c 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -252,8 +252,9 @@ nv40_grctx_init(struct drm_device *dev) memcpy(pgraph->ctxprog, fw->data, fw->size); cp = pgraph->ctxprog; - if (cp->signature != 0x5043564e || cp->version != 0 || - cp->length != ((fw->size - 7) / 4)) { + if (le32_to_cpu(cp->signature) != 0x5043564e || + cp->version != 0 || + le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) { NV_ERROR(dev, "ctxprog invalid\n"); release_firmware(fw); nv40_grctx_fini(dev); @@ -281,8 +282,9 @@ nv40_grctx_init(struct drm_device *dev) memcpy(pgraph->ctxvals, fw->data, fw->size); cv = (void *)pgraph->ctxvals; - if (cv->signature != 0x5643564e || cv->version != 0 || - cv->length != ((fw->size - 9) / 8)) { + if (le32_to_cpu(cv->signature) != 0x5643564e || + cv->version != 0 || + le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) { NV_ERROR(dev, "ctxvals invalid\n"); release_firmware(fw); nv40_grctx_fini(dev); @@ -294,8 +296,9 @@ nv40_grctx_init(struct drm_device *dev) cp = pgraph->ctxprog; nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); - for (i = 0; i < cp->length; i++) - nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp->data[i]); + for (i = 0; i < le16_to_cpu(cp->length); i++) + nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, + le32_to_cpu(cp->data[i])); pgraph->accel_blocked = false; return 0; @@ -329,8 +332,9 @@ nv40_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx) if (!cv) return; - for (i = 0; i < cv->length; i++) - nv_wo32(dev, ctx, cv->data[i].offset, cv->data[i].value); + for (i = 0; i < le32_to_cpu(cv->length); i++) + nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset), + le32_to_cpu(cv->data[i].value)); } /* -- cgit v0.10.2 From 9ddc8c52f58338ddc278fc82e540d9eaf4489dc7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 15 Dec 2009 11:04:25 +1000 Subject: drm/nouveau: remove use of -ERESTART Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 0cff7eb..dacac9a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -205,7 +205,7 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) schedule_timeout(1); if (intr && signal_pending(current)) { - ret = -ERESTART; + ret = -ERESTARTSYS; break; } } diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 11f831f..18fd8ac 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -342,8 +342,6 @@ retry: } ret = ttm_bo_wait_cpu(&nvbo->bo, false); - if (ret == -ERESTART) - ret = -EAGAIN; if (ret) return ret; goto retry; @@ -915,8 +913,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, goto out; ret = ttm_bo_wait_cpu(&nvbo->bo, no_wait); - if (ret == -ERESTART) - ret = -EAGAIN; if (ret) goto out; } @@ -925,9 +921,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, ret = ttm_bo_wait(&nvbo->bo, false, false, no_wait); } else { ret = ttm_bo_synccpu_write_grab(&nvbo->bo, no_wait); - if (ret == -ERESTART) - ret = -EAGAIN; - else if (ret == 0) nvbo->cpu_filp = file_priv; } -- cgit v0.10.2 From 03a05ed1152944000151d57b71000de287a1eb02 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Fri, 11 Dec 2009 15:17:20 +0800 Subject: ACPI: Use the ARB_DISABLE for the CPU which model id is less than 0x0f. Currently, ARB_DISABLE is a NOP on all of the recent Intel platforms. For such platforms, reduce contention on c3_lock by skipping the fake ARB_DISABLE. The cpu model id on one laptop is 14. If we disable ARB_DISABLE on this box, the box can't be booted correctly. But if we still enable ARB_DISABLE on this box, the box can be booted correctly. So we still use the ARB_DISABLE for the cpu which mode id is less than 0x0f. http://bugzilla.kernel.org/show_bug.cgi?id=14700 Signed-off-by: Zhao Yakui Acked-by: Pallipadi, Venkatesh cc: stable@kernel.org Signed-off-by: Len Brown diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index 59cdfa4..2e837f5 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c @@ -48,7 +48,7 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, * P4, Core and beyond CPUs */ if (c->x86_vendor == X86_VENDOR_INTEL && - (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 14))) + (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 0x0f))) flags->bm_control = 0; } EXPORT_SYMBOL(acpi_processor_power_init_bm_check); -- cgit v0.10.2 From 7b6fd3bf82c4901f6ba0101ba71a5c507c24f9cf Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 14 Dec 2009 10:24:42 +0000 Subject: sh-sci: Extend sh-sci driver with early console V2 This is V2 of early serial console support for the sh-sci driver. The early serial console is using early platform devices and "earlyprintk". To use this feature the early platform devices must be broken out to one device per port and the desired port should be selected on the kernel command line like: "earlyprintk=sh-sci.N[,baudrate][,keep]" Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c index 81a4614..fe7dc3f 100644 --- a/arch/sh/kernel/early_printk.c +++ b/arch/sh/kernel/early_printk.c @@ -191,15 +191,7 @@ static void scif_sercon_init(char *s) * Setup a default console, if more than one is compiled in, rely on the * earlyprintk= parsing to give priority. */ -static struct console *early_console = -#ifdef CONFIG_SH_STANDARD_BIOS - &bios_console -#elif defined(CONFIG_EARLY_SCIF_CONSOLE) - &scif_console -#else - NULL -#endif - ; +static struct console *early_console; static int __init setup_early_printk(char *buf) { diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 5a947a2..8b0e697 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -423,6 +423,9 @@ void __init setup_arch(char **cmdline_p) plat_early_device_setup(); + /* Let earlyprintk output early console messages */ + early_platform_driver_probe("earlyprintk", 1, 1); + sh_mv_setup(); /* diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index ff38dbd..d96c7c7 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -1043,10 +1043,14 @@ static void __devinit sci_init_single(struct platform_device *dev, sci_port->port.iotype = UPIO_MEM; sci_port->port.line = index; sci_port->port.fifosize = 1; - sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; - sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); - sci_port->enable = sci_clk_enable; - sci_port->disable = sci_clk_disable; + + if (dev) { + sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; + sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); + sci_port->enable = sci_clk_enable; + sci_port->disable = sci_clk_disable; + sci_port->port.dev = &dev->dev; + } sci_port->break_timer.data = (unsigned long)sci_port; sci_port->break_timer.function = sci_break_timer; @@ -1057,7 +1061,6 @@ static void __devinit sci_init_single(struct platform_device *dev, sci_port->port.irq = p->irqs[SCIx_TXI_IRQ]; sci_port->port.flags = p->flags; - sci_port->port.dev = &dev->dev; sci_port->type = sci_port->port.type = p->type; memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); @@ -1101,7 +1104,7 @@ static void serial_console_write(struct console *co, const char *s, sci_port->disable(port); } -static int __init serial_console_setup(struct console *co, char *options) +static int __devinit serial_console_setup(struct console *co, char *options) { struct sci_port *sci_port; struct uart_port *port; @@ -1119,9 +1122,14 @@ static int __init serial_console_setup(struct console *co, char *options) if (co->index >= SCI_NPORTS) co->index = 0; - sci_port = &sci_ports[co->index]; - port = &sci_port->port; - co->data = port; + if (co->data) { + port = co->data; + sci_port = to_sci_port(port); + } else { + sci_port = &sci_ports[co->index]; + port = &sci_port->port; + co->data = port; + } /* * Also need to check port->type, we don't actually have any @@ -1165,6 +1173,15 @@ static int __init sci_console_init(void) return 0; } console_initcall(sci_console_init); + +static struct sci_port early_serial_port; +static struct console early_serial_console = { + .name = "early_ttySC", + .write = serial_console_write, + .flags = CON_PRINTBUFFER, +}; +static char early_serial_buf[32]; + #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) @@ -1250,6 +1267,21 @@ static int __devinit sci_probe(struct platform_device *dev) struct sh_sci_priv *priv; int i, ret = -EINVAL; +#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE + if (is_early_platform_device(dev)) { + if (dev->id == -1) + return -ENOTSUPP; + early_serial_console.index = dev->id; + early_serial_console.data = &early_serial_port.port; + sci_init_single(NULL, &early_serial_port, dev->id, p); + serial_console_setup(&early_serial_console, early_serial_buf); + if (!strstr(early_serial_buf, "keep")) + early_serial_console.flags |= CON_BOOT; + register_console(&early_serial_console); + return 0; + } +#endif + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -1349,6 +1381,10 @@ static void __exit sci_exit(void) uart_unregister_driver(&sci_uart_driver); } +#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE +early_platform_init_buffer("earlyprintk", &sci_driver, + early_serial_buf, ARRAY_SIZE(early_serial_buf)); +#endif module_init(sci_init); module_exit(sci_exit); -- cgit v0.10.2 From 632fd800f54f361cd9d36dd48587756dab670ccf Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 14 Dec 2009 12:29:48 +0000 Subject: sh: sh2 scif pdata (sh7616) This patch breaks out the sh2 scif serial port platform data from a shared platform device to one platform device per port. Also, add serial ports to the list of early platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index 8555c05..114c7ce 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -59,32 +59,48 @@ static struct intc_prio_reg prio_registers[] __initdata = { static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, NULL, NULL, prio_registers, NULL); -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xf8400000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 88, 88, 88, 88 }, - }, { - .mapbase = 0xf8410000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 92, 92, 92, 92 }, - }, { - .mapbase = 0xf8420000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 96, 96, 96, 96 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xf8400000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 88, 88, 88, 88 }, +}; + +static struct platform_device scif0_device = { + .name = "sh-sci", + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xf8410000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 92, 92, 92, 92 }, +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, + }, +}; + +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xf8420000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 96, 96, 96, 96 }, +}; + +static struct platform_device scif2_device = { .name = "sh-sci", - .id = -1, + .id = 2, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif2_platform_data, }, }; @@ -176,7 +192,9 @@ static struct platform_device cmt1_device = { }; static struct platform_device *sh7619_devices[] __initdata = { - &sci_device, + &scif0_device, + &scif1_device, + &scif2_device, ð_device, &cmt0_device, &cmt1_device, @@ -195,6 +213,9 @@ void __init plat_irq_setup(void) } static struct platform_device *sh7619_early_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, &cmt0_device, &cmt1_device, }; -- cgit v0.10.2 From be091d20efe7b045ca02bdf91c63c72d91f5899d Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 14 Dec 2009 12:29:56 +0000 Subject: sh: sh2a scif pdata (sh7201/sh7203/sh7206/mxg) This patch breaks out the sh2a scif serial port platform data from a shared platform device to one platform device per port. Also, add serial ports to the list of early platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c index b673764..8f669dc 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c +++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c @@ -207,27 +207,23 @@ static struct platform_device mtu2_2_device = { .num_resources = ARRAY_SIZE(mtu2_2_resources), }; -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xff804000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 220, 220, 220, 220 }, - }, { - .flags = 0, - } +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xff804000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 220, 220, 220, 220 }, }; -static struct platform_device sci_device = { +static struct platform_device scif0_device = { .name = "sh-sci", - .id = -1, + .id = 0, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif0_platform_data, }, }; static struct platform_device *mxg_devices[] __initdata = { - &sci_device, + &scif0_device, &mtu2_0_device, &mtu2_1_device, &mtu2_2_device, @@ -246,6 +242,7 @@ void __init plat_irq_setup(void) } static struct platform_device *mxg_early_devices[] __initdata = { + &scif0_device, &mtu2_0_device, &mtu2_1_device, &mtu2_2_device, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c index fbde5b7..4ccfeb5 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c @@ -177,57 +177,123 @@ static struct intc_mask_reg mask_registers[] __initdata = { static DECLARE_INTC_DESC(intc_desc, "sh7201", vectors, groups, mask_registers, prio_registers, NULL); -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xfffe8000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 180, 180, 180, 180 } - }, { - .mapbase = 0xfffe8800, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 184, 184, 184, 184 } - }, { - .mapbase = 0xfffe9000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 188, 188, 188, 188 } - }, { - .mapbase = 0xfffe9800, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 192, 192, 192, 192 } - }, { - .mapbase = 0xfffea000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 196, 196, 196, 196 } - }, { - .mapbase = 0xfffea800, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 200, 200, 200, 200 } - }, { - .mapbase = 0xfffeb000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 204, 204, 204, 204 } - }, { - .mapbase = 0xfffeb800, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 208, 208, 208, 208 } - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xfffe8000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 180, 180, 180, 180 } +}; + +static struct platform_device scif0_device = { .name = "sh-sci", - .id = -1, + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xfffe8800, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 184, 184, 184, 184 } +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, + }, +}; + +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xfffe9000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 188, 188, 188, 188 } +}; + +static struct platform_device scif2_device = { + .name = "sh-sci", + .id = 2, + .dev = { + .platform_data = &scif2_platform_data, + }, +}; + +static struct plat_sci_port scif3_platform_data = { + .mapbase = 0xfffe9800, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 192, 192, 192, 192 } +}; + +static struct platform_device scif3_device = { + .name = "sh-sci", + .id = 3, + .dev = { + .platform_data = &scif3_platform_data, + }, +}; + +static struct plat_sci_port scif4_platform_data = { + .mapbase = 0xfffea000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 196, 196, 196, 196 } +}; + +static struct platform_device scif4_device = { + .name = "sh-sci", + .id = 4, + .dev = { + .platform_data = &scif4_platform_data, + }, +}; + +static struct plat_sci_port scif5_platform_data = { + .mapbase = 0xfffea800, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 200, 200, 200, 200 } +}; + +static struct platform_device scif5_device = { + .name = "sh-sci", + .id = 5, + .dev = { + .platform_data = &scif5_platform_data, + }, +}; + +static struct plat_sci_port scif6_platform_data = { + .mapbase = 0xfffeb000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 204, 204, 204, 204 } +}; + +static struct platform_device scif6_device = { + .name = "sh-sci", + .id = 6, + .dev = { + .platform_data = &scif6_platform_data, + }, +}; + +static struct plat_sci_port scif7_platform_data = { + .mapbase = 0xfffeb800, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 208, 208, 208, 208 } +}; + +static struct platform_device scif7_device = { + .name = "sh-sci", + .id = 7, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif7_platform_data, }, }; @@ -345,7 +411,14 @@ static struct platform_device mtu2_2_device = { }; static struct platform_device *sh7201_devices[] __initdata = { - &sci_device, + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, + &scif4_device, + &scif5_device, + &scif6_device, + &scif7_device, &rtc_device, &mtu2_0_device, &mtu2_1_device, @@ -365,6 +438,14 @@ void __init plat_irq_setup(void) } static struct platform_device *sh7201_early_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, + &scif4_device, + &scif5_device, + &scif6_device, + &scif7_device, &mtu2_0_device, &mtu2_1_device, &mtu2_2_device, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index d3fd536..3136966 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -173,37 +173,63 @@ static struct intc_mask_reg mask_registers[] __initdata = { static DECLARE_INTC_DESC(intc_desc, "sh7203", vectors, groups, mask_registers, prio_registers, NULL); -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xfffe8000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 192, 192, 192, 192 }, - }, { - .mapbase = 0xfffe8800, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 196, 196, 196, 196 }, - }, { - .mapbase = 0xfffe9000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 200, 200, 200, 200 }, - }, { - .mapbase = 0xfffe9800, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 204, 204, 204, 204 }, - }, { - .flags = 0, - } +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xfffe8000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 192, 192, 192, 192 }, }; -static struct platform_device sci_device = { +static struct platform_device scif0_device = { .name = "sh-sci", - .id = -1, + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xfffe8800, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 196, 196, 196, 196 }, +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, + }, +}; + +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xfffe9000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 200, 200, 200, 200 }, +}; + +static struct platform_device scif2_device = { + .name = "sh-sci", + .id = 2, + .dev = { + .platform_data = &scif2_platform_data, + }, +}; + +static struct plat_sci_port scif3_platform_data = { + .mapbase = 0xfffe9800, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 204, 204, 204, 204 }, +}; + +static struct platform_device scif3_device = { + .name = "sh-sci", + .id = 3, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif3_platform_data, }, }; @@ -354,7 +380,10 @@ static struct platform_device rtc_device = { }; static struct platform_device *sh7203_devices[] __initdata = { - &sci_device, + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, &cmt0_device, &cmt1_device, &mtu2_0_device, @@ -375,6 +404,10 @@ void __init plat_irq_setup(void) } static struct platform_device *sh7203_early_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, &cmt0_device, &cmt1_device, &mtu2_0_device, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index a9ccc5e..0648735 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -133,37 +133,63 @@ static struct intc_mask_reg mask_registers[] __initdata = { static DECLARE_INTC_DESC(intc_desc, "sh7206", vectors, groups, mask_registers, prio_registers, NULL); -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xfffe8000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 240, 240, 240, 240 }, - }, { - .mapbase = 0xfffe8800, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 244, 244, 244, 244 }, - }, { - .mapbase = 0xfffe9000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 248, 248, 248, 248 }, - }, { - .mapbase = 0xfffe9800, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 252, 252, 252, 252 }, - }, { - .flags = 0, - } +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xfffe8000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 240, 240, 240, 240 }, }; -static struct platform_device sci_device = { +static struct platform_device scif0_device = { .name = "sh-sci", - .id = -1, + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xfffe8800, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 244, 244, 244, 244 }, +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, + }, +}; + +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xfffe9000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 248, 248, 248, 248 }, +}; + +static struct platform_device scif2_device = { + .name = "sh-sci", + .id = 2, + .dev = { + .platform_data = &scif2_platform_data, + }, +}; + +static struct plat_sci_port scif3_platform_data = { + .mapbase = 0xfffe9800, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 252, 252, 252, 252 }, +}; + +static struct platform_device scif3_device = { + .name = "sh-sci", + .id = 3, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif3_platform_data, }, }; @@ -325,7 +351,10 @@ static struct platform_device mtu2_2_device = { }; static struct platform_device *sh7206_devices[] __initdata = { - &sci_device, + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, &cmt0_device, &cmt1_device, &mtu2_0_device, @@ -346,6 +375,10 @@ void __init plat_irq_setup(void) } static struct platform_device *sh7206_early_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, &cmt0_device, &cmt1_device, &mtu2_0_device, -- cgit v0.10.2 From 44658dfb660c4744b862571a3d8e1dae65e8b75a Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 14 Dec 2009 12:30:05 +0000 Subject: sh: sh3 scif pdata (sh7705/sh770x/sh7710/sh7720) This patch breaks out the sh3 scif serial port platform data from a shared platform device to one platform device per port. Also, add serial ports to the list of early platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index c231059..7b892d6 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -67,27 +67,33 @@ static struct intc_prio_reg prio_registers[] __initdata = { static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, NULL, NULL, prio_registers, NULL); -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xa4410000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 56, 56, 56 }, - }, { - .mapbase = 0xa4400000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 52, 52, 52 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xa4410000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 56, 56, 56 }, +}; + +static struct platform_device scif0_device = { .name = "sh-sci", - .id = -1, + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xa4400000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 52, 52, 52 }, +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif1_platform_data, }, }; @@ -210,10 +216,11 @@ static struct platform_device tmu2_device = { }; static struct platform_device *sh7705_devices[] __initdata = { + &scif0_device, + &scif1_device, &tmu0_device, &tmu1_device, &tmu2_device, - &sci_device, &rtc_device, }; @@ -225,6 +232,8 @@ static int __init sh7705_devices_setup(void) arch_initcall(sh7705_devices_setup); static struct platform_device *sh7705_early_devices[] __initdata = { + &scif0_device, + &scif1_device, &tmu0_device, &tmu1_device, &tmu2_device, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 347ab35..bc0c4f6 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -106,44 +106,55 @@ static struct platform_device rtc_device = { .resource = rtc_resources, }; -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xfffffe80, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCI, - .irqs = { 23, 23, 23, 0 }, +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xfffffe80, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCI, + .irqs = { 23, 23, 23, 0 }, +}; + +static struct platform_device scif0_device = { + .name = "sh-sci", + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, }, +}; #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7707) || \ defined(CONFIG_CPU_SUBTYPE_SH7709) - { - .mapbase = 0xa4000150, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 56, 56, 56, 56 }, +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xa4000150, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 56, 56, 56, 56 }, +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, }, +}; #endif #if defined(CONFIG_CPU_SUBTYPE_SH7707) || \ defined(CONFIG_CPU_SUBTYPE_SH7709) - { - .mapbase = 0xa4000140, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_IRDA, - .irqs = { 52, 52, 52, 52 }, - }, -#endif - { - .flags = 0, - } +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xa4000140, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_IRDA, + .irqs = { 52, 52, 52, 52 }, }; -static struct platform_device sci_device = { +static struct platform_device scif2_device = { .name = "sh-sci", - .id = -1, + .id = 2, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif2_platform_data, }, }; +#endif static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", @@ -238,10 +249,19 @@ static struct platform_device tmu2_device = { }; static struct platform_device *sh770x_devices[] __initdata = { + &scif0_device, +#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) + &scif1_device, +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) + &scif2_device, +#endif &tmu0_device, &tmu1_device, &tmu2_device, - &sci_device, &rtc_device, }; @@ -253,6 +273,16 @@ static int __init sh770x_devices_setup(void) arch_initcall(sh770x_devices_setup); static struct platform_device *sh770x_early_devices[] __initdata = { + &scif0_device, +#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) + &scif1_device, +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) + &scif2_device, +#endif &tmu0_device, &tmu1_device, &tmu2_device, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 717e90a..0845a3a 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -96,28 +96,33 @@ static struct platform_device rtc_device = { }, }; -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xa4400000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 52, 52, 52, 52 }, - }, { - .mapbase = 0xa4410000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 56, 56, 56, 56 }, - }, { - - .flags = 0, - } -}; - -static struct platform_device sci_device = { +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xa4400000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 52, 52, 52, 52 }, +}; + +static struct platform_device scif0_device = { .name = "sh-sci", - .id = -1, + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xa4410000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 56, 56, 56, 56 }, +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif1_platform_data, }, }; @@ -214,10 +219,11 @@ static struct platform_device tmu2_device = { }; static struct platform_device *sh7710_devices[] __initdata = { + &scif0_device, + &scif1_device, &tmu0_device, &tmu1_device, &tmu2_device, - &sci_device, &rtc_device, }; @@ -229,6 +235,8 @@ static int __init sh7710_devices_setup(void) arch_initcall(sh7710_devices_setup); static struct platform_device *sh7710_early_devices[] __initdata = { + &scif0_device, + &scif1_device, &tmu0_device, &tmu1_device, &tmu2_device, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 74d8baa..a718a62 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -48,28 +48,33 @@ static struct platform_device rtc_device = { }, }; -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xa4430000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 80, 80, 80 }, - }, { - .mapbase = 0xa4438000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 81, 81, 81, 81 }, - }, { - - .flags = 0, - } -}; - -static struct platform_device sci_device = { +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xa4430000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 80, 80, 80 }, +}; + +static struct platform_device scif0_device = { .name = "sh-sci", - .id = -1, + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xa4438000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 81, 81, 81, 81 }, +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif1_platform_data, }, }; @@ -369,6 +374,8 @@ static struct platform_device tmu2_device = { }; static struct platform_device *sh7720_devices[] __initdata = { + &scif0_device, + &scif1_device, &cmt0_device, &cmt1_device, &cmt2_device, @@ -378,7 +385,6 @@ static struct platform_device *sh7720_devices[] __initdata = { &tmu1_device, &tmu2_device, &rtc_device, - &sci_device, &usb_ohci_device, &usbf_device, }; @@ -391,6 +397,8 @@ static int __init sh7720_devices_setup(void) arch_initcall(sh7720_devices_setup); static struct platform_device *sh7720_early_devices[] __initdata = { + &scif0_device, + &scif1_device, &cmt0_device, &cmt1_device, &cmt2_device, -- cgit v0.10.2 From cd5f107628ab89c5dec5ad923f1c27f4cba41972 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 14 Dec 2009 12:30:14 +0000 Subject: sh: sh4 scif pdata (sh7750/sh7760/sh4-202) This patch breaks out the sh4 scif serial port platform data from a shared platform device to one platform device per port. Also, add serial ports to the list of early platform devices. While at it, get rid of the R2D ifdef in the processor code and adjust the defconfigs to use ttySC1. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/sh/configs/rts7751r2d1_defconfig b/arch/sh/configs/rts7751r2d1_defconfig index f521e82..6f1126b 100644 --- a/arch/sh/configs/rts7751r2d1_defconfig +++ b/arch/sh/configs/rts7751r2d1_defconfig @@ -324,7 +324,7 @@ CONFIG_ENTRY_OFFSET=0x00001000 # CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_OVERWRITE=y # CONFIG_CMDLINE_EXTEND is not set -CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=serial" +CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 root=/dev/sda1" # # Bus options diff --git a/arch/sh/configs/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig index a156cd1..9215bbb1 100644 --- a/arch/sh/configs/rts7751r2dplus_defconfig +++ b/arch/sh/configs/rts7751r2dplus_defconfig @@ -324,7 +324,7 @@ CONFIG_ENTRY_OFFSET=0x00001000 # CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_OVERWRITE=y # CONFIG_CMDLINE_EXTEND is not set -CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=serial" +CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 root=/dev/sda1" # # Bus options diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index de4827d..4b73371 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -15,22 +15,18 @@ #include #include -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe80000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 40, 41, 43, 42 }, - }, { - .flags = 0, - } +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xffe80000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 40, 41, 43, 42 }, }; -static struct platform_device sci_device = { +static struct platform_device scif0_device = { .name = "sh-sci", - .id = -1, + .id = 0, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif0_platform_data, }, }; @@ -127,7 +123,7 @@ static struct platform_device tmu2_device = { }; static struct platform_device *sh4202_devices[] __initdata = { - &sci_device, + &scif0_device, &tmu0_device, &tmu1_device, &tmu2_device, @@ -141,6 +137,7 @@ static int __init sh4202_devices_setup(void) arch_initcall(sh4202_devices_setup); static struct platform_device *sh4202_early_devices[] __initdata = { + &scif0_device, &tmu0_device, &tmu1_device, &tmu2_device, diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 1b8b122..b2a9df1 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -35,29 +35,33 @@ static struct platform_device rtc_device = { .resource = rtc_resources, }; -static struct plat_sci_port sci_platform_data[] = { - { -#ifndef CONFIG_SH_RTS7751R2D - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCI, - .irqs = { 23, 23, 23, 0 }, - }, { -#endif - .mapbase = 0xffe80000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 40, 40, 40, 40 }, - }, { - .flags = 0, - } +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCI, + .irqs = { 23, 23, 23, 0 }, }; -static struct platform_device sci_device = { +static struct platform_device scif0_device = { .name = "sh-sci", - .id = -1, + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xffe80000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 40, 40, 40, 40 }, +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif1_platform_data, }, }; @@ -221,8 +225,9 @@ static struct platform_device tmu4_device = { #endif static struct platform_device *sh7750_devices[] __initdata = { + &scif0_device, + &scif1_device, &rtc_device, - &sci_device, &tmu0_device, &tmu1_device, &tmu2_device, @@ -242,6 +247,8 @@ static int __init sh7750_devices_setup(void) arch_initcall(sh7750_devices_setup); static struct platform_device *sh7750_early_devices[] __initdata = { + &scif0_device, + &scif1_device, &tmu0_device, &tmu1_device, &tmu2_device, diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 7fbb7be..5b74cc0 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -126,37 +126,63 @@ static struct intc_vect vectors_irq[] __initdata = { static DECLARE_INTC_DESC(intc_desc_irq, "sh7760-irq", vectors_irq, groups, mask_registers, prio_registers, NULL); -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xfe600000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 52, 53, 55, 54 }, - }, { - .mapbase = 0xfe610000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 72, 73, 75, 74 }, - }, { - .mapbase = 0xfe620000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 76, 77, 79, 78 }, - }, { - .mapbase = 0xfe480000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCI, - .irqs = { 80, 81, 82, 0 }, - }, { - .flags = 0, - } +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xfe600000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 52, 53, 55, 54 }, +}; + +static struct platform_device scif0_device = { + .name = "sh-sci", + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xfe610000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 72, 73, 75, 74 }, +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, + }, +}; + +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xfe620000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 76, 77, 79, 78 }, +}; + +static struct platform_device scif2_device = { + .name = "sh-sci", + .id = 2, + .dev = { + .platform_data = &scif2_platform_data, + }, +}; + +static struct plat_sci_port scif3_platform_data = { + .mapbase = 0xfe480000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCI, + .irqs = { 80, 81, 82, 0 }, }; -static struct platform_device sci_device = { +static struct platform_device scif3_device = { .name = "sh-sci", - .id = -1, + .id = 3, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif3_platform_data, }, }; @@ -254,7 +280,10 @@ static struct platform_device tmu2_device = { static struct platform_device *sh7760_devices[] __initdata = { - &sci_device, + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, &tmu0_device, &tmu1_device, &tmu2_device, @@ -268,6 +297,10 @@ static int __init sh7760_devices_setup(void) arch_initcall(sh7760_devices_setup); static struct platform_device *sh7760_early_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, &tmu0_device, &tmu1_device, &tmu2_device, -- cgit v0.10.2 From bcac24d0535402d6e3414d3951609f12caaa1c7d Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 14 Dec 2009 12:30:22 +0000 Subject: sh: sh4a scif pdata (sh7343/sh7366/sh7722/sh7723/sh7724) This patch breaks out the sh4a scif serial port platform data from a shared platform device to one platform device per port. Also, add serial ports to the list of early platform devices. Only sh4a SuperH Mobile processors are modified by this patch. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index ac4d567..45eb1bf 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -15,6 +15,71 @@ #include #include +/* Serial */ +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 80, 80, 80 }, + .clk = "scif0", +}; + +static struct platform_device scif0_device = { + .name = "sh-sci", + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xffe10000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 81, 81, 81, 81 }, + .clk = "scif1", +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, + }, +}; + +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xffe20000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 82, 82, 82, 82 }, + .clk = "scif2", +}; + +static struct platform_device scif2_device = { + .name = "sh-sci", + .id = 2, + .dev = { + .platform_data = &scif2_platform_data, + }, +}; + +static struct plat_sci_port scif3_platform_data = { + .mapbase = 0xffe30000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 83, 83, 83, 83 }, + .clk = "scif3", +}; + +static struct platform_device scif3_device = { + .name = "sh-sci", + .id = 3, + .dev = { + .platform_data = &scif3_platform_data, + }, +}; + static struct resource iic0_resources[] = { [0] = { .name = "IIC0", @@ -265,52 +330,17 @@ static struct platform_device tmu2_device = { .num_resources = ARRAY_SIZE(tmu2_resources), }; -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 80, 80, 80 }, - .clk = "scif0", - }, { - .mapbase = 0xffe10000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 81, 81, 81, 81 }, - .clk = "scif1", - }, { - .mapbase = 0xffe20000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 82, 82, 82, 82 }, - .clk = "scif2", - }, { - .mapbase = 0xffe30000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 83, 83, 83, 83 }, - .clk = "scif3", - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - static struct platform_device *sh7343_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, &cmt_device, &tmu0_device, &tmu1_device, &tmu2_device, &iic0_device, &iic1_device, - &sci_device, &vpu_device, &veu_device, &jpu_device, @@ -328,6 +358,10 @@ static int __init sh7343_devices_setup(void) arch_initcall(sh7343_devices_setup); static struct platform_device *sh7343_early_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, &cmt_device, &tmu0_device, &tmu1_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index 4a9010b..c494c19 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -18,6 +18,22 @@ #include #include +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 80, 80, 80 }, + .clk = "scif0", +}; + +static struct platform_device scif0_device = { + .name = "sh-sci", + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + static struct resource iic_resources[] = { [0] = { .name = "IIC", @@ -276,33 +292,13 @@ static struct platform_device tmu2_device = { .num_resources = ARRAY_SIZE(tmu2_resources), }; -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 80, 80, 80 }, - .clk = "scif0", - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - static struct platform_device *sh7366_devices[] __initdata = { + &scif0_device, &cmt_device, &tmu0_device, &tmu1_device, &tmu2_device, &iic_device, - &sci_device, &usb_host_device, &vpu_device, &veu0_device, @@ -321,6 +317,7 @@ static int __init sh7366_devices_setup(void) arch_initcall(sh7366_devices_setup); static struct platform_device *sh7366_early_devices[] __initdata = { + &scif0_device, &cmt_device, &tmu0_device, &tmu1_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 5491b09..b5335b5 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -20,6 +20,55 @@ #include #include +/* Serial */ +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 80, 80, 80 }, + .clk = "scif0", +}; + +static struct platform_device scif0_device = { + .name = "sh-sci", + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xffe10000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 81, 81, 81, 81 }, + .clk = "scif1", +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, + }, +}; + +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xffe20000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 82, 82, 82, 82 }, + .clk = "scif2", +}; + +static struct platform_device scif2_device = { + .name = "sh-sci", + .id = 2, + .dev = { + .platform_data = &scif2_platform_data, + }, +}; + static struct resource rtc_resources[] = { [0] = { .start = 0xa465fec0, @@ -339,41 +388,6 @@ static struct platform_device tmu2_device = { }, }; -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 80, 80, 80 }, - .clk = "scif0", - }, - { - .mapbase = 0xffe10000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 81, 81, 81, 81 }, - .clk = "scif1", - }, - { - .mapbase = 0xffe20000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 82, 82, 82, 82 }, - .clk = "scif2", - }, - { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - static struct sh_dmae_pdata dma_platform_data = { .mode = 0, }; @@ -387,6 +401,9 @@ static struct platform_device dma_device = { }; static struct platform_device *sh7722_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, &cmt_device, &tmu0_device, &tmu1_device, @@ -394,7 +411,6 @@ static struct platform_device *sh7722_devices[] __initdata = { &rtc_device, &usbf_device, &iic_device, - &sci_device, &vpu_device, &veu_device, &jpu_device, @@ -413,6 +429,9 @@ static int __init sh7722_devices_setup(void) arch_initcall(sh7722_devices_setup); static struct platform_device *sh7722_early_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, &cmt_device, &tmu0_device, &tmu1_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 4caa5a7..772b926 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -20,6 +20,103 @@ #include #include +/* Serial */ +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 80, 80, 80 }, + .clk = "scif0", +}; + +static struct platform_device scif0_device = { + .name = "sh-sci", + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xffe10000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 81, 81, 81, 81 }, + .clk = "scif1", +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, + }, +}; + +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xffe20000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 82, 82, 82, 82 }, + .clk = "scif2", +}; + +static struct platform_device scif2_device = { + .name = "sh-sci", + .id = 2, + .dev = { + .platform_data = &scif2_platform_data, + }, +}; + +static struct plat_sci_port scif3_platform_data = { + .mapbase = 0xa4e30000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIFA, + .irqs = { 56, 56, 56, 56 }, + .clk = "scif3", +}; + +static struct platform_device scif3_device = { + .name = "sh-sci", + .id = 3, + .dev = { + .platform_data = &scif3_platform_data, + }, +}; + +static struct plat_sci_port scif4_platform_data = { + .mapbase = 0xa4e40000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIFA, + .irqs = { 88, 88, 88, 88 }, + .clk = "scif4", +}; + +static struct platform_device scif4_device = { + .name = "sh-sci", + .id = 4, + .dev = { + .platform_data = &scif4_platform_data, + }, +}; + +static struct plat_sci_port scif5_platform_data = { + .mapbase = 0xa4e50000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIFA, + .irqs = { 109, 109, 109, 109 }, + .clk = "scif5", +}; + +static struct platform_device scif5_device = { + .name = "sh-sci", + .id = 5, + .dev = { + .platform_data = &scif5_platform_data, + }, +}; + static struct uio_info vpu_platform_data = { .name = "VPU5", .version = "0", @@ -348,56 +445,6 @@ static struct platform_device tmu5_device = { }, }; -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 80, 80, 80 }, - .clk = "scif0", - },{ - .mapbase = 0xffe10000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 81, 81, 81, 81 }, - .clk = "scif1", - },{ - .mapbase = 0xffe20000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 82, 82, 82, 82 }, - .clk = "scif2", - },{ - .mapbase = 0xa4e30000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIFA, - .irqs = { 56, 56, 56, 56 }, - .clk = "scif3", - },{ - .mapbase = 0xa4e40000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIFA, - .irqs = { 88, 88, 88, 88 }, - .clk = "scif4", - },{ - .mapbase = 0xa4e50000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIFA, - .irqs = { 109, 109, 109, 109 }, - .clk = "scif5", - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - static struct resource rtc_resources[] = { [0] = { .start = 0xa465fec0, @@ -488,6 +535,12 @@ static struct platform_device iic_device = { }; static struct platform_device *sh7723_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, + &scif4_device, + &scif5_device, &cmt_device, &tmu0_device, &tmu1_device, @@ -495,7 +548,6 @@ static struct platform_device *sh7723_devices[] __initdata = { &tmu3_device, &tmu4_device, &tmu5_device, - &sci_device, &rtc_device, &iic_device, &sh7723_usb_host_device, @@ -516,6 +568,12 @@ static int __init sh7723_devices_setup(void) arch_initcall(sh7723_devices_setup); static struct platform_device *sh7723_early_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, + &scif4_device, + &scif5_device, &cmt_device, &tmu0_device, &tmu1_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 845e89c..a52f351 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -27,53 +27,99 @@ #include /* Serial */ -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 80, 80, 80 }, - .clk = "scif0", - }, { - .mapbase = 0xffe10000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 81, 81, 81, 81 }, - .clk = "scif1", - }, { - .mapbase = 0xffe20000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 82, 82, 82, 82 }, - .clk = "scif2", - }, { - .mapbase = 0xa4e30000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIFA, - .irqs = { 56, 56, 56, 56 }, - .clk = "scif3", - }, { - .mapbase = 0xa4e40000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIFA, - .irqs = { 88, 88, 88, 88 }, - .clk = "scif4", - }, { - .mapbase = 0xa4e50000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIFA, - .irqs = { 109, 109, 109, 109 }, - .clk = "scif5", - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 80, 80, 80 }, + .clk = "scif0", +}; + +static struct platform_device scif0_device = { .name = "sh-sci", - .id = -1, + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xffe10000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 81, 81, 81, 81 }, + .clk = "scif1", +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, + }, +}; + +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xffe20000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 82, 82, 82, 82 }, + .clk = "scif2", +}; + +static struct platform_device scif2_device = { + .name = "sh-sci", + .id = 2, + .dev = { + .platform_data = &scif2_platform_data, + }, +}; + +static struct plat_sci_port scif3_platform_data = { + .mapbase = 0xa4e30000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIFA, + .irqs = { 56, 56, 56, 56 }, + .clk = "scif3", +}; + +static struct platform_device scif3_device = { + .name = "sh-sci", + .id = 3, + .dev = { + .platform_data = &scif3_platform_data, + }, +}; + +static struct plat_sci_port scif4_platform_data = { + .mapbase = 0xa4e40000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIFA, + .irqs = { 88, 88, 88, 88 }, + .clk = "scif4", +}; + +static struct platform_device scif4_device = { + .name = "sh-sci", + .id = 4, + .dev = { + .platform_data = &scif4_platform_data, + }, +}; + +static struct plat_sci_port scif5_platform_data = { + .mapbase = 0xa4e50000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIFA, + .irqs = { 109, 109, 109, 109 }, + .clk = "scif5", +}; + +static struct platform_device scif5_device = { + .name = "sh-sci", + .id = 5, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif5_platform_data, }, }; @@ -590,6 +636,12 @@ static struct platform_device spu1_device = { }; static struct platform_device *sh7724_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, + &scif4_device, + &scif5_device, &cmt_device, &tmu0_device, &tmu1_device, @@ -597,7 +649,6 @@ static struct platform_device *sh7724_devices[] __initdata = { &tmu3_device, &tmu4_device, &tmu5_device, - &sci_device, &rtc_device, &iic0_device, &iic1_device, @@ -624,6 +675,12 @@ static int __init sh7724_devices_setup(void) arch_initcall(sh7724_devices_setup); static struct platform_device *sh7724_early_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, + &scif4_device, + &scif5_device, &cmt_device, &tmu0_device, &tmu1_device, -- cgit v0.10.2 From a9571d7b045eb3b38d856c6dfda1798fb67ca44c Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 14 Dec 2009 12:30:31 +0000 Subject: sh: sh4a scif pdata (sh7757/sh7763/sh7770/sh7780/sh7785/sh7786/x3) This patch breaks out the sh4a scif serial port platform data from a shared platform device to one platform device per port. Also, add serial ports to the list of early platform devices. All sh4a except SuperH Mobile processors are modified by this patch. While at it, sh7757 gets early platform device support. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index c470e15..37e32ef 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c @@ -17,6 +17,51 @@ #include #include +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xfe4b0000, /* SCIF2 */ + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 40, 40, 40, 40 }, +}; + +static struct platform_device scif2_device = { + .name = "sh-sci", + .id = 2, + .dev = { + .platform_data = &scif2_platform_data, + }, +}; + +static struct plat_sci_port scif3_platform_data = { + .mapbase = 0xfe4c0000, /* SCIF3 */ + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 76, 76, 76, 76 }, +}; + +static struct platform_device scif3_device = { + .name = "sh-sci", + .id = 3, + .dev = { + .platform_data = &scif3_platform_data, + }, +}; + +static struct plat_sci_port scif4_platform_data = { + .mapbase = 0xfe4d0000, /* SCIF4 */ + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 104, 104, 104, 104 }, +}; + +static struct platform_device scif4_device = { + .name = "sh-sci", + .id = 4, + .dev = { + .platform_data = &scif4_platform_data, + }, +}; + static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x04, @@ -79,39 +124,12 @@ static struct platform_device tmu1_device = { .num_resources = ARRAY_SIZE(tmu1_resources), }; -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xfe4b0000, /* SCIF2 */ - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 40, 40, 40, 40 }, - }, { - .mapbase = 0xfe4c0000, /* SCIF3 */ - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 76, 76, 76, 76 }, - }, { - .mapbase = 0xfe4d0000, /* SCIF4 */ - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 104, 104, 104, 104 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - static struct platform_device *sh7757_devices[] __initdata = { + &scif2_device, + &scif3_device, + &scif4_device, &tmu0_device, &tmu1_device, - &sci_device, }; static int __init sh7757_devices_setup(void) @@ -121,6 +139,20 @@ static int __init sh7757_devices_setup(void) } arch_initcall(sh7757_devices_setup); +static struct platform_device *sh7757_early_devices[] __initdata = { + &scif2_device, + &scif3_device, + &scif4_device, + &tmu0_device, + &tmu1_device, +}; + +void __init plat_early_device_setup(void) +{ + early_platform_add_devices(sh7757_early_devices, + ARRAY_SIZE(sh7757_early_devices)); +} + enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index 4659fff..6aba26f 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -16,6 +16,51 @@ #include #include +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 40, 40, 40, 40 }, +}; + +static struct platform_device scif0_device = { + .name = "sh-sci", + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xffe08000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 76, 76, 76, 76 }, +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, + }, +}; + +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xffe10000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 104, 104, 104, 104 }, +}; + +static struct platform_device scif2_device = { + .name = "sh-sci", + .id = 2, + .dev = { + .platform_data = &scif2_platform_data, + }, +}; + static struct resource rtc_resources[] = { [0] = { .start = 0xffe80000, @@ -36,35 +81,6 @@ static struct platform_device rtc_device = { .resource = rtc_resources, }; -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 40, 40, 40, 40 }, - }, { - .mapbase = 0xffe08000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 76, 76, 76, 76 }, - }, { - .mapbase = 0xffe10000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 104, 104, 104, 104 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - static struct resource usb_ohci_resources[] = { [0] = { .start = 0xffec8000, @@ -297,6 +313,9 @@ static struct platform_device tmu5_device = { }; static struct platform_device *sh7763_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, &tmu0_device, &tmu1_device, &tmu2_device, @@ -304,7 +323,6 @@ static struct platform_device *sh7763_devices[] __initdata = { &tmu4_device, &tmu5_device, &rtc_device, - &sci_device, &usb_ohci_device, &usbf_device, }; @@ -317,6 +335,9 @@ static int __init sh7763_devices_setup(void) arch_initcall(sh7763_devices_setup); static struct platform_device *sh7763_early_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, &tmu0_device, &tmu1_device, &tmu2_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index eead08d..c1643bc 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -14,67 +14,153 @@ #include #include -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xff923000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 61, 61, 61, 61 }, - }, { - .mapbase = 0xff924000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 62, 62, 62, 62 }, - }, { - .mapbase = 0xff925000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 63, 63, 63, 63 }, - }, { - .mapbase = 0xff926000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 64, 64, 64, 64 }, - }, { - .mapbase = 0xff927000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 65, 65, 65, 65 }, - }, { - .mapbase = 0xff928000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 66, 66, 66, 66 }, - }, { - .mapbase = 0xff929000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 67, 67, 67, 67 }, - }, { - .mapbase = 0xff92a000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 68, 68, 68, 68 }, - }, { - .mapbase = 0xff92b000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 69, 69, 69, 69 }, - }, { - .mapbase = 0xff92c000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 70, 70, 70, 70 }, - }, { - .flags = 0, - } +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xff923000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 61, 61, 61, 61 }, +}; + +static struct platform_device scif0_device = { + .name = "sh-sci", + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xff924000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 62, 62, 62, 62 }, +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, + }, +}; + +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xff925000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 63, 63, 63, 63 }, +}; + +static struct platform_device scif2_device = { + .name = "sh-sci", + .id = 2, + .dev = { + .platform_data = &scif2_platform_data, + }, +}; + +static struct plat_sci_port scif3_platform_data = { + .mapbase = 0xff926000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 64, 64, 64, 64 }, +}; + +static struct platform_device scif3_device = { + .name = "sh-sci", + .id = 3, + .dev = { + .platform_data = &scif3_platform_data, + }, +}; + +static struct plat_sci_port scif4_platform_data = { + .mapbase = 0xff927000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 65, 65, 65, 65 }, +}; + +static struct platform_device scif4_device = { + .name = "sh-sci", + .id = 4, + .dev = { + .platform_data = &scif4_platform_data, + }, +}; + +static struct plat_sci_port scif5_platform_data = { + .mapbase = 0xff928000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 66, 66, 66, 66 }, +}; + +static struct platform_device scif5_device = { + .name = "sh-sci", + .id = 5, + .dev = { + .platform_data = &scif5_platform_data, + }, +}; + +static struct plat_sci_port scif6_platform_data = { + .mapbase = 0xff929000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 67, 67, 67, 67 }, +}; + +static struct platform_device scif6_device = { + .name = "sh-sci", + .id = 6, + .dev = { + .platform_data = &scif6_platform_data, + }, +}; + +static struct plat_sci_port scif7_platform_data = { + .mapbase = 0xff92a000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 68, 68, 68, 68 }, +}; + +static struct platform_device scif7_device = { + .name = "sh-sci", + .id = 7, + .dev = { + .platform_data = &scif7_platform_data, + }, +}; + +static struct plat_sci_port scif8_platform_data = { + .mapbase = 0xff92b000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 69, 69, 69, 69 }, +}; + +static struct platform_device scif8_device = { + .name = "sh-sci", + .id = 8, + .dev = { + .platform_data = &scif8_platform_data, + }, +}; + +static struct plat_sci_port scif9_platform_data = { + .mapbase = 0xff92c000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 70, 70, 70, 70 }, }; -static struct platform_device sci_device = { +static struct platform_device scif9_device = { .name = "sh-sci", - .id = -1, + .id = 9, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif9_platform_data, }, }; @@ -351,6 +437,16 @@ static struct platform_device tmu8_device = { }; static struct platform_device *sh7770_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, + &scif4_device, + &scif5_device, + &scif6_device, + &scif7_device, + &scif8_device, + &scif9_device, &tmu0_device, &tmu1_device, &tmu2_device, @@ -360,7 +456,6 @@ static struct platform_device *sh7770_devices[] __initdata = { &tmu6_device, &tmu7_device, &tmu8_device, - &sci_device, }; static int __init sh7770_devices_setup(void) @@ -371,6 +466,16 @@ static int __init sh7770_devices_setup(void) arch_initcall(sh7770_devices_setup); static struct platform_device *sh7770_early_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, + &scif4_device, + &scif5_device, + &scif6_device, + &scif7_device, + &scif8_device, + &scif9_device, &tmu0_device, &tmu1_device, &tmu2_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 12ff56f..c310558 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -15,6 +15,36 @@ #include #include +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 40, 40, 40, 40 }, +}; + +static struct platform_device scif0_device = { + .name = "sh-sci", + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xffe10000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 76, 76, 76, 76 }, +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, + }, +}; + static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x04, @@ -217,30 +247,6 @@ static struct platform_device rtc_device = { .resource = rtc_resources, }; -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 40, 40, 40, 40 }, - }, { - .mapbase = 0xffe10000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 76, 76, 76, 76 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - static struct sh_dmae_pdata dma_platform_data = { .mode = (SHDMA_MIX_IRQ | SHDMA_DMAOR1), }; @@ -254,6 +260,8 @@ static struct platform_device dma_device = { }; static struct platform_device *sh7780_devices[] __initdata = { + &scif0_device, + &scif1_device, &tmu0_device, &tmu1_device, &tmu2_device, @@ -261,7 +269,6 @@ static struct platform_device *sh7780_devices[] __initdata = { &tmu4_device, &tmu5_device, &rtc_device, - &sci_device, &dma_device, }; @@ -271,8 +278,9 @@ static int __init sh7780_devices_setup(void) ARRAY_SIZE(sh7780_devices)); } arch_initcall(sh7780_devices_setup); - static struct platform_device *sh7780_early_devices[] __initdata = { + &scif0_device, + &scif1_device, &tmu0_device, &tmu1_device, &tmu2_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 7f6c718..ef26ebd 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -16,6 +16,102 @@ #include #include +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xffea0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 40, 40, 40, 40 }, + .clk = "scif_fck", +}; + +static struct platform_device scif0_device = { + .name = "sh-sci", + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xffeb0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 44, 44, 44, 44 }, + .clk = "scif_fck", +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, + }, +}; + +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xffec0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 60, 60, 60, 60 }, + .clk = "scif_fck", +}; + +static struct platform_device scif2_device = { + .name = "sh-sci", + .id = 2, + .dev = { + .platform_data = &scif2_platform_data, + }, +}; + +static struct plat_sci_port scif3_platform_data = { + .mapbase = 0xffed0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 61, 61, 61, 61 }, + .clk = "scif_fck", +}; + +static struct platform_device scif3_device = { + .name = "sh-sci", + .id = 3, + .dev = { + .platform_data = &scif3_platform_data, + }, +}; + +static struct plat_sci_port scif4_platform_data = { + .mapbase = 0xffee0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 62, 62, 62, 62 }, + .clk = "scif_fck", +}; + +static struct platform_device scif4_device = { + .name = "sh-sci", + .id = 4, + .dev = { + .platform_data = &scif4_platform_data, + }, +}; + +static struct plat_sci_port scif5_platform_data = { + .mapbase = 0xffef0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 63, 63, 63, 63 }, + .clk = "scif_fck", +}; + +static struct platform_device scif5_device = { + .name = "sh-sci", + .id = 5, + .dev = { + .platform_data = &scif5_platform_data, + }, +}; + static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x04, @@ -198,64 +294,19 @@ static struct platform_device tmu5_device = { .num_resources = ARRAY_SIZE(tmu5_resources), }; -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffea0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 40, 40, 40, 40 }, - .clk = "scif_fck", - }, { - .mapbase = 0xffeb0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 44, 44, 44, 44 }, - .clk = "scif_fck", - }, { - .mapbase = 0xffec0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 60, 60, 60, 60 }, - .clk = "scif_fck", - }, { - .mapbase = 0xffed0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 61, 61, 61, 61 }, - .clk = "scif_fck", - }, { - .mapbase = 0xffee0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 62, 62, 62, 62 }, - .clk = "scif_fck", - }, { - .mapbase = 0xffef0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 63, 63, 63, 63 }, - .clk = "scif_fck", - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - static struct platform_device *sh7785_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, + &scif4_device, + &scif5_device, &tmu0_device, &tmu1_device, &tmu2_device, &tmu3_device, &tmu4_device, &tmu5_device, - &sci_device, }; static int __init sh7785_devices_setup(void) @@ -266,6 +317,12 @@ static int __init sh7785_devices_setup(void) arch_initcall(sh7785_devices_setup); static struct platform_device *sh7785_early_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, + &scif4_device, + &scif5_device, &tmu0_device, &tmu1_device, &tmu2_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 0104a8e..7167348 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -23,51 +23,96 @@ #include #include -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffea0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 40, 41, 43, 42 }, +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xffea0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 40, 41, 43, 42 }, +}; + +static struct platform_device scif0_device = { + .name = "sh-sci", + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, }, - /* - * The rest of these all have multiplexed IRQs - */ - { - .mapbase = 0xffeb0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 44, 44, 44, 44 }, - }, { - .mapbase = 0xffec0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 50, 50, 50, 50 }, - }, { - .mapbase = 0xffed0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 51, 51, 51, 51 }, - }, { - .mapbase = 0xffee0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 52, 52, 52, 52 }, - }, { - .mapbase = 0xffef0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 53, 53, 53, 53 }, - }, { - .flags = 0, - } }; -static struct platform_device sci_device = { +/* + * The rest of these all have multiplexed IRQs + */ +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xffeb0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 44, 44, 44, 44 }, +}; + +static struct platform_device scif1_device = { .name = "sh-sci", - .id = -1, + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, + }, +}; + +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xffec0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 50, 50, 50, 50 }, +}; + +static struct platform_device scif2_device = { + .name = "sh-sci", + .id = 2, + .dev = { + .platform_data = &scif2_platform_data, + }, +}; + +static struct plat_sci_port scif3_platform_data = { + .mapbase = 0xffed0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 51, 51, 51, 51 }, +}; + +static struct platform_device scif3_device = { + .name = "sh-sci", + .id = 3, + .dev = { + .platform_data = &scif3_platform_data, + }, +}; + +static struct plat_sci_port scif4_platform_data = { + .mapbase = 0xffee0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 52, 52, 52, 52 }, +}; + +static struct platform_device scif4_device = { + .name = "sh-sci", + .id = 4, + .dev = { + .platform_data = &scif4_platform_data, + }, +}; + +static struct plat_sci_port scif5_platform_data = { + .mapbase = 0xffef0000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 53, 53, 53, 53 }, +}; + +static struct platform_device scif5_device = { + .name = "sh-sci", + .id = 5, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif5_platform_data, }, }; @@ -459,6 +504,12 @@ static struct platform_device usb_ohci_device = { }; static struct platform_device *sh7786_early_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, + &scif3_device, + &scif4_device, + &scif5_device, &tmu0_device, &tmu1_device, &tmu2_device, @@ -474,7 +525,6 @@ static struct platform_device *sh7786_early_devices[] __initdata = { }; static struct platform_device *sh7786_devices[] __initdata = { - &sci_device, &usb_ohci_device, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index c7ba916..780ba17 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -24,32 +24,48 @@ * silicon in the first place, we just refuse to deal with the port at * all rather than adding infrastructure to hack around it. */ -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffc30000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 40, 41, 43, 42 }, - }, { - .mapbase = 0xffc40000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 44, 45, 47, 46 }, - }, { - .mapbase = 0xffc60000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 52, 53, 55, 54 }, - }, { - .flags = 0, - } +static struct plat_sci_port scif0_platform_data = { + .mapbase = 0xffc30000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 40, 41, 43, 42 }, +}; + +static struct platform_device scif0_device = { + .name = "sh-sci", + .id = 0, + .dev = { + .platform_data = &scif0_platform_data, + }, +}; + +static struct plat_sci_port scif1_platform_data = { + .mapbase = 0xffc40000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 44, 45, 47, 46 }, +}; + +static struct platform_device scif1_device = { + .name = "sh-sci", + .id = 1, + .dev = { + .platform_data = &scif1_platform_data, + }, +}; + +static struct plat_sci_port scif2_platform_data = { + .mapbase = 0xffc60000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 52, 53, 55, 54 }, }; -static struct platform_device sci_device = { +static struct platform_device scif2_device = { .name = "sh-sci", - .id = -1, + .id = 2, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif2_platform_data, }, }; @@ -236,6 +252,9 @@ static struct platform_device tmu5_device = { }; static struct platform_device *shx3_early_devices[] __initdata = { + &scif0_device, + &scif1_device, + &scif2_device, &tmu0_device, &tmu1_device, &tmu2_device, @@ -244,21 +263,10 @@ static struct platform_device *shx3_early_devices[] __initdata = { &tmu5_device, }; -static struct platform_device *shx3_devices[] __initdata = { - &sci_device, -}; - static int __init shx3_devices_setup(void) { - int ret; - - ret = platform_add_devices(shx3_early_devices, + return platform_add_devices(shx3_early_devices, ARRAY_SIZE(shx3_early_devices)); - if (unlikely(ret != 0)) - return ret; - - return platform_add_devices(shx3_devices, - ARRAY_SIZE(shx3_devices)); } arch_initcall(shx3_devices_setup); -- cgit v0.10.2 From d8d3fbb0248dd0bc9b961f9ccfad8aa8e6b3ccfe Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 14 Dec 2009 12:30:41 +0000 Subject: sh: sh5 scif pdata (sh5-101/sh5-103) This patch breaks out the sh5 scif serial port platform data from a shared platform device to one platform device per port. Also, move the serial port to the list of early platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c index 6a0f82f..e7a3c1e 100644 --- a/arch/sh/kernel/cpu/sh5/setup-sh5.c +++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c @@ -16,22 +16,18 @@ #include #include -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = PHYS_PERIPHERAL_BLOCK + 0x01030000, - .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, - .type = PORT_SCIF, - .irqs = { 39, 40, 42, 0 }, - }, { - .flags = 0, - } +static struct plat_sci_port scif0_platform_data = { + .mapbase = PHYS_PERIPHERAL_BLOCK + 0x01030000, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, + .type = PORT_SCIF, + .irqs = { 39, 40, 42, 0 }, }; -static struct platform_device sci_device = { +static struct platform_device scif0_device = { .name = "sh-sci", - .id = -1, + .id = 0, .dev = { - .platform_data = sci_platform_data, + .platform_data = &scif0_platform_data, }, }; @@ -164,13 +160,13 @@ static struct platform_device tmu2_device = { }; static struct platform_device *sh5_early_devices[] __initdata = { + &scif0_device, &tmu0_device, &tmu1_device, &tmu2_device, }; static struct platform_device *sh5_devices[] __initdata = { - &sci_device, &rtc_device, }; -- cgit v0.10.2 From e76fe57447e88916954bdcab1c0d2c708ec3c943 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 14 Dec 2009 12:52:53 +0000 Subject: sh: Remove old early serial console code V2 Now when the sh-sci driver can do early serial output, get rid of the old duplicated code. This patch is V2 and removes support for "earlyprintk=serial" together with the following kconfig options: CONFIG_EARLY_SCIF_CONSOLE CONFIG_EARLY_SCIF_CONSOLE_PORT CONFIG_EARLY_PRINTK With this patch applied "earlyprintk=" support is always built-in the SuperH kernel. For this to work the serial driver must have early platform support and in the case of sh-sci the serial console needs to be enabled: CONFIG_SERIAL_SH_SCI_CONSOLE=y So after enabling the SuperH SCI console kconfig option you also need to point out port using the kernel command line: "earlyprintk=sh-sci.N[,baudrate][,keep]" Remember that clocks may be disabled by the boot loader so you may have to do some board specific static clock setup before earlyprintk will work on your platform. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 55907af..12fec72 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -19,50 +19,6 @@ config SH_STANDARD_BIOS mask ROM and no flash (WindowsCE machines fall in this category). If unsure, say N. -config EARLY_SCIF_CONSOLE - bool "Use early SCIF console" - help - This enables an early console using a fixed SCIF port. This can - be used by platforms that are either not running the SH - standard BIOS, or do not wish to use the BIOS callbacks for the - serial I/O. - -config EARLY_SCIF_CONSOLE_PORT - hex - depends on EARLY_SCIF_CONSOLE - default "0xa4400000" if CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7705 - default "0xa4430000" if CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721 - default "0xf8420000" if CPU_SUBTYPE_SH7619 - default "0xff804000" if CPU_SUBTYPE_MXG - default "0xffc30000" if CPU_SUBTYPE_SHX3 - default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 || \ - CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 || \ - CPU_SUBTYPE_SH7343 - default "0xfe4c0000" if CPU_SUBTYPE_SH7757 - default "0xffeb0000" if CPU_SUBTYPE_SH7785 - default "0xffeb0000" if CPU_SUBTYPE_SH7786 - default "0xfffe8000" if CPU_SUBTYPE_SH7203 - default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263 - default "0xffe80000" if CPU_SH4 - default "0xa4000150" if CPU_SH3 - default "0x00000000" - -config EARLY_PRINTK - bool "Early printk support" - depends on SH_STANDARD_BIOS || EARLY_SCIF_CONSOLE - help - Say Y here to redirect kernel printk messages to the serial port - used by the SH-IPL bootloader, starting very early in the boot - process and ending when the kernel's serial console is initialised. - This option is only useful porting the kernel to a new machine, - when the kernel may crash or hang before the serial console is - initialised. If unsure, say N. - - On devices that are running SH-IPL and want to keep the port - initialization consistent while not using the BIOS callbacks, - select both the EARLY_SCIF_CONSOLE and SH_STANDARD_BIOS, using - the kernel command line option to toggle back and forth. - config STACK_DEBUG bool "Check for stack overflows" depends on DEBUG_KERNEL && SUPERH32 diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index 0471a3e..0d587da 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -22,11 +22,10 @@ obj-y := debugtraps.o dma-nommu.o dumpstack.o \ obj-y += cpu/ obj-$(CONFIG_VSYSCALL) += vsyscall/ obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o +obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o early_printk.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o obj-$(CONFIG_MODULES) += sh_ksyms_$(BITS).o module.o -obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_STACKTRACE) += stacktrace.o diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c index fe7dc3f..f8bb50c 100644 --- a/arch/sh/kernel/early_printk.c +++ b/arch/sh/kernel/early_printk.c @@ -15,7 +15,6 @@ #include #include -#ifdef CONFIG_SH_STANDARD_BIOS #include /* @@ -57,140 +56,7 @@ static struct console bios_console = { .flags = CON_PRINTBUFFER, .index = -1, }; -#endif -#ifdef CONFIG_EARLY_SCIF_CONSOLE -#include -#include "../../../drivers/serial/sh-sci.h" - -#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ - defined(CONFIG_CPU_SUBTYPE_SH7721) -#define EPK_SCSMR_VALUE 0x000 -#define EPK_SCBRR_VALUE 0x00C -#define EPK_FIFO_SIZE 64 -#define EPK_FIFO_BITS (0x7f00 >> 8) -#else -#define EPK_FIFO_SIZE 16 -#define EPK_FIFO_BITS (0x1f00 >> 8) -#endif - -static struct uart_port scif_port = { - .type = PORT_SCIF, - .mapbase = CONFIG_EARLY_SCIF_CONSOLE_PORT, - .membase = (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT, -}; - -static void scif_sercon_putc(int c) -{ - while (((sci_in(&scif_port, SCFDR) & EPK_FIFO_BITS) >= EPK_FIFO_SIZE)) - ; - - sci_in(&scif_port, SCxSR); - sci_out(&scif_port, SCxSR, 0xf3 & ~(0x20 | 0x40)); - sci_out(&scif_port, SCxTDR, c); - - while ((sci_in(&scif_port, SCxSR) & 0x40) == 0) - ; - - if (c == '\n') - scif_sercon_putc('\r'); -} - -static void scif_sercon_write(struct console *con, const char *s, - unsigned count) -{ - while (count-- > 0) - scif_sercon_putc(*s++); -} - -static int __init scif_sercon_setup(struct console *con, char *options) -{ - con->cflag = CREAD | HUPCL | CLOCAL | B115200 | CS8; - - return 0; -} - -static struct console scif_console = { - .name = "sercon", - .write = scif_sercon_write, - .setup = scif_sercon_setup, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -#if !defined(CONFIG_SH_STANDARD_BIOS) -#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ - defined(CONFIG_CPU_SUBTYPE_SH7721) -static void scif_sercon_init(char *s) -{ - sci_out(&scif_port, SCSCR, 0x0000); /* clear TE and RE */ - sci_out(&scif_port, SCFCR, 0x4006); /* reset */ - sci_out(&scif_port, SCSCR, 0x0000); /* select internal clock */ - sci_out(&scif_port, SCSMR, EPK_SCSMR_VALUE); - sci_out(&scif_port, SCBRR, EPK_SCBRR_VALUE); - - mdelay(1); /* wait 1-bit time */ - - sci_out(&scif_port, SCFCR, 0x0030); /* TTRG=b'11 */ - sci_out(&scif_port, SCSCR, 0x0030); /* TE, RE */ -} -#elif defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SH3) -#define DEFAULT_BAUD 115200 -/* - * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4 - * devices that aren't using sh-ipl+g. - */ -static void scif_sercon_init(char *s) -{ - struct uart_port *port = &scif_port; - unsigned baud = DEFAULT_BAUD; - unsigned int status; - char *e; - - if (*s == ',') - ++s; - - if (*s) { - /* ignore ioport/device name */ - s += strcspn(s, ","); - if (*s == ',') - s++; - } - - if (*s) { - baud = simple_strtoul(s, &e, 0); - if (baud == 0 || s == e) - baud = DEFAULT_BAUD; - } - - do { - status = sci_in(port, SCxSR); - } while (!(status & SCxSR_TEND(port))); - - sci_out(port, SCSCR, 0); /* TE=0, RE=0 */ - sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); - sci_out(port, SCSMR, 0); - - /* Set baud rate */ - sci_out(port, SCBRR, (CONFIG_SH_PCLK_FREQ + 16 * baud) / - (32 * baud) - 1); - udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ - - sci_out(port, SCSPTR, 0); - sci_out(port, SCxSR, 0x60); - sci_out(port, SCLSR, 0); - - sci_out(port, SCFCR, 0); - sci_out(port, SCSCR, 0x30); /* TE=1, RE=1 */ -} -#endif /* defined(CONFIG_CPU_SUBTYPE_SH7720) */ -#endif /* !defined(CONFIG_SH_STANDARD_BIOS) */ -#endif /* CONFIG_EARLY_SCIF_CONSOLE */ - -/* - * Setup a default console, if more than one is compiled in, rely on the - * earlyprintk= parsing to give priority. - */ static struct console *early_console; static int __init setup_early_printk(char *buf) @@ -203,21 +69,8 @@ static int __init setup_early_printk(char *buf) if (strstr(buf, "keep")) keep_early = 1; -#ifdef CONFIG_SH_STANDARD_BIOS if (!strncmp(buf, "bios", 4)) early_console = &bios_console; -#endif -#if defined(CONFIG_EARLY_SCIF_CONSOLE) - if (!strncmp(buf, "serial", 6)) { - early_console = &scif_console; - -#if !defined(CONFIG_SH_STANDARD_BIOS) -#if defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SH3) - scif_sercon_init(buf + 6); -#endif -#endif - } -#endif if (likely(early_console)) { if (keep_early) -- cgit v0.10.2 From 61cc7b0a172b047aa6d2c3e8b62bb1590f37e897 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Mon, 14 Dec 2009 20:12:04 +0000 Subject: sh: Fix up FPU build for SH5 After the recent FPU optimisation commit the signature of save_fpu() changed. "regs" wasn't used in the implementation of save_fpu() anyway. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/cpu/sh5/fpu.c b/arch/sh/kernel/cpu/sh5/fpu.c index dd4f51f..4648cce 100644 --- a/arch/sh/kernel/cpu/sh5/fpu.c +++ b/arch/sh/kernel/cpu/sh5/fpu.c @@ -34,7 +34,7 @@ static union sh_fpu_union init_fpuregs = { } }; -void save_fpu(struct task_struct *tsk, struct pt_regs *regs) +void save_fpu(struct task_struct *tsk) { asm volatile("fst.p %0, (0*8), fp0\n\t" "fst.p %0, (1*8), fp2\n\t" @@ -153,7 +153,7 @@ do_fpu_state_restore(unsigned long ex, struct pt_regs *regs) enable_fpu(); if (last_task_used_math != NULL) /* Other processes fpu state, save away */ - save_fpu(last_task_used_math, regs); + save_fpu(last_task_used_math); last_task_used_math = current; if (used_math()) { diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index 359b8a2..31f80c6 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c @@ -404,7 +404,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) if (fpvalid) { if (current == last_task_used_math) { enable_fpu(); - save_fpu(tsk, regs); + save_fpu(tsk); disable_fpu(); last_task_used_math = 0; regs->sr |= SR_FD; @@ -431,7 +431,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, #ifdef CONFIG_SH_FPU if(last_task_used_math == current) { enable_fpu(); - save_fpu(current, regs); + save_fpu(current); disable_fpu(); last_task_used_math = NULL; regs->sr |= SR_FD; diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c index 952da83..873ebdc 100644 --- a/arch/sh/kernel/ptrace_64.c +++ b/arch/sh/kernel/ptrace_64.c @@ -82,7 +82,7 @@ get_fpu_long(struct task_struct *task, unsigned long addr) if (last_task_used_math == task) { enable_fpu(); - save_fpu(task, regs); + save_fpu(task); disable_fpu(); last_task_used_math = 0; regs->sr |= SR_FD; @@ -118,7 +118,7 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data) set_stopped_child_used_math(task); } else if (last_task_used_math == task) { enable_fpu(); - save_fpu(task, regs); + save_fpu(task); disable_fpu(); last_task_used_math = 0; regs->sr |= SR_FD; diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index feb3ddd..ce76dbd 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c @@ -314,7 +314,7 @@ setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc) if (current == last_task_used_math) { enable_fpu(); - save_fpu(current, regs); + save_fpu(current); disable_fpu(); last_task_used_math = NULL; regs->sr |= SR_FD; diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c index 75c0cbe..d86f531 100644 --- a/arch/sh/kernel/traps_64.c +++ b/arch/sh/kernel/traps_64.c @@ -600,7 +600,7 @@ static int misaligned_fpu_load(struct pt_regs *regs, indexed by register number. */ if (last_task_used_math == current) { enable_fpu(); - save_fpu(current, regs); + save_fpu(current); disable_fpu(); last_task_used_math = NULL; regs->sr |= SR_FD; @@ -673,7 +673,7 @@ static int misaligned_fpu_store(struct pt_regs *regs, indexed by register number. */ if (last_task_used_math == current) { enable_fpu(); - save_fpu(current, regs); + save_fpu(current); disable_fpu(); last_task_used_math = NULL; regs->sr |= SR_FD; -- cgit v0.10.2 From 9f815a1765b0ce766ab1d26ef192d30410f70b2b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 15 Dec 2009 00:27:57 +0000 Subject: sh: ms7724se: Add ak4642 support Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 4b0f0c0..5d0f70b 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -514,6 +514,13 @@ static struct platform_device *ms7724se_devices[] __initdata = { &sdhi1_cn8_device, }; +/* I2C device */ +static struct i2c_board_info i2c0_devices[] = { + { + I2C_BOARD_INFO("ak4642", 0x12), + }, +}; + #define EEPROM_OP 0xBA206000 #define EEPROM_ADR 0xBA206004 #define EEPROM_DATA 0xBA20600C @@ -575,6 +582,16 @@ extern char ms7724se_sdram_enter_end; extern char ms7724se_sdram_leave_start; extern char ms7724se_sdram_leave_end; + +static int __init arch_setup(void) +{ + /* enable I2C device */ + i2c_register_board_info(0, i2c0_devices, + ARRAY_SIZE(i2c0_devices)); + return 0; +} +arch_initcall(arch_setup); + static int __init devices_setup(void) { u16 sw = ctrl_inw(SW4140); /* select camera, monitor */ -- cgit v0.10.2 From 1ce4da7a502ea637748bc55460fc43eb2acc4f01 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 7 Dec 2009 14:05:45 +0000 Subject: sh: MSIOF/mmc_spi platform data for the Ecovec24 board This patch adds MSIOF and mmc_spi platform data for the CN11 port on the SuperH Ecovec24 board. No card detect interrupt is available so the MMC code is configured to poll. The WP signal is implemented together with CD and power control. The board only supports 3.3V power. The platform data is wrapped in SDHI #ifdefs to allow both the SDHI and the MSIOF to coexist. Only one configuration is allowed at a time. The pin routing is selected by a dip switch but we can unfortunately not detect this setting at run time. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 826e623..cfd958c 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -19,6 +19,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -421,6 +425,7 @@ static struct i2c_board_info ts_i2c_clients = { .irq = IRQ0, }; +#ifdef CONFIG_MFD_SH_MOBILE_SDHI /* SHDI0 */ static void sdhi0_set_pwr(struct platform_device *pdev, int state) { @@ -493,6 +498,73 @@ static struct platform_device sdhi1_device = { }, }; +#else + +static int mmc_spi_get_ro(struct device *dev) +{ + return gpio_get_value(GPIO_PTY6); +} + +static int mmc_spi_get_cd(struct device *dev) +{ + return !gpio_get_value(GPIO_PTY7); +} + +static void mmc_spi_setpower(struct device *dev, unsigned int maskval) +{ + gpio_set_value(GPIO_PTB6, maskval ? 1 : 0); +} + +static struct mmc_spi_platform_data mmc_spi_info = { + .get_ro = mmc_spi_get_ro, + .get_cd = mmc_spi_get_cd, + .caps = MMC_CAP_NEEDS_POLL, + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, /* 3.3V only */ + .setpower = mmc_spi_setpower, +}; + +static struct spi_board_info spi_bus[] = { + { + .modalias = "mmc_spi", + .platform_data = &mmc_spi_info, + .max_speed_hz = 5000000, + .mode = SPI_MODE_0, + .controller_data = (void *) GPIO_PTM4, + }, +}; + +static struct sh_msiof_spi_info msiof0_data = { + .num_chipselect = 1, +}; + +static struct resource msiof0_resources[] = { + [0] = { + .name = "MSIOF0", + .start = 0xa4c40000, + .end = 0xa4c40063, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 84, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device msiof0_device = { + .name = "spi_sh_msiof", + .id = 0, /* MSIOF0 */ + .dev = { + .platform_data = &msiof0_data, + }, + .num_resources = ARRAY_SIZE(msiof0_resources), + .resource = msiof0_resources, + .archdata = { + .hwblk_id = HWBLK_MSIOF0, + }, +}; + +#endif + static struct platform_device *ecovec_devices[] __initdata = { &heartbeat_device, &nor_flash_device, @@ -503,8 +575,12 @@ static struct platform_device *ecovec_devices[] __initdata = { &ceu0_device, &ceu1_device, &keysc_device, +#ifdef CONFIG_MFD_SH_MOBILE_SDHI &sdhi0_device, &sdhi1_device, +#else + &msiof0_device, +#endif }; #define EEPROM_ADDR 0x50 @@ -773,7 +849,8 @@ static int __init arch_setup(void) gpio_direction_input(GPIO_PTR5); gpio_direction_input(GPIO_PTR6); - /* enable SDHI0 (needs DS2.4 set to ON) */ +#ifdef CONFIG_MFD_SH_MOBILE_SDHI + /* enable SDHI0 on CN11 (needs DS2.4 set to ON) */ gpio_request(GPIO_FN_SDHI0CD, NULL); gpio_request(GPIO_FN_SDHI0WP, NULL); gpio_request(GPIO_FN_SDHI0CMD, NULL); @@ -785,7 +862,7 @@ static int __init arch_setup(void) gpio_request(GPIO_PTB6, NULL); gpio_direction_output(GPIO_PTB6, 0); - /* enable SDHI1 (needs DS2.6,7 set to ON,OFF) */ + /* enable SDHI1 on CN12 (needs DS2.6,7 set to ON,OFF) */ gpio_request(GPIO_FN_SDHI1CD, NULL); gpio_request(GPIO_FN_SDHI1WP, NULL); gpio_request(GPIO_FN_SDHI1CMD, NULL); @@ -799,6 +876,22 @@ static int __init arch_setup(void) /* I/O buffer drive ability is high for SDHI1 */ ctrl_outw((ctrl_inw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA); +#else + /* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */ + gpio_request(GPIO_FN_MSIOF0_TXD, NULL); + gpio_request(GPIO_FN_MSIOF0_RXD, NULL); + gpio_request(GPIO_FN_MSIOF0_TSCK, NULL); + gpio_request(GPIO_PTM4, NULL); /* software CS control of TSYNC pin */ + gpio_direction_output(GPIO_PTM4, 1); /* active low CS */ + gpio_request(GPIO_PTB6, NULL); /* 3.3V power control */ + gpio_direction_output(GPIO_PTB6, 0); /* disable power by default */ + gpio_request(GPIO_PTY6, NULL); /* write protect */ + gpio_direction_input(GPIO_PTY6); + gpio_request(GPIO_PTY7, NULL); /* card detect */ + gpio_direction_input(GPIO_PTY7); + + spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus)); +#endif /* enable I2C device */ i2c_register_board_info(1, i2c1_devices, -- cgit v0.10.2 From 7574aa92f9b4952c458024e1fa51f20fed65ba07 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 25 Nov 2009 00:00:19 +0000 Subject: xfs: cleanup bmap extent state macros Cleanup the extent state macros in the bmap code to use one common set of flags that we can pass to the tracing code later and remove a lot of the macro obsfucation. Signed-off-by: Christoph Hellwig Signed-off-by: Alex Elder diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 8971fb0..6154ca0 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -759,26 +759,10 @@ xfs_bmap_add_extent_delay_real( xfs_filblks_t temp=0; /* value for dnew calculations */ xfs_filblks_t temp2=0;/* value for dnew calculations */ int tmp_rval; /* partial logging flags */ - enum { /* bit number definitions for state */ - LEFT_CONTIG, RIGHT_CONTIG, - LEFT_FILLING, RIGHT_FILLING, - LEFT_DELAY, RIGHT_DELAY, - LEFT_VALID, RIGHT_VALID - }; #define LEFT r[0] #define RIGHT r[1] #define PREV r[2] -#define MASK(b) (1 << (b)) -#define MASK2(a,b) (MASK(a) | MASK(b)) -#define MASK3(a,b,c) (MASK2(a,b) | MASK(c)) -#define MASK4(a,b,c,d) (MASK3(a,b,c) | MASK(d)) -#define STATE_SET(b,v) ((v) ? (state |= MASK(b)) : (state &= ~MASK(b))) -#define STATE_TEST(b) (state & MASK(b)) -#define STATE_SET_TEST(b,v) ((v) ? ((state |= MASK(b)), 1) : \ - ((state &= ~MASK(b)), 0)) -#define SWITCH_STATE \ - (state & MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG)) /* * Set up a bunch of variables to make the tests simpler. @@ -790,56 +774,69 @@ xfs_bmap_add_extent_delay_real( new_endoff = new->br_startoff + new->br_blockcount; ASSERT(PREV.br_startoff <= new->br_startoff); ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff); + /* * Set flags determining what part of the previous delayed allocation * extent is being replaced by a real allocation. */ - STATE_SET(LEFT_FILLING, PREV.br_startoff == new->br_startoff); - STATE_SET(RIGHT_FILLING, - PREV.br_startoff + PREV.br_blockcount == new_endoff); + if (PREV.br_startoff == new->br_startoff) + state |= BMAP_LEFT_FILLING; + if (PREV.br_startoff + PREV.br_blockcount == new_endoff) + state |= BMAP_RIGHT_FILLING; + /* * Check and set flags if this segment has a left neighbor. * Don't set contiguous if the combined extent would be too large. */ - if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { + if (idx > 0) { + state |= BMAP_LEFT_VALID; xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); - STATE_SET(LEFT_DELAY, isnullstartblock(LEFT.br_startblock)); + + if (isnullstartblock(LEFT.br_startblock)) + state |= BMAP_LEFT_DELAY; } - STATE_SET(LEFT_CONTIG, - STATE_TEST(LEFT_VALID) && !STATE_TEST(LEFT_DELAY) && - LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && - LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && - LEFT.br_state == new->br_state && - LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN); + + if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) && + LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && + LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && + LEFT.br_state == new->br_state && + LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN) + state |= BMAP_LEFT_CONTIG; + /* * Check and set flags if this segment has a right neighbor. * Don't set contiguous if the combined extent would be too large. * Also check for all-three-contiguous being too large. */ - if (STATE_SET_TEST(RIGHT_VALID, - idx < - ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) { + if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { + state |= BMAP_RIGHT_VALID; xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); - STATE_SET(RIGHT_DELAY, isnullstartblock(RIGHT.br_startblock)); + + if (isnullstartblock(RIGHT.br_startblock)) + state |= BMAP_RIGHT_DELAY; } - STATE_SET(RIGHT_CONTIG, - STATE_TEST(RIGHT_VALID) && !STATE_TEST(RIGHT_DELAY) && - new_endoff == RIGHT.br_startoff && - new->br_startblock + new->br_blockcount == - RIGHT.br_startblock && - new->br_state == RIGHT.br_state && - new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN && - ((state & MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING)) != - MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING) || - LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount - <= MAXEXTLEN)); + + if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) && + new_endoff == RIGHT.br_startoff && + new->br_startblock + new->br_blockcount == RIGHT.br_startblock && + new->br_state == RIGHT.br_state && + new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN && + ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | + BMAP_RIGHT_FILLING)) != + (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | + BMAP_RIGHT_FILLING) || + LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount + <= MAXEXTLEN)) + state |= BMAP_RIGHT_CONTIG; + error = 0; /* * Switch out based on the FILLING and CONTIG state bits. */ - switch (SWITCH_STATE) { - - case MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): + switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | + BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) { + case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | + BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* * Filling in all of a previously delayed allocation extent. * The left and right neighbors are both contiguous with new. @@ -885,7 +882,7 @@ xfs_bmap_add_extent_delay_real( RIGHT.br_blockcount; break; - case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): + case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: /* * Filling in all of a previously delayed allocation extent. * The left neighbor is contiguous, the right is not. @@ -921,7 +918,7 @@ xfs_bmap_add_extent_delay_real( PREV.br_blockcount; break; - case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): + case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* * Filling in all of a previously delayed allocation extent. * The right neighbor is contiguous, the left is not. @@ -956,7 +953,7 @@ xfs_bmap_add_extent_delay_real( RIGHT.br_blockcount; break; - case MASK2(LEFT_FILLING, RIGHT_FILLING): + case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: /* * Filling in all of a previously delayed allocation extent. * Neither the left nor right neighbors are contiguous with @@ -987,7 +984,7 @@ xfs_bmap_add_extent_delay_real( temp2 = new->br_blockcount; break; - case MASK2(LEFT_FILLING, LEFT_CONTIG): + case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG: /* * Filling in the first part of a previous delayed allocation. * The left neighbor is contiguous. @@ -1029,7 +1026,7 @@ xfs_bmap_add_extent_delay_real( PREV.br_blockcount; break; - case MASK(LEFT_FILLING): + case BMAP_LEFT_FILLING: /* * Filling in the first part of a previous delayed allocation. * The left neighbor is not contiguous. @@ -1078,7 +1075,7 @@ xfs_bmap_add_extent_delay_real( temp2 = PREV.br_blockcount; break; - case MASK2(RIGHT_FILLING, RIGHT_CONTIG): + case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* * Filling in the last part of a previous delayed allocation. * The right neighbor is contiguous with the new allocation. @@ -1120,7 +1117,7 @@ xfs_bmap_add_extent_delay_real( RIGHT.br_blockcount; break; - case MASK(RIGHT_FILLING): + case BMAP_RIGHT_FILLING: /* * Filling in the last part of a previous delayed allocation. * The right neighbor is not contiguous. @@ -1253,13 +1250,13 @@ xfs_bmap_add_extent_delay_real( temp2 = PREV.br_blockcount; break; - case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): - case MASK3(RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): - case MASK2(LEFT_FILLING, RIGHT_CONTIG): - case MASK2(RIGHT_FILLING, LEFT_CONTIG): - case MASK2(LEFT_CONTIG, RIGHT_CONTIG): - case MASK(LEFT_CONTIG): - case MASK(RIGHT_CONTIG): + case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: + case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: + case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG: + case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: + case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: + case BMAP_LEFT_CONTIG: + case BMAP_RIGHT_CONTIG: /* * These cases are all impossible. */ @@ -1279,14 +1276,6 @@ done: #undef LEFT #undef RIGHT #undef PREV -#undef MASK -#undef MASK2 -#undef MASK3 -#undef MASK4 -#undef STATE_SET -#undef STATE_TEST -#undef STATE_SET_TEST -#undef SWITCH_STATE } /* @@ -1316,27 +1305,10 @@ xfs_bmap_add_extent_unwritten_real( int state = 0;/* state bits, accessed thru macros */ xfs_filblks_t temp=0; xfs_filblks_t temp2=0; - enum { /* bit number definitions for state */ - LEFT_CONTIG, RIGHT_CONTIG, - LEFT_FILLING, RIGHT_FILLING, - LEFT_DELAY, RIGHT_DELAY, - LEFT_VALID, RIGHT_VALID - }; #define LEFT r[0] #define RIGHT r[1] #define PREV r[2] -#define MASK(b) (1 << (b)) -#define MASK2(a,b) (MASK(a) | MASK(b)) -#define MASK3(a,b,c) (MASK2(a,b) | MASK(c)) -#define MASK4(a,b,c,d) (MASK3(a,b,c) | MASK(d)) -#define STATE_SET(b,v) ((v) ? (state |= MASK(b)) : (state &= ~MASK(b))) -#define STATE_TEST(b) (state & MASK(b)) -#define STATE_SET_TEST(b,v) ((v) ? ((state |= MASK(b)), 1) : \ - ((state &= ~MASK(b)), 0)) -#define SWITCH_STATE \ - (state & MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG)) - /* * Set up a bunch of variables to make the tests simpler. */ @@ -1352,55 +1324,67 @@ xfs_bmap_add_extent_unwritten_real( new_endoff = new->br_startoff + new->br_blockcount; ASSERT(PREV.br_startoff <= new->br_startoff); ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff); + /* * Set flags determining what part of the previous oldext allocation * extent is being replaced by a newext allocation. */ - STATE_SET(LEFT_FILLING, PREV.br_startoff == new->br_startoff); - STATE_SET(RIGHT_FILLING, - PREV.br_startoff + PREV.br_blockcount == new_endoff); + if (PREV.br_startoff == new->br_startoff) + state |= BMAP_LEFT_FILLING; + if (PREV.br_startoff + PREV.br_blockcount == new_endoff) + state |= BMAP_RIGHT_FILLING; + /* * Check and set flags if this segment has a left neighbor. * Don't set contiguous if the combined extent would be too large. */ - if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { + if (idx > 0) { + state |= BMAP_LEFT_VALID; xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); - STATE_SET(LEFT_DELAY, isnullstartblock(LEFT.br_startblock)); + + if (isnullstartblock(LEFT.br_startblock)) + state |= BMAP_LEFT_DELAY; } - STATE_SET(LEFT_CONTIG, - STATE_TEST(LEFT_VALID) && !STATE_TEST(LEFT_DELAY) && - LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && - LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && - LEFT.br_state == newext && - LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN); + + if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) && + LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && + LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && + LEFT.br_state == newext && + LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN) + state |= BMAP_LEFT_CONTIG; + /* * Check and set flags if this segment has a right neighbor. * Don't set contiguous if the combined extent would be too large. * Also check for all-three-contiguous being too large. */ - if (STATE_SET_TEST(RIGHT_VALID, - idx < - ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) { + if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1) { + state |= BMAP_RIGHT_VALID; xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); - STATE_SET(RIGHT_DELAY, isnullstartblock(RIGHT.br_startblock)); + if (isnullstartblock(RIGHT.br_startblock)) + state |= BMAP_RIGHT_DELAY; } - STATE_SET(RIGHT_CONTIG, - STATE_TEST(RIGHT_VALID) && !STATE_TEST(RIGHT_DELAY) && - new_endoff == RIGHT.br_startoff && - new->br_startblock + new->br_blockcount == - RIGHT.br_startblock && - newext == RIGHT.br_state && - new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN && - ((state & MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING)) != - MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING) || - LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount - <= MAXEXTLEN)); + + if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) && + new_endoff == RIGHT.br_startoff && + new->br_startblock + new->br_blockcount == RIGHT.br_startblock && + newext == RIGHT.br_state && + new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN && + ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | + BMAP_RIGHT_FILLING)) != + (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING | + BMAP_RIGHT_FILLING) || + LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount + <= MAXEXTLEN)) + state |= BMAP_RIGHT_CONTIG; + /* * Switch out based on the FILLING and CONTIG state bits. */ - switch (SWITCH_STATE) { - - case MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): + switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | + BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) { + case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | + BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* * Setting all of a previous oldext extent to newext. * The left and right neighbors are both contiguous with new. @@ -1450,7 +1434,7 @@ xfs_bmap_add_extent_unwritten_real( RIGHT.br_blockcount; break; - case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): + case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: /* * Setting all of a previous oldext extent to newext. * The left neighbor is contiguous, the right is not. @@ -1492,7 +1476,7 @@ xfs_bmap_add_extent_unwritten_real( PREV.br_blockcount; break; - case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): + case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* * Setting all of a previous oldext extent to newext. * The right neighbor is contiguous, the left is not. @@ -1535,7 +1519,7 @@ xfs_bmap_add_extent_unwritten_real( RIGHT.br_blockcount; break; - case MASK2(LEFT_FILLING, RIGHT_FILLING): + case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: /* * Setting all of a previous oldext extent to newext. * Neither the left nor right neighbors are contiguous with @@ -1566,7 +1550,7 @@ xfs_bmap_add_extent_unwritten_real( temp2 = new->br_blockcount; break; - case MASK2(LEFT_FILLING, LEFT_CONTIG): + case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG: /* * Setting the first part of a previous oldext extent to newext. * The left neighbor is contiguous. @@ -1617,7 +1601,7 @@ xfs_bmap_add_extent_unwritten_real( PREV.br_blockcount; break; - case MASK(LEFT_FILLING): + case BMAP_LEFT_FILLING: /* * Setting the first part of a previous oldext extent to newext. * The left neighbor is not contiguous. @@ -1660,7 +1644,7 @@ xfs_bmap_add_extent_unwritten_real( temp2 = PREV.br_blockcount; break; - case MASK2(RIGHT_FILLING, RIGHT_CONTIG): + case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: /* * Setting the last part of a previous oldext extent to newext. * The right neighbor is contiguous with the new allocation. @@ -1707,7 +1691,7 @@ xfs_bmap_add_extent_unwritten_real( RIGHT.br_blockcount; break; - case MASK(RIGHT_FILLING): + case BMAP_RIGHT_FILLING: /* * Setting the last part of a previous oldext extent to newext. * The right neighbor is not contiguous. @@ -1813,13 +1797,13 @@ xfs_bmap_add_extent_unwritten_real( temp2 = PREV.br_blockcount; break; - case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): - case MASK3(RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): - case MASK2(LEFT_FILLING, RIGHT_CONTIG): - case MASK2(RIGHT_FILLING, LEFT_CONTIG): - case MASK2(LEFT_CONTIG, RIGHT_CONTIG): - case MASK(LEFT_CONTIG): - case MASK(RIGHT_CONTIG): + case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: + case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: + case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG: + case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: + case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: + case BMAP_LEFT_CONTIG: + case BMAP_RIGHT_CONTIG: /* * These cases are all impossible. */ @@ -1839,14 +1823,6 @@ done: #undef LEFT #undef RIGHT #undef PREV -#undef MASK -#undef MASK2 -#undef MASK3 -#undef MASK4 -#undef STATE_SET -#undef STATE_TEST -#undef STATE_SET_TEST -#undef SWITCH_STATE } /* @@ -1872,62 +1848,57 @@ xfs_bmap_add_extent_hole_delay( int state; /* state bits, accessed thru macros */ xfs_filblks_t temp=0; /* temp for indirect calculations */ xfs_filblks_t temp2=0; - enum { /* bit number definitions for state */ - LEFT_CONTIG, RIGHT_CONTIG, - LEFT_DELAY, RIGHT_DELAY, - LEFT_VALID, RIGHT_VALID - }; - -#define MASK(b) (1 << (b)) -#define MASK2(a,b) (MASK(a) | MASK(b)) -#define STATE_SET(b,v) ((v) ? (state |= MASK(b)) : (state &= ~MASK(b))) -#define STATE_TEST(b) (state & MASK(b)) -#define STATE_SET_TEST(b,v) ((v) ? ((state |= MASK(b)), 1) : \ - ((state &= ~MASK(b)), 0)) -#define SWITCH_STATE (state & MASK2(LEFT_CONTIG, RIGHT_CONTIG)) ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); ep = xfs_iext_get_ext(ifp, idx); state = 0; ASSERT(isnullstartblock(new->br_startblock)); + /* * Check and set flags if this segment has a left neighbor */ - if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { + if (idx > 0) { + state |= BMAP_LEFT_VALID; xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); - STATE_SET(LEFT_DELAY, isnullstartblock(left.br_startblock)); + + if (isnullstartblock(left.br_startblock)) + state |= BMAP_LEFT_DELAY; } + /* * Check and set flags if the current (right) segment exists. * If it doesn't exist, we're converting the hole at end-of-file. */ - if (STATE_SET_TEST(RIGHT_VALID, - idx < - ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) { + if (idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { + state |= BMAP_RIGHT_VALID; xfs_bmbt_get_all(ep, &right); - STATE_SET(RIGHT_DELAY, isnullstartblock(right.br_startblock)); + + if (isnullstartblock(right.br_startblock)) + state |= BMAP_RIGHT_DELAY; } + /* * Set contiguity flags on the left and right neighbors. * Don't let extents get too large, even if the pieces are contiguous. */ - STATE_SET(LEFT_CONTIG, - STATE_TEST(LEFT_VALID) && STATE_TEST(LEFT_DELAY) && - left.br_startoff + left.br_blockcount == new->br_startoff && - left.br_blockcount + new->br_blockcount <= MAXEXTLEN); - STATE_SET(RIGHT_CONTIG, - STATE_TEST(RIGHT_VALID) && STATE_TEST(RIGHT_DELAY) && - new->br_startoff + new->br_blockcount == right.br_startoff && - new->br_blockcount + right.br_blockcount <= MAXEXTLEN && - (!STATE_TEST(LEFT_CONTIG) || - (left.br_blockcount + new->br_blockcount + - right.br_blockcount <= MAXEXTLEN))); + if ((state & BMAP_LEFT_VALID) && (state & BMAP_LEFT_DELAY) && + left.br_startoff + left.br_blockcount == new->br_startoff && + left.br_blockcount + new->br_blockcount <= MAXEXTLEN) + state |= BMAP_LEFT_CONTIG; + + if ((state & BMAP_RIGHT_VALID) && (state & BMAP_RIGHT_DELAY) && + new->br_startoff + new->br_blockcount == right.br_startoff && + new->br_blockcount + right.br_blockcount <= MAXEXTLEN && + (!(state & BMAP_LEFT_CONTIG) || + (left.br_blockcount + new->br_blockcount + + right.br_blockcount <= MAXEXTLEN))) + state |= BMAP_RIGHT_CONTIG; + /* * Switch out based on the contiguity flags. */ - switch (SWITCH_STATE) { - - case MASK2(LEFT_CONTIG, RIGHT_CONTIG): + switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) { + case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: /* * New allocation is contiguous with delayed allocations * on the left and on the right. @@ -1954,7 +1925,7 @@ xfs_bmap_add_extent_hole_delay( temp = left.br_startoff; break; - case MASK(LEFT_CONTIG): + case BMAP_LEFT_CONTIG: /* * New allocation is contiguous with a delayed allocation * on the left. @@ -1977,7 +1948,7 @@ xfs_bmap_add_extent_hole_delay( temp = left.br_startoff; break; - case MASK(RIGHT_CONTIG): + case BMAP_RIGHT_CONTIG: /* * New allocation is contiguous with a delayed allocation * on the right. @@ -2030,12 +2001,6 @@ xfs_bmap_add_extent_hole_delay( } *logflagsp = 0; return 0; -#undef MASK -#undef MASK2 -#undef STATE_SET -#undef STATE_TEST -#undef STATE_SET_TEST -#undef SWITCH_STATE } /* @@ -2062,69 +2027,60 @@ xfs_bmap_add_extent_hole_real( int state; /* state bits, accessed thru macros */ xfs_filblks_t temp=0; xfs_filblks_t temp2=0; - enum { /* bit number definitions for state */ - LEFT_CONTIG, RIGHT_CONTIG, - LEFT_DELAY, RIGHT_DELAY, - LEFT_VALID, RIGHT_VALID - }; - -#define MASK(b) (1 << (b)) -#define MASK2(a,b) (MASK(a) | MASK(b)) -#define STATE_SET(b,v) ((v) ? (state |= MASK(b)) : (state &= ~MASK(b))) -#define STATE_TEST(b) (state & MASK(b)) -#define STATE_SET_TEST(b,v) ((v) ? ((state |= MASK(b)), 1) : \ - ((state &= ~MASK(b)), 0)) -#define SWITCH_STATE (state & MASK2(LEFT_CONTIG, RIGHT_CONTIG)) ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); ep = xfs_iext_get_ext(ifp, idx); state = 0; + /* * Check and set flags if this segment has a left neighbor. */ - if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { + if (idx > 0) { + state |= BMAP_LEFT_VALID; xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); - STATE_SET(LEFT_DELAY, isnullstartblock(left.br_startblock)); + if (isnullstartblock(left.br_startblock)) + state |= BMAP_LEFT_DELAY; } + /* * Check and set flags if this segment has a current value. * Not true if we're inserting into the "hole" at eof. */ - if (STATE_SET_TEST(RIGHT_VALID, - idx < - ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) { + if (idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)) { + state |= BMAP_RIGHT_VALID; xfs_bmbt_get_all(ep, &right); - STATE_SET(RIGHT_DELAY, isnullstartblock(right.br_startblock)); + if (isnullstartblock(right.br_startblock)) + state |= BMAP_RIGHT_DELAY; } + /* * We're inserting a real allocation between "left" and "right". * Set the contiguity flags. Don't let extents get too large. */ - STATE_SET(LEFT_CONTIG, - STATE_TEST(LEFT_VALID) && !STATE_TEST(LEFT_DELAY) && - left.br_startoff + left.br_blockcount == new->br_startoff && - left.br_startblock + left.br_blockcount == new->br_startblock && - left.br_state == new->br_state && - left.br_blockcount + new->br_blockcount <= MAXEXTLEN); - STATE_SET(RIGHT_CONTIG, - STATE_TEST(RIGHT_VALID) && !STATE_TEST(RIGHT_DELAY) && - new->br_startoff + new->br_blockcount == right.br_startoff && - new->br_startblock + new->br_blockcount == - right.br_startblock && - new->br_state == right.br_state && - new->br_blockcount + right.br_blockcount <= MAXEXTLEN && - (!STATE_TEST(LEFT_CONTIG) || - left.br_blockcount + new->br_blockcount + - right.br_blockcount <= MAXEXTLEN)); + if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) && + left.br_startoff + left.br_blockcount == new->br_startoff && + left.br_startblock + left.br_blockcount == new->br_startblock && + left.br_state == new->br_state && + left.br_blockcount + new->br_blockcount <= MAXEXTLEN) + state |= BMAP_LEFT_CONTIG; + + if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) && + new->br_startoff + new->br_blockcount == right.br_startoff && + new->br_startblock + new->br_blockcount == right.br_startblock && + new->br_state == right.br_state && + new->br_blockcount + right.br_blockcount <= MAXEXTLEN && + (!(state & BMAP_LEFT_CONTIG) || + left.br_blockcount + new->br_blockcount + + right.br_blockcount <= MAXEXTLEN)) + state |= BMAP_RIGHT_CONTIG; error = 0; /* * Select which case we're in here, and implement it. */ - switch (SWITCH_STATE) { - - case MASK2(LEFT_CONTIG, RIGHT_CONTIG): + switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) { + case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: /* * New allocation is contiguous with real allocations on the * left and on the right. @@ -2173,7 +2129,7 @@ xfs_bmap_add_extent_hole_real( right.br_blockcount; break; - case MASK(LEFT_CONTIG): + case BMAP_LEFT_CONTIG: /* * New allocation is contiguous with a real allocation * on the left. @@ -2207,7 +2163,7 @@ xfs_bmap_add_extent_hole_real( new->br_blockcount; break; - case MASK(RIGHT_CONTIG): + case BMAP_RIGHT_CONTIG: /* * New allocation is contiguous with a real allocation * on the right. @@ -2283,12 +2239,6 @@ xfs_bmap_add_extent_hole_real( done: *logflagsp = rval; return error; -#undef MASK -#undef MASK2 -#undef STATE_SET -#undef STATE_TEST -#undef STATE_SET_TEST -#undef SWITCH_STATE } /* diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index 56f62d2..f1ae5a1 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h @@ -135,6 +135,18 @@ typedef struct xfs_bmalloca { char conv; /* overwriting unwritten extents */ } xfs_bmalloca_t; +/* + * Flags for xfs_bmap_add_extent*. + */ +#define BMAP_LEFT_CONTIG (1 << 0) +#define BMAP_RIGHT_CONTIG (1 << 1) +#define BMAP_LEFT_FILLING (1 << 2) +#define BMAP_RIGHT_FILLING (1 << 3) +#define BMAP_LEFT_DELAY (1 << 4) +#define BMAP_RIGHT_DELAY (1 << 5) +#define BMAP_LEFT_VALID (1 << 6) +#define BMAP_RIGHT_VALID (1 << 7) + #if defined(__KERNEL__) && defined(XFS_BMAP_TRACE) /* * Trace operations for bmap extent tracing -- cgit v0.10.2 From 6ef3554422e2c7e7aa424ba63737da498881dff4 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 25 Nov 2009 00:00:21 +0000 Subject: xfs: change the xfs_iext_insert / xfs_iext_remove Change the xfs_iext_insert / xfs_iext_remove prototypes to pass more information which will allow pushing the trace points from the callers into those functions. This includes folding the whichfork information into the state variable to minimize the addition stack footprint. Signed-off-by: Christoph Hellwig Signed-off-by: Alex Elder diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 6154ca0..5874098 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -592,7 +592,9 @@ xfs_bmap_add_extent( if (nextents == 0) { XFS_BMAP_TRACE_INSERT("insert empty", ip, 0, 1, new, NULL, whichfork); - xfs_iext_insert(ifp, 0, 1, new); + xfs_iext_insert(ip, 0, 1, new, + whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); + ASSERT(cur == NULL); ifp->if_lastex = 0; if (!isnullstartblock(new->br_startblock)) { @@ -849,7 +851,7 @@ xfs_bmap_add_extent_delay_real( XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC|RC", ip, idx - 1, XFS_DATA_FORK); XFS_BMAP_TRACE_DELETE("LF|RF|LC|RC", ip, idx, 2, XFS_DATA_FORK); - xfs_iext_remove(ifp, idx, 2); + xfs_iext_remove(ip, idx, 2, state); ip->i_df.if_lastex = idx - 1; ip->i_d.di_nextents--; if (cur == NULL) @@ -895,7 +897,7 @@ xfs_bmap_add_extent_delay_real( XFS_DATA_FORK); ip->i_df.if_lastex = idx - 1; XFS_BMAP_TRACE_DELETE("LF|RF|LC", ip, idx, 1, XFS_DATA_FORK); - xfs_iext_remove(ifp, idx, 1); + xfs_iext_remove(ip, idx, 1, state); if (cur == NULL) rval = XFS_ILOG_DEXT; else { @@ -930,7 +932,7 @@ xfs_bmap_add_extent_delay_real( XFS_BMAP_TRACE_POST_UPDATE("LF|RF|RC", ip, idx, XFS_DATA_FORK); ip->i_df.if_lastex = idx; XFS_BMAP_TRACE_DELETE("LF|RF|RC", ip, idx + 1, 1, XFS_DATA_FORK); - xfs_iext_remove(ifp, idx + 1, 1); + xfs_iext_remove(ip, idx + 1, 1, state); if (cur == NULL) rval = XFS_ILOG_DEXT; else { @@ -1037,7 +1039,7 @@ xfs_bmap_add_extent_delay_real( xfs_bmbt_set_blockcount(ep, temp); XFS_BMAP_TRACE_INSERT("LF", ip, idx, 1, new, NULL, XFS_DATA_FORK); - xfs_iext_insert(ifp, idx, 1, new); + xfs_iext_insert(ip, idx, 1, new, state); ip->i_df.if_lastex = idx; ip->i_d.di_nextents++; if (cur == NULL) @@ -1127,7 +1129,7 @@ xfs_bmap_add_extent_delay_real( xfs_bmbt_set_blockcount(ep, temp); XFS_BMAP_TRACE_INSERT("RF", ip, idx + 1, 1, new, NULL, XFS_DATA_FORK); - xfs_iext_insert(ifp, idx + 1, 1, new); + xfs_iext_insert(ip, idx + 1, 1, new, state); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents++; if (cur == NULL) @@ -1182,7 +1184,7 @@ xfs_bmap_add_extent_delay_real( r[1].br_blockcount = temp2; XFS_BMAP_TRACE_INSERT("0", ip, idx + 1, 2, &r[0], &r[1], XFS_DATA_FORK); - xfs_iext_insert(ifp, idx + 1, 2, &r[0]); + xfs_iext_insert(ip, idx + 1, 2, &r[0], state); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents++; if (cur == NULL) @@ -1397,7 +1399,7 @@ xfs_bmap_add_extent_unwritten_real( XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC|RC", ip, idx - 1, XFS_DATA_FORK); XFS_BMAP_TRACE_DELETE("LF|RF|LC|RC", ip, idx, 2, XFS_DATA_FORK); - xfs_iext_remove(ifp, idx, 2); + xfs_iext_remove(ip, idx, 2, state); ip->i_df.if_lastex = idx - 1; ip->i_d.di_nextents -= 2; if (cur == NULL) @@ -1447,7 +1449,7 @@ xfs_bmap_add_extent_unwritten_real( XFS_DATA_FORK); ip->i_df.if_lastex = idx - 1; XFS_BMAP_TRACE_DELETE("LF|RF|LC", ip, idx, 1, XFS_DATA_FORK); - xfs_iext_remove(ifp, idx, 1); + xfs_iext_remove(ip, idx, 1, state); ip->i_d.di_nextents--; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; @@ -1490,7 +1492,7 @@ xfs_bmap_add_extent_unwritten_real( XFS_DATA_FORK); ip->i_df.if_lastex = idx; XFS_BMAP_TRACE_DELETE("LF|RF|RC", ip, idx + 1, 1, XFS_DATA_FORK); - xfs_iext_remove(ifp, idx + 1, 1); + xfs_iext_remove(ip, idx + 1, 1, state); ip->i_d.di_nextents--; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; @@ -1616,7 +1618,7 @@ xfs_bmap_add_extent_unwritten_real( XFS_BMAP_TRACE_POST_UPDATE("LF", ip, idx, XFS_DATA_FORK); XFS_BMAP_TRACE_INSERT("LF", ip, idx, 1, new, NULL, XFS_DATA_FORK); - xfs_iext_insert(ifp, idx, 1, new); + xfs_iext_insert(ip, idx, 1, new, state); ip->i_df.if_lastex = idx; ip->i_d.di_nextents++; if (cur == NULL) @@ -1702,7 +1704,7 @@ xfs_bmap_add_extent_unwritten_real( XFS_BMAP_TRACE_POST_UPDATE("RF", ip, idx, XFS_DATA_FORK); XFS_BMAP_TRACE_INSERT("RF", ip, idx + 1, 1, new, NULL, XFS_DATA_FORK); - xfs_iext_insert(ifp, idx + 1, 1, new); + xfs_iext_insert(ip, idx + 1, 1, new, state); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents++; if (cur == NULL) @@ -1752,7 +1754,7 @@ xfs_bmap_add_extent_unwritten_real( r[1].br_state = oldext; XFS_BMAP_TRACE_INSERT("0", ip, idx + 1, 2, &r[0], &r[1], XFS_DATA_FORK); - xfs_iext_insert(ifp, idx + 1, 2, &r[0]); + xfs_iext_insert(ip, idx + 1, 2, &r[0], state); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents += 2; if (cur == NULL) @@ -1918,7 +1920,7 @@ xfs_bmap_add_extent_hole_delay( XFS_BMAP_TRACE_POST_UPDATE("LC|RC", ip, idx - 1, XFS_DATA_FORK); XFS_BMAP_TRACE_DELETE("LC|RC", ip, idx, 1, XFS_DATA_FORK); - xfs_iext_remove(ifp, idx, 1); + xfs_iext_remove(ip, idx, 1, state); ip->i_df.if_lastex = idx - 1; /* DELTA: Two in-core extents were replaced by one. */ temp2 = temp; @@ -1977,7 +1979,7 @@ xfs_bmap_add_extent_hole_delay( oldlen = newlen = 0; XFS_BMAP_TRACE_INSERT("0", ip, idx, 1, new, NULL, XFS_DATA_FORK); - xfs_iext_insert(ifp, idx, 1, new); + xfs_iext_insert(ip, idx, 1, new, state); ip->i_df.if_lastex = idx; /* DELTA: A new in-core extent was added in a hole. */ temp2 = new->br_blockcount; @@ -2033,6 +2035,9 @@ xfs_bmap_add_extent_hole_real( ep = xfs_iext_get_ext(ifp, idx); state = 0; + if (whichfork == XFS_ATTR_FORK) + state |= BMAP_ATTRFORK; + /* * Check and set flags if this segment has a left neighbor. */ @@ -2094,7 +2099,7 @@ xfs_bmap_add_extent_hole_real( XFS_BMAP_TRACE_POST_UPDATE("LC|RC", ip, idx - 1, whichfork); XFS_BMAP_TRACE_DELETE("LC|RC", ip, idx, 1, whichfork); - xfs_iext_remove(ifp, idx, 1); + xfs_iext_remove(ip, idx, 1, state); ifp->if_lastex = idx - 1; XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) - 1); @@ -2205,7 +2210,7 @@ xfs_bmap_add_extent_hole_real( * Insert a new entry. */ XFS_BMAP_TRACE_INSERT("0", ip, idx, 1, new, NULL, whichfork); - xfs_iext_insert(ifp, idx, 1, new); + xfs_iext_insert(ip, idx, 1, new, state); ifp->if_lastex = idx; XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) + 1); @@ -3147,7 +3152,8 @@ xfs_bmap_del_extent( * Matches the whole extent. Delete the entry. */ XFS_BMAP_TRACE_DELETE("3", ip, idx, 1, whichfork); - xfs_iext_remove(ifp, idx, 1); + xfs_iext_remove(ip, idx, 1, + whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); ifp->if_lastex = idx; if (delay) break; @@ -3317,7 +3323,8 @@ xfs_bmap_del_extent( XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx, whichfork); XFS_BMAP_TRACE_INSERT("0", ip, idx + 1, 1, &new, NULL, whichfork); - xfs_iext_insert(ifp, idx + 1, 1, &new); + xfs_iext_insert(ip, idx + 1, 1, &new, + whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); ifp->if_lastex = idx + 1; break; } diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index f1ae5a1..3e84e8e 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h @@ -146,6 +146,7 @@ typedef struct xfs_bmalloca { #define BMAP_RIGHT_DELAY (1 << 5) #define BMAP_LEFT_VALID (1 << 6) #define BMAP_RIGHT_VALID (1 << 7) +#define BMAP_ATTRFORK (1 << 8) #if defined(__KERNEL__) && defined(XFS_BMAP_TRACE) /* diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index b92a4fa..614acd5 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3300,11 +3300,13 @@ xfs_iext_get_ext( */ void xfs_iext_insert( - xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* starting index of new items */ xfs_extnum_t count, /* number of inserted items */ - xfs_bmbt_irec_t *new) /* items to insert */ + xfs_bmbt_irec_t *new, /* items to insert */ + int state) /* type of extent conversion */ { + xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df; xfs_extnum_t i; /* extent record index */ ASSERT(ifp->if_flags & XFS_IFEXTENTS); @@ -3549,10 +3551,12 @@ xfs_iext_add_indirect_multi( */ void xfs_iext_remove( - xfs_ifork_t *ifp, /* inode fork pointer */ + xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t idx, /* index to begin removing exts */ - int ext_diff) /* number of extents to remove */ + int ext_diff, /* number of extents to remove */ + int state) /* type of extent conversion */ { + xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df; xfs_extnum_t nextents; /* number of extents in file */ int new_size; /* size of extents after removal */ diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 41555de..946a8ca 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -577,11 +577,11 @@ int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int); int xfs_iextents_copy(struct xfs_inode *, xfs_bmbt_rec_t *, int); xfs_bmbt_rec_host_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t); -void xfs_iext_insert(xfs_ifork_t *, xfs_extnum_t, xfs_extnum_t, - xfs_bmbt_irec_t *); +void xfs_iext_insert(xfs_inode_t *, xfs_extnum_t, xfs_extnum_t, + xfs_bmbt_irec_t *, int); void xfs_iext_add(xfs_ifork_t *, xfs_extnum_t, int); void xfs_iext_add_indirect_multi(xfs_ifork_t *, int, xfs_extnum_t, int); -void xfs_iext_remove(xfs_ifork_t *, xfs_extnum_t, int); +void xfs_iext_remove(xfs_inode_t *, xfs_extnum_t, int, int); void xfs_iext_remove_inline(xfs_ifork_t *, xfs_extnum_t, int); void xfs_iext_remove_direct(xfs_ifork_t *, xfs_extnum_t, int); void xfs_iext_remove_indirect(xfs_ifork_t *, xfs_extnum_t, int); -- cgit v0.10.2 From 0b1b213fcf3a8486ada99a2bab84ab8c6f51b264 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 14 Dec 2009 23:14:59 +0000 Subject: xfs: event tracing support Convert the old xfs tracing support that could only be used with the out of tree kdb and xfsidbg patches to use the generic event tracer. To use it make sure CONFIG_EVENT_TRACING is enabled and then enable all xfs trace channels by: echo 1 > /sys/kernel/debug/tracing/events/xfs/enable or alternatively enable single events by just doing the same in one event subdirectory, e.g. echo 1 > /sys/kernel/debug/tracing/events/xfs/xfs_ihold/enable or set more complex filters, etc. In Documentation/trace/events.txt all this is desctribed in more detail. To reads the events do a cat /sys/kernel/debug/tracing/trace Compared to the last posting this patch converts the tracing mostly to the one tracepoint per callsite model that other users of the new tracing facility also employ. This allows a very fine-grained control of the tracing, a cleaner output of the traces and also enables the perf tool to use each tracepoint as a virtual performance counter, allowing us to e.g. count how often certain workloads git various spots in XFS. Take a look at http://lwn.net/Articles/346470/ for some examples. Also the btree tracing isn't included at all yet, as it will require additional core tracing features not in mainline yet, I plan to deliver it later. And the really nice thing about this patch is that it actually removes many lines of code while adding this nice functionality: fs/xfs/Makefile | 8 fs/xfs/linux-2.6/xfs_acl.c | 1 fs/xfs/linux-2.6/xfs_aops.c | 52 - fs/xfs/linux-2.6/xfs_aops.h | 2 fs/xfs/linux-2.6/xfs_buf.c | 117 +-- fs/xfs/linux-2.6/xfs_buf.h | 33 fs/xfs/linux-2.6/xfs_fs_subr.c | 3 fs/xfs/linux-2.6/xfs_ioctl.c | 1 fs/xfs/linux-2.6/xfs_ioctl32.c | 1 fs/xfs/linux-2.6/xfs_iops.c | 1 fs/xfs/linux-2.6/xfs_linux.h | 1 fs/xfs/linux-2.6/xfs_lrw.c | 87 -- fs/xfs/linux-2.6/xfs_lrw.h | 45 - fs/xfs/linux-2.6/xfs_super.c | 104 --- fs/xfs/linux-2.6/xfs_super.h | 7 fs/xfs/linux-2.6/xfs_sync.c | 1 fs/xfs/linux-2.6/xfs_trace.c | 75 ++ fs/xfs/linux-2.6/xfs_trace.h | 1369 +++++++++++++++++++++++++++++++++++++++++ fs/xfs/linux-2.6/xfs_vnode.h | 4 fs/xfs/quota/xfs_dquot.c | 110 --- fs/xfs/quota/xfs_dquot.h | 21 fs/xfs/quota/xfs_qm.c | 40 - fs/xfs/quota/xfs_qm_syscalls.c | 4 fs/xfs/support/ktrace.c | 323 --------- fs/xfs/support/ktrace.h | 85 -- fs/xfs/xfs.h | 16 fs/xfs/xfs_ag.h | 14 fs/xfs/xfs_alloc.c | 230 +----- fs/xfs/xfs_alloc.h | 27 fs/xfs/xfs_alloc_btree.c | 1 fs/xfs/xfs_attr.c | 107 --- fs/xfs/xfs_attr.h | 10 fs/xfs/xfs_attr_leaf.c | 14 fs/xfs/xfs_attr_sf.h | 40 - fs/xfs/xfs_bmap.c | 507 +++------------ fs/xfs/xfs_bmap.h | 49 - fs/xfs/xfs_bmap_btree.c | 6 fs/xfs/xfs_btree.c | 5 fs/xfs/xfs_btree_trace.h | 17 fs/xfs/xfs_buf_item.c | 87 -- fs/xfs/xfs_buf_item.h | 20 fs/xfs/xfs_da_btree.c | 3 fs/xfs/xfs_da_btree.h | 7 fs/xfs/xfs_dfrag.c | 2 fs/xfs/xfs_dir2.c | 8 fs/xfs/xfs_dir2_block.c | 20 fs/xfs/xfs_dir2_leaf.c | 21 fs/xfs/xfs_dir2_node.c | 27 fs/xfs/xfs_dir2_sf.c | 26 fs/xfs/xfs_dir2_trace.c | 216 ------ fs/xfs/xfs_dir2_trace.h | 72 -- fs/xfs/xfs_filestream.c | 8 fs/xfs/xfs_fsops.c | 2 fs/xfs/xfs_iget.c | 111 --- fs/xfs/xfs_inode.c | 67 -- fs/xfs/xfs_inode.h | 76 -- fs/xfs/xfs_inode_item.c | 5 fs/xfs/xfs_iomap.c | 85 -- fs/xfs/xfs_iomap.h | 8 fs/xfs/xfs_log.c | 181 +---- fs/xfs/xfs_log_priv.h | 20 fs/xfs/xfs_log_recover.c | 1 fs/xfs/xfs_mount.c | 2 fs/xfs/xfs_quota.h | 8 fs/xfs/xfs_rename.c | 1 fs/xfs/xfs_rtalloc.c | 1 fs/xfs/xfs_rw.c | 3 fs/xfs/xfs_trans.h | 47 + fs/xfs/xfs_trans_buf.c | 62 - fs/xfs/xfs_vnodeops.c | 8 70 files changed, 2151 insertions(+), 2592 deletions(-) Signed-off-by: Christoph Hellwig Signed-off-by: Alex Elder diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 7a59dae..56641fe 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -26,6 +26,8 @@ endif obj-$(CONFIG_XFS_FS) += xfs.o +xfs-y += linux-2.6/xfs_trace.o + xfs-$(CONFIG_XFS_QUOTA) += $(addprefix quota/, \ xfs_dquot.o \ xfs_dquot_item.o \ @@ -90,8 +92,7 @@ xfs-y += xfs_alloc.o \ xfs_rw.o \ xfs_dmops.o -xfs-$(CONFIG_XFS_TRACE) += xfs_btree_trace.o \ - xfs_dir2_trace.o +xfs-$(CONFIG_XFS_TRACE) += xfs_btree_trace.o # Objects in linux/ xfs-y += $(addprefix $(XFS_LINUX)/, \ @@ -113,6 +114,3 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \ xfs-y += $(addprefix support/, \ debug.o \ uuid.o) - -xfs-$(CONFIG_XFS_TRACE) += support/ktrace.o - diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c index b23a545..69e598b 100644 --- a/fs/xfs/linux-2.6/xfs_acl.c +++ b/fs/xfs/linux-2.6/xfs_acl.c @@ -21,6 +21,7 @@ #include "xfs_bmap_btree.h" #include "xfs_inode.h" #include "xfs_vnodeops.h" +#include "xfs_trace.h" #include #include diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 87813e4..d798c54 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -38,6 +38,7 @@ #include "xfs_rw.h" #include "xfs_iomap.h" #include "xfs_vnodeops.h" +#include "xfs_trace.h" #include #include #include @@ -76,7 +77,7 @@ xfs_ioend_wake( wake_up(to_ioend_wq(ip)); } -STATIC void +void xfs_count_page_state( struct page *page, int *delalloc, @@ -98,48 +99,6 @@ xfs_count_page_state( } while ((bh = bh->b_this_page) != head); } -#if defined(XFS_RW_TRACE) -void -xfs_page_trace( - int tag, - struct inode *inode, - struct page *page, - unsigned long pgoff) -{ - xfs_inode_t *ip; - loff_t isize = i_size_read(inode); - loff_t offset = page_offset(page); - int delalloc = -1, unmapped = -1, unwritten = -1; - - if (page_has_buffers(page)) - xfs_count_page_state(page, &delalloc, &unmapped, &unwritten); - - ip = XFS_I(inode); - if (!ip->i_rwtrace) - return; - - ktrace_enter(ip->i_rwtrace, - (void *)((unsigned long)tag), - (void *)ip, - (void *)inode, - (void *)page, - (void *)pgoff, - (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)), - (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)), - (void *)((unsigned long)((isize >> 32) & 0xffffffff)), - (void *)((unsigned long)(isize & 0xffffffff)), - (void *)((unsigned long)((offset >> 32) & 0xffffffff)), - (void *)((unsigned long)(offset & 0xffffffff)), - (void *)((unsigned long)delalloc), - (void *)((unsigned long)unmapped), - (void *)((unsigned long)unwritten), - (void *)((unsigned long)current_pid()), - (void *)NULL); -} -#else -#define xfs_page_trace(tag, inode, page, pgoff) -#endif - STATIC struct block_device * xfs_find_bdev_for_inode( struct xfs_inode *ip) @@ -1202,7 +1161,7 @@ xfs_vm_writepage( int delalloc, unmapped, unwritten; struct inode *inode = page->mapping->host; - xfs_page_trace(XFS_WRITEPAGE_ENTER, inode, page, 0); + trace_xfs_writepage(inode, page, 0); /* * We need a transaction if: @@ -1307,7 +1266,7 @@ xfs_vm_releasepage( .nr_to_write = 1, }; - xfs_page_trace(XFS_RELEASEPAGE_ENTER, inode, page, 0); + trace_xfs_releasepage(inode, page, 0); if (!page_has_buffers(page)) return 0; @@ -1587,8 +1546,7 @@ xfs_vm_invalidatepage( struct page *page, unsigned long offset) { - xfs_page_trace(XFS_INVALIDPAGE_ENTER, - page->mapping->host, page, offset); + trace_xfs_invalidatepage(page->mapping->host, page, offset); block_invalidatepage(page, offset); } diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h index 221b3e6..4cfc6ea 100644 --- a/fs/xfs/linux-2.6/xfs_aops.h +++ b/fs/xfs/linux-2.6/xfs_aops.h @@ -45,4 +45,6 @@ extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int); extern void xfs_ioend_init(void); extern void xfs_ioend_wait(struct xfs_inode *); +extern void xfs_count_page_state(struct page *, int *, int *, int *); + #endif /* __XFS_AOPS_H__ */ diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 4ddc973..b4c7d42 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -39,6 +39,7 @@ #include "xfs_ag.h" #include "xfs_dmapi.h" #include "xfs_mount.h" +#include "xfs_trace.h" static kmem_zone_t *xfs_buf_zone; STATIC int xfsbufd(void *); @@ -53,34 +54,6 @@ static struct workqueue_struct *xfslogd_workqueue; struct workqueue_struct *xfsdatad_workqueue; struct workqueue_struct *xfsconvertd_workqueue; -#ifdef XFS_BUF_TRACE -void -xfs_buf_trace( - xfs_buf_t *bp, - char *id, - void *data, - void *ra) -{ - ktrace_enter(xfs_buf_trace_buf, - bp, id, - (void *)(unsigned long)bp->b_flags, - (void *)(unsigned long)bp->b_hold.counter, - (void *)(unsigned long)bp->b_sema.count, - (void *)current, - data, ra, - (void *)(unsigned long)((bp->b_file_offset>>32) & 0xffffffff), - (void *)(unsigned long)(bp->b_file_offset & 0xffffffff), - (void *)(unsigned long)bp->b_buffer_length, - NULL, NULL, NULL, NULL, NULL); -} -ktrace_t *xfs_buf_trace_buf; -#define XFS_BUF_TRACE_SIZE 4096 -#define XB_TRACE(bp, id, data) \ - xfs_buf_trace(bp, id, (void *)data, (void *)__builtin_return_address(0)) -#else -#define XB_TRACE(bp, id, data) do { } while (0) -#endif - #ifdef XFS_BUF_LOCK_TRACKING # define XB_SET_OWNER(bp) ((bp)->b_last_holder = current->pid) # define XB_CLEAR_OWNER(bp) ((bp)->b_last_holder = -1) @@ -279,7 +252,8 @@ _xfs_buf_initialize( init_waitqueue_head(&bp->b_waiters); XFS_STATS_INC(xb_create); - XB_TRACE(bp, "initialize", target); + + trace_xfs_buf_init(bp, _RET_IP_); } /* @@ -332,7 +306,7 @@ void xfs_buf_free( xfs_buf_t *bp) { - XB_TRACE(bp, "free", 0); + trace_xfs_buf_free(bp, _RET_IP_); ASSERT(list_empty(&bp->b_hash_list)); @@ -445,7 +419,6 @@ _xfs_buf_lookup_pages( if (page_count == bp->b_page_count) bp->b_flags |= XBF_DONE; - XB_TRACE(bp, "lookup_pages", (long)page_count); return error; } @@ -548,7 +521,6 @@ found: if (down_trylock(&bp->b_sema)) { if (!(flags & XBF_TRYLOCK)) { /* wait for buffer ownership */ - XB_TRACE(bp, "get_lock", 0); xfs_buf_lock(bp); XFS_STATS_INC(xb_get_locked_waited); } else { @@ -571,7 +543,8 @@ found: ASSERT((bp->b_flags & _XBF_DELWRI_Q) == 0); bp->b_flags &= XBF_MAPPED; } - XB_TRACE(bp, "got_lock", 0); + + trace_xfs_buf_find(bp, flags, _RET_IP_); XFS_STATS_INC(xb_get_locked); return bp; } @@ -627,7 +600,7 @@ xfs_buf_get( bp->b_bn = ioff; bp->b_count_desired = bp->b_buffer_length; - XB_TRACE(bp, "get", (unsigned long)flags); + trace_xfs_buf_get(bp, flags, _RET_IP_); return bp; no_buffer: @@ -644,8 +617,6 @@ _xfs_buf_read( { int status; - XB_TRACE(bp, "_xfs_buf_read", (unsigned long)flags); - ASSERT(!(flags & (XBF_DELWRI|XBF_WRITE))); ASSERT(bp->b_bn != XFS_BUF_DADDR_NULL); @@ -673,19 +644,18 @@ xfs_buf_read( bp = xfs_buf_get(target, ioff, isize, flags); if (bp) { + trace_xfs_buf_read(bp, flags, _RET_IP_); + if (!XFS_BUF_ISDONE(bp)) { - XB_TRACE(bp, "read", (unsigned long)flags); XFS_STATS_INC(xb_get_read); _xfs_buf_read(bp, flags); } else if (flags & XBF_ASYNC) { - XB_TRACE(bp, "read_async", (unsigned long)flags); /* * Read ahead call which is already satisfied, * drop the buffer */ goto no_buffer; } else { - XB_TRACE(bp, "read_done", (unsigned long)flags); /* We do not want read in the flags */ bp->b_flags &= ~XBF_READ; } @@ -823,7 +793,7 @@ xfs_buf_get_noaddr( xfs_buf_unlock(bp); - XB_TRACE(bp, "no_daddr", len); + trace_xfs_buf_get_noaddr(bp, _RET_IP_); return bp; fail_free_mem: @@ -845,8 +815,8 @@ void xfs_buf_hold( xfs_buf_t *bp) { + trace_xfs_buf_hold(bp, _RET_IP_); atomic_inc(&bp->b_hold); - XB_TRACE(bp, "hold", 0); } /* @@ -859,7 +829,7 @@ xfs_buf_rele( { xfs_bufhash_t *hash = bp->b_hash; - XB_TRACE(bp, "rele", bp->b_relse); + trace_xfs_buf_rele(bp, _RET_IP_); if (unlikely(!hash)) { ASSERT(!bp->b_relse); @@ -909,21 +879,19 @@ xfs_buf_cond_lock( int locked; locked = down_trylock(&bp->b_sema) == 0; - if (locked) { + if (locked) XB_SET_OWNER(bp); - } - XB_TRACE(bp, "cond_lock", (long)locked); + + trace_xfs_buf_cond_lock(bp, _RET_IP_); return locked ? 0 : -EBUSY; } -#if defined(DEBUG) || defined(XFS_BLI_TRACE) int xfs_buf_lock_value( xfs_buf_t *bp) { return bp->b_sema.count; } -#endif /* * Locks a buffer object. @@ -935,12 +903,14 @@ void xfs_buf_lock( xfs_buf_t *bp) { - XB_TRACE(bp, "lock", 0); + trace_xfs_buf_lock(bp, _RET_IP_); + if (atomic_read(&bp->b_io_remaining)) blk_run_address_space(bp->b_target->bt_mapping); down(&bp->b_sema); XB_SET_OWNER(bp); - XB_TRACE(bp, "locked", 0); + + trace_xfs_buf_lock_done(bp, _RET_IP_); } /* @@ -962,7 +932,8 @@ xfs_buf_unlock( XB_CLEAR_OWNER(bp); up(&bp->b_sema); - XB_TRACE(bp, "unlock", 0); + + trace_xfs_buf_unlock(bp, _RET_IP_); } @@ -974,17 +945,18 @@ void xfs_buf_pin( xfs_buf_t *bp) { + trace_xfs_buf_pin(bp, _RET_IP_); atomic_inc(&bp->b_pin_count); - XB_TRACE(bp, "pin", (long)bp->b_pin_count.counter); } void xfs_buf_unpin( xfs_buf_t *bp) { + trace_xfs_buf_unpin(bp, _RET_IP_); + if (atomic_dec_and_test(&bp->b_pin_count)) wake_up_all(&bp->b_waiters); - XB_TRACE(bp, "unpin", (long)bp->b_pin_count.counter); } int @@ -1035,7 +1007,7 @@ xfs_buf_iodone_work( */ if ((bp->b_error == EOPNOTSUPP) && (bp->b_flags & (XBF_ORDERED|XBF_ASYNC)) == (XBF_ORDERED|XBF_ASYNC)) { - XB_TRACE(bp, "ordered_retry", bp->b_iodone); + trace_xfs_buf_ordered_retry(bp, _RET_IP_); bp->b_flags &= ~XBF_ORDERED; bp->b_flags |= _XFS_BARRIER_FAILED; xfs_buf_iorequest(bp); @@ -1050,12 +1022,12 @@ xfs_buf_ioend( xfs_buf_t *bp, int schedule) { + trace_xfs_buf_iodone(bp, _RET_IP_); + bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD); if (bp->b_error == 0) bp->b_flags |= XBF_DONE; - XB_TRACE(bp, "iodone", bp->b_iodone); - if ((bp->b_iodone) || (bp->b_flags & XBF_ASYNC)) { if (schedule) { INIT_WORK(&bp->b_iodone_work, xfs_buf_iodone_work); @@ -1075,7 +1047,7 @@ xfs_buf_ioerror( { ASSERT(error >= 0 && error <= 0xffff); bp->b_error = (unsigned short)error; - XB_TRACE(bp, "ioerror", (unsigned long)error); + trace_xfs_buf_ioerror(bp, error, _RET_IP_); } int @@ -1083,7 +1055,7 @@ xfs_bawrite( void *mp, struct xfs_buf *bp) { - XB_TRACE(bp, "bawrite", 0); + trace_xfs_buf_bawrite(bp, _RET_IP_); ASSERT(bp->b_bn != XFS_BUF_DADDR_NULL); @@ -1102,7 +1074,7 @@ xfs_bdwrite( void *mp, struct xfs_buf *bp) { - XB_TRACE(bp, "bdwrite", 0); + trace_xfs_buf_bdwrite(bp, _RET_IP_); bp->b_strat = xfs_bdstrat_cb; bp->b_mount = mp; @@ -1253,7 +1225,7 @@ int xfs_buf_iorequest( xfs_buf_t *bp) { - XB_TRACE(bp, "iorequest", 0); + trace_xfs_buf_iorequest(bp, _RET_IP_); if (bp->b_flags & XBF_DELWRI) { xfs_buf_delwri_queue(bp, 1); @@ -1287,11 +1259,13 @@ int xfs_buf_iowait( xfs_buf_t *bp) { - XB_TRACE(bp, "iowait", 0); + trace_xfs_buf_iowait(bp, _RET_IP_); + if (atomic_read(&bp->b_io_remaining)) blk_run_address_space(bp->b_target->bt_mapping); wait_for_completion(&bp->b_iowait); - XB_TRACE(bp, "iowaited", (long)bp->b_error); + + trace_xfs_buf_iowait_done(bp, _RET_IP_); return bp->b_error; } @@ -1604,7 +1578,8 @@ xfs_buf_delwri_queue( struct list_head *dwq = &bp->b_target->bt_delwrite_queue; spinlock_t *dwlk = &bp->b_target->bt_delwrite_lock; - XB_TRACE(bp, "delwri_q", (long)unlock); + trace_xfs_buf_delwri_queue(bp, _RET_IP_); + ASSERT((bp->b_flags&(XBF_DELWRI|XBF_ASYNC)) == (XBF_DELWRI|XBF_ASYNC)); spin_lock(dwlk); @@ -1644,7 +1619,7 @@ xfs_buf_delwri_dequeue( if (dequeued) xfs_buf_rele(bp); - XB_TRACE(bp, "delwri_dq", (long)dequeued); + trace_xfs_buf_delwri_dequeue(bp, _RET_IP_); } STATIC void @@ -1692,7 +1667,7 @@ xfs_buf_delwri_split( INIT_LIST_HEAD(list); spin_lock(dwlk); list_for_each_entry_safe(bp, n, dwq, b_list) { - XB_TRACE(bp, "walkq1", (long)xfs_buf_ispin(bp)); + trace_xfs_buf_delwri_split(bp, _RET_IP_); ASSERT(bp->b_flags & XBF_DELWRI); if (!xfs_buf_ispin(bp) && !xfs_buf_cond_lock(bp)) { @@ -1816,14 +1791,10 @@ xfs_flush_buftarg( int __init xfs_buf_init(void) { -#ifdef XFS_BUF_TRACE - xfs_buf_trace_buf = ktrace_alloc(XFS_BUF_TRACE_SIZE, KM_NOFS); -#endif - xfs_buf_zone = kmem_zone_init_flags(sizeof(xfs_buf_t), "xfs_buf", KM_ZONE_HWALIGN, NULL); if (!xfs_buf_zone) - goto out_free_trace_buf; + goto out; xfslogd_workqueue = create_workqueue("xfslogd"); if (!xfslogd_workqueue) @@ -1846,10 +1817,7 @@ xfs_buf_init(void) destroy_workqueue(xfslogd_workqueue); out_free_buf_zone: kmem_zone_destroy(xfs_buf_zone); - out_free_trace_buf: -#ifdef XFS_BUF_TRACE - ktrace_free(xfs_buf_trace_buf); -#endif + out: return -ENOMEM; } @@ -1861,9 +1829,6 @@ xfs_buf_terminate(void) destroy_workqueue(xfsdatad_workqueue); destroy_workqueue(xfslogd_workqueue); kmem_zone_destroy(xfs_buf_zone); -#ifdef XFS_BUF_TRACE - ktrace_free(xfs_buf_trace_buf); -#endif } #ifdef CONFIG_KDB_MODULES diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 5f07dd9..a509f4a 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h @@ -95,6 +95,28 @@ typedef enum { _XFS_BARRIER_FAILED = (1 << 23), } xfs_buf_flags_t; +#define XFS_BUF_FLAGS \ + { XBF_READ, "READ" }, \ + { XBF_WRITE, "WRITE" }, \ + { XBF_MAPPED, "MAPPED" }, \ + { XBF_ASYNC, "ASYNC" }, \ + { XBF_DONE, "DONE" }, \ + { XBF_DELWRI, "DELWRI" }, \ + { XBF_STALE, "STALE" }, \ + { XBF_FS_MANAGED, "FS_MANAGED" }, \ + { XBF_ORDERED, "ORDERED" }, \ + { XBF_READ_AHEAD, "READ_AHEAD" }, \ + { XBF_LOCK, "LOCK" }, /* should never be set */\ + { XBF_TRYLOCK, "TRYLOCK" }, /* ditto */\ + { XBF_DONT_BLOCK, "DONT_BLOCK" }, /* ditto */\ + { _XBF_PAGE_CACHE, "PAGE_CACHE" }, \ + { _XBF_PAGES, "PAGES" }, \ + { _XBF_RUN_QUEUES, "RUN_QUEUES" }, \ + { _XBF_DELWRI_Q, "DELWRI_Q" }, \ + { _XBF_PAGE_LOCKED, "PAGE_LOCKED" }, \ + { _XFS_BARRIER_FAILED, "BARRIER_FAILED" } + + typedef enum { XBT_FORCE_SLEEP = 0, XBT_FORCE_FLUSH = 1, @@ -243,13 +265,6 @@ extern void xfs_buf_delwri_dequeue(xfs_buf_t *); extern int xfs_buf_init(void); extern void xfs_buf_terminate(void); -#ifdef XFS_BUF_TRACE -extern ktrace_t *xfs_buf_trace_buf; -extern void xfs_buf_trace(xfs_buf_t *, char *, void *, void *); -#else -#define xfs_buf_trace(bp,id,ptr,ra) do { } while (0) -#endif - #define xfs_buf_target_name(target) \ ({ char __b[BDEVNAME_SIZE]; bdevname((target)->bt_bdev, __b); __b; }) @@ -365,10 +380,6 @@ static inline void xfs_buf_relse(xfs_buf_t *bp) #define xfs_bpin(bp) xfs_buf_pin(bp) #define xfs_bunpin(bp) xfs_buf_unpin(bp) - -#define xfs_buftrace(id, bp) \ - xfs_buf_trace(bp, id, NULL, (void *)__builtin_return_address(0)) - #define xfs_biodone(bp) xfs_buf_ioend(bp, 0) #define xfs_biomove(bp, off, len, data, rw) \ diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c index 08be36d..7501b85 100644 --- a/fs/xfs/linux-2.6/xfs_fs_subr.c +++ b/fs/xfs/linux-2.6/xfs_fs_subr.c @@ -19,6 +19,7 @@ #include "xfs_vnodeops.h" #include "xfs_bmap_btree.h" #include "xfs_inode.h" +#include "xfs_trace.h" int fs_noerr(void) { return 0; } int fs_nosys(void) { return ENOSYS; } @@ -51,6 +52,8 @@ xfs_flushinval_pages( struct address_space *mapping = VFS_I(ip)->i_mapping; int ret = 0; + trace_xfs_pagecache_inval(ip, first, last); + if (mapping->nrpages) { xfs_iflags_clear(ip, XFS_ITRUNCATED); ret = filemap_write_and_wait(mapping); diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 5bb523d..a034cf6 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c @@ -51,6 +51,7 @@ #include "xfs_quota.h" #include "xfs_inode_item.h" #include "xfs_export.h" +#include "xfs_trace.h" #include #include diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c index eafcc7c..be1527b 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c @@ -46,6 +46,7 @@ #include "xfs_attr.h" #include "xfs_ioctl.h" #include "xfs_ioctl32.h" +#include "xfs_trace.h" #define _NATIVE_IOC(cmd, type) \ _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(type)) diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 1f3b4b8..1d5b298 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -47,6 +47,7 @@ #include "xfs_buf_item.h" #include "xfs_utils.h" #include "xfs_vnodeops.h" +#include "xfs_trace.h" #include #include diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index 6127e24..5af0c81c 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h @@ -40,7 +40,6 @@ #include #include -#include #include #include diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 1bf47f2..0d32457 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -48,73 +48,12 @@ #include "xfs_utils.h" #include "xfs_iomap.h" #include "xfs_vnodeops.h" +#include "xfs_trace.h" #include #include -#if defined(XFS_RW_TRACE) -void -xfs_rw_enter_trace( - int tag, - xfs_inode_t *ip, - void *data, - size_t segs, - loff_t offset, - int ioflags) -{ - if (ip->i_rwtrace == NULL) - return; - ktrace_enter(ip->i_rwtrace, - (void *)(unsigned long)tag, - (void *)ip, - (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)), - (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)), - (void *)data, - (void *)((unsigned long)segs), - (void *)((unsigned long)((offset >> 32) & 0xffffffff)), - (void *)((unsigned long)(offset & 0xffffffff)), - (void *)((unsigned long)ioflags), - (void *)((unsigned long)((ip->i_new_size >> 32) & 0xffffffff)), - (void *)((unsigned long)(ip->i_new_size & 0xffffffff)), - (void *)((unsigned long)current_pid()), - (void *)NULL, - (void *)NULL, - (void *)NULL, - (void *)NULL); -} - -void -xfs_inval_cached_trace( - xfs_inode_t *ip, - xfs_off_t offset, - xfs_off_t len, - xfs_off_t first, - xfs_off_t last) -{ - - if (ip->i_rwtrace == NULL) - return; - ktrace_enter(ip->i_rwtrace, - (void *)(__psint_t)XFS_INVAL_CACHED, - (void *)ip, - (void *)((unsigned long)((offset >> 32) & 0xffffffff)), - (void *)((unsigned long)(offset & 0xffffffff)), - (void *)((unsigned long)((len >> 32) & 0xffffffff)), - (void *)((unsigned long)(len & 0xffffffff)), - (void *)((unsigned long)((first >> 32) & 0xffffffff)), - (void *)((unsigned long)(first & 0xffffffff)), - (void *)((unsigned long)((last >> 32) & 0xffffffff)), - (void *)((unsigned long)(last & 0xffffffff)), - (void *)((unsigned long)current_pid()), - (void *)NULL, - (void *)NULL, - (void *)NULL, - (void *)NULL, - (void *)NULL); -} -#endif - /* * xfs_iozero * @@ -250,8 +189,7 @@ xfs_read( } } - xfs_rw_enter_trace(XFS_READ_ENTER, ip, - (void *)iovp, segs, *offset, ioflags); + trace_xfs_file_read(ip, size, *offset, ioflags); iocb->ki_pos = *offset; ret = generic_file_aio_read(iocb, iovp, segs, *offset); @@ -292,8 +230,9 @@ xfs_splice_read( return -error; } } - xfs_rw_enter_trace(XFS_SPLICE_READ_ENTER, ip, - pipe, count, *ppos, ioflags); + + trace_xfs_file_splice_read(ip, count, *ppos, ioflags); + ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); if (ret > 0) XFS_STATS_ADD(xs_read_bytes, ret); @@ -342,8 +281,8 @@ xfs_splice_write( ip->i_new_size = new_size; xfs_iunlock(ip, XFS_ILOCK_EXCL); - xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, ip, - pipe, count, *ppos, ioflags); + trace_xfs_file_splice_write(ip, count, *ppos, ioflags); + ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); if (ret > 0) XFS_STATS_ADD(xs_write_bytes, ret); @@ -710,8 +649,6 @@ start: if ((ioflags & IO_ISDIRECT)) { if (mapping->nrpages) { WARN_ON(need_i_mutex == 0); - xfs_inval_cached_trace(xip, pos, -1, - (pos & PAGE_CACHE_MASK), -1); error = xfs_flushinval_pages(xip, (pos & PAGE_CACHE_MASK), -1, FI_REMAPF_LOCKED); @@ -728,8 +665,7 @@ start: need_i_mutex = 0; } - xfs_rw_enter_trace(XFS_DIOWR_ENTER, xip, (void *)iovp, segs, - *offset, ioflags); + trace_xfs_file_direct_write(xip, count, *offset, ioflags); ret = generic_file_direct_write(iocb, iovp, &segs, pos, offset, count, ocount); @@ -752,8 +688,7 @@ start: ssize_t ret2 = 0; write_retry: - xfs_rw_enter_trace(XFS_WRITE_ENTER, xip, (void *)iovp, segs, - *offset, ioflags); + trace_xfs_file_buffered_write(xip, count, *offset, ioflags); ret2 = generic_file_buffered_write(iocb, iovp, segs, pos, offset, count, ret); /* @@ -858,7 +793,7 @@ int xfs_bdstrat_cb(struct xfs_buf *bp) { if (XFS_FORCED_SHUTDOWN(bp->b_mount)) { - xfs_buftrace("XFS__BDSTRAT IOERROR", bp); + trace_xfs_bdstrat_shut(bp, _RET_IP_); /* * Metadata write that didn't get logged but * written delayed anyway. These aren't associated @@ -891,7 +826,7 @@ xfsbdstrat( return; } - xfs_buftrace("XFSBDSTRAT IOERROR", bp); + trace_xfs_bdstrat_shut(bp, _RET_IP_); xfs_bioerror_relse(bp); } diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h index e6be37d..d1f7789 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.h +++ b/fs/xfs/linux-2.6/xfs_lrw.h @@ -20,52 +20,7 @@ struct xfs_mount; struct xfs_inode; -struct xfs_bmbt_irec; struct xfs_buf; -struct xfs_iomap; - -#if defined(XFS_RW_TRACE) -/* - * Defines for the trace mechanisms in xfs_lrw.c. - */ -#define XFS_RW_KTRACE_SIZE 128 - -#define XFS_READ_ENTER 1 -#define XFS_WRITE_ENTER 2 -#define XFS_IOMAP_READ_ENTER 3 -#define XFS_IOMAP_WRITE_ENTER 4 -#define XFS_IOMAP_READ_MAP 5 -#define XFS_IOMAP_WRITE_MAP 6 -#define XFS_IOMAP_WRITE_NOSPACE 7 -#define XFS_ITRUNC_START 8 -#define XFS_ITRUNC_FINISH1 9 -#define XFS_ITRUNC_FINISH2 10 -#define XFS_CTRUNC1 11 -#define XFS_CTRUNC2 12 -#define XFS_CTRUNC3 13 -#define XFS_CTRUNC4 14 -#define XFS_CTRUNC5 15 -#define XFS_CTRUNC6 16 -#define XFS_BUNMAP 17 -#define XFS_INVAL_CACHED 18 -#define XFS_DIORD_ENTER 19 -#define XFS_DIOWR_ENTER 20 -#define XFS_WRITEPAGE_ENTER 22 -#define XFS_RELEASEPAGE_ENTER 23 -#define XFS_INVALIDPAGE_ENTER 24 -#define XFS_IOMAP_ALLOC_ENTER 25 -#define XFS_IOMAP_ALLOC_MAP 26 -#define XFS_IOMAP_UNWRITTEN 27 -#define XFS_SPLICE_READ_ENTER 28 -#define XFS_SPLICE_WRITE_ENTER 29 -extern void xfs_rw_enter_trace(int, struct xfs_inode *, - void *, size_t, loff_t, int); -extern void xfs_inval_cached_trace(struct xfs_inode *, - xfs_off_t, xfs_off_t, xfs_off_t, xfs_off_t); -#else -#define xfs_rw_enter_trace(tag, ip, data, size, offset, ioflags) -#define xfs_inval_cached_trace(ip, offset, len, first, last) -#endif /* errors from xfsbdstrat() must be extracted from the buffer */ extern void xfsbdstrat(struct xfs_mount *, struct xfs_buf *); diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 1bfb0e9..09783cc 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -15,6 +15,7 @@ * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + #include "xfs.h" #include "xfs_bit.h" #include "xfs_log.h" @@ -52,11 +53,11 @@ #include "xfs_trans_priv.h" #include "xfs_filestream.h" #include "xfs_da_btree.h" -#include "xfs_dir2_trace.h" #include "xfs_extfree_item.h" #include "xfs_mru_cache.h" #include "xfs_inode_item.h" #include "xfs_sync.h" +#include "xfs_trace.h" #include #include @@ -1525,8 +1526,6 @@ xfs_fs_fill_super( goto fail_vnrele; kfree(mtpt); - - xfs_itrace_exit(XFS_I(sb->s_root->d_inode)); return 0; out_filestream_unmount: @@ -1602,94 +1601,6 @@ static struct file_system_type xfs_fs_type = { }; STATIC int __init -xfs_alloc_trace_bufs(void) -{ -#ifdef XFS_ALLOC_TRACE - xfs_alloc_trace_buf = ktrace_alloc(XFS_ALLOC_TRACE_SIZE, KM_MAYFAIL); - if (!xfs_alloc_trace_buf) - goto out; -#endif -#ifdef XFS_BMAP_TRACE - xfs_bmap_trace_buf = ktrace_alloc(XFS_BMAP_TRACE_SIZE, KM_MAYFAIL); - if (!xfs_bmap_trace_buf) - goto out_free_alloc_trace; -#endif -#ifdef XFS_BTREE_TRACE - xfs_allocbt_trace_buf = ktrace_alloc(XFS_ALLOCBT_TRACE_SIZE, - KM_MAYFAIL); - if (!xfs_allocbt_trace_buf) - goto out_free_bmap_trace; - - xfs_inobt_trace_buf = ktrace_alloc(XFS_INOBT_TRACE_SIZE, KM_MAYFAIL); - if (!xfs_inobt_trace_buf) - goto out_free_allocbt_trace; - - xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_MAYFAIL); - if (!xfs_bmbt_trace_buf) - goto out_free_inobt_trace; -#endif -#ifdef XFS_ATTR_TRACE - xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_MAYFAIL); - if (!xfs_attr_trace_buf) - goto out_free_bmbt_trace; -#endif -#ifdef XFS_DIR2_TRACE - xfs_dir2_trace_buf = ktrace_alloc(XFS_DIR2_GTRACE_SIZE, KM_MAYFAIL); - if (!xfs_dir2_trace_buf) - goto out_free_attr_trace; -#endif - - return 0; - -#ifdef XFS_DIR2_TRACE - out_free_attr_trace: -#endif -#ifdef XFS_ATTR_TRACE - ktrace_free(xfs_attr_trace_buf); - out_free_bmbt_trace: -#endif -#ifdef XFS_BTREE_TRACE - ktrace_free(xfs_bmbt_trace_buf); - out_free_inobt_trace: - ktrace_free(xfs_inobt_trace_buf); - out_free_allocbt_trace: - ktrace_free(xfs_allocbt_trace_buf); - out_free_bmap_trace: -#endif -#ifdef XFS_BMAP_TRACE - ktrace_free(xfs_bmap_trace_buf); - out_free_alloc_trace: -#endif -#ifdef XFS_ALLOC_TRACE - ktrace_free(xfs_alloc_trace_buf); - out: -#endif - return -ENOMEM; -} - -STATIC void -xfs_free_trace_bufs(void) -{ -#ifdef XFS_DIR2_TRACE - ktrace_free(xfs_dir2_trace_buf); -#endif -#ifdef XFS_ATTR_TRACE - ktrace_free(xfs_attr_trace_buf); -#endif -#ifdef XFS_BTREE_TRACE - ktrace_free(xfs_bmbt_trace_buf); - ktrace_free(xfs_inobt_trace_buf); - ktrace_free(xfs_allocbt_trace_buf); -#endif -#ifdef XFS_BMAP_TRACE - ktrace_free(xfs_bmap_trace_buf); -#endif -#ifdef XFS_ALLOC_TRACE - ktrace_free(xfs_alloc_trace_buf); -#endif -} - -STATIC int __init xfs_init_zones(void) { @@ -1830,7 +1741,6 @@ init_xfs_fs(void) printk(KERN_INFO XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled\n"); - ktrace_init(64); xfs_ioend_init(); xfs_dir_startup(); @@ -1838,13 +1748,9 @@ init_xfs_fs(void) if (error) goto out; - error = xfs_alloc_trace_bufs(); - if (error) - goto out_destroy_zones; - error = xfs_mru_cache_init(); if (error) - goto out_free_trace_buffers; + goto out_destroy_zones; error = xfs_filestream_init(); if (error) @@ -1879,8 +1785,6 @@ init_xfs_fs(void) xfs_filestream_uninit(); out_mru_cache_uninit: xfs_mru_cache_uninit(); - out_free_trace_buffers: - xfs_free_trace_bufs(); out_destroy_zones: xfs_destroy_zones(); out: @@ -1897,9 +1801,7 @@ exit_xfs_fs(void) xfs_buf_terminate(); xfs_filestream_uninit(); xfs_mru_cache_uninit(); - xfs_free_trace_bufs(); xfs_destroy_zones(); - ktrace_uninit(); } module_init(init_xfs_fs); diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h index 18175eb..233d4b9 100644 --- a/fs/xfs/linux-2.6/xfs_super.h +++ b/fs/xfs/linux-2.6/xfs_super.h @@ -56,12 +56,6 @@ extern void xfs_qm_exit(void); # define XFS_BIGFS_STRING #endif -#ifdef CONFIG_XFS_TRACE -# define XFS_TRACE_STRING "tracing, " -#else -# define XFS_TRACE_STRING -#endif - #ifdef CONFIG_XFS_DMAPI # define XFS_DMAPI_STRING "dmapi support, " #else @@ -78,7 +72,6 @@ extern void xfs_qm_exit(void); XFS_SECURITY_STRING \ XFS_REALTIME_STRING \ XFS_BIGFS_STRING \ - XFS_TRACE_STRING \ XFS_DMAPI_STRING \ XFS_DBG_STRING /* DBG must be last */ diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index d895a3a..6fed97a 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c @@ -44,6 +44,7 @@ #include "xfs_inode_item.h" #include "xfs_rw.h" #include "xfs_quota.h" +#include "xfs_trace.h" #include #include diff --git a/fs/xfs/linux-2.6/xfs_trace.c b/fs/xfs/linux-2.6/xfs_trace.c new file mode 100644 index 0000000..856eb3c --- /dev/null +++ b/fs/xfs/linux-2.6/xfs_trace.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2009, Christoph Hellwig + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_types.h" +#include "xfs_bit.h" +#include "xfs_log.h" +#include "xfs_inum.h" +#include "xfs_trans.h" +#include "xfs_sb.h" +#include "xfs_ag.h" +#include "xfs_dir2.h" +#include "xfs_da_btree.h" +#include "xfs_bmap_btree.h" +#include "xfs_alloc_btree.h" +#include "xfs_ialloc_btree.h" +#include "xfs_dir2_sf.h" +#include "xfs_attr_sf.h" +#include "xfs_dinode.h" +#include "xfs_inode.h" +#include "xfs_btree.h" +#include "xfs_dmapi.h" +#include "xfs_mount.h" +#include "xfs_ialloc.h" +#include "xfs_itable.h" +#include "xfs_alloc.h" +#include "xfs_bmap.h" +#include "xfs_attr.h" +#include "xfs_attr_sf.h" +#include "xfs_attr_leaf.h" +#include "xfs_log_priv.h" +#include "xfs_buf_item.h" +#include "xfs_quota.h" +#include "xfs_iomap.h" +#include "xfs_aops.h" +#include "quota/xfs_dquot_item.h" +#include "quota/xfs_dquot.h" + +/* + * Format fsblock number into a static buffer & return it. + */ +STATIC char *xfs_fmtfsblock(xfs_fsblock_t bno) +{ + static char rval[50]; + + if (bno == NULLFSBLOCK) + sprintf(rval, "NULLFSBLOCK"); + else if (isnullstartblock(bno)) + sprintf(rval, "NULLSTARTBLOCK(%lld)", startblockval(bno)); + else + sprintf(rval, "%lld", (xfs_dfsbno_t)bno); + return rval; +} + +/* + * We include this last to have the helpers above available for the trace + * event implementations. + */ +#define CREATE_TRACE_POINTS +#include "xfs_trace.h" diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h new file mode 100644 index 0000000..c40834b --- /dev/null +++ b/fs/xfs/linux-2.6/xfs_trace.h @@ -0,0 +1,1369 @@ +/* + * Copyright (c) 2009, Christoph Hellwig + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM xfs + +#if !defined(_TRACE_XFS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_XFS_H + +#include + +struct xfs_agf; +struct xfs_alloc_arg; +struct xfs_attr_list_context; +struct xfs_buf_log_item; +struct xfs_da_args; +struct xfs_da_node_entry; +struct xfs_dquot; +struct xlog_ticket; +struct log; + +#define DEFINE_ATTR_LIST_EVENT(name) \ +TRACE_EVENT(name, \ + TP_PROTO(struct xfs_attr_list_context *ctx), \ + TP_ARGS(ctx), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_ino_t, ino) \ + __field(u32, hashval) \ + __field(u32, blkno) \ + __field(u32, offset) \ + __field(void *, alist) \ + __field(int, bufsize) \ + __field(int, count) \ + __field(int, firstu) \ + __field(int, dupcnt) \ + __field(int, flags) \ + ), \ + TP_fast_assign( \ + __entry->dev = VFS_I(ctx->dp)->i_sb->s_dev; \ + __entry->ino = ctx->dp->i_ino; \ + __entry->hashval = ctx->cursor->hashval; \ + __entry->blkno = ctx->cursor->blkno; \ + __entry->offset = ctx->cursor->offset; \ + __entry->alist = ctx->alist; \ + __entry->bufsize = ctx->bufsize; \ + __entry->count = ctx->count; \ + __entry->firstu = ctx->firstu; \ + __entry->flags = ctx->flags; \ + ), \ + TP_printk("dev %d:%d ino 0x%llx cursor h/b/o 0x%x/0x%x/%u dupcnt %u " \ + "alist 0x%p size %u count %u firstu %u flags %d %s", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + __entry->ino, \ + __entry->hashval, \ + __entry->blkno, \ + __entry->offset, \ + __entry->dupcnt, \ + __entry->alist, \ + __entry->bufsize, \ + __entry->count, \ + __entry->firstu, \ + __entry->flags, \ + __print_flags(__entry->flags, "|", XFS_ATTR_FLAGS) \ + ) \ +) +DEFINE_ATTR_LIST_EVENT(xfs_attr_list_sf); +DEFINE_ATTR_LIST_EVENT(xfs_attr_list_sf_all); +DEFINE_ATTR_LIST_EVENT(xfs_attr_list_leaf); +DEFINE_ATTR_LIST_EVENT(xfs_attr_list_leaf_end); +DEFINE_ATTR_LIST_EVENT(xfs_attr_list_full); +DEFINE_ATTR_LIST_EVENT(xfs_attr_list_add); +DEFINE_ATTR_LIST_EVENT(xfs_attr_list_wrong_blk); +DEFINE_ATTR_LIST_EVENT(xfs_attr_list_notfound); + +TRACE_EVENT(xfs_attr_list_node_descend, + TP_PROTO(struct xfs_attr_list_context *ctx, + struct xfs_da_node_entry *btree), + TP_ARGS(ctx, btree), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(u32, hashval) + __field(u32, blkno) + __field(u32, offset) + __field(void *, alist) + __field(int, bufsize) + __field(int, count) + __field(int, firstu) + __field(int, dupcnt) + __field(int, flags) + __field(u32, bt_hashval) + __field(u32, bt_before) + ), + TP_fast_assign( + __entry->dev = VFS_I(ctx->dp)->i_sb->s_dev; + __entry->ino = ctx->dp->i_ino; + __entry->hashval = ctx->cursor->hashval; + __entry->blkno = ctx->cursor->blkno; + __entry->offset = ctx->cursor->offset; + __entry->alist = ctx->alist; + __entry->bufsize = ctx->bufsize; + __entry->count = ctx->count; + __entry->firstu = ctx->firstu; + __entry->flags = ctx->flags; + __entry->bt_hashval = be32_to_cpu(btree->hashval); + __entry->bt_before = be32_to_cpu(btree->before); + ), + TP_printk("dev %d:%d ino 0x%llx cursor h/b/o 0x%x/0x%x/%u dupcnt %u " + "alist 0x%p size %u count %u firstu %u flags %d %s " + "node hashval %u, node before %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->hashval, + __entry->blkno, + __entry->offset, + __entry->dupcnt, + __entry->alist, + __entry->bufsize, + __entry->count, + __entry->firstu, + __entry->flags, + __print_flags(__entry->flags, "|", XFS_ATTR_FLAGS), + __entry->bt_hashval, + __entry->bt_before) +); + +TRACE_EVENT(xfs_iext_insert, + TP_PROTO(struct xfs_inode *ip, xfs_extnum_t idx, + struct xfs_bmbt_irec *r, int state, unsigned long caller_ip), + TP_ARGS(ip, idx, r, state, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(xfs_extnum_t, idx) + __field(xfs_fileoff_t, startoff) + __field(xfs_fsblock_t, startblock) + __field(xfs_filblks_t, blockcount) + __field(xfs_exntst_t, state) + __field(int, bmap_state) + __field(unsigned long, caller_ip) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->idx = idx; + __entry->startoff = r->br_startoff; + __entry->startblock = r->br_startblock; + __entry->blockcount = r->br_blockcount; + __entry->state = r->br_state; + __entry->bmap_state = state; + __entry->caller_ip = caller_ip; + ), + TP_printk("dev %d:%d ino 0x%llx state %s idx %ld " + "offset %lld block %s count %lld flag %d caller %pf", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __print_flags(__entry->bmap_state, "|", XFS_BMAP_EXT_FLAGS), + (long)__entry->idx, + __entry->startoff, + xfs_fmtfsblock(__entry->startblock), + __entry->blockcount, + __entry->state, + (char *)__entry->caller_ip) +); + +#define DEFINE_BMAP_EVENT(name) \ +TRACE_EVENT(name, \ + TP_PROTO(struct xfs_inode *ip, xfs_extnum_t idx, int state, \ + unsigned long caller_ip), \ + TP_ARGS(ip, idx, state, caller_ip), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_ino_t, ino) \ + __field(xfs_extnum_t, idx) \ + __field(xfs_fileoff_t, startoff) \ + __field(xfs_fsblock_t, startblock) \ + __field(xfs_filblks_t, blockcount) \ + __field(xfs_exntst_t, state) \ + __field(int, bmap_state) \ + __field(unsigned long, caller_ip) \ + ), \ + TP_fast_assign( \ + struct xfs_ifork *ifp = (state & BMAP_ATTRFORK) ? \ + ip->i_afp : &ip->i_df; \ + struct xfs_bmbt_irec r; \ + \ + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx), &r); \ + __entry->dev = VFS_I(ip)->i_sb->s_dev; \ + __entry->ino = ip->i_ino; \ + __entry->idx = idx; \ + __entry->startoff = r.br_startoff; \ + __entry->startblock = r.br_startblock; \ + __entry->blockcount = r.br_blockcount; \ + __entry->state = r.br_state; \ + __entry->bmap_state = state; \ + __entry->caller_ip = caller_ip; \ + ), \ + TP_printk("dev %d:%d ino 0x%llx state %s idx %ld " \ + "offset %lld block %s count %lld flag %d caller %pf", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + __entry->ino, \ + __print_flags(__entry->bmap_state, "|", XFS_BMAP_EXT_FLAGS), \ + (long)__entry->idx, \ + __entry->startoff, \ + xfs_fmtfsblock(__entry->startblock), \ + __entry->blockcount, \ + __entry->state, \ + (char *)__entry->caller_ip) \ +) + +DEFINE_BMAP_EVENT(xfs_iext_remove); +DEFINE_BMAP_EVENT(xfs_bmap_pre_update); +DEFINE_BMAP_EVENT(xfs_bmap_post_update); +DEFINE_BMAP_EVENT(xfs_extlist); + +#define DEFINE_BUF_EVENT(tname) \ +TRACE_EVENT(tname, \ + TP_PROTO(struct xfs_buf *bp, unsigned long caller_ip), \ + TP_ARGS(bp, caller_ip), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_daddr_t, bno) \ + __field(size_t, buffer_length) \ + __field(int, hold) \ + __field(int, pincount) \ + __field(unsigned, lockval) \ + __field(unsigned, flags) \ + __field(unsigned long, caller_ip) \ + ), \ + TP_fast_assign( \ + __entry->dev = bp->b_target->bt_dev; \ + __entry->bno = bp->b_bn; \ + __entry->buffer_length = bp->b_buffer_length; \ + __entry->hold = atomic_read(&bp->b_hold); \ + __entry->pincount = atomic_read(&bp->b_pin_count); \ + __entry->lockval = xfs_buf_lock_value(bp); \ + __entry->flags = bp->b_flags; \ + __entry->caller_ip = caller_ip; \ + ), \ + TP_printk("dev %d:%d bno 0x%llx len 0x%zx hold %d pincount %d " \ + "lock %d flags %s caller %pf", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + (unsigned long long)__entry->bno, \ + __entry->buffer_length, \ + __entry->hold, \ + __entry->pincount, \ + __entry->lockval, \ + __print_flags(__entry->flags, "|", XFS_BUF_FLAGS), \ + (void *)__entry->caller_ip) \ +) +DEFINE_BUF_EVENT(xfs_buf_init); +DEFINE_BUF_EVENT(xfs_buf_free); +DEFINE_BUF_EVENT(xfs_buf_hold); +DEFINE_BUF_EVENT(xfs_buf_rele); +DEFINE_BUF_EVENT(xfs_buf_pin); +DEFINE_BUF_EVENT(xfs_buf_unpin); +DEFINE_BUF_EVENT(xfs_buf_iodone); +DEFINE_BUF_EVENT(xfs_buf_iorequest); +DEFINE_BUF_EVENT(xfs_buf_bawrite); +DEFINE_BUF_EVENT(xfs_buf_bdwrite); +DEFINE_BUF_EVENT(xfs_buf_lock); +DEFINE_BUF_EVENT(xfs_buf_lock_done); +DEFINE_BUF_EVENT(xfs_buf_cond_lock); +DEFINE_BUF_EVENT(xfs_buf_unlock); +DEFINE_BUF_EVENT(xfs_buf_ordered_retry); +DEFINE_BUF_EVENT(xfs_buf_iowait); +DEFINE_BUF_EVENT(xfs_buf_iowait_done); +DEFINE_BUF_EVENT(xfs_buf_delwri_queue); +DEFINE_BUF_EVENT(xfs_buf_delwri_dequeue); +DEFINE_BUF_EVENT(xfs_buf_delwri_split); +DEFINE_BUF_EVENT(xfs_buf_get_noaddr); +DEFINE_BUF_EVENT(xfs_bdstrat_shut); +DEFINE_BUF_EVENT(xfs_buf_item_relse); +DEFINE_BUF_EVENT(xfs_buf_item_iodone); +DEFINE_BUF_EVENT(xfs_buf_item_iodone_async); +DEFINE_BUF_EVENT(xfs_buf_error_relse); +DEFINE_BUF_EVENT(xfs_trans_read_buf_io); +DEFINE_BUF_EVENT(xfs_trans_read_buf_shut); + +/* not really buffer traces, but the buf provides useful information */ +DEFINE_BUF_EVENT(xfs_btree_corrupt); +DEFINE_BUF_EVENT(xfs_da_btree_corrupt); +DEFINE_BUF_EVENT(xfs_reset_dqcounts); +DEFINE_BUF_EVENT(xfs_inode_item_push); + +/* pass flags explicitly */ +#define DEFINE_BUF_FLAGS_EVENT(tname) \ +TRACE_EVENT(tname, \ + TP_PROTO(struct xfs_buf *bp, unsigned flags, unsigned long caller_ip), \ + TP_ARGS(bp, flags, caller_ip), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_daddr_t, bno) \ + __field(size_t, buffer_length) \ + __field(int, hold) \ + __field(int, pincount) \ + __field(unsigned, lockval) \ + __field(unsigned, flags) \ + __field(unsigned long, caller_ip) \ + ), \ + TP_fast_assign( \ + __entry->dev = bp->b_target->bt_dev; \ + __entry->bno = bp->b_bn; \ + __entry->buffer_length = bp->b_buffer_length; \ + __entry->flags = flags; \ + __entry->hold = atomic_read(&bp->b_hold); \ + __entry->pincount = atomic_read(&bp->b_pin_count); \ + __entry->lockval = xfs_buf_lock_value(bp); \ + __entry->caller_ip = caller_ip; \ + ), \ + TP_printk("dev %d:%d bno 0x%llx len 0x%zx hold %d pincount %d " \ + "lock %d flags %s caller %pf", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + (unsigned long long)__entry->bno, \ + __entry->buffer_length, \ + __entry->hold, \ + __entry->pincount, \ + __entry->lockval, \ + __print_flags(__entry->flags, "|", XFS_BUF_FLAGS), \ + (void *)__entry->caller_ip) \ +) +DEFINE_BUF_FLAGS_EVENT(xfs_buf_find); +DEFINE_BUF_FLAGS_EVENT(xfs_buf_get); +DEFINE_BUF_FLAGS_EVENT(xfs_buf_read); + +TRACE_EVENT(xfs_buf_ioerror, + TP_PROTO(struct xfs_buf *bp, int error, unsigned long caller_ip), + TP_ARGS(bp, error, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_daddr_t, bno) + __field(size_t, buffer_length) + __field(unsigned, flags) + __field(int, hold) + __field(int, pincount) + __field(unsigned, lockval) + __field(int, error) + __field(unsigned long, caller_ip) + ), + TP_fast_assign( + __entry->dev = bp->b_target->bt_dev; + __entry->bno = bp->b_bn; + __entry->buffer_length = bp->b_buffer_length; + __entry->hold = atomic_read(&bp->b_hold); + __entry->pincount = atomic_read(&bp->b_pin_count); + __entry->lockval = xfs_buf_lock_value(bp); + __entry->error = error; + __entry->flags = bp->b_flags; + __entry->caller_ip = caller_ip; + ), + TP_printk("dev %d:%d bno 0x%llx len 0x%zx hold %d pincount %d " + "lock %d error %d flags %s caller %pf", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long long)__entry->bno, + __entry->buffer_length, + __entry->hold, + __entry->pincount, + __entry->lockval, + __entry->error, + __print_flags(__entry->flags, "|", XFS_BUF_FLAGS), + (void *)__entry->caller_ip) +); + +#define DEFINE_BUF_ITEM_EVENT(tname) \ +TRACE_EVENT(tname, \ + TP_PROTO(struct xfs_buf_log_item *bip), \ + TP_ARGS(bip), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_daddr_t, buf_bno) \ + __field(size_t, buf_len) \ + __field(int, buf_hold) \ + __field(int, buf_pincount) \ + __field(int, buf_lockval) \ + __field(unsigned, buf_flags) \ + __field(unsigned, bli_recur) \ + __field(int, bli_refcount) \ + __field(unsigned, bli_flags) \ + __field(void *, li_desc) \ + __field(unsigned, li_flags) \ + ), \ + TP_fast_assign( \ + __entry->dev = bip->bli_buf->b_target->bt_dev; \ + __entry->bli_flags = bip->bli_flags; \ + __entry->bli_recur = bip->bli_recur; \ + __entry->bli_refcount = atomic_read(&bip->bli_refcount); \ + __entry->buf_bno = bip->bli_buf->b_bn; \ + __entry->buf_len = bip->bli_buf->b_buffer_length; \ + __entry->buf_flags = bip->bli_buf->b_flags; \ + __entry->buf_hold = atomic_read(&bip->bli_buf->b_hold); \ + __entry->buf_pincount = \ + atomic_read(&bip->bli_buf->b_pin_count); \ + __entry->buf_lockval = xfs_buf_lock_value(bip->bli_buf); \ + __entry->li_desc = bip->bli_item.li_desc; \ + __entry->li_flags = bip->bli_item.li_flags; \ + ), \ + TP_printk("dev %d:%d bno 0x%llx len 0x%zx hold %d pincount %d " \ + "lock %d flags %s recur %d refcount %d bliflags %s " \ + "lidesc 0x%p liflags %s", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + (unsigned long long)__entry->buf_bno, \ + __entry->buf_len, \ + __entry->buf_hold, \ + __entry->buf_pincount, \ + __entry->buf_lockval, \ + __print_flags(__entry->buf_flags, "|", XFS_BUF_FLAGS), \ + __entry->bli_recur, \ + __entry->bli_refcount, \ + __print_flags(__entry->bli_flags, "|", XFS_BLI_FLAGS), \ + __entry->li_desc, \ + __print_flags(__entry->li_flags, "|", XFS_LI_FLAGS)) \ +) +DEFINE_BUF_ITEM_EVENT(xfs_buf_item_size); +DEFINE_BUF_ITEM_EVENT(xfs_buf_item_size_stale); +DEFINE_BUF_ITEM_EVENT(xfs_buf_item_format); +DEFINE_BUF_ITEM_EVENT(xfs_buf_item_format_stale); +DEFINE_BUF_ITEM_EVENT(xfs_buf_item_pin); +DEFINE_BUF_ITEM_EVENT(xfs_buf_item_unpin); +DEFINE_BUF_ITEM_EVENT(xfs_buf_item_unpin_stale); +DEFINE_BUF_ITEM_EVENT(xfs_buf_item_trylock); +DEFINE_BUF_ITEM_EVENT(xfs_buf_item_unlock); +DEFINE_BUF_ITEM_EVENT(xfs_buf_item_unlock_stale); +DEFINE_BUF_ITEM_EVENT(xfs_buf_item_committed); +DEFINE_BUF_ITEM_EVENT(xfs_buf_item_push); +DEFINE_BUF_ITEM_EVENT(xfs_trans_get_buf); +DEFINE_BUF_ITEM_EVENT(xfs_trans_get_buf_recur); +DEFINE_BUF_ITEM_EVENT(xfs_trans_getsb); +DEFINE_BUF_ITEM_EVENT(xfs_trans_getsb_recur); +DEFINE_BUF_ITEM_EVENT(xfs_trans_read_buf); +DEFINE_BUF_ITEM_EVENT(xfs_trans_read_buf_recur); +DEFINE_BUF_ITEM_EVENT(xfs_trans_log_buf); +DEFINE_BUF_ITEM_EVENT(xfs_trans_brelse); +DEFINE_BUF_ITEM_EVENT(xfs_trans_bjoin); +DEFINE_BUF_ITEM_EVENT(xfs_trans_bhold); +DEFINE_BUF_ITEM_EVENT(xfs_trans_bhold_release); +DEFINE_BUF_ITEM_EVENT(xfs_trans_binval); + +#define DEFINE_LOCK_EVENT(name) \ +TRACE_EVENT(name, \ + TP_PROTO(struct xfs_inode *ip, unsigned lock_flags, \ + unsigned long caller_ip), \ + TP_ARGS(ip, lock_flags, caller_ip), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_ino_t, ino) \ + __field(int, lock_flags) \ + __field(unsigned long, caller_ip) \ + ), \ + TP_fast_assign( \ + __entry->dev = VFS_I(ip)->i_sb->s_dev; \ + __entry->ino = ip->i_ino; \ + __entry->lock_flags = lock_flags; \ + __entry->caller_ip = caller_ip; \ + ), \ + TP_printk("dev %d:%d ino 0x%llx flags %s caller %pf", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + __entry->ino, \ + __print_flags(__entry->lock_flags, "|", XFS_LOCK_FLAGS), \ + (void *)__entry->caller_ip) \ +) + +DEFINE_LOCK_EVENT(xfs_ilock); +DEFINE_LOCK_EVENT(xfs_ilock_nowait); +DEFINE_LOCK_EVENT(xfs_ilock_demote); +DEFINE_LOCK_EVENT(xfs_iunlock); + +#define DEFINE_IGET_EVENT(name) \ +TRACE_EVENT(name, \ + TP_PROTO(struct xfs_inode *ip), \ + TP_ARGS(ip), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_ino_t, ino) \ + ), \ + TP_fast_assign( \ + __entry->dev = VFS_I(ip)->i_sb->s_dev; \ + __entry->ino = ip->i_ino; \ + ), \ + TP_printk("dev %d:%d ino 0x%llx", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + __entry->ino) \ +) +DEFINE_IGET_EVENT(xfs_iget_skip); +DEFINE_IGET_EVENT(xfs_iget_reclaim); +DEFINE_IGET_EVENT(xfs_iget_found); +DEFINE_IGET_EVENT(xfs_iget_alloc); + +#define DEFINE_INODE_EVENT(name) \ +TRACE_EVENT(name, \ + TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), \ + TP_ARGS(ip, caller_ip), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_ino_t, ino) \ + __field(int, count) \ + __field(unsigned long, caller_ip) \ + ), \ + TP_fast_assign( \ + __entry->dev = VFS_I(ip)->i_sb->s_dev; \ + __entry->ino = ip->i_ino; \ + __entry->count = atomic_read(&VFS_I(ip)->i_count); \ + __entry->caller_ip = caller_ip; \ + ), \ + TP_printk("dev %d:%d ino 0x%llx count %d caller %pf", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + __entry->ino, \ + __entry->count, \ + (char *)__entry->caller_ip) \ +) +DEFINE_INODE_EVENT(xfs_ihold); +DEFINE_INODE_EVENT(xfs_irele); +/* the old xfs_itrace_entry tracer - to be replaced by s.th. in the VFS */ +DEFINE_INODE_EVENT(xfs_inode); +#define xfs_itrace_entry(ip) \ + trace_xfs_inode(ip, _THIS_IP_) + +#define DEFINE_DQUOT_EVENT(tname) \ +TRACE_EVENT(tname, \ + TP_PROTO(struct xfs_dquot *dqp), \ + TP_ARGS(dqp), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(__be32, id) \ + __field(unsigned, flags) \ + __field(unsigned, nrefs) \ + __field(unsigned long long, res_bcount) \ + __field(unsigned long long, bcount) \ + __field(unsigned long long, icount) \ + __field(unsigned long long, blk_hardlimit) \ + __field(unsigned long long, blk_softlimit) \ + __field(unsigned long long, ino_hardlimit) \ + __field(unsigned long long, ino_softlimit) \ + ), \ + TP_fast_assign( \ + __entry->dev = dqp->q_mount->m_super->s_dev; \ + __entry->id = dqp->q_core.d_id; \ + __entry->flags = dqp->dq_flags; \ + __entry->nrefs = dqp->q_nrefs; \ + __entry->res_bcount = dqp->q_res_bcount; \ + __entry->bcount = be64_to_cpu(dqp->q_core.d_bcount); \ + __entry->icount = be64_to_cpu(dqp->q_core.d_icount); \ + __entry->blk_hardlimit = \ + be64_to_cpu(dqp->q_core.d_blk_hardlimit); \ + __entry->blk_softlimit = \ + be64_to_cpu(dqp->q_core.d_blk_softlimit); \ + __entry->ino_hardlimit = \ + be64_to_cpu(dqp->q_core.d_ino_hardlimit); \ + __entry->ino_softlimit = \ + be64_to_cpu(dqp->q_core.d_ino_softlimit); \ + ), \ + TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx " \ + "bcnt 0x%llx [hard 0x%llx | soft 0x%llx] " \ + "icnt 0x%llx [hard 0x%llx | soft 0x%llx]", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + be32_to_cpu(__entry->id), \ + __print_flags(__entry->flags, "|", XFS_DQ_FLAGS), \ + __entry->nrefs, \ + __entry->res_bcount, \ + __entry->bcount, \ + __entry->blk_hardlimit, \ + __entry->blk_softlimit, \ + __entry->icount, \ + __entry->ino_hardlimit, \ + __entry->ino_softlimit) \ +) +DEFINE_DQUOT_EVENT(xfs_dqadjust); +DEFINE_DQUOT_EVENT(xfs_dqshake_dirty); +DEFINE_DQUOT_EVENT(xfs_dqshake_unlink); +DEFINE_DQUOT_EVENT(xfs_dqreclaim_want); +DEFINE_DQUOT_EVENT(xfs_dqreclaim_dirty); +DEFINE_DQUOT_EVENT(xfs_dqreclaim_unlink); +DEFINE_DQUOT_EVENT(xfs_dqattach_found); +DEFINE_DQUOT_EVENT(xfs_dqattach_get); +DEFINE_DQUOT_EVENT(xfs_dqinit); +DEFINE_DQUOT_EVENT(xfs_dqreuse); +DEFINE_DQUOT_EVENT(xfs_dqalloc); +DEFINE_DQUOT_EVENT(xfs_dqtobp_read); +DEFINE_DQUOT_EVENT(xfs_dqread); +DEFINE_DQUOT_EVENT(xfs_dqread_fail); +DEFINE_DQUOT_EVENT(xfs_dqlookup_found); +DEFINE_DQUOT_EVENT(xfs_dqlookup_want); +DEFINE_DQUOT_EVENT(xfs_dqlookup_freelist); +DEFINE_DQUOT_EVENT(xfs_dqlookup_move); +DEFINE_DQUOT_EVENT(xfs_dqlookup_done); +DEFINE_DQUOT_EVENT(xfs_dqget_hit); +DEFINE_DQUOT_EVENT(xfs_dqget_miss); +DEFINE_DQUOT_EVENT(xfs_dqput); +DEFINE_DQUOT_EVENT(xfs_dqput_wait); +DEFINE_DQUOT_EVENT(xfs_dqput_free); +DEFINE_DQUOT_EVENT(xfs_dqrele); +DEFINE_DQUOT_EVENT(xfs_dqflush); +DEFINE_DQUOT_EVENT(xfs_dqflush_force); +DEFINE_DQUOT_EVENT(xfs_dqflush_done); +/* not really iget events, but we re-use the format */ +DEFINE_IGET_EVENT(xfs_dquot_dqalloc); +DEFINE_IGET_EVENT(xfs_dquot_dqdetach); + + +#define DEFINE_LOGGRANT_EVENT(tname) \ +TRACE_EVENT(tname, \ + TP_PROTO(struct log *log, struct xlog_ticket *tic), \ + TP_ARGS(log, tic), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(unsigned, trans_type) \ + __field(char, ocnt) \ + __field(char, cnt) \ + __field(int, curr_res) \ + __field(int, unit_res) \ + __field(unsigned int, flags) \ + __field(void *, reserve_headq) \ + __field(void *, write_headq) \ + __field(int, grant_reserve_cycle) \ + __field(int, grant_reserve_bytes) \ + __field(int, grant_write_cycle) \ + __field(int, grant_write_bytes) \ + __field(int, curr_cycle) \ + __field(int, curr_block) \ + __field(xfs_lsn_t, tail_lsn) \ + ), \ + TP_fast_assign( \ + __entry->dev = log->l_mp->m_super->s_dev; \ + __entry->trans_type = tic->t_trans_type; \ + __entry->ocnt = tic->t_ocnt; \ + __entry->cnt = tic->t_cnt; \ + __entry->curr_res = tic->t_curr_res; \ + __entry->unit_res = tic->t_unit_res; \ + __entry->flags = tic->t_flags; \ + __entry->reserve_headq = log->l_reserve_headq; \ + __entry->write_headq = log->l_write_headq; \ + __entry->grant_reserve_cycle = log->l_grant_reserve_cycle; \ + __entry->grant_reserve_bytes = log->l_grant_reserve_bytes; \ + __entry->grant_write_cycle = log->l_grant_write_cycle; \ + __entry->grant_write_bytes = log->l_grant_write_bytes; \ + __entry->curr_cycle = log->l_curr_cycle; \ + __entry->curr_block = log->l_curr_block; \ + __entry->tail_lsn = log->l_tail_lsn; \ + ), \ + TP_printk("dev %d:%d type %s t_ocnt %u t_cnt %u t_curr_res %u " \ + "t_unit_res %u t_flags %s reserve_headq 0x%p " \ + "write_headq 0x%p grant_reserve_cycle %d " \ + "grant_reserve_bytes %d grant_write_cycle %d " \ + "grant_write_bytes %d curr_cycle %d curr_block %d " \ + "tail_cycle %d tail_block %d", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + __print_symbolic(__entry->trans_type, XFS_TRANS_TYPES), \ + __entry->ocnt, \ + __entry->cnt, \ + __entry->curr_res, \ + __entry->unit_res, \ + __print_flags(__entry->flags, "|", XLOG_TIC_FLAGS), \ + __entry->reserve_headq, \ + __entry->write_headq, \ + __entry->grant_reserve_cycle, \ + __entry->grant_reserve_bytes, \ + __entry->grant_write_cycle, \ + __entry->grant_write_bytes, \ + __entry->curr_cycle, \ + __entry->curr_block, \ + CYCLE_LSN(__entry->tail_lsn), \ + BLOCK_LSN(__entry->tail_lsn) \ + ) \ +) +DEFINE_LOGGRANT_EVENT(xfs_log_done_nonperm); +DEFINE_LOGGRANT_EVENT(xfs_log_done_perm); +DEFINE_LOGGRANT_EVENT(xfs_log_reserve); +DEFINE_LOGGRANT_EVENT(xfs_log_umount_write); +DEFINE_LOGGRANT_EVENT(xfs_log_grant_enter); +DEFINE_LOGGRANT_EVENT(xfs_log_grant_exit); +DEFINE_LOGGRANT_EVENT(xfs_log_grant_error); +DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep1); +DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake1); +DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep2); +DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake2); +DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_enter); +DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_exit); +DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_error); +DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep1); +DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake1); +DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep2); +DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake2); +DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_enter); +DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_exit); +DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_sub); +DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_enter); +DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_exit); +DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_sub); + +#define DEFINE_RW_EVENT(name) \ +TRACE_EVENT(name, \ + TP_PROTO(struct xfs_inode *ip, size_t count, loff_t offset, int flags), \ + TP_ARGS(ip, count, offset, flags), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_ino_t, ino) \ + __field(xfs_fsize_t, size) \ + __field(xfs_fsize_t, new_size) \ + __field(loff_t, offset) \ + __field(size_t, count) \ + __field(int, flags) \ + ), \ + TP_fast_assign( \ + __entry->dev = VFS_I(ip)->i_sb->s_dev; \ + __entry->ino = ip->i_ino; \ + __entry->size = ip->i_d.di_size; \ + __entry->new_size = ip->i_new_size; \ + __entry->offset = offset; \ + __entry->count = count; \ + __entry->flags = flags; \ + ), \ + TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \ + "offset 0x%llx count 0x%zx ioflags %s", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + __entry->ino, \ + __entry->size, \ + __entry->new_size, \ + __entry->offset, \ + __entry->count, \ + __print_flags(__entry->flags, "|", XFS_IO_FLAGS)) \ +) +DEFINE_RW_EVENT(xfs_file_read); +DEFINE_RW_EVENT(xfs_file_buffered_write); +DEFINE_RW_EVENT(xfs_file_direct_write); +DEFINE_RW_EVENT(xfs_file_splice_read); +DEFINE_RW_EVENT(xfs_file_splice_write); + + +#define DEFINE_PAGE_EVENT(name) \ +TRACE_EVENT(name, \ + TP_PROTO(struct inode *inode, struct page *page, unsigned long off), \ + TP_ARGS(inode, page, off), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_ino_t, ino) \ + __field(pgoff_t, pgoff) \ + __field(loff_t, size) \ + __field(unsigned long, offset) \ + __field(int, delalloc) \ + __field(int, unmapped) \ + __field(int, unwritten) \ + ), \ + TP_fast_assign( \ + int delalloc = -1, unmapped = -1, unwritten = -1; \ + \ + if (page_has_buffers(page)) \ + xfs_count_page_state(page, &delalloc, \ + &unmapped, &unwritten); \ + __entry->dev = inode->i_sb->s_dev; \ + __entry->ino = XFS_I(inode)->i_ino; \ + __entry->pgoff = page_offset(page); \ + __entry->size = i_size_read(inode); \ + __entry->offset = off; \ + __entry->delalloc = delalloc; \ + __entry->unmapped = unmapped; \ + __entry->unwritten = unwritten; \ + ), \ + TP_printk("dev %d:%d ino 0x%llx pgoff 0x%lx size 0x%llx offset %lx " \ + "delalloc %d unmapped %d unwritten %d", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + __entry->ino, \ + __entry->pgoff, \ + __entry->size, \ + __entry->offset, \ + __entry->delalloc, \ + __entry->unmapped, \ + __entry->unwritten) \ +) +DEFINE_PAGE_EVENT(xfs_writepage); +DEFINE_PAGE_EVENT(xfs_releasepage); +DEFINE_PAGE_EVENT(xfs_invalidatepage); + +#define DEFINE_IOMAP_EVENT(name) \ +TRACE_EVENT(name, \ + TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, \ + int flags, struct xfs_bmbt_irec *irec), \ + TP_ARGS(ip, offset, count, flags, irec), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_ino_t, ino) \ + __field(loff_t, size) \ + __field(loff_t, new_size) \ + __field(loff_t, offset) \ + __field(size_t, count) \ + __field(int, flags) \ + __field(xfs_fileoff_t, startoff) \ + __field(xfs_fsblock_t, startblock) \ + __field(xfs_filblks_t, blockcount) \ + ), \ + TP_fast_assign( \ + __entry->dev = VFS_I(ip)->i_sb->s_dev; \ + __entry->ino = ip->i_ino; \ + __entry->size = ip->i_d.di_size; \ + __entry->new_size = ip->i_new_size; \ + __entry->offset = offset; \ + __entry->count = count; \ + __entry->flags = flags; \ + __entry->startoff = irec ? irec->br_startoff : 0; \ + __entry->startblock = irec ? irec->br_startblock : 0; \ + __entry->blockcount = irec ? irec->br_blockcount : 0; \ + ), \ + TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \ + "offset 0x%llx count %zd flags %s " \ + "startoff 0x%llx startblock 0x%llx blockcount 0x%llx", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + __entry->ino, \ + __entry->size, \ + __entry->new_size, \ + __entry->offset, \ + __entry->count, \ + __print_flags(__entry->flags, "|", BMAPI_FLAGS), \ + __entry->startoff, \ + __entry->startblock, \ + __entry->blockcount) \ +) +DEFINE_IOMAP_EVENT(xfs_iomap_enter); +DEFINE_IOMAP_EVENT(xfs_iomap_found); +DEFINE_IOMAP_EVENT(xfs_iomap_alloc); + +#define DEFINE_SIMPLE_IO_EVENT(name) \ +TRACE_EVENT(name, \ + TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count), \ + TP_ARGS(ip, offset, count), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_ino_t, ino) \ + __field(loff_t, size) \ + __field(loff_t, new_size) \ + __field(loff_t, offset) \ + __field(size_t, count) \ + ), \ + TP_fast_assign( \ + __entry->dev = VFS_I(ip)->i_sb->s_dev; \ + __entry->ino = ip->i_ino; \ + __entry->size = ip->i_d.di_size; \ + __entry->new_size = ip->i_new_size; \ + __entry->offset = offset; \ + __entry->count = count; \ + ), \ + TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \ + "offset 0x%llx count %zd", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + __entry->ino, \ + __entry->size, \ + __entry->new_size, \ + __entry->offset, \ + __entry->count) \ +); +DEFINE_SIMPLE_IO_EVENT(xfs_delalloc_enospc); +DEFINE_SIMPLE_IO_EVENT(xfs_unwritten_convert); + + +TRACE_EVENT(xfs_itruncate_start, + TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size, int flag, + xfs_off_t toss_start, xfs_off_t toss_finish), + TP_ARGS(ip, new_size, flag, toss_start, toss_finish), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(xfs_fsize_t, size) + __field(xfs_fsize_t, new_size) + __field(xfs_off_t, toss_start) + __field(xfs_off_t, toss_finish) + __field(int, flag) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->size = ip->i_d.di_size; + __entry->new_size = new_size; + __entry->toss_start = toss_start; + __entry->toss_finish = toss_finish; + __entry->flag = flag; + ), + TP_printk("dev %d:%d ino 0x%llx %s size 0x%llx new_size 0x%llx " + "toss start 0x%llx toss finish 0x%llx", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __print_flags(__entry->flag, "|", XFS_ITRUNC_FLAGS), + __entry->size, + __entry->new_size, + __entry->toss_start, + __entry->toss_finish) +); + +#define DEFINE_ITRUNC_EVENT(name) \ +TRACE_EVENT(name, \ + TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size), \ + TP_ARGS(ip, new_size), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_ino_t, ino) \ + __field(xfs_fsize_t, size) \ + __field(xfs_fsize_t, new_size) \ + ), \ + TP_fast_assign( \ + __entry->dev = VFS_I(ip)->i_sb->s_dev; \ + __entry->ino = ip->i_ino; \ + __entry->size = ip->i_d.di_size; \ + __entry->new_size = new_size; \ + ), \ + TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + __entry->ino, \ + __entry->size, \ + __entry->new_size) \ +) +DEFINE_ITRUNC_EVENT(xfs_itruncate_finish_start); +DEFINE_ITRUNC_EVENT(xfs_itruncate_finish_end); + +TRACE_EVENT(xfs_pagecache_inval, + TP_PROTO(struct xfs_inode *ip, xfs_off_t start, xfs_off_t finish), + TP_ARGS(ip, start, finish), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(xfs_fsize_t, size) + __field(xfs_off_t, start) + __field(xfs_off_t, finish) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->size = ip->i_d.di_size; + __entry->start = start; + __entry->finish = finish; + ), + TP_printk("dev %d:%d ino 0x%llx size 0x%llx start 0x%llx finish 0x%llx", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->size, + __entry->start, + __entry->finish) +); + +TRACE_EVENT(xfs_bunmap, + TP_PROTO(struct xfs_inode *ip, xfs_fileoff_t bno, xfs_filblks_t len, + int flags, unsigned long caller_ip), + TP_ARGS(ip, bno, len, flags, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(xfs_fsize_t, size) + __field(xfs_fileoff_t, bno) + __field(xfs_filblks_t, len) + __field(unsigned long, caller_ip) + __field(int, flags) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->size = ip->i_d.di_size; + __entry->bno = bno; + __entry->len = len; + __entry->caller_ip = caller_ip; + __entry->flags = flags; + ), + TP_printk("dev %d:%d ino 0x%llx size 0x%llx bno 0x%llx len 0x%llx" + "flags %s caller %pf", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->size, + __entry->bno, + __entry->len, + __print_flags(__entry->flags, "|", XFS_BMAPI_FLAGS), + (void *)__entry->caller_ip) + +); + +TRACE_EVENT(xfs_alloc_busy, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno, + xfs_extlen_t len, int slot), + TP_ARGS(mp, agno, agbno, len, slot), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_agblock_t, agbno) + __field(xfs_extlen_t, len) + __field(int, slot) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->agbno = agbno; + __entry->len = len; + __entry->slot = slot; + ), + TP_printk("dev %d:%d agno %u agbno %u len %u slot %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->agbno, + __entry->len, + __entry->slot) + +); + +#define XFS_BUSY_STATES \ + { 0, "found" }, \ + { 1, "missing" } + +TRACE_EVENT(xfs_alloc_unbusy, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, + int slot, int found), + TP_ARGS(mp, agno, slot, found), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(int, slot) + __field(int, found) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->slot = slot; + __entry->found = found; + ), + TP_printk("dev %d:%d agno %u slot %d %s", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->slot, + __print_symbolic(__entry->found, XFS_BUSY_STATES)) +); + +TRACE_EVENT(xfs_alloc_busysearch, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno, + xfs_extlen_t len, int found), + TP_ARGS(mp, agno, agbno, len, found), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_agblock_t, agbno) + __field(xfs_extlen_t, len) + __field(int, found) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->agbno = agbno; + __entry->len = len; + __entry->found = found; + ), + TP_printk("dev %d:%d agno %u agbno %u len %u %s", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->agbno, + __entry->len, + __print_symbolic(__entry->found, XFS_BUSY_STATES)) +); + +TRACE_EVENT(xfs_agf, + TP_PROTO(struct xfs_mount *mp, struct xfs_agf *agf, int flags, + unsigned long caller_ip), + TP_ARGS(mp, agf, flags, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(int, flags) + __field(__u32, length) + __field(__u32, bno_root) + __field(__u32, cnt_root) + __field(__u32, bno_level) + __field(__u32, cnt_level) + __field(__u32, flfirst) + __field(__u32, fllast) + __field(__u32, flcount) + __field(__u32, freeblks) + __field(__u32, longest) + __field(unsigned long, caller_ip) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = be32_to_cpu(agf->agf_seqno), + __entry->flags = flags; + __entry->length = be32_to_cpu(agf->agf_length), + __entry->bno_root = be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]), + __entry->cnt_root = be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]), + __entry->bno_level = + be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]), + __entry->cnt_level = + be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]), + __entry->flfirst = be32_to_cpu(agf->agf_flfirst), + __entry->fllast = be32_to_cpu(agf->agf_fllast), + __entry->flcount = be32_to_cpu(agf->agf_flcount), + __entry->freeblks = be32_to_cpu(agf->agf_freeblks), + __entry->longest = be32_to_cpu(agf->agf_longest); + __entry->caller_ip = caller_ip; + ), + TP_printk("dev %d:%d agno %u flags %s length %u roots b %u c %u " + "levels b %u c %u flfirst %u fllast %u flcount %u " + "freeblks %u longest %u caller %pf", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __print_flags(__entry->flags, "|", XFS_AGF_FLAGS), + __entry->length, + __entry->bno_root, + __entry->cnt_root, + __entry->bno_level, + __entry->cnt_level, + __entry->flfirst, + __entry->fllast, + __entry->flcount, + __entry->freeblks, + __entry->longest, + (void *)__entry->caller_ip) +); + +TRACE_EVENT(xfs_free_extent, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno, + xfs_extlen_t len, bool isfl, int haveleft, int haveright), + TP_ARGS(mp, agno, agbno, len, isfl, haveleft, haveright), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_agblock_t, agbno) + __field(xfs_extlen_t, len) + __field(int, isfl) + __field(int, haveleft) + __field(int, haveright) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->agbno = agbno; + __entry->len = len; + __entry->isfl = isfl; + __entry->haveleft = haveleft; + __entry->haveright = haveright; + ), + TP_printk("dev %d:%d agno %u agbno %u len %u isfl %d %s", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->agbno, + __entry->len, + __entry->isfl, + __entry->haveleft ? + (__entry->haveright ? "both" : "left") : + (__entry->haveright ? "right" : "none")) + +); + +#define DEFINE_ALLOC_EVENT(name) \ +TRACE_EVENT(name, \ + TP_PROTO(struct xfs_alloc_arg *args), \ + TP_ARGS(args), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_agnumber_t, agno) \ + __field(xfs_agblock_t, agbno) \ + __field(xfs_extlen_t, minlen) \ + __field(xfs_extlen_t, maxlen) \ + __field(xfs_extlen_t, mod) \ + __field(xfs_extlen_t, prod) \ + __field(xfs_extlen_t, minleft) \ + __field(xfs_extlen_t, total) \ + __field(xfs_extlen_t, alignment) \ + __field(xfs_extlen_t, minalignslop) \ + __field(xfs_extlen_t, len) \ + __field(short, type) \ + __field(short, otype) \ + __field(char, wasdel) \ + __field(char, wasfromfl) \ + __field(char, isfl) \ + __field(char, userdata) \ + __field(xfs_fsblock_t, firstblock) \ + ), \ + TP_fast_assign( \ + __entry->dev = args->mp->m_super->s_dev; \ + __entry->agno = args->agno; \ + __entry->agbno = args->agbno; \ + __entry->minlen = args->minlen; \ + __entry->maxlen = args->maxlen; \ + __entry->mod = args->mod; \ + __entry->prod = args->prod; \ + __entry->minleft = args->minleft; \ + __entry->total = args->total; \ + __entry->alignment = args->alignment; \ + __entry->minalignslop = args->minalignslop; \ + __entry->len = args->len; \ + __entry->type = args->type; \ + __entry->otype = args->otype; \ + __entry->wasdel = args->wasdel; \ + __entry->wasfromfl = args->wasfromfl; \ + __entry->isfl = args->isfl; \ + __entry->userdata = args->userdata; \ + __entry->firstblock = args->firstblock; \ + ), \ + TP_printk("dev %d:%d agno %u agbno %u minlen %u maxlen %u mod %u " \ + "prod %u minleft %u total %u alignment %u minalignslop %u " \ + "len %u type %s otype %s wasdel %d wasfromfl %d isfl %d " \ + "userdata %d firstblock 0x%llx", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + __entry->agno, \ + __entry->agbno, \ + __entry->minlen, \ + __entry->maxlen, \ + __entry->mod, \ + __entry->prod, \ + __entry->minleft, \ + __entry->total, \ + __entry->alignment, \ + __entry->minalignslop, \ + __entry->len, \ + __print_symbolic(__entry->type, XFS_ALLOC_TYPES), \ + __print_symbolic(__entry->otype, XFS_ALLOC_TYPES), \ + __entry->wasdel, \ + __entry->wasfromfl, \ + __entry->isfl, \ + __entry->userdata, \ + __entry->firstblock) \ +) + +DEFINE_ALLOC_EVENT(xfs_alloc_exact_done); +DEFINE_ALLOC_EVENT(xfs_alloc_exact_error); +DEFINE_ALLOC_EVENT(xfs_alloc_near_nominleft); +DEFINE_ALLOC_EVENT(xfs_alloc_near_first); +DEFINE_ALLOC_EVENT(xfs_alloc_near_greater); +DEFINE_ALLOC_EVENT(xfs_alloc_near_lesser); +DEFINE_ALLOC_EVENT(xfs_alloc_near_error); +DEFINE_ALLOC_EVENT(xfs_alloc_size_neither); +DEFINE_ALLOC_EVENT(xfs_alloc_size_noentry); +DEFINE_ALLOC_EVENT(xfs_alloc_size_nominleft); +DEFINE_ALLOC_EVENT(xfs_alloc_size_done); +DEFINE_ALLOC_EVENT(xfs_alloc_size_error); +DEFINE_ALLOC_EVENT(xfs_alloc_small_freelist); +DEFINE_ALLOC_EVENT(xfs_alloc_small_notenough); +DEFINE_ALLOC_EVENT(xfs_alloc_small_done); +DEFINE_ALLOC_EVENT(xfs_alloc_small_error); +DEFINE_ALLOC_EVENT(xfs_alloc_vextent_badargs); +DEFINE_ALLOC_EVENT(xfs_alloc_vextent_nofix); +DEFINE_ALLOC_EVENT(xfs_alloc_vextent_noagbp); +DEFINE_ALLOC_EVENT(xfs_alloc_vextent_loopfailed); +DEFINE_ALLOC_EVENT(xfs_alloc_vextent_allfailed); + +#define DEFINE_DIR2_TRACE(tname) \ +TRACE_EVENT(tname, \ + TP_PROTO(struct xfs_da_args *args), \ + TP_ARGS(args), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_ino_t, ino) \ + __dynamic_array(char, name, args->namelen) \ + __field(int, namelen) \ + __field(xfs_dahash_t, hashval) \ + __field(xfs_ino_t, inumber) \ + __field(int, op_flags) \ + ), \ + TP_fast_assign( \ + __entry->dev = VFS_I(args->dp)->i_sb->s_dev; \ + __entry->ino = args->dp->i_ino; \ + if (args->namelen) \ + memcpy(__get_str(name), args->name, args->namelen); \ + __entry->namelen = args->namelen; \ + __entry->hashval = args->hashval; \ + __entry->inumber = args->inumber; \ + __entry->op_flags = args->op_flags; \ + ), \ + TP_printk("dev %d:%d ino 0x%llx name %.*s namelen %d hashval 0x%x " \ + "inumber 0x%llx op_flags %s", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + __entry->ino, \ + __entry->namelen, \ + __entry->namelen ? __get_str(name) : NULL, \ + __entry->namelen, \ + __entry->hashval, \ + __entry->inumber, \ + __print_flags(__entry->op_flags, "|", XFS_DA_OP_FLAGS)) \ +) +DEFINE_DIR2_TRACE(xfs_dir2_sf_addname); +DEFINE_DIR2_TRACE(xfs_dir2_sf_create); +DEFINE_DIR2_TRACE(xfs_dir2_sf_lookup); +DEFINE_DIR2_TRACE(xfs_dir2_sf_replace); +DEFINE_DIR2_TRACE(xfs_dir2_sf_removename); +DEFINE_DIR2_TRACE(xfs_dir2_sf_toino4); +DEFINE_DIR2_TRACE(xfs_dir2_sf_toino8); +DEFINE_DIR2_TRACE(xfs_dir2_sf_to_block); +DEFINE_DIR2_TRACE(xfs_dir2_block_addname); +DEFINE_DIR2_TRACE(xfs_dir2_block_lookup); +DEFINE_DIR2_TRACE(xfs_dir2_block_replace); +DEFINE_DIR2_TRACE(xfs_dir2_block_removename); +DEFINE_DIR2_TRACE(xfs_dir2_block_to_sf); +DEFINE_DIR2_TRACE(xfs_dir2_block_to_leaf); +DEFINE_DIR2_TRACE(xfs_dir2_leaf_addname); +DEFINE_DIR2_TRACE(xfs_dir2_leaf_lookup); +DEFINE_DIR2_TRACE(xfs_dir2_leaf_replace); +DEFINE_DIR2_TRACE(xfs_dir2_leaf_removename); +DEFINE_DIR2_TRACE(xfs_dir2_leaf_to_block); +DEFINE_DIR2_TRACE(xfs_dir2_leaf_to_node); +DEFINE_DIR2_TRACE(xfs_dir2_node_addname); +DEFINE_DIR2_TRACE(xfs_dir2_node_lookup); +DEFINE_DIR2_TRACE(xfs_dir2_node_replace); +DEFINE_DIR2_TRACE(xfs_dir2_node_removename); +DEFINE_DIR2_TRACE(xfs_dir2_node_to_leaf); + +#define DEFINE_DIR2_SPACE_TRACE(tname) \ +TRACE_EVENT(tname, \ + TP_PROTO(struct xfs_da_args *args, int idx), \ + TP_ARGS(args, idx), \ + TP_STRUCT__entry( \ + __field(dev_t, dev) \ + __field(xfs_ino_t, ino) \ + __field(int, op_flags) \ + __field(int, idx) \ + ), \ + TP_fast_assign( \ + __entry->dev = VFS_I(args->dp)->i_sb->s_dev; \ + __entry->ino = args->dp->i_ino; \ + __entry->op_flags = args->op_flags; \ + __entry->idx = idx; \ + ), \ + TP_printk("dev %d:%d ino 0x%llx op_flags %s index %d", \ + MAJOR(__entry->dev), MINOR(__entry->dev), \ + __entry->ino, \ + __print_flags(__entry->op_flags, "|", XFS_DA_OP_FLAGS), \ + __entry->idx) \ +) +DEFINE_DIR2_SPACE_TRACE(xfs_dir2_leafn_add); +DEFINE_DIR2_SPACE_TRACE(xfs_dir2_leafn_remove); +DEFINE_DIR2_SPACE_TRACE(xfs_dir2_grow_inode); +DEFINE_DIR2_SPACE_TRACE(xfs_dir2_shrink_inode); + +TRACE_EVENT(xfs_dir2_leafn_moveents, + TP_PROTO(struct xfs_da_args *args, int src_idx, int dst_idx, int count), + TP_ARGS(args, src_idx, dst_idx, count), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(int, op_flags) + __field(int, src_idx) + __field(int, dst_idx) + __field(int, count) + ), + TP_fast_assign( + __entry->dev = VFS_I(args->dp)->i_sb->s_dev; + __entry->ino = args->dp->i_ino; + __entry->op_flags = args->op_flags; + __entry->src_idx = src_idx; + __entry->dst_idx = dst_idx; + __entry->count = count; + ), + TP_printk("dev %d:%d ino 0x%llx op_flags %s " + "src_idx %d dst_idx %d count %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __print_flags(__entry->op_flags, "|", XFS_DA_OP_FLAGS), + __entry->src_idx, + __entry->dst_idx, + __entry->count) +); + +#endif /* _TRACE_XFS_H */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE xfs_trace +#include diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index 00cabf5..7c220b4 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h @@ -39,6 +39,10 @@ struct attrlist_cursor_kern; #define IO_ISDIRECT 0x00004 /* bypass page cache */ #define IO_INVIS 0x00020 /* don't update inode timestamps */ +#define XFS_IO_FLAGS \ + { IO_ISDIRECT, "DIRECT" }, \ + { IO_INVIS, "INVIS"} + /* * Flush/Invalidate options for vop_toss/flush/flushinval_pages. */ diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 2f3f2229..d7c7eea 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -47,6 +47,7 @@ #include "xfs_trans_space.h" #include "xfs_trans_priv.h" #include "xfs_qm.h" +#include "xfs_trace.h" /* @@ -112,10 +113,7 @@ xfs_qm_dqinit( init_completion(&dqp->q_flush); complete(&dqp->q_flush); -#ifdef XFS_DQUOT_TRACE - dqp->q_trace = ktrace_alloc(DQUOT_TRACE_SIZE, KM_NOFS); - xfs_dqtrace_entry(dqp, "DQINIT"); -#endif + trace_xfs_dqinit(dqp); } else { /* * Only the q_core portion was zeroed in dqreclaim_one(). @@ -136,10 +134,7 @@ xfs_qm_dqinit( dqp->q_hash = NULL; ASSERT(dqp->dq_flnext == dqp->dq_flprev); -#ifdef XFS_DQUOT_TRACE - ASSERT(dqp->q_trace); - xfs_dqtrace_entry(dqp, "DQRECLAIMED_INIT"); -#endif + trace_xfs_dqreuse(dqp); } /* @@ -167,13 +162,8 @@ xfs_qm_dqdestroy( mutex_destroy(&dqp->q_qlock); sv_destroy(&dqp->q_pinwait); - -#ifdef XFS_DQUOT_TRACE - if (dqp->q_trace) - ktrace_free(dqp->q_trace); - dqp->q_trace = NULL; -#endif kmem_zone_free(xfs_Gqm->qm_dqzone, dqp); + atomic_dec(&xfs_Gqm->qm_totaldquots); } @@ -195,49 +185,6 @@ xfs_qm_dqinit_core( d->dd_diskdq.d_flags = type; } - -#ifdef XFS_DQUOT_TRACE -/* - * Dquot tracing for debugging. - */ -/* ARGSUSED */ -void -__xfs_dqtrace_entry( - xfs_dquot_t *dqp, - char *func, - void *retaddr, - xfs_inode_t *ip) -{ - xfs_dquot_t *udqp = NULL; - xfs_ino_t ino = 0; - - ASSERT(dqp->q_trace); - if (ip) { - ino = ip->i_ino; - udqp = ip->i_udquot; - } - ktrace_enter(dqp->q_trace, - (void *)(__psint_t)DQUOT_KTRACE_ENTRY, - (void *)func, - (void *)(__psint_t)dqp->q_nrefs, - (void *)(__psint_t)dqp->dq_flags, - (void *)(__psint_t)dqp->q_res_bcount, - (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_bcount), - (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_icount), - (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_blk_hardlimit), - (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_blk_softlimit), - (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_ino_hardlimit), - (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_ino_softlimit), - (void *)(__psint_t)be32_to_cpu(dqp->q_core.d_id), - (void *)(__psint_t)current_pid(), - (void *)(__psint_t)ino, - (void *)(__psint_t)retaddr, - (void *)(__psint_t)udqp); - return; -} -#endif - - /* * If default limits are in force, push them into the dquot now. * We overwrite the dquot limits only if they are zero and this @@ -425,7 +372,8 @@ xfs_qm_dqalloc( xfs_trans_t *tp = *tpp; ASSERT(tp != NULL); - xfs_dqtrace_entry(dqp, "DQALLOC"); + + trace_xfs_dqalloc(dqp); /* * Initialize the bmap freelist prior to calling bmapi code. @@ -612,7 +560,8 @@ xfs_qm_dqtobp( * (in which case we already have the buf). */ if (! newdquot) { - xfs_dqtrace_entry(dqp, "DQTOBP READBUF"); + trace_xfs_dqtobp_read(dqp); + if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, dqp->q_blkno, XFS_QI_DQCHUNKLEN(mp), @@ -670,11 +619,12 @@ xfs_qm_dqread( ASSERT(tpp); + trace_xfs_dqread(dqp); + /* * get a pointer to the on-disk dquot and the buffer containing it * dqp already knows its own type (GROUP/USER). */ - xfs_dqtrace_entry(dqp, "DQREAD"); if ((error = xfs_qm_dqtobp(tpp, dqp, &ddqp, &bp, flags))) { return (error); } @@ -763,7 +713,7 @@ xfs_qm_idtodq( * or if the dquot didn't exist on disk and we ask to * allocate (ENOENT). */ - xfs_dqtrace_entry(dqp, "DQREAD FAIL"); + trace_xfs_dqread_fail(dqp); cancelflags |= XFS_TRANS_ABORT; goto error0; } @@ -817,7 +767,8 @@ xfs_qm_dqlookup( * id can't be modified without the hashlock anyway. */ if (be32_to_cpu(dqp->q_core.d_id) == id && dqp->q_mount == mp) { - xfs_dqtrace_entry(dqp, "DQFOUND BY LOOKUP"); + trace_xfs_dqlookup_found(dqp); + /* * All in core dquots must be on the dqlist of mp */ @@ -827,7 +778,7 @@ xfs_qm_dqlookup( if (dqp->q_nrefs == 0) { ASSERT (XFS_DQ_IS_ON_FREELIST(dqp)); if (! xfs_qm_freelist_lock_nowait(xfs_Gqm)) { - xfs_dqtrace_entry(dqp, "DQLOOKUP: WANT"); + trace_xfs_dqlookup_want(dqp); /* * We may have raced with dqreclaim_one() @@ -857,8 +808,7 @@ xfs_qm_dqlookup( /* * take it off the freelist */ - xfs_dqtrace_entry(dqp, - "DQLOOKUP: TAKEOFF FL"); + trace_xfs_dqlookup_freelist(dqp); XQM_FREELIST_REMOVE(dqp); /* xfs_qm_freelist_print(&(xfs_Gqm-> qm_dqfreelist), @@ -878,8 +828,7 @@ xfs_qm_dqlookup( */ ASSERT(mutex_is_locked(&qh->qh_lock)); if (dqp->HL_PREVP != &qh->qh_next) { - xfs_dqtrace_entry(dqp, - "DQLOOKUP: HASH MOVETOFRONT"); + trace_xfs_dqlookup_move(dqp); if ((d = dqp->HL_NEXT)) d->HL_PREVP = dqp->HL_PREVP; *(dqp->HL_PREVP) = d; @@ -889,7 +838,7 @@ xfs_qm_dqlookup( dqp->HL_PREVP = &qh->qh_next; qh->qh_next = dqp; } - xfs_dqtrace_entry(dqp, "LOOKUP END"); + trace_xfs_dqlookup_done(dqp); *O_dqpp = dqp; ASSERT(mutex_is_locked(&qh->qh_lock)); return (0); @@ -971,7 +920,7 @@ xfs_qm_dqget( ASSERT(*O_dqpp); ASSERT(XFS_DQ_IS_LOCKED(*O_dqpp)); mutex_unlock(&h->qh_lock); - xfs_dqtrace_entry(*O_dqpp, "DQGET DONE (FROM CACHE)"); + trace_xfs_dqget_hit(*O_dqpp); return (0); /* success */ } XQM_STATS_INC(xqmstats.xs_qm_dqcachemisses); @@ -1104,7 +1053,7 @@ xfs_qm_dqget( mutex_unlock(&h->qh_lock); dqret: ASSERT((ip == NULL) || xfs_isilocked(ip, XFS_ILOCK_EXCL)); - xfs_dqtrace_entry(dqp, "DQGET DONE"); + trace_xfs_dqget_miss(dqp); *O_dqpp = dqp; return (0); } @@ -1124,7 +1073,8 @@ xfs_qm_dqput( ASSERT(dqp->q_nrefs > 0); ASSERT(XFS_DQ_IS_LOCKED(dqp)); - xfs_dqtrace_entry(dqp, "DQPUT"); + + trace_xfs_dqput(dqp); if (dqp->q_nrefs != 1) { dqp->q_nrefs--; @@ -1137,7 +1087,7 @@ xfs_qm_dqput( * in the right order; but try to get it out-of-order first */ if (! xfs_qm_freelist_lock_nowait(xfs_Gqm)) { - xfs_dqtrace_entry(dqp, "DQPUT: FLLOCK-WAIT"); + trace_xfs_dqput_wait(dqp); xfs_dqunlock(dqp); xfs_qm_freelist_lock(xfs_Gqm); xfs_dqlock(dqp); @@ -1148,7 +1098,8 @@ xfs_qm_dqput( /* We can't depend on nrefs being == 1 here */ if (--dqp->q_nrefs == 0) { - xfs_dqtrace_entry(dqp, "DQPUT: ON FREELIST"); + trace_xfs_dqput_free(dqp); + /* * insert at end of the freelist. */ @@ -1196,7 +1147,7 @@ xfs_qm_dqrele( if (!dqp) return; - xfs_dqtrace_entry(dqp, "DQRELE"); + trace_xfs_dqrele(dqp); xfs_dqlock(dqp); /* @@ -1229,7 +1180,7 @@ xfs_qm_dqflush( ASSERT(XFS_DQ_IS_LOCKED(dqp)); ASSERT(!completion_done(&dqp->q_flush)); - xfs_dqtrace_entry(dqp, "DQFLUSH"); + trace_xfs_dqflush(dqp); /* * If not dirty, or it's pinned and we are not supposed to @@ -1259,7 +1210,6 @@ xfs_qm_dqflush( * the ondisk-dquot has already been allocated for. */ if ((error = xfs_qm_dqtobp(NULL, dqp, &ddqp, &bp, XFS_QMOPT_DOWARN))) { - xfs_dqtrace_entry(dqp, "DQTOBP FAIL"); ASSERT(error != ENOENT); /* * Quotas could have gotten turned off (ESRCH) @@ -1297,7 +1247,7 @@ xfs_qm_dqflush( * get stuck waiting in the write for too long. */ if (XFS_BUF_ISPINNED(bp)) { - xfs_dqtrace_entry(dqp, "DQFLUSH LOG FORCE"); + trace_xfs_dqflush_force(dqp); xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE); } @@ -1308,7 +1258,9 @@ xfs_qm_dqflush( } else { error = xfs_bwrite(mp, bp); } - xfs_dqtrace_entry(dqp, "DQFLUSH END"); + + trace_xfs_dqflush_done(dqp); + /* * dqp is still locked, but caller is free to unlock it now. */ @@ -1483,7 +1435,7 @@ xfs_qm_dqpurge( */ if (XFS_DQ_IS_DIRTY(dqp)) { int error; - xfs_dqtrace_entry(dqp, "DQPURGE ->DQFLUSH: DQDIRTY"); + /* dqflush unlocks dqflock */ /* * Given that dqpurge is a very rare occurrence, it is OK diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h index a2c16bc..a0f7da5 100644 --- a/fs/xfs/quota/xfs_dquot.h +++ b/fs/xfs/quota/xfs_dquot.h @@ -85,9 +85,6 @@ typedef struct xfs_dquot { struct completion q_flush; /* flush completion queue */ atomic_t q_pincount; /* dquot pin count */ wait_queue_head_t q_pinwait; /* dquot pinning wait queue */ -#ifdef XFS_DQUOT_TRACE - struct ktrace *q_trace; /* trace header structure */ -#endif } xfs_dquot_t; @@ -144,24 +141,6 @@ static inline void xfs_dqfunlock(xfs_dquot_t *dqp) (XFS_IS_UQUOTA_ON((d)->q_mount)) : \ (XFS_IS_OQUOTA_ON((d)->q_mount)))) -#ifdef XFS_DQUOT_TRACE -/* - * Dquot Tracing stuff. - */ -#define DQUOT_TRACE_SIZE 64 -#define DQUOT_KTRACE_ENTRY 1 - -extern void __xfs_dqtrace_entry(xfs_dquot_t *dqp, char *func, - void *, xfs_inode_t *); -#define xfs_dqtrace_entry_ino(a,b,ip) \ - __xfs_dqtrace_entry((a), (b), (void*)__return_address, (ip)) -#define xfs_dqtrace_entry(a,b) \ - __xfs_dqtrace_entry((a), (b), (void*)__return_address, NULL) -#else -#define xfs_dqtrace_entry(a,b) -#define xfs_dqtrace_entry_ino(a,b,ip) -#endif - #ifdef QUOTADEBUG extern void xfs_qm_dqprint(xfs_dquot_t *); #else diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 45b1bfe..9e627a8 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -47,6 +47,7 @@ #include "xfs_trans_space.h" #include "xfs_utils.h" #include "xfs_qm.h" +#include "xfs_trace.h" /* * The global quota manager. There is only one of these for the entire @@ -453,7 +454,7 @@ again: xfs_dqunlock(dqp); continue; } - xfs_dqtrace_entry(dqp, "FLUSHALL: DQDIRTY"); + /* XXX a sentinel would be better */ recl = XFS_QI_MPLRECLAIMS(mp); if (!xfs_dqflock_nowait(dqp)) { @@ -651,7 +652,7 @@ xfs_qm_dqattach_one( */ dqp = *IO_idqpp; if (dqp) { - xfs_dqtrace_entry(dqp, "DQATTACH: found in ip"); + trace_xfs_dqattach_found(dqp); return 0; } @@ -704,7 +705,7 @@ xfs_qm_dqattach_one( if (error) return error; - xfs_dqtrace_entry(dqp, "DQATTACH: found by dqget"); + trace_xfs_dqattach_get(dqp); /* * dqget may have dropped and re-acquired the ilock, but it guarantees @@ -890,15 +891,15 @@ xfs_qm_dqdetach( if (!(ip->i_udquot || ip->i_gdquot)) return; + trace_xfs_dquot_dqdetach(ip); + ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino); ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino); if (ip->i_udquot) { - xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip); xfs_qm_dqrele(ip->i_udquot); ip->i_udquot = NULL; } if (ip->i_gdquot) { - xfs_dqtrace_entry_ino(ip->i_gdquot, "DQDETTACH", ip); xfs_qm_dqrele(ip->i_gdquot); ip->i_gdquot = NULL; } @@ -977,7 +978,6 @@ xfs_qm_sync( * across a disk write */ xfs_qm_mplist_unlock(mp); - xfs_dqtrace_entry(dqp, "XQM_SYNC: DQFLUSH"); error = xfs_qm_dqflush(dqp, flush_flags); xfs_dqunlock(dqp); if (error && XFS_FORCED_SHUTDOWN(mp)) @@ -1350,7 +1350,8 @@ xfs_qm_reset_dqcounts( xfs_disk_dquot_t *ddq; int j; - xfs_buftrace("RESET DQUOTS", bp); + trace_xfs_reset_dqcounts(bp, _RET_IP_); + /* * Reset all counters and timers. They'll be * started afresh by xfs_qm_quotacheck. @@ -1543,7 +1544,9 @@ xfs_qm_quotacheck_dqadjust( xfs_qcnt_t rtblks) { ASSERT(XFS_DQ_IS_LOCKED(dqp)); - xfs_dqtrace_entry(dqp, "QCHECK DQADJUST"); + + trace_xfs_dqadjust(dqp); + /* * Adjust the inode count and the block count to reflect this inode's * resource usage. @@ -1994,7 +1997,9 @@ xfs_qm_shake_freelist( */ if (XFS_DQ_IS_DIRTY(dqp)) { int error; - xfs_dqtrace_entry(dqp, "DQSHAKE: DQDIRTY"); + + trace_xfs_dqshake_dirty(dqp); + /* * We flush it delayed write, so don't bother * releasing the mplock. @@ -2038,7 +2043,9 @@ xfs_qm_shake_freelist( return nreclaimed; goto tryagain; } - xfs_dqtrace_entry(dqp, "DQSHAKE: UNLINKING"); + + trace_xfs_dqshake_unlink(dqp); + #ifdef QUOTADEBUG cmn_err(CE_DEBUG, "Shake 0x%p, ID 0x%x\n", dqp, be32_to_cpu(dqp->q_core.d_id)); @@ -2125,7 +2132,9 @@ xfs_qm_dqreclaim_one(void) */ if (dqp->dq_flags & XFS_DQ_WANT) { ASSERT(! (dqp->dq_flags & XFS_DQ_INACTIVE)); - xfs_dqtrace_entry(dqp, "DQRECLAIM: DQWANT"); + + trace_xfs_dqreclaim_want(dqp); + xfs_dqunlock(dqp); xfs_qm_freelist_unlock(xfs_Gqm); if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS) @@ -2171,7 +2180,9 @@ xfs_qm_dqreclaim_one(void) */ if (XFS_DQ_IS_DIRTY(dqp)) { int error; - xfs_dqtrace_entry(dqp, "DQRECLAIM: DQDIRTY"); + + trace_xfs_dqreclaim_dirty(dqp); + /* * We flush it delayed write, so don't bother * releasing the freelist lock. @@ -2194,8 +2205,9 @@ xfs_qm_dqreclaim_one(void) if (!mutex_trylock(&dqp->q_hash->qh_lock)) goto mplistunlock; + trace_xfs_dqreclaim_unlink(dqp); + ASSERT(dqp->q_nrefs == 0); - xfs_dqtrace_entry(dqp, "DQRECLAIM: UNLINKING"); XQM_MPLIST_REMOVE(&(XFS_QI_MPL_LIST(dqp->q_mount)), dqp); XQM_HASHLIST_REMOVE(dqp->q_hash, dqp); XQM_FREELIST_REMOVE(dqp); @@ -2430,7 +2442,7 @@ xfs_qm_vop_dqalloc( } } if (uq) - xfs_dqtrace_entry_ino(uq, "DQALLOC", ip); + trace_xfs_dquot_dqalloc(ip); xfs_iunlock(ip, lockflags); if (O_udqpp) diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 5d1a3b9..71af76f 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c @@ -49,6 +49,7 @@ #include "xfs_buf_item.h" #include "xfs_utils.h" #include "xfs_qm.h" +#include "xfs_trace.h" #ifdef DEBUG # define qdprintk(s, args...) cmn_err(CE_DEBUG, s, ## args) @@ -496,7 +497,6 @@ xfs_qm_scall_setqlim( ASSERT(error != ENOENT); return (error); } - xfs_dqtrace_entry(dqp, "Q_SETQLIM: AFT DQGET"); xfs_trans_dqjoin(tp, dqp); ddq = &dqp->q_core; @@ -602,7 +602,6 @@ xfs_qm_scall_setqlim( dqp->dq_flags |= XFS_DQ_DIRTY; xfs_trans_log_dquot(tp, dqp); - xfs_dqtrace_entry(dqp, "Q_SETQLIM: COMMIT"); error = xfs_trans_commit(tp, 0); xfs_qm_dqprint(dqp); xfs_qm_dqrele(dqp); @@ -630,7 +629,6 @@ xfs_qm_scall_getquota( return (error); } - xfs_dqtrace_entry(dqp, "Q_GETQUOTA SUCCESS"); /* * If everything's NULL, this dquot doesn't quite exist as far as * our utility programs are concerned. diff --git a/fs/xfs/support/ktrace.c b/fs/xfs/support/ktrace.c deleted file mode 100644 index 2d494c2..0000000 --- a/fs/xfs/support/ktrace.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include - -static kmem_zone_t *ktrace_hdr_zone; -static kmem_zone_t *ktrace_ent_zone; -static int ktrace_zentries; - -void __init -ktrace_init(int zentries) -{ - ktrace_zentries = roundup_pow_of_two(zentries); - - ktrace_hdr_zone = kmem_zone_init(sizeof(ktrace_t), - "ktrace_hdr"); - ASSERT(ktrace_hdr_zone); - - ktrace_ent_zone = kmem_zone_init(ktrace_zentries - * sizeof(ktrace_entry_t), - "ktrace_ent"); - ASSERT(ktrace_ent_zone); -} - -void __exit -ktrace_uninit(void) -{ - kmem_zone_destroy(ktrace_hdr_zone); - kmem_zone_destroy(ktrace_ent_zone); -} - -/* - * ktrace_alloc() - * - * Allocate a ktrace header and enough buffering for the given - * number of entries. Round the number of entries up to a - * power of 2 so we can do fast masking to get the index from - * the atomic index counter. - */ -ktrace_t * -ktrace_alloc(int nentries, unsigned int __nocast sleep) -{ - ktrace_t *ktp; - ktrace_entry_t *ktep; - int entries; - - ktp = (ktrace_t*)kmem_zone_alloc(ktrace_hdr_zone, sleep); - - if (ktp == (ktrace_t*)NULL) { - /* - * KM_SLEEP callers don't expect failure. - */ - if (sleep & KM_SLEEP) - panic("ktrace_alloc: NULL memory on KM_SLEEP request!"); - - return NULL; - } - - /* - * Special treatment for buffers with the ktrace_zentries entries - */ - entries = roundup_pow_of_two(nentries); - if (entries == ktrace_zentries) { - ktep = (ktrace_entry_t*)kmem_zone_zalloc(ktrace_ent_zone, - sleep); - } else { - ktep = (ktrace_entry_t*)kmem_zalloc((entries * sizeof(*ktep)), - sleep | KM_LARGE); - } - - if (ktep == NULL) { - /* - * KM_SLEEP callers don't expect failure. - */ - if (sleep & KM_SLEEP) - panic("ktrace_alloc: NULL memory on KM_SLEEP request!"); - - kmem_free(ktp); - - return NULL; - } - - ktp->kt_entries = ktep; - ktp->kt_nentries = entries; - ASSERT(is_power_of_2(entries)); - ktp->kt_index_mask = entries - 1; - atomic_set(&ktp->kt_index, 0); - ktp->kt_rollover = 0; - return ktp; -} - - -/* - * ktrace_free() - * - * Free up the ktrace header and buffer. It is up to the caller - * to ensure that no-one is referencing it. - */ -void -ktrace_free(ktrace_t *ktp) -{ - if (ktp == (ktrace_t *)NULL) - return; - - /* - * Special treatment for the Vnode trace buffer. - */ - if (ktp->kt_nentries == ktrace_zentries) - kmem_zone_free(ktrace_ent_zone, ktp->kt_entries); - else - kmem_free(ktp->kt_entries); - - kmem_zone_free(ktrace_hdr_zone, ktp); -} - - -/* - * Enter the given values into the "next" entry in the trace buffer. - * kt_index is always the index of the next entry to be filled. - */ -void -ktrace_enter( - ktrace_t *ktp, - void *val0, - void *val1, - void *val2, - void *val3, - void *val4, - void *val5, - void *val6, - void *val7, - void *val8, - void *val9, - void *val10, - void *val11, - void *val12, - void *val13, - void *val14, - void *val15) -{ - int index; - ktrace_entry_t *ktep; - - ASSERT(ktp != NULL); - - /* - * Grab an entry by pushing the index up to the next one. - */ - index = atomic_add_return(1, &ktp->kt_index); - index = (index - 1) & ktp->kt_index_mask; - if (!ktp->kt_rollover && index == ktp->kt_nentries - 1) - ktp->kt_rollover = 1; - - ASSERT((index >= 0) && (index < ktp->kt_nentries)); - - ktep = &(ktp->kt_entries[index]); - - ktep->val[0] = val0; - ktep->val[1] = val1; - ktep->val[2] = val2; - ktep->val[3] = val3; - ktep->val[4] = val4; - ktep->val[5] = val5; - ktep->val[6] = val6; - ktep->val[7] = val7; - ktep->val[8] = val8; - ktep->val[9] = val9; - ktep->val[10] = val10; - ktep->val[11] = val11; - ktep->val[12] = val12; - ktep->val[13] = val13; - ktep->val[14] = val14; - ktep->val[15] = val15; -} - -/* - * Return the number of entries in the trace buffer. - */ -int -ktrace_nentries( - ktrace_t *ktp) -{ - int index; - if (ktp == NULL) - return 0; - - index = atomic_read(&ktp->kt_index) & ktp->kt_index_mask; - return (ktp->kt_rollover ? ktp->kt_nentries : index); -} - -/* - * ktrace_first() - * - * This is used to find the start of the trace buffer. - * In conjunction with ktrace_next() it can be used to - * iterate through the entire trace buffer. This code does - * not do any locking because it is assumed that it is called - * from the debugger. - * - * The caller must pass in a pointer to a ktrace_snap - * structure in which we will keep some state used to - * iterate through the buffer. This state must not touched - * by any code outside of this module. - */ -ktrace_entry_t * -ktrace_first(ktrace_t *ktp, ktrace_snap_t *ktsp) -{ - ktrace_entry_t *ktep; - int index; - int nentries; - - if (ktp->kt_rollover) - index = atomic_read(&ktp->kt_index) & ktp->kt_index_mask; - else - index = 0; - - ktsp->ks_start = index; - ktep = &(ktp->kt_entries[index]); - - nentries = ktrace_nentries(ktp); - index++; - if (index < nentries) { - ktsp->ks_index = index; - } else { - ktsp->ks_index = 0; - if (index > nentries) - ktep = NULL; - } - return ktep; -} - -/* - * ktrace_next() - * - * This is used to iterate through the entries of the given - * trace buffer. The caller must pass in the ktrace_snap_t - * structure initialized by ktrace_first(). The return value - * will be either a pointer to the next ktrace_entry or NULL - * if all of the entries have been traversed. - */ -ktrace_entry_t * -ktrace_next( - ktrace_t *ktp, - ktrace_snap_t *ktsp) -{ - int index; - ktrace_entry_t *ktep; - - index = ktsp->ks_index; - if (index == ktsp->ks_start) { - ktep = NULL; - } else { - ktep = &ktp->kt_entries[index]; - } - - index++; - if (index == ktrace_nentries(ktp)) { - ktsp->ks_index = 0; - } else { - ktsp->ks_index = index; - } - - return ktep; -} - -/* - * ktrace_skip() - * - * Skip the next "count" entries and return the entry after that. - * Return NULL if this causes us to iterate past the beginning again. - */ -ktrace_entry_t * -ktrace_skip( - ktrace_t *ktp, - int count, - ktrace_snap_t *ktsp) -{ - int index; - int new_index; - ktrace_entry_t *ktep; - int nentries = ktrace_nentries(ktp); - - index = ktsp->ks_index; - new_index = index + count; - while (new_index >= nentries) { - new_index -= nentries; - } - if (index == ktsp->ks_start) { - /* - * We've iterated around to the start, so we're done. - */ - ktep = NULL; - } else if ((new_index < index) && (index < ktsp->ks_index)) { - /* - * We've skipped past the start again, so we're done. - */ - ktep = NULL; - ktsp->ks_index = ktsp->ks_start; - } else { - ktep = &(ktp->kt_entries[new_index]); - new_index++; - if (new_index == nentries) { - ktsp->ks_index = 0; - } else { - ktsp->ks_index = new_index; - } - } - return ktep; -} diff --git a/fs/xfs/support/ktrace.h b/fs/xfs/support/ktrace.h deleted file mode 100644 index 741d694..0000000 --- a/fs/xfs/support/ktrace.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_SUPPORT_KTRACE_H__ -#define __XFS_SUPPORT_KTRACE_H__ - -/* - * Trace buffer entry structure. - */ -typedef struct ktrace_entry { - void *val[16]; -} ktrace_entry_t; - -/* - * Trace buffer header structure. - */ -typedef struct ktrace { - int kt_nentries; /* number of entries in trace buf */ - atomic_t kt_index; /* current index in entries */ - unsigned int kt_index_mask; - int kt_rollover; - ktrace_entry_t *kt_entries; /* buffer of entries */ -} ktrace_t; - -/* - * Trace buffer snapshot structure. - */ -typedef struct ktrace_snap { - int ks_start; /* kt_index at time of snap */ - int ks_index; /* current index */ -} ktrace_snap_t; - - -#ifdef CONFIG_XFS_TRACE - -extern void ktrace_init(int zentries); -extern void ktrace_uninit(void); - -extern ktrace_t *ktrace_alloc(int, unsigned int __nocast); -extern void ktrace_free(ktrace_t *); - -extern void ktrace_enter( - ktrace_t *, - void *, - void *, - void *, - void *, - void *, - void *, - void *, - void *, - void *, - void *, - void *, - void *, - void *, - void *, - void *, - void *); - -extern ktrace_entry_t *ktrace_first(ktrace_t *, ktrace_snap_t *); -extern int ktrace_nentries(ktrace_t *); -extern ktrace_entry_t *ktrace_next(ktrace_t *, ktrace_snap_t *); -extern ktrace_entry_t *ktrace_skip(ktrace_t *, int, ktrace_snap_t *); - -#else -#define ktrace_init(x) do { } while (0) -#define ktrace_uninit() do { } while (0) -#endif /* CONFIG_XFS_TRACE */ - -#endif /* __XFS_SUPPORT_KTRACE_H__ */ diff --git a/fs/xfs/xfs.h b/fs/xfs/xfs.h index 17254b5..5ad8ad3 100644 --- a/fs/xfs/xfs.h +++ b/fs/xfs/xfs.h @@ -25,21 +25,5 @@ /* #define QUOTADEBUG 1 */ #endif -#ifdef CONFIG_XFS_TRACE -#define XFS_ALLOC_TRACE 1 -#define XFS_ATTR_TRACE 1 -#define XFS_BLI_TRACE 1 -#define XFS_BMAP_TRACE 1 -#define XFS_BTREE_TRACE 1 -#define XFS_DIR2_TRACE 1 -#define XFS_DQUOT_TRACE 1 -#define XFS_ILOCK_TRACE 1 -#define XFS_LOG_TRACE 1 -#define XFS_RW_TRACE 1 -#define XFS_BUF_TRACE 1 -#define XFS_INODE_TRACE 1 -#define XFS_FILESTREAMS_TRACE 1 -#endif - #include #endif /* __XFS_H__ */ diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h index a5d54bf..6702bd8 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h @@ -86,6 +86,20 @@ typedef struct xfs_agf { #define XFS_AGF_NUM_BITS 12 #define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1) +#define XFS_AGF_FLAGS \ + { XFS_AGF_MAGICNUM, "MAGICNUM" }, \ + { XFS_AGF_VERSIONNUM, "VERSIONNUM" }, \ + { XFS_AGF_SEQNO, "SEQNO" }, \ + { XFS_AGF_LENGTH, "LENGTH" }, \ + { XFS_AGF_ROOTS, "ROOTS" }, \ + { XFS_AGF_LEVELS, "LEVELS" }, \ + { XFS_AGF_FLFIRST, "FLFIRST" }, \ + { XFS_AGF_FLLAST, "FLLAST" }, \ + { XFS_AGF_FLCOUNT, "FLCOUNT" }, \ + { XFS_AGF_FREEBLKS, "FREEBLKS" }, \ + { XFS_AGF_LONGEST, "LONGEST" }, \ + { XFS_AGF_BTREEBLKS, "BTREEBLKS" } + /* disk block (xfs_daddr_t) in the AG */ #define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log)) #define XFS_AGF_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp)) diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 2cf944e..a1c65fc 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c @@ -38,6 +38,7 @@ #include "xfs_ialloc.h" #include "xfs_alloc.h" #include "xfs_error.h" +#include "xfs_trace.h" #define XFS_ABSDIFF(a,b) (((a) <= (b)) ? ((b) - (a)) : ((a) - (b))) @@ -51,30 +52,6 @@ xfs_alloc_search_busy(xfs_trans_t *tp, xfs_agblock_t bno, xfs_extlen_t len); -#if defined(XFS_ALLOC_TRACE) -ktrace_t *xfs_alloc_trace_buf; - -#define TRACE_ALLOC(s,a) \ - xfs_alloc_trace_alloc(__func__, s, a, __LINE__) -#define TRACE_FREE(s,a,b,x,f) \ - xfs_alloc_trace_free(__func__, s, mp, a, b, x, f, __LINE__) -#define TRACE_MODAGF(s,a,f) \ - xfs_alloc_trace_modagf(__func__, s, mp, a, f, __LINE__) -#define TRACE_BUSY(__func__,s,ag,agb,l,sl,tp) \ - xfs_alloc_trace_busy(__func__, s, mp, ag, agb, l, sl, tp, XFS_ALLOC_KTRACE_BUSY, __LINE__) -#define TRACE_UNBUSY(__func__,s,ag,sl,tp) \ - xfs_alloc_trace_busy(__func__, s, mp, ag, -1, -1, sl, tp, XFS_ALLOC_KTRACE_UNBUSY, __LINE__) -#define TRACE_BUSYSEARCH(__func__,s,ag,agb,l,tp) \ - xfs_alloc_trace_busy(__func__, s, mp, ag, agb, l, 0, tp, XFS_ALLOC_KTRACE_BUSYSEARCH, __LINE__) -#else -#define TRACE_ALLOC(s,a) -#define TRACE_FREE(s,a,b,x,f) -#define TRACE_MODAGF(s,a,f) -#define TRACE_BUSY(s,a,ag,agb,l,sl,tp) -#define TRACE_UNBUSY(fname,s,ag,sl,tp) -#define TRACE_BUSYSEARCH(fname,s,ag,agb,l,tp) -#endif /* XFS_ALLOC_TRACE */ - /* * Prototypes for per-ag allocation routines */ @@ -498,124 +475,6 @@ xfs_alloc_read_agfl( return 0; } -#if defined(XFS_ALLOC_TRACE) -/* - * Add an allocation trace entry for an alloc call. - */ -STATIC void -xfs_alloc_trace_alloc( - const char *name, /* function tag string */ - char *str, /* additional string */ - xfs_alloc_arg_t *args, /* allocation argument structure */ - int line) /* source line number */ -{ - ktrace_enter(xfs_alloc_trace_buf, - (void *)(__psint_t)(XFS_ALLOC_KTRACE_ALLOC | (line << 16)), - (void *)name, - (void *)str, - (void *)args->mp, - (void *)(__psunsigned_t)args->agno, - (void *)(__psunsigned_t)args->agbno, - (void *)(__psunsigned_t)args->minlen, - (void *)(__psunsigned_t)args->maxlen, - (void *)(__psunsigned_t)args->mod, - (void *)(__psunsigned_t)args->prod, - (void *)(__psunsigned_t)args->minleft, - (void *)(__psunsigned_t)args->total, - (void *)(__psunsigned_t)args->alignment, - (void *)(__psunsigned_t)args->len, - (void *)((((__psint_t)args->type) << 16) | - (__psint_t)args->otype), - (void *)(__psint_t)((args->wasdel << 3) | - (args->wasfromfl << 2) | - (args->isfl << 1) | - (args->userdata << 0))); -} - -/* - * Add an allocation trace entry for a free call. - */ -STATIC void -xfs_alloc_trace_free( - const char *name, /* function tag string */ - char *str, /* additional string */ - xfs_mount_t *mp, /* file system mount point */ - xfs_agnumber_t agno, /* allocation group number */ - xfs_agblock_t agbno, /* a.g. relative block number */ - xfs_extlen_t len, /* length of extent */ - int isfl, /* set if is freelist allocation/free */ - int line) /* source line number */ -{ - ktrace_enter(xfs_alloc_trace_buf, - (void *)(__psint_t)(XFS_ALLOC_KTRACE_FREE | (line << 16)), - (void *)name, - (void *)str, - (void *)mp, - (void *)(__psunsigned_t)agno, - (void *)(__psunsigned_t)agbno, - (void *)(__psunsigned_t)len, - (void *)(__psint_t)isfl, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); -} - -/* - * Add an allocation trace entry for modifying an agf. - */ -STATIC void -xfs_alloc_trace_modagf( - const char *name, /* function tag string */ - char *str, /* additional string */ - xfs_mount_t *mp, /* file system mount point */ - xfs_agf_t *agf, /* new agf value */ - int flags, /* logging flags for agf */ - int line) /* source line number */ -{ - ktrace_enter(xfs_alloc_trace_buf, - (void *)(__psint_t)(XFS_ALLOC_KTRACE_MODAGF | (line << 16)), - (void *)name, - (void *)str, - (void *)mp, - (void *)(__psint_t)flags, - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_seqno), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_length), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_flfirst), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_fllast), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_flcount), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_freeblks), - (void *)(__psunsigned_t)be32_to_cpu(agf->agf_longest)); -} - -STATIC void -xfs_alloc_trace_busy( - const char *name, /* function tag string */ - char *str, /* additional string */ - xfs_mount_t *mp, /* file system mount point */ - xfs_agnumber_t agno, /* allocation group number */ - xfs_agblock_t agbno, /* a.g. relative block number */ - xfs_extlen_t len, /* length of extent */ - int slot, /* perag Busy slot */ - xfs_trans_t *tp, - int trtype, /* type: add, delete, search */ - int line) /* source line number */ -{ - ktrace_enter(xfs_alloc_trace_buf, - (void *)(__psint_t)(trtype | (line << 16)), - (void *)name, - (void *)str, - (void *)mp, - (void *)(__psunsigned_t)agno, - (void *)(__psunsigned_t)agbno, - (void *)(__psunsigned_t)len, - (void *)(__psint_t)slot, - (void *)tp, - NULL, NULL, NULL, NULL, NULL, NULL, NULL); -} -#endif /* XFS_ALLOC_TRACE */ - /* * Allocation group level functions. */ @@ -665,9 +524,6 @@ xfs_alloc_ag_vextent( */ if (args->agbno != NULLAGBLOCK) { xfs_agf_t *agf; /* allocation group freelist header */ -#ifdef XFS_ALLOC_TRACE - xfs_mount_t *mp = args->mp; -#endif long slen = (long)args->len; ASSERT(args->len >= args->minlen && args->len <= args->maxlen); @@ -682,7 +538,6 @@ xfs_alloc_ag_vextent( args->pag->pagf_freeblks -= args->len; ASSERT(be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length)); - TRACE_MODAGF(NULL, agf, XFS_AGF_FREEBLKS); xfs_alloc_log_agf(args->tp, args->agbp, XFS_AGF_FREEBLKS); /* search the busylist for these blocks */ @@ -792,13 +647,14 @@ xfs_alloc_ag_vextent_exact( } xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); - TRACE_ALLOC("normal", args); + + trace_xfs_alloc_exact_done(args); args->wasfromfl = 0; return 0; error0: xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR); - TRACE_ALLOC("error", args); + trace_xfs_alloc_exact_error(args); return error; } @@ -958,7 +814,7 @@ xfs_alloc_ag_vextent_near( args->len = blen; if (!xfs_alloc_fix_minleft(args)) { xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); - TRACE_ALLOC("nominleft", args); + trace_xfs_alloc_near_nominleft(args); return 0; } blen = args->len; @@ -981,7 +837,8 @@ xfs_alloc_ag_vextent_near( goto error0; xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); - TRACE_ALLOC("first", args); + + trace_xfs_alloc_near_first(args); return 0; } /* @@ -1272,7 +1129,7 @@ xfs_alloc_ag_vextent_near( * If we couldn't get anything, give up. */ if (bno_cur_lt == NULL && bno_cur_gt == NULL) { - TRACE_ALLOC("neither", args); + trace_xfs_alloc_size_neither(args); args->agbno = NULLAGBLOCK; return 0; } @@ -1299,7 +1156,7 @@ xfs_alloc_ag_vextent_near( args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); xfs_alloc_fix_len(args); if (!xfs_alloc_fix_minleft(args)) { - TRACE_ALLOC("nominleft", args); + trace_xfs_alloc_near_nominleft(args); xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); return 0; @@ -1314,13 +1171,18 @@ xfs_alloc_ag_vextent_near( if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, ltlen, ltnew, rlen, XFSA_FIXUP_BNO_OK))) goto error0; - TRACE_ALLOC(j ? "gt" : "lt", args); + + if (j) + trace_xfs_alloc_near_greater(args); + else + trace_xfs_alloc_near_lesser(args); + xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); return 0; error0: - TRACE_ALLOC("error", args); + trace_xfs_alloc_near_error(args); if (cnt_cur != NULL) xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); if (bno_cur_lt != NULL) @@ -1371,7 +1233,7 @@ xfs_alloc_ag_vextent_size( goto error0; if (i == 0 || flen == 0) { xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); - TRACE_ALLOC("noentry", args); + trace_xfs_alloc_size_noentry(args); return 0; } ASSERT(i == 1); @@ -1448,7 +1310,7 @@ xfs_alloc_ag_vextent_size( xfs_alloc_fix_len(args); if (rlen < args->minlen || !xfs_alloc_fix_minleft(args)) { xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); - TRACE_ALLOC("nominleft", args); + trace_xfs_alloc_size_nominleft(args); args->agbno = NULLAGBLOCK; return 0; } @@ -1471,11 +1333,11 @@ xfs_alloc_ag_vextent_size( args->agbno + args->len <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), error0); - TRACE_ALLOC("normal", args); + trace_xfs_alloc_size_done(args); return 0; error0: - TRACE_ALLOC("error", args); + trace_xfs_alloc_size_error(args); if (cnt_cur) xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); if (bno_cur) @@ -1534,7 +1396,7 @@ xfs_alloc_ag_vextent_small( be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), error0); args->wasfromfl = 1; - TRACE_ALLOC("freelist", args); + trace_xfs_alloc_small_freelist(args); *stat = 0; return 0; } @@ -1556,17 +1418,17 @@ xfs_alloc_ag_vextent_small( */ if (flen < args->minlen) { args->agbno = NULLAGBLOCK; - TRACE_ALLOC("notenough", args); + trace_xfs_alloc_small_notenough(args); flen = 0; } *fbnop = fbno; *flenp = flen; *stat = 1; - TRACE_ALLOC("normal", args); + trace_xfs_alloc_small_done(args); return 0; error0: - TRACE_ALLOC("error", args); + trace_xfs_alloc_small_error(args); return error; } @@ -1809,17 +1671,14 @@ xfs_free_ag_extent( be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length), error0); - TRACE_MODAGF(NULL, agf, XFS_AGF_FREEBLKS); xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS); if (!isfl) xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len); XFS_STATS_INC(xs_freex); XFS_STATS_ADD(xs_freeb, len); } - TRACE_FREE(haveleft ? - (haveright ? "both" : "left") : - (haveright ? "right" : "none"), - agno, bno, len, isfl); + + trace_xfs_free_extent(mp, agno, bno, len, isfl, haveleft, haveright); /* * Since blocks move to the free list without the coordination @@ -1836,7 +1695,7 @@ xfs_free_ag_extent( return 0; error0: - TRACE_FREE("error", agno, bno, len, isfl); + trace_xfs_free_extent(mp, agno, bno, len, isfl, -1, -1); if (bno_cur) xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR); if (cnt_cur) @@ -2122,7 +1981,6 @@ xfs_alloc_get_freelist( logflags |= XFS_AGF_BTREEBLKS; } - TRACE_MODAGF(NULL, agf, logflags); xfs_alloc_log_agf(tp, agbp, logflags); *bnop = bno; @@ -2165,6 +2023,8 @@ xfs_alloc_log_agf( sizeof(xfs_agf_t) }; + trace_xfs_agf(tp->t_mountp, XFS_BUF_TO_AGF(bp), fields, _RET_IP_); + xfs_btree_offsets(fields, offsets, XFS_AGF_NUM_BITS, &first, &last); xfs_trans_log_buf(tp, bp, (uint)first, (uint)last); } @@ -2230,13 +2090,11 @@ xfs_alloc_put_freelist( logflags |= XFS_AGF_BTREEBLKS; } - TRACE_MODAGF(NULL, agf, logflags); xfs_alloc_log_agf(tp, agbp, logflags); ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)); blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)]; *blockp = cpu_to_be32(bno); - TRACE_MODAGF(NULL, agf, logflags); xfs_alloc_log_agf(tp, agbp, logflags); xfs_trans_log_buf(tp, agflbp, (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl), @@ -2399,7 +2257,7 @@ xfs_alloc_vextent( args->minlen > args->maxlen || args->minlen > agsize || args->mod >= args->prod) { args->fsbno = NULLFSBLOCK; - TRACE_ALLOC("badargs", args); + trace_xfs_alloc_vextent_badargs(args); return 0; } minleft = args->minleft; @@ -2418,12 +2276,12 @@ xfs_alloc_vextent( error = xfs_alloc_fix_freelist(args, 0); args->minleft = minleft; if (error) { - TRACE_ALLOC("nofix", args); + trace_xfs_alloc_vextent_nofix(args); goto error0; } if (!args->agbp) { up_read(&mp->m_peraglock); - TRACE_ALLOC("noagbp", args); + trace_xfs_alloc_vextent_noagbp(args); break; } args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno); @@ -2488,7 +2346,7 @@ xfs_alloc_vextent( error = xfs_alloc_fix_freelist(args, flags); args->minleft = minleft; if (error) { - TRACE_ALLOC("nofix", args); + trace_xfs_alloc_vextent_nofix(args); goto error0; } /* @@ -2499,7 +2357,9 @@ xfs_alloc_vextent( goto error0; break; } - TRACE_ALLOC("loopfailed", args); + + trace_xfs_alloc_vextent_loopfailed(args); + /* * Didn't work, figure out the next iteration. */ @@ -2526,7 +2386,7 @@ xfs_alloc_vextent( if (args->agno == sagno) { if (no_min == 1) { args->agbno = NULLAGBLOCK; - TRACE_ALLOC("allfailed", args); + trace_xfs_alloc_vextent_allfailed(args); break; } if (flags == 0) { @@ -2642,16 +2502,16 @@ xfs_alloc_mark_busy(xfs_trans_t *tp, } } + trace_xfs_alloc_busy(mp, agno, bno, len, n); + if (n < XFS_PAGB_NUM_SLOTS) { bsy = &mp->m_perag[agno].pagb_list[n]; mp->m_perag[agno].pagb_count++; - TRACE_BUSY("xfs_alloc_mark_busy", "got", agno, bno, len, n, tp); bsy->busy_start = bno; bsy->busy_length = len; bsy->busy_tp = tp; xfs_trans_add_busy(tp, agno, n); } else { - TRACE_BUSY("xfs_alloc_mark_busy", "FULL", agno, bno, len, -1, tp); /* * The busy list is full! Since it is now not possible to * track the free block, make this a synchronous transaction @@ -2678,12 +2538,12 @@ xfs_alloc_clear_busy(xfs_trans_t *tp, list = mp->m_perag[agno].pagb_list; ASSERT(idx < XFS_PAGB_NUM_SLOTS); + + trace_xfs_alloc_unbusy(mp, agno, idx, list[idx].busy_tp == tp); + if (list[idx].busy_tp == tp) { - TRACE_UNBUSY("xfs_alloc_clear_busy", "found", agno, idx, tp); list[idx].busy_tp = NULL; mp->m_perag[agno].pagb_count--; - } else { - TRACE_UNBUSY("xfs_alloc_clear_busy", "missing", agno, idx, tp); } spin_unlock(&mp->m_perag[agno].pagb_lock); @@ -2724,24 +2584,22 @@ xfs_alloc_search_busy(xfs_trans_t *tp, if ((bno > bend) || (uend < bsy->busy_start)) { cnt--; } else { - TRACE_BUSYSEARCH("xfs_alloc_search_busy", - "found1", agno, bno, len, tp); break; } } } + trace_xfs_alloc_busysearch(mp, agno, bno, len, !!cnt); + /* * If a block was found, force the log through the LSN of the * transaction that freed the block */ if (cnt) { - TRACE_BUSYSEARCH("xfs_alloc_search_busy", "found", agno, bno, len, tp); lsn = bsy->busy_tp->t_commit_lsn; spin_unlock(&mp->m_perag[agno].pagb_lock); xfs_log_force(mp, lsn, XFS_LOG_FORCE|XFS_LOG_SYNC); } else { - TRACE_BUSYSEARCH("xfs_alloc_search_busy", "not-found", agno, bno, len, tp); spin_unlock(&mp->m_perag[agno].pagb_lock); } } diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h index e704caee..599bffa 100644 --- a/fs/xfs/xfs_alloc.h +++ b/fs/xfs/xfs_alloc.h @@ -37,6 +37,15 @@ typedef enum xfs_alloctype XFS_ALLOCTYPE_THIS_BNO /* at exactly this block */ } xfs_alloctype_t; +#define XFS_ALLOC_TYPES \ + { XFS_ALLOCTYPE_ANY_AG, "ANY_AG" }, \ + { XFS_ALLOCTYPE_FIRST_AG, "FIRST_AG" }, \ + { XFS_ALLOCTYPE_START_AG, "START_AG" }, \ + { XFS_ALLOCTYPE_THIS_AG, "THIS_AG" }, \ + { XFS_ALLOCTYPE_START_BNO, "START_BNO" }, \ + { XFS_ALLOCTYPE_NEAR_BNO, "NEAR_BNO" }, \ + { XFS_ALLOCTYPE_THIS_BNO, "THIS_BNO" } + /* * Flags for xfs_alloc_fix_freelist. */ @@ -109,24 +118,6 @@ xfs_alloc_longest_free_extent(struct xfs_mount *mp, #ifdef __KERNEL__ -#if defined(XFS_ALLOC_TRACE) -/* - * Allocation tracing buffer size. - */ -#define XFS_ALLOC_TRACE_SIZE 4096 -extern ktrace_t *xfs_alloc_trace_buf; - -/* - * Types for alloc tracing. - */ -#define XFS_ALLOC_KTRACE_ALLOC 1 -#define XFS_ALLOC_KTRACE_FREE 2 -#define XFS_ALLOC_KTRACE_MODAGF 3 -#define XFS_ALLOC_KTRACE_BUSY 4 -#define XFS_ALLOC_KTRACE_UNBUSY 5 -#define XFS_ALLOC_KTRACE_BUSYSEARCH 6 -#endif - void xfs_alloc_mark_busy(xfs_trans_t *tp, xfs_agnumber_t agno, diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index c10c3a2..adbd914 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c @@ -39,6 +39,7 @@ #include "xfs_ialloc.h" #include "xfs_alloc.h" #include "xfs_error.h" +#include "xfs_trace.h" STATIC struct xfs_btree_cur * diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 8fe6f6b..e953b6cf 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c @@ -47,6 +47,7 @@ #include "xfs_trans_space.h" #include "xfs_rw.h" #include "xfs_vnodeops.h" +#include "xfs_trace.h" /* * xfs_attr.c @@ -89,10 +90,6 @@ STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args); #define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */ -#if defined(XFS_ATTR_TRACE) -ktrace_t *xfs_attr_trace_buf; -#endif - STATIC int xfs_attr_name_to_xname( struct xfs_name *xname, @@ -640,7 +637,6 @@ xfs_attr_list_int(xfs_attr_list_context_t *context) return EIO; xfs_ilock(dp, XFS_ILOCK_SHARED); - xfs_attr_trace_l_c("syscall start", context); /* * Decide on what work routines to call based on the inode size. @@ -656,7 +652,6 @@ xfs_attr_list_int(xfs_attr_list_context_t *context) } xfs_iunlock(dp, XFS_ILOCK_SHARED); - xfs_attr_trace_l_c("syscall end", context); return error; } @@ -702,7 +697,7 @@ xfs_attr_put_listent(xfs_attr_list_context_t *context, int flags, context->count * sizeof(alist->al_offset[0]); context->firstu -= ATTR_ENTSIZE(namelen); if (context->firstu < arraytop) { - xfs_attr_trace_l_c("buffer full", context); + trace_xfs_attr_list_full(context); alist->al_more = 1; context->seen_enough = 1; return 1; @@ -714,7 +709,7 @@ xfs_attr_put_listent(xfs_attr_list_context_t *context, int flags, aep->a_name[namelen] = 0; alist->al_offset[context->count++] = context->firstu; alist->al_count = context->count; - xfs_attr_trace_l_c("add", context); + trace_xfs_attr_list_add(context); return 0; } @@ -1853,7 +1848,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) node = bp->data; switch (be16_to_cpu(node->hdr.info.magic)) { case XFS_DA_NODE_MAGIC: - xfs_attr_trace_l_cn("wrong blk", context, node); + trace_xfs_attr_list_wrong_blk(context); xfs_da_brelse(NULL, bp); bp = NULL; break; @@ -1861,20 +1856,18 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) leaf = bp->data; if (cursor->hashval > be32_to_cpu(leaf->entries[ be16_to_cpu(leaf->hdr.count)-1].hashval)) { - xfs_attr_trace_l_cl("wrong blk", - context, leaf); + trace_xfs_attr_list_wrong_blk(context); xfs_da_brelse(NULL, bp); bp = NULL; } else if (cursor->hashval <= be32_to_cpu(leaf->entries[0].hashval)) { - xfs_attr_trace_l_cl("maybe wrong blk", - context, leaf); + trace_xfs_attr_list_wrong_blk(context); xfs_da_brelse(NULL, bp); bp = NULL; } break; default: - xfs_attr_trace_l_c("wrong blk - ??", context); + trace_xfs_attr_list_wrong_blk(context); xfs_da_brelse(NULL, bp); bp = NULL; } @@ -1919,8 +1912,8 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) if (cursor->hashval <= be32_to_cpu(btree->hashval)) { cursor->blkno = be32_to_cpu(btree->before); - xfs_attr_trace_l_cb("descending", - context, btree); + trace_xfs_attr_list_node_descend(context, + btree); break; } } @@ -2270,85 +2263,3 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) } return(0); } - -#if defined(XFS_ATTR_TRACE) -/* - * Add a trace buffer entry for an attr_list context structure. - */ -void -xfs_attr_trace_l_c(char *where, struct xfs_attr_list_context *context) -{ - xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_C, where, context, - (__psunsigned_t)NULL, - (__psunsigned_t)NULL, - (__psunsigned_t)NULL); -} - -/* - * Add a trace buffer entry for a context structure and a Btree node. - */ -void -xfs_attr_trace_l_cn(char *where, struct xfs_attr_list_context *context, - struct xfs_da_intnode *node) -{ - xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_CN, where, context, - (__psunsigned_t)be16_to_cpu(node->hdr.count), - (__psunsigned_t)be32_to_cpu(node->btree[0].hashval), - (__psunsigned_t)be32_to_cpu(node->btree[ - be16_to_cpu(node->hdr.count)-1].hashval)); -} - -/* - * Add a trace buffer entry for a context structure and a Btree element. - */ -void -xfs_attr_trace_l_cb(char *where, struct xfs_attr_list_context *context, - struct xfs_da_node_entry *btree) -{ - xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_CB, where, context, - (__psunsigned_t)be32_to_cpu(btree->hashval), - (__psunsigned_t)be32_to_cpu(btree->before), - (__psunsigned_t)NULL); -} - -/* - * Add a trace buffer entry for a context structure and a leaf block. - */ -void -xfs_attr_trace_l_cl(char *where, struct xfs_attr_list_context *context, - struct xfs_attr_leafblock *leaf) -{ - xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_CL, where, context, - (__psunsigned_t)be16_to_cpu(leaf->hdr.count), - (__psunsigned_t)be32_to_cpu(leaf->entries[0].hashval), - (__psunsigned_t)be32_to_cpu(leaf->entries[ - be16_to_cpu(leaf->hdr.count)-1].hashval)); -} - -/* - * Add a trace buffer entry for the arguments given to the routine, - * generic form. - */ -void -xfs_attr_trace_enter(int type, char *where, - struct xfs_attr_list_context *context, - __psunsigned_t a13, __psunsigned_t a14, - __psunsigned_t a15) -{ - ASSERT(xfs_attr_trace_buf); - ktrace_enter(xfs_attr_trace_buf, (void *)((__psunsigned_t)type), - (void *)((__psunsigned_t)where), - (void *)((__psunsigned_t)context->dp), - (void *)((__psunsigned_t)context->cursor->hashval), - (void *)((__psunsigned_t)context->cursor->blkno), - (void *)((__psunsigned_t)context->cursor->offset), - (void *)((__psunsigned_t)context->alist), - (void *)((__psunsigned_t)context->bufsize), - (void *)((__psunsigned_t)context->count), - (void *)((__psunsigned_t)context->firstu), - NULL, - (void *)((__psunsigned_t)context->dupcnt), - (void *)((__psunsigned_t)context->flags), - (void *)a13, (void *)a14, (void *)a15); -} -#endif /* XFS_ATTR_TRACE */ diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h index 12f0be3..59b410c 100644 --- a/fs/xfs/xfs_attr.h +++ b/fs/xfs/xfs_attr.h @@ -48,6 +48,16 @@ struct xfs_attr_list_context; #define ATTR_KERNOTIME 0x1000 /* [kernel] don't update inode timestamps */ #define ATTR_KERNOVAL 0x2000 /* [kernel] get attr size only, not value */ +#define XFS_ATTR_FLAGS \ + { ATTR_DONTFOLLOW, "DONTFOLLOW" }, \ + { ATTR_ROOT, "ROOT" }, \ + { ATTR_TRUST, "TRUST" }, \ + { ATTR_SECURE, "SECURE" }, \ + { ATTR_CREATE, "CREATE" }, \ + { ATTR_REPLACE, "REPLACE" }, \ + { ATTR_KERNOTIME, "KERNOTIME" }, \ + { ATTR_KERNOVAL, "KERNOVAL" } + /* * The maximum size (into the kernel or returned from the kernel) of an * attribute value or the buffer used for an attr_list() call. Larger diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index 0b68735..baf41b5 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c @@ -42,6 +42,7 @@ #include "xfs_attr.h" #include "xfs_attr_leaf.h" #include "xfs_error.h" +#include "xfs_trace.h" /* * xfs_attr_leaf.c @@ -594,7 +595,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) cursor = context->cursor; ASSERT(cursor != NULL); - xfs_attr_trace_l_c("sf start", context); + trace_xfs_attr_list_sf(context); /* * If the buffer is large enough and the cursor is at the start, @@ -627,7 +628,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) return error; sfe = XFS_ATTR_SF_NEXTENTRY(sfe); } - xfs_attr_trace_l_c("sf big-gulp", context); + trace_xfs_attr_list_sf_all(context); return(0); } @@ -653,7 +654,6 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) XFS_CORRUPTION_ERROR("xfs_attr_shortform_list", XFS_ERRLEVEL_LOW, context->dp->i_mount, sfe); - xfs_attr_trace_l_c("sf corrupted", context); kmem_free(sbuf); return XFS_ERROR(EFSCORRUPTED); } @@ -693,7 +693,6 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) } if (i == nsbuf) { kmem_free(sbuf); - xfs_attr_trace_l_c("blk end", context); return(0); } @@ -719,7 +718,6 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) } kmem_free(sbuf); - xfs_attr_trace_l_c("sf E-O-F", context); return(0); } @@ -2323,7 +2321,7 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) cursor = context->cursor; cursor->initted = 1; - xfs_attr_trace_l_cl("blk start", context, leaf); + trace_xfs_attr_list_leaf(context); /* * Re-find our place in the leaf block if this is a new syscall. @@ -2344,7 +2342,7 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) } } if (i == be16_to_cpu(leaf->hdr.count)) { - xfs_attr_trace_l_c("not found", context); + trace_xfs_attr_list_notfound(context); return(0); } } else { @@ -2419,7 +2417,7 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) break; cursor->offset++; } - xfs_attr_trace_l_cl("blk end", context, leaf); + trace_xfs_attr_list_leaf_end(context); return(retval); } diff --git a/fs/xfs/xfs_attr_sf.h b/fs/xfs/xfs_attr_sf.h index ea22839..76ab7b0 100644 --- a/fs/xfs/xfs_attr_sf.h +++ b/fs/xfs/xfs_attr_sf.h @@ -25,8 +25,6 @@ * to fit into the literal area of the inode. */ -struct xfs_inode; - /* * Entries are packed toward the top as tight as possible. */ @@ -69,42 +67,4 @@ typedef struct xfs_attr_sf_sort { (be16_to_cpu(((xfs_attr_shortform_t *) \ ((dp)->i_afp->if_u1.if_data))->hdr.totsize)) -#if defined(XFS_ATTR_TRACE) -/* - * Kernel tracing support for attribute lists - */ -struct xfs_attr_list_context; -struct xfs_da_intnode; -struct xfs_da_node_entry; -struct xfs_attr_leafblock; - -#define XFS_ATTR_TRACE_SIZE 4096 /* size of global trace buffer */ -extern ktrace_t *xfs_attr_trace_buf; - -/* - * Trace record types. - */ -#define XFS_ATTR_KTRACE_L_C 1 /* context */ -#define XFS_ATTR_KTRACE_L_CN 2 /* context, node */ -#define XFS_ATTR_KTRACE_L_CB 3 /* context, btree */ -#define XFS_ATTR_KTRACE_L_CL 4 /* context, leaf */ - -void xfs_attr_trace_l_c(char *where, struct xfs_attr_list_context *context); -void xfs_attr_trace_l_cn(char *where, struct xfs_attr_list_context *context, - struct xfs_da_intnode *node); -void xfs_attr_trace_l_cb(char *where, struct xfs_attr_list_context *context, - struct xfs_da_node_entry *btree); -void xfs_attr_trace_l_cl(char *where, struct xfs_attr_list_context *context, - struct xfs_attr_leafblock *leaf); -void xfs_attr_trace_enter(int type, char *where, - struct xfs_attr_list_context *context, - __psunsigned_t a13, __psunsigned_t a14, - __psunsigned_t a15); -#else -#define xfs_attr_trace_l_c(w,c) -#define xfs_attr_trace_l_cn(w,c,n) -#define xfs_attr_trace_l_cb(w,c,b) -#define xfs_attr_trace_l_cl(w,c,l) -#endif /* XFS_ATTR_TRACE */ - #endif /* __XFS_ATTR_SF_H__ */ diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 5874098..98251cd 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -54,6 +54,7 @@ #include "xfs_buf_item.h" #include "xfs_filestream.h" #include "xfs_vnodeops.h" +#include "xfs_trace.h" #ifdef DEBUG @@ -272,71 +273,6 @@ xfs_bmap_isaeof( int whichfork, /* data or attribute fork */ char *aeof); /* return value */ -#ifdef XFS_BMAP_TRACE -/* - * Add bmap trace entry prior to a call to xfs_iext_remove. - */ -STATIC void -xfs_bmap_trace_delete( - const char *fname, /* function name */ - char *desc, /* operation description */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* index of entry(entries) deleted */ - xfs_extnum_t cnt, /* count of entries deleted, 1 or 2 */ - int whichfork); /* data or attr fork */ - -/* - * Add bmap trace entry prior to a call to xfs_iext_insert, or - * reading in the extents list from the disk (in the btree). - */ -STATIC void -xfs_bmap_trace_insert( - const char *fname, /* function name */ - char *desc, /* operation description */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* index of entry(entries) inserted */ - xfs_extnum_t cnt, /* count of entries inserted, 1 or 2 */ - xfs_bmbt_irec_t *r1, /* inserted record 1 */ - xfs_bmbt_irec_t *r2, /* inserted record 2 or null */ - int whichfork); /* data or attr fork */ - -/* - * Add bmap trace entry after updating an extent record in place. - */ -STATIC void -xfs_bmap_trace_post_update( - const char *fname, /* function name */ - char *desc, /* operation description */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* index of entry updated */ - int whichfork); /* data or attr fork */ - -/* - * Add bmap trace entry prior to updating an extent record in place. - */ -STATIC void -xfs_bmap_trace_pre_update( - const char *fname, /* function name */ - char *desc, /* operation description */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* index of entry to be updated */ - int whichfork); /* data or attr fork */ - -#define XFS_BMAP_TRACE_DELETE(d,ip,i,c,w) \ - xfs_bmap_trace_delete(__func__,d,ip,i,c,w) -#define XFS_BMAP_TRACE_INSERT(d,ip,i,c,r1,r2,w) \ - xfs_bmap_trace_insert(__func__,d,ip,i,c,r1,r2,w) -#define XFS_BMAP_TRACE_POST_UPDATE(d,ip,i,w) \ - xfs_bmap_trace_post_update(__func__,d,ip,i,w) -#define XFS_BMAP_TRACE_PRE_UPDATE(d,ip,i,w) \ - xfs_bmap_trace_pre_update(__func__,d,ip,i,w) -#else -#define XFS_BMAP_TRACE_DELETE(d,ip,i,c,w) -#define XFS_BMAP_TRACE_INSERT(d,ip,i,c,r1,r2,w) -#define XFS_BMAP_TRACE_POST_UPDATE(d,ip,i,w) -#define XFS_BMAP_TRACE_PRE_UPDATE(d,ip,i,w) -#endif /* XFS_BMAP_TRACE */ - /* * Compute the worst-case number of indirect blocks that will be used * for ip's delayed extent of length "len". @@ -363,18 +299,6 @@ xfs_bmap_validate_ret( #define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) #endif /* DEBUG */ -#if defined(XFS_RW_TRACE) -STATIC void -xfs_bunmap_trace( - xfs_inode_t *ip, - xfs_fileoff_t bno, - xfs_filblks_t len, - int flags, - inst_t *ra); -#else -#define xfs_bunmap_trace(ip, bno, len, flags, ra) -#endif /* XFS_RW_TRACE */ - STATIC int xfs_bmap_count_tree( xfs_mount_t *mp, @@ -590,8 +514,6 @@ xfs_bmap_add_extent( * already extents in the list. */ if (nextents == 0) { - XFS_BMAP_TRACE_INSERT("insert empty", ip, 0, 1, new, NULL, - whichfork); xfs_iext_insert(ip, 0, 1, new, whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); @@ -843,14 +765,12 @@ xfs_bmap_add_extent_delay_real( * Filling in all of a previously delayed allocation extent. * The left and right neighbors are both contiguous with new. */ - XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC|RC", ip, idx - 1, - XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + PREV.br_blockcount + RIGHT.br_blockcount); - XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC|RC", ip, idx - 1, - XFS_DATA_FORK); - XFS_BMAP_TRACE_DELETE("LF|RF|LC|RC", ip, idx, 2, XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); + xfs_iext_remove(ip, idx, 2, state); ip->i_df.if_lastex = idx - 1; ip->i_d.di_nextents--; @@ -889,14 +809,12 @@ xfs_bmap_add_extent_delay_real( * Filling in all of a previously delayed allocation extent. * The left neighbor is contiguous, the right is not. */ - XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC", ip, idx - 1, - XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + PREV.br_blockcount); - XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC", ip, idx - 1, - XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); + ip->i_df.if_lastex = idx - 1; - XFS_BMAP_TRACE_DELETE("LF|RF|LC", ip, idx, 1, XFS_DATA_FORK); xfs_iext_remove(ip, idx, 1, state); if (cur == NULL) rval = XFS_ILOG_DEXT; @@ -925,13 +843,13 @@ xfs_bmap_add_extent_delay_real( * Filling in all of a previously delayed allocation extent. * The right neighbor is contiguous, the left is not. */ - XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|RC", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_startblock(ep, new->br_startblock); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount + RIGHT.br_blockcount); - XFS_BMAP_TRACE_POST_UPDATE("LF|RF|RC", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + ip->i_df.if_lastex = idx; - XFS_BMAP_TRACE_DELETE("LF|RF|RC", ip, idx + 1, 1, XFS_DATA_FORK); xfs_iext_remove(ip, idx + 1, 1, state); if (cur == NULL) rval = XFS_ILOG_DEXT; @@ -961,9 +879,10 @@ xfs_bmap_add_extent_delay_real( * Neither the left nor right neighbors are contiguous with * the new one. */ - XFS_BMAP_TRACE_PRE_UPDATE("LF|RF", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_startblock(ep, new->br_startblock); - XFS_BMAP_TRACE_POST_UPDATE("LF|RF", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + ip->i_df.if_lastex = idx; ip->i_d.di_nextents++; if (cur == NULL) @@ -991,14 +910,15 @@ xfs_bmap_add_extent_delay_real( * Filling in the first part of a previous delayed allocation. * The left neighbor is contiguous. */ - XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx - 1, XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + new->br_blockcount); xfs_bmbt_set_startoff(ep, PREV.br_startoff + new->br_blockcount); - XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx - 1, XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); + temp = PREV.br_blockcount - new->br_blockcount; - XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, temp); ip->i_df.if_lastex = idx - 1; if (cur == NULL) @@ -1020,7 +940,7 @@ xfs_bmap_add_extent_delay_real( temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), startblockval(PREV.br_startblock)); xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); - XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); *dnew = temp; /* DELTA: The boundary between two in-core extents moved. */ temp = LEFT.br_startoff; @@ -1033,12 +953,10 @@ xfs_bmap_add_extent_delay_real( * Filling in the first part of a previous delayed allocation. * The left neighbor is not contiguous. */ - XFS_BMAP_TRACE_PRE_UPDATE("LF", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_startoff(ep, new_endoff); temp = PREV.br_blockcount - new->br_blockcount; xfs_bmbt_set_blockcount(ep, temp); - XFS_BMAP_TRACE_INSERT("LF", ip, idx, 1, new, NULL, - XFS_DATA_FORK); xfs_iext_insert(ip, idx, 1, new, state); ip->i_df.if_lastex = idx; ip->i_d.di_nextents++; @@ -1070,7 +988,7 @@ xfs_bmap_add_extent_delay_real( (cur ? cur->bc_private.b.allocated : 0)); ep = xfs_iext_get_ext(ifp, idx + 1); xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); - XFS_BMAP_TRACE_POST_UPDATE("LF", ip, idx + 1, XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); *dnew = temp; /* DELTA: One in-core extent is split in two. */ temp = PREV.br_startoff; @@ -1083,14 +1001,14 @@ xfs_bmap_add_extent_delay_real( * The right neighbor is contiguous with the new allocation. */ temp = PREV.br_blockcount - new->br_blockcount; - XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx, XFS_DATA_FORK); - XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx + 1, XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); + trace_xfs_bmap_pre_update(ip, idx + 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, temp); xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), new->br_startoff, new->br_startblock, new->br_blockcount + RIGHT.br_blockcount, RIGHT.br_state); - XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx + 1, XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); ip->i_df.if_lastex = idx + 1; if (cur == NULL) rval = XFS_ILOG_DEXT; @@ -1111,7 +1029,7 @@ xfs_bmap_add_extent_delay_real( temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), startblockval(PREV.br_startblock)); xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); - XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); *dnew = temp; /* DELTA: The boundary between two in-core extents moved. */ temp = PREV.br_startoff; @@ -1125,10 +1043,8 @@ xfs_bmap_add_extent_delay_real( * The right neighbor is not contiguous. */ temp = PREV.br_blockcount - new->br_blockcount; - XFS_BMAP_TRACE_PRE_UPDATE("RF", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, temp); - XFS_BMAP_TRACE_INSERT("RF", ip, idx + 1, 1, new, NULL, - XFS_DATA_FORK); xfs_iext_insert(ip, idx + 1, 1, new, state); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents++; @@ -1160,7 +1076,7 @@ xfs_bmap_add_extent_delay_real( (cur ? cur->bc_private.b.allocated : 0)); ep = xfs_iext_get_ext(ifp, idx); xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); - XFS_BMAP_TRACE_POST_UPDATE("RF", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); *dnew = temp; /* DELTA: One in-core extent is split in two. */ temp = PREV.br_startoff; @@ -1174,7 +1090,7 @@ xfs_bmap_add_extent_delay_real( * This case is avoided almost all the time. */ temp = new->br_startoff - PREV.br_startoff; - XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx, 0, _THIS_IP_); xfs_bmbt_set_blockcount(ep, temp); r[0] = *new; r[1].br_state = PREV.br_state; @@ -1182,8 +1098,6 @@ xfs_bmap_add_extent_delay_real( r[1].br_startoff = new_endoff; temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; r[1].br_blockcount = temp2; - XFS_BMAP_TRACE_INSERT("0", ip, idx + 1, 2, &r[0], &r[1], - XFS_DATA_FORK); xfs_iext_insert(ip, idx + 1, 2, &r[0], state); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents++; @@ -1241,11 +1155,11 @@ xfs_bmap_add_extent_delay_real( } ep = xfs_iext_get_ext(ifp, idx); xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); - XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx, XFS_DATA_FORK); - XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx + 2, XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + trace_xfs_bmap_pre_update(ip, idx + 2, state, _THIS_IP_); xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx + 2), nullstartblock((int)temp2)); - XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx + 2, XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx + 2, state, _THIS_IP_); *dnew = temp + temp2; /* DELTA: One in-core extent is split in three. */ temp = PREV.br_startoff; @@ -1391,14 +1305,12 @@ xfs_bmap_add_extent_unwritten_real( * Setting all of a previous oldext extent to newext. * The left and right neighbors are both contiguous with new. */ - XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC|RC", ip, idx - 1, - XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + PREV.br_blockcount + RIGHT.br_blockcount); - XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC|RC", ip, idx - 1, - XFS_DATA_FORK); - XFS_BMAP_TRACE_DELETE("LF|RF|LC|RC", ip, idx, 2, XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); + xfs_iext_remove(ip, idx, 2, state); ip->i_df.if_lastex = idx - 1; ip->i_d.di_nextents -= 2; @@ -1441,14 +1353,12 @@ xfs_bmap_add_extent_unwritten_real( * Setting all of a previous oldext extent to newext. * The left neighbor is contiguous, the right is not. */ - XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC", ip, idx - 1, - XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + PREV.br_blockcount); - XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC", ip, idx - 1, - XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); + ip->i_df.if_lastex = idx - 1; - XFS_BMAP_TRACE_DELETE("LF|RF|LC", ip, idx, 1, XFS_DATA_FORK); xfs_iext_remove(ip, idx, 1, state); ip->i_d.di_nextents--; if (cur == NULL) @@ -1483,15 +1393,12 @@ xfs_bmap_add_extent_unwritten_real( * Setting all of a previous oldext extent to newext. * The right neighbor is contiguous, the left is not. */ - XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|RC", ip, idx, - XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount + RIGHT.br_blockcount); xfs_bmbt_set_state(ep, newext); - XFS_BMAP_TRACE_POST_UPDATE("LF|RF|RC", ip, idx, - XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); ip->i_df.if_lastex = idx; - XFS_BMAP_TRACE_DELETE("LF|RF|RC", ip, idx + 1, 1, XFS_DATA_FORK); xfs_iext_remove(ip, idx + 1, 1, state); ip->i_d.di_nextents--; if (cur == NULL) @@ -1527,11 +1434,10 @@ xfs_bmap_add_extent_unwritten_real( * Neither the left nor right neighbors are contiguous with * the new one. */ - XFS_BMAP_TRACE_PRE_UPDATE("LF|RF", ip, idx, - XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_state(ep, newext); - XFS_BMAP_TRACE_POST_UPDATE("LF|RF", ip, idx, - XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + ip->i_df.if_lastex = idx; if (cur == NULL) rval = XFS_ILOG_DEXT; @@ -1557,22 +1463,20 @@ xfs_bmap_add_extent_unwritten_real( * Setting the first part of a previous oldext extent to newext. * The left neighbor is contiguous. */ - XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx - 1, - XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), LEFT.br_blockcount + new->br_blockcount); xfs_bmbt_set_startoff(ep, PREV.br_startoff + new->br_blockcount); - XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx - 1, - XFS_DATA_FORK); - XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx, - XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); + + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_startblock(ep, new->br_startblock + new->br_blockcount); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount - new->br_blockcount); - XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx, - XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + ip->i_df.if_lastex = idx - 1; if (cur == NULL) rval = XFS_ILOG_DEXT; @@ -1608,16 +1512,15 @@ xfs_bmap_add_extent_unwritten_real( * Setting the first part of a previous oldext extent to newext. * The left neighbor is not contiguous. */ - XFS_BMAP_TRACE_PRE_UPDATE("LF", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); ASSERT(ep && xfs_bmbt_get_state(ep) == oldext); xfs_bmbt_set_startoff(ep, new_endoff); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount - new->br_blockcount); xfs_bmbt_set_startblock(ep, new->br_startblock + new->br_blockcount); - XFS_BMAP_TRACE_POST_UPDATE("LF", ip, idx, XFS_DATA_FORK); - XFS_BMAP_TRACE_INSERT("LF", ip, idx, 1, new, NULL, - XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + xfs_iext_insert(ip, idx, 1, new, state); ip->i_df.if_lastex = idx; ip->i_d.di_nextents++; @@ -1651,19 +1554,16 @@ xfs_bmap_add_extent_unwritten_real( * Setting the last part of a previous oldext extent to newext. * The right neighbor is contiguous with the new allocation. */ - XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx, - XFS_DATA_FORK); - XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx + 1, - XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); + trace_xfs_bmap_pre_update(ip, idx + 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount - new->br_blockcount); - XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx, - XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), new->br_startoff, new->br_startblock, new->br_blockcount + RIGHT.br_blockcount, newext); - XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx + 1, - XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_); + ip->i_df.if_lastex = idx + 1; if (cur == NULL) rval = XFS_ILOG_DEXT; @@ -1698,12 +1598,11 @@ xfs_bmap_add_extent_unwritten_real( * Setting the last part of a previous oldext extent to newext. * The right neighbor is not contiguous. */ - XFS_BMAP_TRACE_PRE_UPDATE("RF", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, PREV.br_blockcount - new->br_blockcount); - XFS_BMAP_TRACE_POST_UPDATE("RF", ip, idx, XFS_DATA_FORK); - XFS_BMAP_TRACE_INSERT("RF", ip, idx + 1, 1, new, NULL, - XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + xfs_iext_insert(ip, idx + 1, 1, new, state); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents++; @@ -1742,18 +1641,17 @@ xfs_bmap_add_extent_unwritten_real( * newext. Contiguity is impossible here. * One extent becomes three extents. */ - XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, new->br_startoff - PREV.br_startoff); - XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + r[0] = *new; r[1].br_startoff = new_endoff; r[1].br_blockcount = PREV.br_startoff + PREV.br_blockcount - new_endoff; r[1].br_startblock = new->br_startblock + new->br_blockcount; r[1].br_state = oldext; - XFS_BMAP_TRACE_INSERT("0", ip, idx + 1, 2, &r[0], &r[1], - XFS_DATA_FORK); xfs_iext_insert(ip, idx + 1, 2, &r[0], state); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents += 2; @@ -1908,8 +1806,8 @@ xfs_bmap_add_extent_hole_delay( */ temp = left.br_blockcount + new->br_blockcount + right.br_blockcount; - XFS_BMAP_TRACE_PRE_UPDATE("LC|RC", ip, idx - 1, - XFS_DATA_FORK); + + trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); oldlen = startblockval(left.br_startblock) + startblockval(new->br_startblock) + @@ -1917,9 +1815,8 @@ xfs_bmap_add_extent_hole_delay( newlen = xfs_bmap_worst_indlen(ip, temp); xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), nullstartblock((int)newlen)); - XFS_BMAP_TRACE_POST_UPDATE("LC|RC", ip, idx - 1, - XFS_DATA_FORK); - XFS_BMAP_TRACE_DELETE("LC|RC", ip, idx, 1, XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); + xfs_iext_remove(ip, idx, 1, state); ip->i_df.if_lastex = idx - 1; /* DELTA: Two in-core extents were replaced by one. */ @@ -1934,16 +1831,15 @@ xfs_bmap_add_extent_hole_delay( * Merge the new allocation with the left neighbor. */ temp = left.br_blockcount + new->br_blockcount; - XFS_BMAP_TRACE_PRE_UPDATE("LC", ip, idx - 1, - XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); oldlen = startblockval(left.br_startblock) + startblockval(new->br_startblock); newlen = xfs_bmap_worst_indlen(ip, temp); xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), nullstartblock((int)newlen)); - XFS_BMAP_TRACE_POST_UPDATE("LC", ip, idx - 1, - XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); + ip->i_df.if_lastex = idx - 1; /* DELTA: One in-core extent grew into a hole. */ temp2 = temp; @@ -1956,14 +1852,15 @@ xfs_bmap_add_extent_hole_delay( * on the right. * Merge the new allocation with the right neighbor. */ - XFS_BMAP_TRACE_PRE_UPDATE("RC", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); temp = new->br_blockcount + right.br_blockcount; oldlen = startblockval(new->br_startblock) + startblockval(right.br_startblock); newlen = xfs_bmap_worst_indlen(ip, temp); xfs_bmbt_set_allf(ep, new->br_startoff, nullstartblock((int)newlen), temp, right.br_state); - XFS_BMAP_TRACE_POST_UPDATE("RC", ip, idx, XFS_DATA_FORK); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + ip->i_df.if_lastex = idx; /* DELTA: One in-core extent grew into a hole. */ temp2 = temp; @@ -1977,8 +1874,6 @@ xfs_bmap_add_extent_hole_delay( * Insert a new entry. */ oldlen = newlen = 0; - XFS_BMAP_TRACE_INSERT("0", ip, idx, 1, new, NULL, - XFS_DATA_FORK); xfs_iext_insert(ip, idx, 1, new, state); ip->i_df.if_lastex = idx; /* DELTA: A new in-core extent was added in a hole. */ @@ -2091,14 +1986,12 @@ xfs_bmap_add_extent_hole_real( * left and on the right. * Merge all three into a single extent record. */ - XFS_BMAP_TRACE_PRE_UPDATE("LC|RC", ip, idx - 1, - whichfork); + trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), left.br_blockcount + new->br_blockcount + right.br_blockcount); - XFS_BMAP_TRACE_POST_UPDATE("LC|RC", ip, idx - 1, - whichfork); - XFS_BMAP_TRACE_DELETE("LC|RC", ip, idx, 1, whichfork); + trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); + xfs_iext_remove(ip, idx, 1, state); ifp->if_lastex = idx - 1; XFS_IFORK_NEXT_SET(ip, whichfork, @@ -2140,10 +2033,11 @@ xfs_bmap_add_extent_hole_real( * on the left. * Merge the new allocation with the left neighbor. */ - XFS_BMAP_TRACE_PRE_UPDATE("LC", ip, idx - 1, whichfork); + trace_xfs_bmap_pre_update(ip, idx - 1, state, _THIS_IP_); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), left.br_blockcount + new->br_blockcount); - XFS_BMAP_TRACE_POST_UPDATE("LC", ip, idx - 1, whichfork); + trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_); + ifp->if_lastex = idx - 1; if (cur == NULL) { rval = xfs_ilog_fext(whichfork); @@ -2174,11 +2068,12 @@ xfs_bmap_add_extent_hole_real( * on the right. * Merge the new allocation with the right neighbor. */ - XFS_BMAP_TRACE_PRE_UPDATE("RC", ip, idx, whichfork); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_allf(ep, new->br_startoff, new->br_startblock, new->br_blockcount + right.br_blockcount, right.br_state); - XFS_BMAP_TRACE_POST_UPDATE("RC", ip, idx, whichfork); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + ifp->if_lastex = idx; if (cur == NULL) { rval = xfs_ilog_fext(whichfork); @@ -2209,7 +2104,6 @@ xfs_bmap_add_extent_hole_real( * real allocation. * Insert a new entry. */ - XFS_BMAP_TRACE_INSERT("0", ip, idx, 1, new, NULL, whichfork); xfs_iext_insert(ip, idx, 1, new, state); ifp->if_lastex = idx; XFS_IFORK_NEXT_SET(ip, whichfork, @@ -3070,8 +2964,13 @@ xfs_bmap_del_extent( uint qfield; /* quota field to update */ xfs_filblks_t temp; /* for indirect length calculations */ xfs_filblks_t temp2; /* for indirect length calculations */ + int state = 0; XFS_STATS_INC(xs_del_exlist); + + if (whichfork == XFS_ATTR_FORK) + state |= BMAP_ATTRFORK; + mp = ip->i_mount; ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT((idx >= 0) && (idx < ifp->if_bytes / @@ -3151,7 +3050,6 @@ xfs_bmap_del_extent( /* * Matches the whole extent. Delete the entry. */ - XFS_BMAP_TRACE_DELETE("3", ip, idx, 1, whichfork); xfs_iext_remove(ip, idx, 1, whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); ifp->if_lastex = idx; @@ -3173,7 +3071,7 @@ xfs_bmap_del_extent( /* * Deleting the first part of the extent. */ - XFS_BMAP_TRACE_PRE_UPDATE("2", ip, idx, whichfork); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_startoff(ep, del_endoff); temp = got.br_blockcount - del->br_blockcount; xfs_bmbt_set_blockcount(ep, temp); @@ -3182,13 +3080,12 @@ xfs_bmap_del_extent( temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), da_old); xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); - XFS_BMAP_TRACE_POST_UPDATE("2", ip, idx, - whichfork); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); da_new = temp; break; } xfs_bmbt_set_startblock(ep, del_endblock); - XFS_BMAP_TRACE_POST_UPDATE("2", ip, idx, whichfork); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); if (!cur) { flags |= xfs_ilog_fext(whichfork); break; @@ -3204,19 +3101,18 @@ xfs_bmap_del_extent( * Deleting the last part of the extent. */ temp = got.br_blockcount - del->br_blockcount; - XFS_BMAP_TRACE_PRE_UPDATE("1", ip, idx, whichfork); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, temp); ifp->if_lastex = idx; if (delay) { temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), da_old); xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); - XFS_BMAP_TRACE_POST_UPDATE("1", ip, idx, - whichfork); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); da_new = temp; break; } - XFS_BMAP_TRACE_POST_UPDATE("1", ip, idx, whichfork); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); if (!cur) { flags |= xfs_ilog_fext(whichfork); break; @@ -3233,7 +3129,7 @@ xfs_bmap_del_extent( * Deleting the middle of the extent. */ temp = del->br_startoff - got.br_startoff; - XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx, whichfork); + trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_); xfs_bmbt_set_blockcount(ep, temp); new.br_startoff = del_endoff; temp2 = got_endoff - del_endoff; @@ -3320,11 +3216,8 @@ xfs_bmap_del_extent( } } } - XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx, whichfork); - XFS_BMAP_TRACE_INSERT("0", ip, idx + 1, 1, &new, NULL, - whichfork); - xfs_iext_insert(ip, idx + 1, 1, &new, - whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0); + trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_); + xfs_iext_insert(ip, idx + 1, 1, &new, state); ifp->if_lastex = idx + 1; break; } @@ -3644,7 +3537,9 @@ xfs_bmap_local_to_extents( xfs_iext_add(ifp, 0, 1); ep = xfs_iext_get_ext(ifp, 0); xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM); - XFS_BMAP_TRACE_POST_UPDATE("new", ip, 0, whichfork); + trace_xfs_bmap_post_update(ip, 0, + whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0, + _THIS_IP_); XFS_IFORK_NEXT_SET(ip, whichfork, 1); ip->i_d.di_nblocks = 1; xfs_trans_mod_dquot_byino(tp, ip, @@ -3757,158 +3652,6 @@ xfs_bmap_search_extents( return ep; } - -#ifdef XFS_BMAP_TRACE -ktrace_t *xfs_bmap_trace_buf; - -/* - * Add a bmap trace buffer entry. Base routine for the others. - */ -STATIC void -xfs_bmap_trace_addentry( - int opcode, /* operation */ - const char *fname, /* function name */ - char *desc, /* operation description */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* index of entry(ies) */ - xfs_extnum_t cnt, /* count of entries, 1 or 2 */ - xfs_bmbt_rec_host_t *r1, /* first record */ - xfs_bmbt_rec_host_t *r2, /* second record or null */ - int whichfork) /* data or attr fork */ -{ - xfs_bmbt_rec_host_t tr2; - - ASSERT(cnt == 1 || cnt == 2); - ASSERT(r1 != NULL); - if (cnt == 1) { - ASSERT(r2 == NULL); - r2 = &tr2; - memset(&tr2, 0, sizeof(tr2)); - } else - ASSERT(r2 != NULL); - ktrace_enter(xfs_bmap_trace_buf, - (void *)(__psint_t)(opcode | (whichfork << 16)), - (void *)fname, (void *)desc, (void *)ip, - (void *)(__psint_t)idx, - (void *)(__psint_t)cnt, - (void *)(__psunsigned_t)(ip->i_ino >> 32), - (void *)(__psunsigned_t)(unsigned)ip->i_ino, - (void *)(__psunsigned_t)(r1->l0 >> 32), - (void *)(__psunsigned_t)(unsigned)(r1->l0), - (void *)(__psunsigned_t)(r1->l1 >> 32), - (void *)(__psunsigned_t)(unsigned)(r1->l1), - (void *)(__psunsigned_t)(r2->l0 >> 32), - (void *)(__psunsigned_t)(unsigned)(r2->l0), - (void *)(__psunsigned_t)(r2->l1 >> 32), - (void *)(__psunsigned_t)(unsigned)(r2->l1) - ); - ASSERT(ip->i_xtrace); - ktrace_enter(ip->i_xtrace, - (void *)(__psint_t)(opcode | (whichfork << 16)), - (void *)fname, (void *)desc, (void *)ip, - (void *)(__psint_t)idx, - (void *)(__psint_t)cnt, - (void *)(__psunsigned_t)(ip->i_ino >> 32), - (void *)(__psunsigned_t)(unsigned)ip->i_ino, - (void *)(__psunsigned_t)(r1->l0 >> 32), - (void *)(__psunsigned_t)(unsigned)(r1->l0), - (void *)(__psunsigned_t)(r1->l1 >> 32), - (void *)(__psunsigned_t)(unsigned)(r1->l1), - (void *)(__psunsigned_t)(r2->l0 >> 32), - (void *)(__psunsigned_t)(unsigned)(r2->l0), - (void *)(__psunsigned_t)(r2->l1 >> 32), - (void *)(__psunsigned_t)(unsigned)(r2->l1) - ); -} - -/* - * Add bmap trace entry prior to a call to xfs_iext_remove. - */ -STATIC void -xfs_bmap_trace_delete( - const char *fname, /* function name */ - char *desc, /* operation description */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* index of entry(entries) deleted */ - xfs_extnum_t cnt, /* count of entries deleted, 1 or 2 */ - int whichfork) /* data or attr fork */ -{ - xfs_ifork_t *ifp; /* inode fork pointer */ - - ifp = XFS_IFORK_PTR(ip, whichfork); - xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_DELETE, fname, desc, ip, idx, - cnt, xfs_iext_get_ext(ifp, idx), - cnt == 2 ? xfs_iext_get_ext(ifp, idx + 1) : NULL, - whichfork); -} - -/* - * Add bmap trace entry prior to a call to xfs_iext_insert, or - * reading in the extents list from the disk (in the btree). - */ -STATIC void -xfs_bmap_trace_insert( - const char *fname, /* function name */ - char *desc, /* operation description */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* index of entry(entries) inserted */ - xfs_extnum_t cnt, /* count of entries inserted, 1 or 2 */ - xfs_bmbt_irec_t *r1, /* inserted record 1 */ - xfs_bmbt_irec_t *r2, /* inserted record 2 or null */ - int whichfork) /* data or attr fork */ -{ - xfs_bmbt_rec_host_t tr1; /* compressed record 1 */ - xfs_bmbt_rec_host_t tr2; /* compressed record 2 if needed */ - - xfs_bmbt_set_all(&tr1, r1); - if (cnt == 2) { - ASSERT(r2 != NULL); - xfs_bmbt_set_all(&tr2, r2); - } else { - ASSERT(cnt == 1); - ASSERT(r2 == NULL); - } - xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_INSERT, fname, desc, ip, idx, - cnt, &tr1, cnt == 2 ? &tr2 : NULL, whichfork); -} - -/* - * Add bmap trace entry after updating an extent record in place. - */ -STATIC void -xfs_bmap_trace_post_update( - const char *fname, /* function name */ - char *desc, /* operation description */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* index of entry updated */ - int whichfork) /* data or attr fork */ -{ - xfs_ifork_t *ifp; /* inode fork pointer */ - - ifp = XFS_IFORK_PTR(ip, whichfork); - xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_POST_UP, fname, desc, ip, idx, - 1, xfs_iext_get_ext(ifp, idx), NULL, whichfork); -} - -/* - * Add bmap trace entry prior to updating an extent record in place. - */ -STATIC void -xfs_bmap_trace_pre_update( - const char *fname, /* function name */ - char *desc, /* operation description */ - xfs_inode_t *ip, /* incore inode pointer */ - xfs_extnum_t idx, /* index of entry to be updated */ - int whichfork) /* data or attr fork */ -{ - xfs_ifork_t *ifp; /* inode fork pointer */ - - ifp = XFS_IFORK_PTR(ip, whichfork); - xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_PRE_UP, fname, desc, ip, idx, 1, - xfs_iext_get_ext(ifp, idx), NULL, whichfork); -} -#endif /* XFS_BMAP_TRACE */ - /* * Compute the worst-case number of indirect blocks that will be used * for ip's delayed extent of length "len". @@ -3940,37 +3683,6 @@ xfs_bmap_worst_indlen( return rval; } -#if defined(XFS_RW_TRACE) -STATIC void -xfs_bunmap_trace( - xfs_inode_t *ip, - xfs_fileoff_t bno, - xfs_filblks_t len, - int flags, - inst_t *ra) -{ - if (ip->i_rwtrace == NULL) - return; - ktrace_enter(ip->i_rwtrace, - (void *)(__psint_t)XFS_BUNMAP, - (void *)ip, - (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff), - (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff), - (void *)(__psint_t)(((xfs_dfiloff_t)bno >> 32) & 0xffffffff), - (void *)(__psint_t)((xfs_dfiloff_t)bno & 0xffffffff), - (void *)(__psint_t)len, - (void *)(__psint_t)flags, - (void *)(unsigned long)current_cpu(), - (void *)ra, - (void *)0, - (void *)0, - (void *)0, - (void *)0, - (void *)0, - (void *)0); -} -#endif - /* * Convert inode from non-attributed to attributed. * Must not be in a transaction, ip must not be locked. @@ -4659,34 +4371,30 @@ error0: return XFS_ERROR(EFSCORRUPTED); } -#ifdef XFS_BMAP_TRACE +#ifdef DEBUG /* * Add bmap trace insert entries for all the contents of the extent records. */ void xfs_bmap_trace_exlist( - const char *fname, /* function name */ xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t cnt, /* count of entries in the list */ - int whichfork) /* data or attr fork */ + int whichfork, /* data or attr fork */ + unsigned long caller_ip) { - xfs_bmbt_rec_host_t *ep; /* current extent record */ xfs_extnum_t idx; /* extent record index */ xfs_ifork_t *ifp; /* inode fork pointer */ - xfs_bmbt_irec_t s; /* file extent record */ + int state = 0; + + if (whichfork == XFS_ATTR_FORK) + state |= BMAP_ATTRFORK; ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(cnt == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))); - for (idx = 0; idx < cnt; idx++) { - ep = xfs_iext_get_ext(ifp, idx); - xfs_bmbt_get_all(ep, &s); - XFS_BMAP_TRACE_INSERT("exlist", ip, idx, 1, &s, NULL, - whichfork); - } + for (idx = 0; idx < cnt; idx++) + trace_xfs_extlist(ip, idx, whichfork, caller_ip); } -#endif -#ifdef DEBUG /* * Validate that the bmbt_irecs being returned from bmapi are valid * given the callers original parameters. Specifically check the @@ -5435,7 +5143,8 @@ xfs_bunmapi( int rsvd; /* OK to allocate reserved blocks */ xfs_fsblock_t sum; - xfs_bunmap_trace(ip, bno, len, flags, (inst_t *)__return_address); + trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_); + whichfork = (flags & XFS_BMAPI_ATTRFORK) ? XFS_ATTR_FORK : XFS_DATA_FORK; ifp = XFS_IFORK_PTR(ip, whichfork); diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index 3e84e8e..419dafb 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h @@ -95,6 +95,21 @@ typedef struct xfs_bmap_free /* need write cache flushing and no */ /* additional allocation alignments */ +#define XFS_BMAPI_FLAGS \ + { XFS_BMAPI_WRITE, "WRITE" }, \ + { XFS_BMAPI_DELAY, "DELAY" }, \ + { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ + { XFS_BMAPI_METADATA, "METADATA" }, \ + { XFS_BMAPI_EXACT, "EXACT" }, \ + { XFS_BMAPI_ATTRFORK, "ATTRFORK" }, \ + { XFS_BMAPI_ASYNC, "ASYNC" }, \ + { XFS_BMAPI_RSVBLOCKS, "RSVBLOCKS" }, \ + { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ + { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ + { XFS_BMAPI_CONTIG, "CONTIG" }, \ + { XFS_BMAPI_CONVERT, "CONVERT" } + + static inline int xfs_bmapi_aflag(int w) { return (w == XFS_ATTR_FORK ? XFS_BMAPI_ATTRFORK : 0); @@ -148,36 +163,30 @@ typedef struct xfs_bmalloca { #define BMAP_RIGHT_VALID (1 << 7) #define BMAP_ATTRFORK (1 << 8) -#if defined(__KERNEL__) && defined(XFS_BMAP_TRACE) -/* - * Trace operations for bmap extent tracing - */ -#define XFS_BMAP_KTRACE_DELETE 1 -#define XFS_BMAP_KTRACE_INSERT 2 -#define XFS_BMAP_KTRACE_PRE_UP 3 -#define XFS_BMAP_KTRACE_POST_UP 4 - -#define XFS_BMAP_TRACE_SIZE 4096 /* size of global trace buffer */ -#define XFS_BMAP_KTRACE_SIZE 32 /* size of per-inode trace buffer */ -extern ktrace_t *xfs_bmap_trace_buf; +#define XFS_BMAP_EXT_FLAGS \ + { BMAP_LEFT_CONTIG, "LC" }, \ + { BMAP_RIGHT_CONTIG, "RC" }, \ + { BMAP_LEFT_FILLING, "LF" }, \ + { BMAP_RIGHT_FILLING, "RF" }, \ + { BMAP_ATTRFORK, "ATTR" } /* * Add bmap trace insert entries for all the contents of the extent list. + * + * Quite excessive tracing. Only do this for debug builds. */ +#if defined(__KERNEL) && defined(DEBUG) void xfs_bmap_trace_exlist( - const char *fname, /* function name */ struct xfs_inode *ip, /* incore inode pointer */ xfs_extnum_t cnt, /* count of entries in list */ - int whichfork); /* data or attr fork */ + int whichfork, + unsigned long caller_ip); /* data or attr fork */ #define XFS_BMAP_TRACE_EXLIST(ip,c,w) \ - xfs_bmap_trace_exlist(__func__,ip,c,w) - -#else /* __KERNEL__ && XFS_BMAP_TRACE */ - + xfs_bmap_trace_exlist(ip,c,w, _THIS_IP_) +#else #define XFS_BMAP_TRACE_EXLIST(ip,c,w) - -#endif /* __KERNEL__ && XFS_BMAP_TRACE */ +#endif /* * Convert inode from non-attributed to attributed. diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 6f5cced..38751d5 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c @@ -768,12 +768,6 @@ xfs_bmbt_trace_enter( (void *)a0, (void *)a1, (void *)a2, (void *)a3, (void *)a4, (void *)a5, (void *)a6, (void *)a7, (void *)a8, (void *)a9, (void *)a10); - ktrace_enter(ip->i_btrace, - (void *)((__psint_t)type | (whichfork << 8) | (line << 16)), - (void *)func, (void *)s, (void *)ip, (void *)cur, - (void *)a0, (void *)a1, (void *)a2, (void *)a3, - (void *)a4, (void *)a5, (void *)a6, (void *)a7, - (void *)a8, (void *)a9, (void *)a10); } STATIC void diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 52b5f14..36a0992 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c @@ -39,6 +39,7 @@ #include "xfs_btree_trace.h" #include "xfs_ialloc.h" #include "xfs_error.h" +#include "xfs_trace.h" /* * Cursor allocation zone. @@ -81,7 +82,7 @@ xfs_btree_check_lblock( XFS_ERRTAG_BTREE_CHECK_LBLOCK, XFS_RANDOM_BTREE_CHECK_LBLOCK))) { if (bp) - xfs_buftrace("LBTREE ERROR", bp); + trace_xfs_btree_corrupt(bp, _RET_IP_); XFS_ERROR_REPORT("xfs_btree_check_lblock", XFS_ERRLEVEL_LOW, mp); return XFS_ERROR(EFSCORRUPTED); @@ -119,7 +120,7 @@ xfs_btree_check_sblock( XFS_ERRTAG_BTREE_CHECK_SBLOCK, XFS_RANDOM_BTREE_CHECK_SBLOCK))) { if (bp) - xfs_buftrace("SBTREE ERROR", bp); + trace_xfs_btree_corrupt(bp, _RET_IP_); XFS_CORRUPTION_ERROR("xfs_btree_check_sblock", XFS_ERRLEVEL_LOW, cur->bc_mp, block); return XFS_ERROR(EFSCORRUPTED); diff --git a/fs/xfs/xfs_btree_trace.h b/fs/xfs/xfs_btree_trace.h index b3f5eb3..2d8a309 100644 --- a/fs/xfs/xfs_btree_trace.h +++ b/fs/xfs/xfs_btree_trace.h @@ -58,8 +58,6 @@ void xfs_btree_trace_argbi(const char *, struct xfs_btree_cur *, struct xfs_buf *, int, int); void xfs_btree_trace_argbii(const char *, struct xfs_btree_cur *, struct xfs_buf *, int, int, int); -void xfs_btree_trace_argfffi(const char *, struct xfs_btree_cur *, - xfs_dfiloff_t, xfs_dfsbno_t, xfs_dfilblks_t, int, int); void xfs_btree_trace_argi(const char *, struct xfs_btree_cur *, int, int); void xfs_btree_trace_argipk(const char *, struct xfs_btree_cur *, int, union xfs_btree_ptr, union xfs_btree_key *, int); @@ -71,24 +69,10 @@ void xfs_btree_trace_argr(const char *, struct xfs_btree_cur *, union xfs_btree_rec *, int); void xfs_btree_trace_cursor(const char *, struct xfs_btree_cur *, int, int); - -#define XFS_ALLOCBT_TRACE_SIZE 4096 /* size of global trace buffer */ -extern ktrace_t *xfs_allocbt_trace_buf; - -#define XFS_INOBT_TRACE_SIZE 4096 /* size of global trace buffer */ -extern ktrace_t *xfs_inobt_trace_buf; - -#define XFS_BMBT_TRACE_SIZE 4096 /* size of global trace buffer */ -#define XFS_BMBT_KTRACE_SIZE 32 /* size of per-inode trace buffer */ -extern ktrace_t *xfs_bmbt_trace_buf; - - #define XFS_BTREE_TRACE_ARGBI(c, b, i) \ xfs_btree_trace_argbi(__func__, c, b, i, __LINE__) #define XFS_BTREE_TRACE_ARGBII(c, b, i, j) \ xfs_btree_trace_argbii(__func__, c, b, i, j, __LINE__) -#define XFS_BTREE_TRACE_ARGFFFI(c, o, b, i, j) \ - xfs_btree_trace_argfffi(__func__, c, o, b, i, j, __LINE__) #define XFS_BTREE_TRACE_ARGI(c, i) \ xfs_btree_trace_argi(__func__, c, i, __LINE__) #define XFS_BTREE_TRACE_ARGIPK(c, i, p, k) \ @@ -104,7 +88,6 @@ extern ktrace_t *xfs_bmbt_trace_buf; #else #define XFS_BTREE_TRACE_ARGBI(c, b, i) #define XFS_BTREE_TRACE_ARGBII(c, b, i, j) -#define XFS_BTREE_TRACE_ARGFFFI(c, o, b, i, j) #define XFS_BTREE_TRACE_ARGI(c, i) #define XFS_BTREE_TRACE_ARGIPK(c, i, p, s) #define XFS_BTREE_TRACE_ARGIPR(c, i, p, r) diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 92af409..a30f7e9 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -29,6 +29,7 @@ #include "xfs_buf_item.h" #include "xfs_trans_priv.h" #include "xfs_error.h" +#include "xfs_trace.h" kmem_zone_t *xfs_buf_item_zone; @@ -164,7 +165,7 @@ xfs_buf_item_size( * is the buf log format structure with the * cancel flag in it. */ - xfs_buf_item_trace("SIZE STALE", bip); + trace_xfs_buf_item_size_stale(bip); ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL); return 1; } @@ -206,7 +207,7 @@ xfs_buf_item_size( } } - xfs_buf_item_trace("SIZE NORM", bip); + trace_xfs_buf_item_size(bip); return nvecs; } @@ -259,7 +260,7 @@ xfs_buf_item_format( * is the buf log format structure with the * cancel flag in it. */ - xfs_buf_item_trace("FORMAT STALE", bip); + trace_xfs_buf_item_format_stale(bip); ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL); bip->bli_format.blf_size = nvecs; return; @@ -335,7 +336,7 @@ xfs_buf_item_format( /* * Check to make sure everything is consistent. */ - xfs_buf_item_trace("FORMAT NORM", bip); + trace_xfs_buf_item_format(bip); xfs_buf_item_log_check(bip); } @@ -355,8 +356,7 @@ xfs_buf_item_pin( ASSERT(atomic_read(&bip->bli_refcount) > 0); ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || (bip->bli_flags & XFS_BLI_STALE)); - xfs_buf_item_trace("PIN", bip); - xfs_buftrace("XFS_PIN", bp); + trace_xfs_buf_item_pin(bip); xfs_bpin(bp); } @@ -383,8 +383,7 @@ xfs_buf_item_unpin( ASSERT(bp != NULL); ASSERT(XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *) == bip); ASSERT(atomic_read(&bip->bli_refcount) > 0); - xfs_buf_item_trace("UNPIN", bip); - xfs_buftrace("XFS_UNPIN", bp); + trace_xfs_buf_item_unpin(bip); freed = atomic_dec_and_test(&bip->bli_refcount); ailp = bip->bli_item.li_ailp; @@ -395,8 +394,8 @@ xfs_buf_item_unpin( ASSERT(!(XFS_BUF_ISDELAYWRITE(bp))); ASSERT(XFS_BUF_ISSTALE(bp)); ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL); - xfs_buf_item_trace("UNPIN STALE", bip); - xfs_buftrace("XFS_UNPIN STALE", bp); + trace_xfs_buf_item_unpin_stale(bip); + /* * If we get called here because of an IO error, we may * or may not have the item on the AIL. xfs_trans_ail_delete() @@ -440,8 +439,8 @@ xfs_buf_item_unpin_remove( if ((atomic_read(&bip->bli_refcount) == 1) && (bip->bli_flags & XFS_BLI_STALE)) { ASSERT(XFS_BUF_VALUSEMA(bip->bli_buf) <= 0); - xfs_buf_item_trace("UNPIN REMOVE", bip); - xfs_buftrace("XFS_UNPIN_REMOVE", bp); + trace_xfs_buf_item_unpin_stale(bip); + /* * yes -- clear the xaction descriptor in-use flag * and free the chunk if required. We can safely @@ -495,7 +494,7 @@ xfs_buf_item_trylock( XFS_BUF_HOLD(bp); ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); - xfs_buf_item_trace("TRYLOCK SUCCESS", bip); + trace_xfs_buf_item_trylock(bip); return XFS_ITEM_SUCCESS; } @@ -524,7 +523,6 @@ xfs_buf_item_unlock( uint hold; bp = bip->bli_buf; - xfs_buftrace("XFS_UNLOCK", bp); /* * Clear the buffer's association with this transaction. @@ -547,7 +545,7 @@ xfs_buf_item_unlock( */ if (bip->bli_flags & XFS_BLI_STALE) { bip->bli_flags &= ~XFS_BLI_LOGGED; - xfs_buf_item_trace("UNLOCK STALE", bip); + trace_xfs_buf_item_unlock_stale(bip); ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL); if (!aborted) return; @@ -574,7 +572,7 @@ xfs_buf_item_unlock( * release the buffer at the end of this routine. */ hold = bip->bli_flags & XFS_BLI_HOLD; - xfs_buf_item_trace("UNLOCK", bip); + trace_xfs_buf_item_unlock(bip); /* * If the buf item isn't tracking any data, free it. @@ -618,7 +616,8 @@ xfs_buf_item_committed( xfs_buf_log_item_t *bip, xfs_lsn_t lsn) { - xfs_buf_item_trace("COMMITTED", bip); + trace_xfs_buf_item_committed(bip); + if ((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) && (bip->bli_item.li_lsn != 0)) { return bip->bli_item.li_lsn; @@ -640,7 +639,7 @@ xfs_buf_item_push( xfs_buf_t *bp; ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); - xfs_buf_item_trace("PUSH", bip); + trace_xfs_buf_item_push(bip); bp = bip->bli_buf; @@ -738,9 +737,6 @@ xfs_buf_item_init( bip->bli_format.blf_blkno = (__int64_t)XFS_BUF_ADDR(bp); bip->bli_format.blf_len = (ushort)BTOBB(XFS_BUF_COUNT(bp)); bip->bli_format.blf_map_size = map_size; -#ifdef XFS_BLI_TRACE - bip->bli_trace = ktrace_alloc(XFS_BLI_TRACE_SIZE, KM_NOFS); -#endif #ifdef XFS_TRANS_DEBUG /* @@ -878,9 +874,6 @@ xfs_buf_item_free( kmem_free(bip->bli_logged); #endif /* XFS_TRANS_DEBUG */ -#ifdef XFS_BLI_TRACE - ktrace_free(bip->bli_trace); -#endif kmem_zone_free(xfs_buf_item_zone, bip); } @@ -897,7 +890,8 @@ xfs_buf_item_relse( { xfs_buf_log_item_t *bip; - xfs_buftrace("XFS_RELSE", bp); + trace_xfs_buf_item_relse(bp, _RET_IP_); + bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*); XFS_BUF_SET_FSPRIVATE(bp, bip->bli_item.li_bio_list); if ((XFS_BUF_FSPRIVATE(bp, void *) == NULL) && @@ -994,7 +988,7 @@ xfs_buf_iodone_callbacks( if (XFS_FORCED_SHUTDOWN(mp)) { ASSERT(XFS_BUF_TARGET(bp) == mp->m_ddev_targp); XFS_BUF_SUPER_STALE(bp); - xfs_buftrace("BUF_IODONE_CB", bp); + trace_xfs_buf_item_iodone(bp, _RET_IP_); xfs_buf_do_callbacks(bp, lip); XFS_BUF_SET_FSPRIVATE(bp, NULL); XFS_BUF_CLR_IODONE_FUNC(bp); @@ -1030,7 +1024,7 @@ xfs_buf_iodone_callbacks( XFS_BUF_SET_START(bp); } ASSERT(XFS_BUF_IODONE_FUNC(bp)); - xfs_buftrace("BUF_IODONE ASYNC", bp); + trace_xfs_buf_item_iodone_async(bp, _RET_IP_); xfs_buf_relse(bp); } else { /* @@ -1053,9 +1047,7 @@ xfs_buf_iodone_callbacks( } return; } -#ifdef XFSERRORDEBUG - xfs_buftrace("XFS BUFCB NOERR", bp); -#endif + xfs_buf_do_callbacks(bp, lip); XFS_BUF_SET_FSPRIVATE(bp, NULL); XFS_BUF_CLR_IODONE_FUNC(bp); @@ -1081,7 +1073,9 @@ xfs_buf_error_relse( XFS_BUF_DONE(bp); XFS_BUF_UNDELAYWRITE(bp); XFS_BUF_ERROR(bp,0); - xfs_buftrace("BUF_ERROR_RELSE", bp); + + trace_xfs_buf_error_relse(bp, _RET_IP_); + if (! XFS_FORCED_SHUTDOWN(mp)) xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR); /* @@ -1128,34 +1122,3 @@ xfs_buf_iodone( xfs_trans_ail_delete(ailp, (xfs_log_item_t *)bip); xfs_buf_item_free(bip); } - -#if defined(XFS_BLI_TRACE) -void -xfs_buf_item_trace( - char *id, - xfs_buf_log_item_t *bip) -{ - xfs_buf_t *bp; - ASSERT(bip->bli_trace != NULL); - - bp = bip->bli_buf; - ktrace_enter(bip->bli_trace, - (void *)id, - (void *)bip->bli_buf, - (void *)((unsigned long)bip->bli_flags), - (void *)((unsigned long)bip->bli_recur), - (void *)((unsigned long)atomic_read(&bip->bli_refcount)), - (void *)((unsigned long) - (0xFFFFFFFF & XFS_BUF_ADDR(bp) >> 32)), - (void *)((unsigned long)(0xFFFFFFFF & XFS_BUF_ADDR(bp))), - (void *)((unsigned long)XFS_BUF_COUNT(bp)), - (void *)((unsigned long)XFS_BUF_BFLAGS(bp)), - XFS_BUF_FSPRIVATE(bp, void *), - XFS_BUF_FSPRIVATE2(bp, void *), - (void *)(unsigned long)XFS_BUF_ISPINNED(bp), - (void *)XFS_BUF_IODONE_FUNC(bp), - (void *)((unsigned long)(XFS_BUF_VALUSEMA(bp))), - (void *)bip->bli_item.li_desc, - (void *)((unsigned long)bip->bli_item.li_flags)); -} -#endif /* XFS_BLI_TRACE */ diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h index 5a41c34..217f34a 100644 --- a/fs/xfs/xfs_buf_item.h +++ b/fs/xfs/xfs_buf_item.h @@ -70,22 +70,21 @@ typedef struct xfs_buf_log_format_t { #define XFS_BLI_INODE_ALLOC_BUF 0x10 #define XFS_BLI_STALE_INODE 0x20 +#define XFS_BLI_FLAGS \ + { XFS_BLI_HOLD, "HOLD" }, \ + { XFS_BLI_DIRTY, "DIRTY" }, \ + { XFS_BLI_STALE, "STALE" }, \ + { XFS_BLI_LOGGED, "LOGGED" }, \ + { XFS_BLI_INODE_ALLOC_BUF, "INODE_ALLOC" }, \ + { XFS_BLI_STALE_INODE, "STALE_INODE" } + #ifdef __KERNEL__ struct xfs_buf; -struct ktrace; struct xfs_mount; struct xfs_buf_log_item; -#if defined(XFS_BLI_TRACE) -#define XFS_BLI_TRACE_SIZE 32 - -void xfs_buf_item_trace(char *, struct xfs_buf_log_item *); -#else -#define xfs_buf_item_trace(id, bip) -#endif - /* * This is the in core log item structure used to track information * needed to log buffers. It tracks how many times the lock has been @@ -97,9 +96,6 @@ typedef struct xfs_buf_log_item { unsigned int bli_flags; /* misc flags */ unsigned int bli_recur; /* lock recursion count */ atomic_t bli_refcount; /* cnt of tp refs */ -#ifdef XFS_BLI_TRACE - struct ktrace *bli_trace; /* event trace buf */ -#endif #ifdef XFS_TRANS_DEBUG char *bli_orig; /* original buffer copy */ char *bli_logged; /* bytes logged (bitmap) */ diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 2847bbc..c0c8869 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c @@ -46,6 +46,7 @@ #include "xfs_dir2_block.h" #include "xfs_dir2_node.h" #include "xfs_error.h" +#include "xfs_trace.h" /* * xfs_da_btree.c @@ -2107,7 +2108,7 @@ xfs_da_do_buf( (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC), mp, XFS_ERRTAG_DA_READ_BUF, XFS_RANDOM_DA_READ_BUF))) { - xfs_buftrace("DA READ ERROR", rbp->bps[0]); + trace_xfs_da_btree_corrupt(rbp->bps[0], _RET_IP_); XFS_CORRUPTION_ERROR("xfs_da_do_buf(2)", XFS_ERRLEVEL_LOW, mp, info); error = XFS_ERROR(EFSCORRUPTED); diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h index 8c53616..30cd08f 100644 --- a/fs/xfs/xfs_da_btree.h +++ b/fs/xfs/xfs_da_btree.h @@ -125,6 +125,13 @@ typedef struct xfs_da_args { #define XFS_DA_OP_OKNOENT 0x0008 /* lookup/add op, ENOENT ok, else die */ #define XFS_DA_OP_CILOOKUP 0x0010 /* lookup to return CI name if found */ +#define XFS_DA_OP_FLAGS \ + { XFS_DA_OP_JUSTCHECK, "JUSTCHECK" }, \ + { XFS_DA_OP_RENAME, "RENAME" }, \ + { XFS_DA_OP_ADDNAME, "ADDNAME" }, \ + { XFS_DA_OP_OKNOENT, "OKNOENT" }, \ + { XFS_DA_OP_CILOOKUP, "CILOOKUP" } + /* * Structure to describe buffer(s) for a block. * This is needed in the directory version 2 format case, when diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index ab89a7e..d1483a4 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c @@ -43,6 +43,7 @@ #include "xfs_error.h" #include "xfs_rw.h" #include "xfs_vnodeops.h" +#include "xfs_trace.h" /* * Syssgi interface for swapext @@ -168,7 +169,6 @@ xfs_swap_extents( } if (VN_CACHED(VFS_I(tip)) != 0) { - xfs_inval_cached_trace(tip, 0, -1, 0, -1); error = xfs_flushinval_pages(tip, 0, -1, FI_REMAPF_LOCKED); if (error) diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c index bb1d58e..93634a7 100644 --- a/fs/xfs/xfs_dir2.c +++ b/fs/xfs/xfs_dir2.c @@ -40,9 +40,9 @@ #include "xfs_dir2_leaf.h" #include "xfs_dir2_block.h" #include "xfs_dir2_node.h" -#include "xfs_dir2_trace.h" #include "xfs_error.h" #include "xfs_vnodeops.h" +#include "xfs_trace.h" struct xfs_name xfs_name_dotdot = {"..", 2}; @@ -525,7 +525,8 @@ xfs_dir2_grow_inode( xfs_trans_t *tp; xfs_drfsbno_t nblks; - xfs_dir2_trace_args_s("grow_inode", args, space); + trace_xfs_dir2_grow_inode(args, space); + dp = args->dp; tp = args->trans; mp = dp->i_mount; @@ -703,7 +704,8 @@ xfs_dir2_shrink_inode( xfs_mount_t *mp; xfs_trans_t *tp; - xfs_dir2_trace_args_db("shrink_inode", args, db, bp); + trace_xfs_dir2_shrink_inode(args, db); + dp = args->dp; mp = dp->i_mount; tp = args->trans; diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index ab52e9e..ddc4ecc 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c @@ -36,8 +36,8 @@ #include "xfs_dir2_data.h" #include "xfs_dir2_leaf.h" #include "xfs_dir2_block.h" -#include "xfs_dir2_trace.h" #include "xfs_error.h" +#include "xfs_trace.h" /* * Local function prototypes. @@ -94,7 +94,8 @@ xfs_dir2_block_addname( __be16 *tagp; /* pointer to tag value */ xfs_trans_t *tp; /* transaction structure */ - xfs_dir2_trace_args("block_addname", args); + trace_xfs_dir2_block_addname(args); + dp = args->dp; tp = args->trans; mp = dp->i_mount; @@ -590,7 +591,8 @@ xfs_dir2_block_lookup( int error; /* error return value */ xfs_mount_t *mp; /* filesystem mount point */ - xfs_dir2_trace_args("block_lookup", args); + trace_xfs_dir2_block_lookup(args); + /* * Get the buffer, look up the entry. * If not found (ENOENT) then return, have no buffer. @@ -747,7 +749,8 @@ xfs_dir2_block_removename( int size; /* shortform size */ xfs_trans_t *tp; /* transaction pointer */ - xfs_dir2_trace_args("block_removename", args); + trace_xfs_dir2_block_removename(args); + /* * Look up the entry in the block. Gets the buffer and entry index. * It will always be there, the vnodeops level does a lookup first. @@ -823,7 +826,8 @@ xfs_dir2_block_replace( int error; /* error return value */ xfs_mount_t *mp; /* filesystem mount point */ - xfs_dir2_trace_args("block_replace", args); + trace_xfs_dir2_block_replace(args); + /* * Lookup the entry in the directory. Get buffer and entry index. * This will always succeed since the caller has already done a lookup. @@ -897,7 +901,8 @@ xfs_dir2_leaf_to_block( int to; /* block/leaf to index */ xfs_trans_t *tp; /* transaction pointer */ - xfs_dir2_trace_args_bb("leaf_to_block", args, lbp, dbp); + trace_xfs_dir2_leaf_to_block(args); + dp = args->dp; tp = args->trans; mp = dp->i_mount; @@ -1044,7 +1049,8 @@ xfs_dir2_sf_to_block( xfs_trans_t *tp; /* transaction pointer */ struct xfs_name name; - xfs_dir2_trace_args("sf_to_block", args); + trace_xfs_dir2_sf_to_block(args); + dp = args->dp; tp = args->trans; mp = dp->i_mount; diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 41ad537..29f484c 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c @@ -38,8 +38,8 @@ #include "xfs_dir2_leaf.h" #include "xfs_dir2_block.h" #include "xfs_dir2_node.h" -#include "xfs_dir2_trace.h" #include "xfs_error.h" +#include "xfs_trace.h" /* * Local function declarations. @@ -80,7 +80,8 @@ xfs_dir2_block_to_leaf( int needscan; /* need to rescan bestfree */ xfs_trans_t *tp; /* transaction pointer */ - xfs_dir2_trace_args_b("block_to_leaf", args, dbp); + trace_xfs_dir2_block_to_leaf(args); + dp = args->dp; mp = dp->i_mount; tp = args->trans; @@ -188,7 +189,8 @@ xfs_dir2_leaf_addname( xfs_trans_t *tp; /* transaction pointer */ xfs_dir2_db_t use_block; /* data block number */ - xfs_dir2_trace_args("leaf_addname", args); + trace_xfs_dir2_leaf_addname(args); + dp = args->dp; tp = args->trans; mp = dp->i_mount; @@ -1266,7 +1268,8 @@ xfs_dir2_leaf_lookup( xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_trans_t *tp; /* transaction pointer */ - xfs_dir2_trace_args("leaf_lookup", args); + trace_xfs_dir2_leaf_lookup(args); + /* * Look up name in the leaf block, returning both buffers and index. */ @@ -1454,7 +1457,8 @@ xfs_dir2_leaf_removename( xfs_dir2_data_off_t oldbest; /* old value of best free */ xfs_trans_t *tp; /* transaction pointer */ - xfs_dir2_trace_args("leaf_removename", args); + trace_xfs_dir2_leaf_removename(args); + /* * Lookup the leaf entry, get the leaf and data blocks read in. */ @@ -1586,7 +1590,8 @@ xfs_dir2_leaf_replace( xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_trans_t *tp; /* transaction pointer */ - xfs_dir2_trace_args("leaf_replace", args); + trace_xfs_dir2_leaf_replace(args); + /* * Look up the entry. */ @@ -1766,7 +1771,9 @@ xfs_dir2_node_to_leaf( if (state->path.active > 1) return 0; args = state->args; - xfs_dir2_trace_args("node_to_leaf", args); + + trace_xfs_dir2_node_to_leaf(args); + mp = state->mp; dp = args->dp; tp = args->trans; diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c index 5a81ccd..ce6e355 100644 --- a/fs/xfs/xfs_dir2_node.c +++ b/fs/xfs/xfs_dir2_node.c @@ -37,8 +37,8 @@ #include "xfs_dir2_leaf.h" #include "xfs_dir2_block.h" #include "xfs_dir2_node.h" -#include "xfs_dir2_trace.h" #include "xfs_error.h" +#include "xfs_trace.h" /* * Function declarations. @@ -123,7 +123,8 @@ xfs_dir2_leaf_to_node( __be16 *to; /* pointer to freespace entry */ xfs_trans_t *tp; /* transaction pointer */ - xfs_dir2_trace_args_b("leaf_to_node", args, lbp); + trace_xfs_dir2_leaf_to_node(args); + dp = args->dp; mp = dp->i_mount; tp = args->trans; @@ -196,7 +197,8 @@ xfs_dir2_leafn_add( xfs_mount_t *mp; /* filesystem mount point */ xfs_trans_t *tp; /* transaction pointer */ - xfs_dir2_trace_args_sb("leafn_add", args, index, bp); + trace_xfs_dir2_leafn_add(args, index); + dp = args->dp; mp = dp->i_mount; tp = args->trans; @@ -711,8 +713,8 @@ xfs_dir2_leafn_moveents( int stale; /* count stale leaves copied */ xfs_trans_t *tp; /* transaction pointer */ - xfs_dir2_trace_args_bibii("leafn_moveents", args, bp_s, start_s, bp_d, - start_d, count); + trace_xfs_dir2_leafn_moveents(args, start_s, start_d, count); + /* * Silently return if nothing to do. */ @@ -933,7 +935,8 @@ xfs_dir2_leafn_remove( int needscan; /* need to rescan data frees */ xfs_trans_t *tp; /* transaction pointer */ - xfs_dir2_trace_args_sb("leafn_remove", args, index, bp); + trace_xfs_dir2_leafn_remove(args, index); + dp = args->dp; tp = args->trans; mp = dp->i_mount; @@ -1363,7 +1366,8 @@ xfs_dir2_node_addname( int rval; /* sub-return value */ xfs_da_state_t *state; /* btree cursor */ - xfs_dir2_trace_args("node_addname", args); + trace_xfs_dir2_node_addname(args); + /* * Allocate and initialize the state (btree cursor). */ @@ -1822,7 +1826,8 @@ xfs_dir2_node_lookup( int rval; /* operation return value */ xfs_da_state_t *state; /* btree cursor */ - xfs_dir2_trace_args("node_lookup", args); + trace_xfs_dir2_node_lookup(args); + /* * Allocate and initialize the btree cursor. */ @@ -1875,7 +1880,8 @@ xfs_dir2_node_removename( int rval; /* operation return value */ xfs_da_state_t *state; /* btree cursor */ - xfs_dir2_trace_args("node_removename", args); + trace_xfs_dir2_node_removename(args); + /* * Allocate and initialize the btree cursor. */ @@ -1944,7 +1950,8 @@ xfs_dir2_node_replace( int rval; /* internal return value */ xfs_da_state_t *state; /* btree cursor */ - xfs_dir2_trace_args("node_replace", args); + trace_xfs_dir2_node_replace(args); + /* * Allocate and initialize the btree cursor. */ diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c index e89734e..9d4f17a 100644 --- a/fs/xfs/xfs_dir2_sf.c +++ b/fs/xfs/xfs_dir2_sf.c @@ -37,7 +37,7 @@ #include "xfs_dir2_data.h" #include "xfs_dir2_leaf.h" #include "xfs_dir2_block.h" -#include "xfs_dir2_trace.h" +#include "xfs_trace.h" /* * Prototypes for internal functions. @@ -169,7 +169,8 @@ xfs_dir2_block_to_sf( xfs_dir2_sf_t *sfp; /* shortform structure */ xfs_ino_t temp; - xfs_dir2_trace_args_sb("block_to_sf", args, size, bp); + trace_xfs_dir2_block_to_sf(args); + dp = args->dp; mp = dp->i_mount; @@ -281,7 +282,8 @@ xfs_dir2_sf_addname( xfs_dir2_sf_t *sfp; /* shortform structure */ xfs_dir2_sf_entry_t *sfep = NULL; /* shortform entry */ - xfs_dir2_trace_args("sf_addname", args); + trace_xfs_dir2_sf_addname(args); + ASSERT(xfs_dir2_sf_lookup(args) == ENOENT); dp = args->dp; ASSERT(dp->i_df.if_flags & XFS_IFINLINE); @@ -654,7 +656,8 @@ xfs_dir2_sf_create( xfs_dir2_sf_t *sfp; /* shortform structure */ int size; /* directory size */ - xfs_dir2_trace_args_i("sf_create", args, pino); + trace_xfs_dir2_sf_create(args); + dp = args->dp; ASSERT(dp != NULL); @@ -808,7 +811,8 @@ xfs_dir2_sf_lookup( enum xfs_dacmp cmp; /* comparison result */ xfs_dir2_sf_entry_t *ci_sfep; /* case-insens. entry */ - xfs_dir2_trace_args("sf_lookup", args); + trace_xfs_dir2_sf_lookup(args); + xfs_dir2_sf_check(args); dp = args->dp; @@ -891,7 +895,8 @@ xfs_dir2_sf_removename( xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ xfs_dir2_sf_t *sfp; /* shortform structure */ - xfs_dir2_trace_args("sf_removename", args); + trace_xfs_dir2_sf_removename(args); + dp = args->dp; ASSERT(dp->i_df.if_flags & XFS_IFINLINE); @@ -982,7 +987,8 @@ xfs_dir2_sf_replace( xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ xfs_dir2_sf_t *sfp; /* shortform structure */ - xfs_dir2_trace_args("sf_replace", args); + trace_xfs_dir2_sf_replace(args); + dp = args->dp; ASSERT(dp->i_df.if_flags & XFS_IFINLINE); @@ -1125,7 +1131,8 @@ xfs_dir2_sf_toino4( xfs_dir2_sf_entry_t *sfep; /* new sf entry */ xfs_dir2_sf_t *sfp; /* new sf directory */ - xfs_dir2_trace_args("sf_toino4", args); + trace_xfs_dir2_sf_toino4(args); + dp = args->dp; /* @@ -1202,7 +1209,8 @@ xfs_dir2_sf_toino8( xfs_dir2_sf_entry_t *sfep; /* new sf entry */ xfs_dir2_sf_t *sfp; /* new sf directory */ - xfs_dir2_trace_args("sf_toino8", args); + trace_xfs_dir2_sf_toino8(args); + dp = args->dp; /* diff --git a/fs/xfs/xfs_dir2_trace.c b/fs/xfs/xfs_dir2_trace.c deleted file mode 100644 index 6cc7c0c..0000000 --- a/fs/xfs/xfs_dir2_trace.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "xfs.h" -#include "xfs_fs.h" -#include "xfs_types.h" -#include "xfs_inum.h" -#include "xfs_dir2.h" -#include "xfs_da_btree.h" -#include "xfs_bmap_btree.h" -#include "xfs_dir2_sf.h" -#include "xfs_attr_sf.h" -#include "xfs_dinode.h" -#include "xfs_inode.h" -#include "xfs_dir2_trace.h" - -#ifdef XFS_DIR2_TRACE -ktrace_t *xfs_dir2_trace_buf; - -/* - * Enter something in the trace buffers. - */ -static void -xfs_dir2_trace_enter( - xfs_inode_t *dp, - int type, - char *where, - char *name, - int namelen, - void *a0, - void *a1, - void *a2, - void *a3, - void *a4, - void *a5, - void *a6, - void *a7) -{ - void *n[5]; - - ASSERT(xfs_dir2_trace_buf); - ASSERT(dp->i_dir_trace); - if (name) - memcpy(n, name, min((int)sizeof(n), namelen)); - else - memset((char *)n, 0, sizeof(n)); - ktrace_enter(xfs_dir2_trace_buf, - (void *)(long)type, (void *)where, - (void *)a0, (void *)a1, (void *)a2, (void *)a3, - (void *)a4, (void *)a5, (void *)a6, (void *)a7, - (void *)(long)namelen, - (void *)n[0], (void *)n[1], (void *)n[2], - (void *)n[3], (void *)n[4]); - ktrace_enter(dp->i_dir_trace, - (void *)(long)type, (void *)where, - (void *)a0, (void *)a1, (void *)a2, (void *)a3, - (void *)a4, (void *)a5, (void *)a6, (void *)a7, - (void *)(long)namelen, - (void *)n[0], (void *)n[1], (void *)n[2], - (void *)n[3], (void *)n[4]); -} - -void -xfs_dir2_trace_args( - char *where, - xfs_da_args_t *args) -{ - xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS, where, - (char *)args->name, (int)args->namelen, - (void *)(unsigned long)args->hashval, - (void *)((unsigned long)(args->inumber >> 32)), - (void *)((unsigned long)(args->inumber & 0xFFFFFFFF)), - (void *)args->dp, (void *)args->trans, - (void *)(unsigned long)(args->op_flags & XFS_DA_OP_JUSTCHECK), - NULL, NULL); -} - -void -xfs_dir2_trace_args_b( - char *where, - xfs_da_args_t *args, - xfs_dabuf_t *bp) -{ - xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS_B, where, - (char *)args->name, (int)args->namelen, - (void *)(unsigned long)args->hashval, - (void *)((unsigned long)(args->inumber >> 32)), - (void *)((unsigned long)(args->inumber & 0xFFFFFFFF)), - (void *)args->dp, (void *)args->trans, - (void *)(unsigned long)(args->op_flags & XFS_DA_OP_JUSTCHECK), - (void *)(bp ? bp->bps[0] : NULL), NULL); -} - -void -xfs_dir2_trace_args_bb( - char *where, - xfs_da_args_t *args, - xfs_dabuf_t *lbp, - xfs_dabuf_t *dbp) -{ - xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS_BB, where, - (char *)args->name, (int)args->namelen, - (void *)(unsigned long)args->hashval, - (void *)((unsigned long)(args->inumber >> 32)), - (void *)((unsigned long)(args->inumber & 0xFFFFFFFF)), - (void *)args->dp, (void *)args->trans, - (void *)(unsigned long)(args->op_flags & XFS_DA_OP_JUSTCHECK), - (void *)(lbp ? lbp->bps[0] : NULL), - (void *)(dbp ? dbp->bps[0] : NULL)); -} - -void -xfs_dir2_trace_args_bibii( - char *where, - xfs_da_args_t *args, - xfs_dabuf_t *bs, - int ss, - xfs_dabuf_t *bd, - int sd, - int c) -{ - xfs_buf_t *bpbs = bs ? bs->bps[0] : NULL; - xfs_buf_t *bpbd = bd ? bd->bps[0] : NULL; - - xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS_BIBII, where, - (char *)args->name, (int)args->namelen, - (void *)args->dp, (void *)args->trans, - (void *)bpbs, (void *)(long)ss, (void *)bpbd, (void *)(long)sd, - (void *)(long)c, NULL); -} - -void -xfs_dir2_trace_args_db( - char *where, - xfs_da_args_t *args, - xfs_dir2_db_t db, - xfs_dabuf_t *bp) -{ - xfs_buf_t *dbp = bp ? bp->bps[0] : NULL; - - xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS_DB, where, - (char *)args->name, (int)args->namelen, - (void *)(unsigned long)args->hashval, - (void *)((unsigned long)(args->inumber >> 32)), - (void *)((unsigned long)(args->inumber & 0xFFFFFFFF)), - (void *)args->dp, (void *)args->trans, - (void *)(unsigned long)(args->op_flags & XFS_DA_OP_JUSTCHECK), - (void *)(long)db, (void *)dbp); -} - -void -xfs_dir2_trace_args_i( - char *where, - xfs_da_args_t *args, - xfs_ino_t i) -{ - xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS_I, where, - (char *)args->name, (int)args->namelen, - (void *)(unsigned long)args->hashval, - (void *)((unsigned long)(args->inumber >> 32)), - (void *)((unsigned long)(args->inumber & 0xFFFFFFFF)), - (void *)args->dp, (void *)args->trans, - (void *)(unsigned long)(args->op_flags & XFS_DA_OP_JUSTCHECK), - (void *)((unsigned long)(i >> 32)), - (void *)((unsigned long)(i & 0xFFFFFFFF))); -} - -void -xfs_dir2_trace_args_s( - char *where, - xfs_da_args_t *args, - int s) -{ - xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS_S, where, - (char *)args->name, (int)args->namelen, - (void *)(unsigned long)args->hashval, - (void *)((unsigned long)(args->inumber >> 32)), - (void *)((unsigned long)(args->inumber & 0xFFFFFFFF)), - (void *)args->dp, (void *)args->trans, - (void *)(unsigned long)(args->op_flags & XFS_DA_OP_JUSTCHECK), - (void *)(long)s, NULL); -} - -void -xfs_dir2_trace_args_sb( - char *where, - xfs_da_args_t *args, - int s, - xfs_dabuf_t *bp) -{ - xfs_buf_t *dbp = bp ? bp->bps[0] : NULL; - - xfs_dir2_trace_enter(args->dp, XFS_DIR2_KTRACE_ARGS_SB, where, - (char *)args->name, (int)args->namelen, - (void *)(unsigned long)args->hashval, - (void *)((unsigned long)(args->inumber >> 32)), - (void *)((unsigned long)(args->inumber & 0xFFFFFFFF)), - (void *)args->dp, (void *)args->trans, - (void *)(unsigned long)(args->op_flags & XFS_DA_OP_JUSTCHECK), - (void *)(long)s, (void *)dbp); -} -#endif /* XFS_DIR2_TRACE */ diff --git a/fs/xfs/xfs_dir2_trace.h b/fs/xfs/xfs_dir2_trace.h deleted file mode 100644 index ca3c754..0000000 --- a/fs/xfs/xfs_dir2_trace.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2000,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_DIR2_TRACE_H__ -#define __XFS_DIR2_TRACE_H__ - -/* - * Tracing for xfs v2 directories. - */ - -#if defined(XFS_DIR2_TRACE) - -struct ktrace; -struct xfs_dabuf; -struct xfs_da_args; - -#define XFS_DIR2_GTRACE_SIZE 4096 /* global buffer */ -#define XFS_DIR2_KTRACE_SIZE 32 /* per-inode buffer */ -extern struct ktrace *xfs_dir2_trace_buf; - -#define XFS_DIR2_KTRACE_ARGS 1 /* args only */ -#define XFS_DIR2_KTRACE_ARGS_B 2 /* args + buffer */ -#define XFS_DIR2_KTRACE_ARGS_BB 3 /* args + 2 buffers */ -#define XFS_DIR2_KTRACE_ARGS_DB 4 /* args, db, buffer */ -#define XFS_DIR2_KTRACE_ARGS_I 5 /* args, inum */ -#define XFS_DIR2_KTRACE_ARGS_S 6 /* args, int */ -#define XFS_DIR2_KTRACE_ARGS_SB 7 /* args, int, buffer */ -#define XFS_DIR2_KTRACE_ARGS_BIBII 8 /* args, buf/int/buf/int/int */ - -void xfs_dir2_trace_args(char *where, struct xfs_da_args *args); -void xfs_dir2_trace_args_b(char *where, struct xfs_da_args *args, - struct xfs_dabuf *bp); -void xfs_dir2_trace_args_bb(char *where, struct xfs_da_args *args, - struct xfs_dabuf *lbp, struct xfs_dabuf *dbp); -void xfs_dir2_trace_args_bibii(char *where, struct xfs_da_args *args, - struct xfs_dabuf *bs, int ss, - struct xfs_dabuf *bd, int sd, int c); -void xfs_dir2_trace_args_db(char *where, struct xfs_da_args *args, - xfs_dir2_db_t db, struct xfs_dabuf *bp); -void xfs_dir2_trace_args_i(char *where, struct xfs_da_args *args, xfs_ino_t i); -void xfs_dir2_trace_args_s(char *where, struct xfs_da_args *args, int s); -void xfs_dir2_trace_args_sb(char *where, struct xfs_da_args *args, int s, - struct xfs_dabuf *bp); - -#else /* XFS_DIR2_TRACE */ - -#define xfs_dir2_trace_args(where, args) -#define xfs_dir2_trace_args_b(where, args, bp) -#define xfs_dir2_trace_args_bb(where, args, lbp, dbp) -#define xfs_dir2_trace_args_bibii(where, args, bs, ss, bd, sd, c) -#define xfs_dir2_trace_args_db(where, args, db, bp) -#define xfs_dir2_trace_args_i(where, args, i) -#define xfs_dir2_trace_args_s(where, args, s) -#define xfs_dir2_trace_args_sb(where, args, s, bp) - -#endif /* XFS_DIR2_TRACE */ - -#endif /* __XFS_DIR2_TRACE_H__ */ diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index edf8bdf..a631e14 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -34,6 +34,7 @@ #include "xfs_utils.h" #include "xfs_mru_cache.h" #include "xfs_filestream.h" +#include "xfs_trace.h" #ifdef XFS_FILESTREAMS_TRACE @@ -394,9 +395,7 @@ xfs_filestream_init(void) item_zone = kmem_zone_init(sizeof(fstrm_item_t), "fstrm_item"); if (!item_zone) return -ENOMEM; -#ifdef XFS_FILESTREAMS_TRACE - xfs_filestreams_trace_buf = ktrace_alloc(XFS_FSTRM_KTRACE_SIZE, KM_NOFS); -#endif + return 0; } @@ -407,9 +406,6 @@ xfs_filestream_init(void) void xfs_filestream_uninit(void) { -#ifdef XFS_FILESTREAMS_TRACE - ktrace_free(xfs_filestreams_trace_buf); -#endif kmem_zone_destroy(item_zone); } diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 36079aa..a13919a 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -45,6 +45,7 @@ #include "xfs_rtalloc.h" #include "xfs_rw.h" #include "xfs_filestream.h" +#include "xfs_trace.h" /* * File system operations @@ -347,6 +348,7 @@ xfs_growfs_data_private( be32_add_cpu(&agf->agf_length, new); ASSERT(be32_to_cpu(agf->agf_length) == be32_to_cpu(agi->agi_length)); + xfs_alloc_log_agf(tp, bp, XFS_AGF_LENGTH); /* * Free the new space. diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 073bb4a..f5c904a 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -43,7 +43,7 @@ #include "xfs_inode_item.h" #include "xfs_bmap.h" #include "xfs_btree_trace.h" -#include "xfs_dir2_trace.h" +#include "xfs_trace.h" /* @@ -90,28 +90,6 @@ xfs_inode_alloc( ip->i_size = 0; ip->i_new_size = 0; - /* - * Initialize inode's trace buffers. - */ -#ifdef XFS_INODE_TRACE - ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS); -#endif -#ifdef XFS_BMAP_TRACE - ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS); -#endif -#ifdef XFS_BTREE_TRACE - ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS); -#endif -#ifdef XFS_RW_TRACE - ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_NOFS); -#endif -#ifdef XFS_ILOCK_TRACE - ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_NOFS); -#endif -#ifdef XFS_DIR2_TRACE - ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS); -#endif - /* prevent anyone from using this yet */ VFS_I(ip)->i_state = I_NEW|I_LOCK; @@ -133,25 +111,6 @@ xfs_inode_free( if (ip->i_afp) xfs_idestroy_fork(ip, XFS_ATTR_FORK); -#ifdef XFS_INODE_TRACE - ktrace_free(ip->i_trace); -#endif -#ifdef XFS_BMAP_TRACE - ktrace_free(ip->i_xtrace); -#endif -#ifdef XFS_BTREE_TRACE - ktrace_free(ip->i_btrace); -#endif -#ifdef XFS_RW_TRACE - ktrace_free(ip->i_rwtrace); -#endif -#ifdef XFS_ILOCK_TRACE - ktrace_free(ip->i_lock_trace); -#endif -#ifdef XFS_DIR2_TRACE - ktrace_free(ip->i_dir_trace); -#endif - if (ip->i_itemp) { /* * Only if we are shutting down the fs will we see an @@ -210,6 +169,7 @@ xfs_iget_cache_hit( * instead of polling for it. */ if (ip->i_flags & (XFS_INEW|XFS_IRECLAIM)) { + trace_xfs_iget_skip(ip); XFS_STATS_INC(xs_ig_frecycle); error = EAGAIN; goto out_error; @@ -228,7 +188,7 @@ xfs_iget_cache_hit( * Need to carefully get it back into useable state. */ if (ip->i_flags & XFS_IRECLAIMABLE) { - xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); + trace_xfs_iget_reclaim(ip); /* * We need to set XFS_INEW atomically with clearing the @@ -254,6 +214,7 @@ xfs_iget_cache_hit( ip->i_flags &= ~XFS_INEW; ip->i_flags |= XFS_IRECLAIMABLE; __xfs_inode_set_reclaim_tag(pag, ip); + trace_xfs_iget_reclaim(ip); goto out_error; } inode->i_state = I_LOCK|I_NEW; @@ -273,8 +234,9 @@ xfs_iget_cache_hit( xfs_ilock(ip, lock_flags); xfs_iflags_clear(ip, XFS_ISTALE); - xfs_itrace_exit_tag(ip, "xfs_iget.found"); XFS_STATS_INC(xs_ig_found); + + trace_xfs_iget_found(ip); return 0; out_error: @@ -308,7 +270,7 @@ xfs_iget_cache_miss( if (error) goto out_destroy; - xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); + xfs_itrace_entry(ip); if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) { error = ENOENT; @@ -353,6 +315,8 @@ xfs_iget_cache_miss( write_unlock(&pag->pag_ici_lock); radix_tree_preload_end(); + + trace_xfs_iget_alloc(ip); *ipp = ip; return 0; @@ -639,7 +603,7 @@ xfs_ilock( else if (lock_flags & XFS_ILOCK_SHARED) mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags)); - xfs_ilock_trace(ip, 1, lock_flags, (inst_t *)__return_address); + trace_xfs_ilock(ip, lock_flags, _RET_IP_); } /* @@ -684,7 +648,7 @@ xfs_ilock_nowait( if (!mrtryaccess(&ip->i_lock)) goto out_undo_iolock; } - xfs_ilock_trace(ip, 2, lock_flags, (inst_t *)__return_address); + trace_xfs_ilock_nowait(ip, lock_flags, _RET_IP_); return 1; out_undo_iolock: @@ -746,7 +710,7 @@ xfs_iunlock( xfs_trans_unlocked_item(ip->i_itemp->ili_item.li_ailp, (xfs_log_item_t*)(ip->i_itemp)); } - xfs_ilock_trace(ip, 3, lock_flags, (inst_t *)__return_address); + trace_xfs_iunlock(ip, lock_flags, _RET_IP_); } /* @@ -765,6 +729,8 @@ xfs_ilock_demote( mrdemote(&ip->i_lock); if (lock_flags & XFS_IOLOCK_EXCL) mrdemote(&ip->i_iolock); + + trace_xfs_ilock_demote(ip, lock_flags, _RET_IP_); } #ifdef DEBUG @@ -795,52 +761,3 @@ xfs_isilocked( return 1; } #endif - -#ifdef XFS_INODE_TRACE - -#define KTRACE_ENTER(ip, vk, s, line, ra) \ - ktrace_enter((ip)->i_trace, \ -/* 0 */ (void *)(__psint_t)(vk), \ -/* 1 */ (void *)(s), \ -/* 2 */ (void *)(__psint_t) line, \ -/* 3 */ (void *)(__psint_t)atomic_read(&VFS_I(ip)->i_count), \ -/* 4 */ (void *)(ra), \ -/* 5 */ NULL, \ -/* 6 */ (void *)(__psint_t)current_cpu(), \ -/* 7 */ (void *)(__psint_t)current_pid(), \ -/* 8 */ (void *)__return_address, \ -/* 9 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL) - -/* - * Vnode tracing code. - */ -void -_xfs_itrace_entry(xfs_inode_t *ip, const char *func, inst_t *ra) -{ - KTRACE_ENTER(ip, INODE_KTRACE_ENTRY, func, 0, ra); -} - -void -_xfs_itrace_exit(xfs_inode_t *ip, const char *func, inst_t *ra) -{ - KTRACE_ENTER(ip, INODE_KTRACE_EXIT, func, 0, ra); -} - -void -xfs_itrace_hold(xfs_inode_t *ip, char *file, int line, inst_t *ra) -{ - KTRACE_ENTER(ip, INODE_KTRACE_HOLD, file, line, ra); -} - -void -_xfs_itrace_ref(xfs_inode_t *ip, char *file, int line, inst_t *ra) -{ - KTRACE_ENTER(ip, INODE_KTRACE_REF, file, line, ra); -} - -void -xfs_itrace_rele(xfs_inode_t *ip, char *file, int line, inst_t *ra) -{ - KTRACE_ENTER(ip, INODE_KTRACE_RELE, file, line, ra); -} -#endif /* XFS_INODE_TRACE */ diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 614acd5..ce278b3 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -47,10 +47,10 @@ #include "xfs_rw.h" #include "xfs_error.h" #include "xfs_utils.h" -#include "xfs_dir2_trace.h" #include "xfs_quota.h" #include "xfs_filestream.h" #include "xfs_vnodeops.h" +#include "xfs_trace.h" kmem_zone_t *xfs_ifork_zone; kmem_zone_t *xfs_inode_zone; @@ -1291,42 +1291,6 @@ xfs_file_last_byte( return last_byte; } -#if defined(XFS_RW_TRACE) -STATIC void -xfs_itrunc_trace( - int tag, - xfs_inode_t *ip, - int flag, - xfs_fsize_t new_size, - xfs_off_t toss_start, - xfs_off_t toss_finish) -{ - if (ip->i_rwtrace == NULL) { - return; - } - - ktrace_enter(ip->i_rwtrace, - (void*)((long)tag), - (void*)ip, - (void*)(unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff), - (void*)(unsigned long)(ip->i_d.di_size & 0xffffffff), - (void*)((long)flag), - (void*)(unsigned long)((new_size >> 32) & 0xffffffff), - (void*)(unsigned long)(new_size & 0xffffffff), - (void*)(unsigned long)((toss_start >> 32) & 0xffffffff), - (void*)(unsigned long)(toss_start & 0xffffffff), - (void*)(unsigned long)((toss_finish >> 32) & 0xffffffff), - (void*)(unsigned long)(toss_finish & 0xffffffff), - (void*)(unsigned long)current_cpu(), - (void*)(unsigned long)current_pid(), - (void*)NULL, - (void*)NULL, - (void*)NULL); -} -#else -#define xfs_itrunc_trace(tag, ip, flag, new_size, toss_start, toss_finish) -#endif - /* * Start the truncation of the file to new_size. The new size * must be smaller than the current size. This routine will @@ -1409,8 +1373,7 @@ xfs_itruncate_start( return 0; } last_byte = xfs_file_last_byte(ip); - xfs_itrunc_trace(XFS_ITRUNC_START, ip, flags, new_size, toss_start, - last_byte); + trace_xfs_itruncate_start(ip, flags, new_size, toss_start, last_byte); if (last_byte > toss_start) { if (flags & XFS_ITRUNC_DEFINITE) { xfs_tosspages(ip, toss_start, @@ -1514,7 +1477,8 @@ xfs_itruncate_finish( new_size = 0LL; } first_unmap_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size); - xfs_itrunc_trace(XFS_ITRUNC_FINISH1, ip, 0, new_size, 0, 0); + trace_xfs_itruncate_finish_start(ip, new_size); + /* * The first thing we do is set the size to new_size permanently * on disk. This way we don't have to worry about anyone ever @@ -1731,7 +1695,7 @@ xfs_itruncate_finish( ASSERT((new_size != 0) || (fork == XFS_ATTR_FORK) || (ip->i_d.di_nextents == 0)); - xfs_itrunc_trace(XFS_ITRUNC_FINISH2, ip, 0, new_size, 0, 0); + trace_xfs_itruncate_finish_end(ip, new_size); return 0; } @@ -3252,23 +3216,6 @@ corrupt_out: return XFS_ERROR(EFSCORRUPTED); } - - -#ifdef XFS_ILOCK_TRACE -void -xfs_ilock_trace(xfs_inode_t *ip, int lock, unsigned int lockflags, inst_t *ra) -{ - ktrace_enter(ip->i_lock_trace, - (void *)ip, - (void *)(unsigned long)lock, /* 1 = LOCK, 3=UNLOCK, etc */ - (void *)(unsigned long)lockflags, /* XFS_ILOCK_EXCL etc */ - (void *)ra, /* caller of ilock */ - (void *)(unsigned long)current_cpu(), - (void *)(unsigned long)current_pid(), - NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -} -#endif - /* * Return a pointer to the extent record at file index idx. */ @@ -3309,6 +3256,8 @@ xfs_iext_insert( xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df; xfs_extnum_t i; /* extent record index */ + trace_xfs_iext_insert(ip, idx, new, state, _RET_IP_); + ASSERT(ifp->if_flags & XFS_IFEXTENTS); xfs_iext_add(ifp, idx, count); for (i = idx; i < idx + count; i++, new++) @@ -3560,6 +3509,8 @@ xfs_iext_remove( xfs_extnum_t nextents; /* number of extents in file */ int new_size; /* size of extents after removal */ + trace_xfs_iext_remove(ip, idx, state, _RET_IP_); + ASSERT(ext_diff > 0); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); new_size = (nextents - ext_diff) * sizeof(xfs_bmbt_rec_t); diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 946a8ca..ec1f28c 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -213,7 +213,6 @@ typedef struct xfs_icdinode { struct bhv_desc; struct cred; -struct ktrace; struct xfs_buf; struct xfs_bmap_free; struct xfs_bmbt_irec; @@ -222,13 +221,6 @@ struct xfs_mount; struct xfs_trans; struct xfs_dquot; -#if defined(XFS_ILOCK_TRACE) -#define XFS_ILOCK_KTRACE_SIZE 32 -extern void xfs_ilock_trace(struct xfs_inode *, int, unsigned int, inst_t *); -#else -#define xfs_ilock_trace(i,n,f,ra) -#endif - typedef struct dm_attrs_s { __uint32_t da_dmevmask; /* DMIG event mask */ __uint16_t da_dmstate; /* DMIG state info */ @@ -271,26 +263,6 @@ typedef struct xfs_inode { /* VFS inode */ struct inode i_vnode; /* embedded VFS inode */ - - /* Trace buffers per inode. */ -#ifdef XFS_INODE_TRACE - struct ktrace *i_trace; /* general inode trace */ -#endif -#ifdef XFS_BMAP_TRACE - struct ktrace *i_xtrace; /* inode extent list trace */ -#endif -#ifdef XFS_BTREE_TRACE - struct ktrace *i_btrace; /* inode bmap btree trace */ -#endif -#ifdef XFS_RW_TRACE - struct ktrace *i_rwtrace; /* inode read/write trace */ -#endif -#ifdef XFS_ILOCK_TRACE - struct ktrace *i_lock_trace; /* inode lock/unlock trace */ -#endif -#ifdef XFS_DIR2_TRACE - struct ktrace *i_dir_trace; /* inode directory trace */ -#endif } xfs_inode_t; #define XFS_ISIZE(ip) (((ip)->i_d.di_mode & S_IFMT) == S_IFREG) ? \ @@ -406,6 +378,14 @@ static inline void xfs_ifunlock(xfs_inode_t *ip) #define XFS_LOCK_MASK (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \ | XFS_ILOCK_EXCL | XFS_ILOCK_SHARED) +#define XFS_LOCK_FLAGS \ + { XFS_IOLOCK_EXCL, "IOLOCK_EXCL" }, \ + { XFS_IOLOCK_SHARED, "IOLOCK_SHARED" }, \ + { XFS_ILOCK_EXCL, "ILOCK_EXCL" }, \ + { XFS_ILOCK_SHARED, "ILOCK_SHARED" }, \ + { XFS_IUNLOCK_NONOTIFY, "IUNLOCK_NONOTIFY" } + + /* * Flags for lockdep annotations. * @@ -455,6 +435,10 @@ static inline void xfs_ifunlock(xfs_inode_t *ip) #define XFS_ITRUNC_DEFINITE 0x1 #define XFS_ITRUNC_MAYBE 0x2 +#define XFS_ITRUNC_FLAGS \ + { XFS_ITRUNC_DEFINITE, "DEFINITE" }, \ + { XFS_ITRUNC_MAYBE, "MAYBE" } + /* * For multiple groups support: if S_ISGID bit is set in the parent * directory, group of new file is set to that of the parent, and @@ -507,48 +491,16 @@ void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); void xfs_synchronize_times(xfs_inode_t *); void xfs_mark_inode_dirty_sync(xfs_inode_t *); -#if defined(XFS_INODE_TRACE) - -#define INODE_TRACE_SIZE 16 /* number of trace entries */ -#define INODE_KTRACE_ENTRY 1 -#define INODE_KTRACE_EXIT 2 -#define INODE_KTRACE_HOLD 3 -#define INODE_KTRACE_REF 4 -#define INODE_KTRACE_RELE 5 - -extern void _xfs_itrace_entry(struct xfs_inode *, const char *, inst_t *); -extern void _xfs_itrace_exit(struct xfs_inode *, const char *, inst_t *); -extern void xfs_itrace_hold(struct xfs_inode *, char *, int, inst_t *); -extern void _xfs_itrace_ref(struct xfs_inode *, char *, int, inst_t *); -extern void xfs_itrace_rele(struct xfs_inode *, char *, int, inst_t *); -#define xfs_itrace_entry(ip) \ - _xfs_itrace_entry(ip, __func__, (inst_t *)__return_address) -#define xfs_itrace_exit(ip) \ - _xfs_itrace_exit(ip, __func__, (inst_t *)__return_address) -#define xfs_itrace_exit_tag(ip, tag) \ - _xfs_itrace_exit(ip, tag, (inst_t *)__return_address) -#define xfs_itrace_ref(ip) \ - _xfs_itrace_ref(ip, __FILE__, __LINE__, (inst_t *)__return_address) - -#else -#define xfs_itrace_entry(a) -#define xfs_itrace_exit(a) -#define xfs_itrace_exit_tag(a, b) -#define xfs_itrace_hold(a, b, c, d) -#define xfs_itrace_ref(a) -#define xfs_itrace_rele(a, b, c, d) -#endif - #define IHOLD(ip) \ do { \ ASSERT(atomic_read(&VFS_I(ip)->i_count) > 0) ; \ atomic_inc(&(VFS_I(ip)->i_count)); \ - xfs_itrace_hold((ip), __FILE__, __LINE__, (inst_t *)__return_address); \ + trace_xfs_ihold(ip, _THIS_IP_); \ } while (0) #define IRELE(ip) \ do { \ - xfs_itrace_rele((ip), __FILE__, __LINE__, (inst_t *)__return_address); \ + trace_xfs_irele(ip, _THIS_IP_); \ iput(VFS_I(ip)); \ } while (0) diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 9794b87..f38855d 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -41,6 +41,7 @@ #include "xfs_ialloc.h" #include "xfs_rw.h" #include "xfs_error.h" +#include "xfs_trace.h" kmem_zone_t *xfs_ili_zone; /* inode log item zone */ @@ -800,7 +801,9 @@ xfs_inode_item_pushbuf( !completion_done(&ip->i_flush)); iip->ili_pushbuf_flag = 0; xfs_iunlock(ip, XFS_ILOCK_SHARED); - xfs_buftrace("INODE ITEM PUSH", bp); + + trace_xfs_inode_item_push(bp, _RET_IP_); + if (XFS_BUF_ISPINNED(bp)) { xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE); diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 7294abc..0b650399 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -47,72 +47,8 @@ #include "xfs_trans_space.h" #include "xfs_utils.h" #include "xfs_iomap.h" +#include "xfs_trace.h" -#if defined(XFS_RW_TRACE) -void -xfs_iomap_enter_trace( - int tag, - xfs_inode_t *ip, - xfs_off_t offset, - ssize_t count) -{ - if (!ip->i_rwtrace) - return; - - ktrace_enter(ip->i_rwtrace, - (void *)((unsigned long)tag), - (void *)ip, - (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)), - (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)), - (void *)((unsigned long)((offset >> 32) & 0xffffffff)), - (void *)((unsigned long)(offset & 0xffffffff)), - (void *)((unsigned long)count), - (void *)((unsigned long)((ip->i_new_size >> 32) & 0xffffffff)), - (void *)((unsigned long)(ip->i_new_size & 0xffffffff)), - (void *)((unsigned long)current_pid()), - (void *)NULL, - (void *)NULL, - (void *)NULL, - (void *)NULL, - (void *)NULL, - (void *)NULL); -} - -void -xfs_iomap_map_trace( - int tag, - xfs_inode_t *ip, - xfs_off_t offset, - ssize_t count, - xfs_iomap_t *iomapp, - xfs_bmbt_irec_t *imapp, - int flags) -{ - if (!ip->i_rwtrace) - return; - - ktrace_enter(ip->i_rwtrace, - (void *)((unsigned long)tag), - (void *)ip, - (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)), - (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)), - (void *)((unsigned long)((offset >> 32) & 0xffffffff)), - (void *)((unsigned long)(offset & 0xffffffff)), - (void *)((unsigned long)count), - (void *)((unsigned long)flags), - (void *)((unsigned long)((iomapp->iomap_offset >> 32) & 0xffffffff)), - (void *)((unsigned long)(iomapp->iomap_offset & 0xffffffff)), - (void *)((unsigned long)(iomapp->iomap_delta)), - (void *)((unsigned long)(iomapp->iomap_bsize)), - (void *)((unsigned long)(iomapp->iomap_bn)), - (void *)(__psint_t)(imapp->br_startoff), - (void *)((unsigned long)(imapp->br_blockcount)), - (void *)(__psint_t)(imapp->br_startblock)); -} -#else -#define xfs_iomap_enter_trace(tag, io, offset, count) -#define xfs_iomap_map_trace(tag, io, offset, count, iomapp, imapp, flags) -#endif #define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \ << mp->m_writeio_log) @@ -187,21 +123,20 @@ xfs_iomap( if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); + trace_xfs_iomap_enter(ip, offset, count, flags, NULL); + switch (flags & (BMAPI_READ | BMAPI_WRITE | BMAPI_ALLOCATE)) { case BMAPI_READ: - xfs_iomap_enter_trace(XFS_IOMAP_READ_ENTER, ip, offset, count); lockmode = xfs_ilock_map_shared(ip); bmapi_flags = XFS_BMAPI_ENTIRE; break; case BMAPI_WRITE: - xfs_iomap_enter_trace(XFS_IOMAP_WRITE_ENTER, ip, offset, count); lockmode = XFS_ILOCK_EXCL; if (flags & BMAPI_IGNSTATE) bmapi_flags |= XFS_BMAPI_IGSTATE|XFS_BMAPI_ENTIRE; xfs_ilock(ip, lockmode); break; case BMAPI_ALLOCATE: - xfs_iomap_enter_trace(XFS_IOMAP_ALLOC_ENTER, ip, offset, count); lockmode = XFS_ILOCK_SHARED; bmapi_flags = XFS_BMAPI_ENTIRE; @@ -237,8 +172,7 @@ xfs_iomap( if (nimaps && (imap.br_startblock != HOLESTARTBLOCK) && (imap.br_startblock != DELAYSTARTBLOCK)) { - xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, ip, - offset, count, iomapp, &imap, flags); + trace_xfs_iomap_found(ip, offset, count, flags, &imap); break; } @@ -250,8 +184,7 @@ xfs_iomap( &imap, &nimaps); } if (!error) { - xfs_iomap_map_trace(XFS_IOMAP_ALLOC_MAP, ip, - offset, count, iomapp, &imap, flags); + trace_xfs_iomap_alloc(ip, offset, count, flags, &imap); } iomap_flags = IOMAP_NEW; break; @@ -261,8 +194,7 @@ xfs_iomap( lockmode = 0; if (nimaps && !isnullstartblock(imap.br_startblock)) { - xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, ip, - offset, count, iomapp, &imap, flags); + trace_xfs_iomap_found(ip, offset, count, flags, &imap); break; } @@ -623,8 +555,7 @@ retry: * delalloc blocks and retry without EOF preallocation. */ if (nimaps == 0) { - xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE, - ip, offset, count); + trace_xfs_delalloc_enospc(ip, offset, count); if (flushed) return XFS_ERROR(ENOSPC); @@ -837,7 +768,7 @@ xfs_iomap_write_unwritten( int committed; int error; - xfs_iomap_enter_trace(XFS_IOMAP_UNWRITTEN, ip, offset, count); + trace_xfs_unwritten_convert(ip, offset, count); offset_fsb = XFS_B_TO_FSBT(mp, offset); count_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h index fdcf7b8..174f299 100644 --- a/fs/xfs/xfs_iomap.h +++ b/fs/xfs/xfs_iomap.h @@ -43,6 +43,14 @@ typedef enum { BMAPI_TRYLOCK = (1 << 7), /* non-blocking request */ } bmapi_flags_t; +#define BMAPI_FLAGS \ + { BMAPI_READ, "READ" }, \ + { BMAPI_WRITE, "WRITE" }, \ + { BMAPI_ALLOCATE, "ALLOCATE" }, \ + { BMAPI_IGNSTATE, "IGNSTATE" }, \ + { BMAPI_DIRECT, "DIRECT" }, \ + { BMAPI_MMAP, "MMAP" }, \ + { BMAPI_TRYLOCK, "TRYLOCK" } /* * xfs_iomap_t: File system I/O map diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 9dbdff3..4cb1792 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -40,6 +40,7 @@ #include "xfs_dinode.h" #include "xfs_inode.h" #include "xfs_rw.h" +#include "xfs_trace.h" kmem_zone_t *xfs_log_ticket_zone; @@ -122,85 +123,6 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, STATIC int xlog_iclogs_empty(xlog_t *log); -#if defined(XFS_LOG_TRACE) - -#define XLOG_TRACE_LOGGRANT_SIZE 2048 -#define XLOG_TRACE_ICLOG_SIZE 256 - -void -xlog_trace_loggrant_alloc(xlog_t *log) -{ - log->l_grant_trace = ktrace_alloc(XLOG_TRACE_LOGGRANT_SIZE, KM_NOFS); -} - -void -xlog_trace_loggrant_dealloc(xlog_t *log) -{ - ktrace_free(log->l_grant_trace); -} - -void -xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string) -{ - unsigned long cnts; - - /* ticket counts are 1 byte each */ - cnts = ((unsigned long)tic->t_ocnt) | ((unsigned long)tic->t_cnt) << 8; - - ktrace_enter(log->l_grant_trace, - (void *)tic, - (void *)log->l_reserve_headq, - (void *)log->l_write_headq, - (void *)((unsigned long)log->l_grant_reserve_cycle), - (void *)((unsigned long)log->l_grant_reserve_bytes), - (void *)((unsigned long)log->l_grant_write_cycle), - (void *)((unsigned long)log->l_grant_write_bytes), - (void *)((unsigned long)log->l_curr_cycle), - (void *)((unsigned long)log->l_curr_block), - (void *)((unsigned long)CYCLE_LSN(log->l_tail_lsn)), - (void *)((unsigned long)BLOCK_LSN(log->l_tail_lsn)), - (void *)string, - (void *)((unsigned long)tic->t_trans_type), - (void *)cnts, - (void *)((unsigned long)tic->t_curr_res), - (void *)((unsigned long)tic->t_unit_res)); -} - -void -xlog_trace_iclog_alloc(xlog_in_core_t *iclog) -{ - iclog->ic_trace = ktrace_alloc(XLOG_TRACE_ICLOG_SIZE, KM_NOFS); -} - -void -xlog_trace_iclog_dealloc(xlog_in_core_t *iclog) -{ - ktrace_free(iclog->ic_trace); -} - -void -xlog_trace_iclog(xlog_in_core_t *iclog, uint state) -{ - ktrace_enter(iclog->ic_trace, - (void *)((unsigned long)state), - (void *)((unsigned long)current_pid()), - (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL, - (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL, - (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL, - (void *)NULL, (void *)NULL); -} -#else - -#define xlog_trace_loggrant_alloc(log) -#define xlog_trace_loggrant_dealloc(log) -#define xlog_trace_loggrant(log,tic,string) - -#define xlog_trace_iclog_alloc(iclog) -#define xlog_trace_iclog_dealloc(iclog) -#define xlog_trace_iclog(iclog,state) - -#endif /* XFS_LOG_TRACE */ - static void xlog_ins_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic) @@ -353,15 +275,17 @@ xfs_log_done(xfs_mount_t *mp, if ((ticket->t_flags & XLOG_TIC_PERM_RESERV) == 0 || (flags & XFS_LOG_REL_PERM_RESERV)) { + trace_xfs_log_done_nonperm(log, ticket); + /* * Release ticket if not permanent reservation or a specific * request has been made to release a permanent reservation. */ - xlog_trace_loggrant(log, ticket, "xfs_log_done: (non-permanent)"); xlog_ungrant_log_space(log, ticket); xfs_log_ticket_put(ticket); } else { - xlog_trace_loggrant(log, ticket, "xfs_log_done: (permanent)"); + trace_xfs_log_done_perm(log, ticket); + xlog_regrant_reserve_log_space(log, ticket); /* If this ticket was a permanent reservation and we aren't * trying to release it, reset the inited flags; so next time @@ -505,10 +429,13 @@ xfs_log_reserve(xfs_mount_t *mp, XFS_STATS_INC(xs_try_logspace); + if (*ticket != NULL) { ASSERT(flags & XFS_LOG_PERM_RESERV); internal_ticket = (xlog_ticket_t *)*ticket; - xlog_trace_loggrant(log, internal_ticket, "xfs_log_reserve: existing ticket (permanent trans)"); + + trace_xfs_log_reserve(log, internal_ticket); + xlog_grant_push_ail(mp, internal_ticket->t_unit_res); retval = xlog_regrant_write_log_space(log, internal_ticket); } else { @@ -519,10 +446,9 @@ xfs_log_reserve(xfs_mount_t *mp, return XFS_ERROR(ENOMEM); internal_ticket->t_trans_type = t_type; *ticket = internal_ticket; - xlog_trace_loggrant(log, internal_ticket, - (internal_ticket->t_flags & XLOG_TIC_PERM_RESERV) ? - "xfs_log_reserve: create new ticket (permanent trans)" : - "xfs_log_reserve: create new ticket"); + + trace_xfs_log_reserve(log, internal_ticket); + xlog_grant_push_ail(mp, (internal_ticket->t_unit_res * internal_ticket->t_cnt)); @@ -734,7 +660,7 @@ xfs_log_unmount_write(xfs_mount_t *mp) spin_unlock(&log->l_icloglock); } if (tic) { - xlog_trace_loggrant(log, tic, "unmount rec"); + trace_xfs_log_umount_write(log, tic); xlog_ungrant_log_space(log, tic); xfs_log_ticket_put(tic); } @@ -1030,7 +956,6 @@ xlog_iodone(xfs_buf_t *bp) xfs_fs_cmn_err(CE_WARN, l->l_mp, "xlog_iodone: Barriers are no longer supported" " by device. Disabling barriers\n"); - xfs_buftrace("XLOG_IODONE BARRIERS OFF", bp); } /* @@ -1085,13 +1010,10 @@ xlog_bdstrat_cb(struct xfs_buf *bp) return 0; } - xfs_buftrace("XLOG__BDSTRAT IOERROR", bp); XFS_BUF_ERROR(bp, EIO); XFS_BUF_STALE(bp); xfs_biodone(bp); return XFS_ERROR(EIO); - - } /* @@ -1246,7 +1168,6 @@ xlog_alloc_log(xfs_mount_t *mp, spin_lock_init(&log->l_grant_lock); sv_init(&log->l_flush_wait, 0, "flush_wait"); - xlog_trace_loggrant_alloc(log); /* log record size must be multiple of BBSIZE; see xlog_rec_header_t */ ASSERT((XFS_BUF_SIZE(bp) & BBMASK) == 0); @@ -1305,8 +1226,6 @@ xlog_alloc_log(xfs_mount_t *mp, sv_init(&iclog->ic_force_wait, SV_DEFAULT, "iclog-force"); sv_init(&iclog->ic_write_wait, SV_DEFAULT, "iclog-write"); - xlog_trace_iclog_alloc(iclog); - iclogp = &iclog->ic_next; } *iclogp = log->l_iclog; /* complete ring */ @@ -1321,13 +1240,11 @@ out_free_iclog: sv_destroy(&iclog->ic_force_wait); sv_destroy(&iclog->ic_write_wait); xfs_buf_free(iclog->ic_bp); - xlog_trace_iclog_dealloc(iclog); } kmem_free(iclog); } spinlock_destroy(&log->l_icloglock); spinlock_destroy(&log->l_grant_lock); - xlog_trace_loggrant_dealloc(log); xfs_buf_free(log->l_xbuf); out_free_log: kmem_free(log); @@ -1607,7 +1524,6 @@ xlog_dealloc_log(xlog_t *log) sv_destroy(&iclog->ic_force_wait); sv_destroy(&iclog->ic_write_wait); xfs_buf_free(iclog->ic_bp); - xlog_trace_iclog_dealloc(iclog); next_iclog = iclog->ic_next; kmem_free(iclog); iclog = next_iclog; @@ -1616,7 +1532,6 @@ xlog_dealloc_log(xlog_t *log) spinlock_destroy(&log->l_grant_lock); xfs_buf_free(log->l_xbuf); - xlog_trace_loggrant_dealloc(log); log->l_mp->m_log = NULL; kmem_free(log); } /* xlog_dealloc_log */ @@ -2414,7 +2329,6 @@ restart: iclog = log->l_iclog; if (iclog->ic_state != XLOG_STATE_ACTIVE) { - xlog_trace_iclog(iclog, XLOG_TRACE_SLEEP_FLUSH); XFS_STATS_INC(xs_log_noiclogs); /* Wait for log writes to have flushed */ @@ -2520,13 +2434,15 @@ xlog_grant_log_space(xlog_t *log, /* Is there space or do we need to sleep? */ spin_lock(&log->l_grant_lock); - xlog_trace_loggrant(log, tic, "xlog_grant_log_space: enter"); + + trace_xfs_log_grant_enter(log, tic); /* something is already sleeping; insert new transaction at end */ if (log->l_reserve_headq) { xlog_ins_ticketq(&log->l_reserve_headq, tic); - xlog_trace_loggrant(log, tic, - "xlog_grant_log_space: sleep 1"); + + trace_xfs_log_grant_sleep1(log, tic); + /* * Gotta check this before going to sleep, while we're * holding the grant lock. @@ -2540,8 +2456,7 @@ xlog_grant_log_space(xlog_t *log, * If we got an error, and the filesystem is shutting down, * we'll catch it down below. So just continue... */ - xlog_trace_loggrant(log, tic, - "xlog_grant_log_space: wake 1"); + trace_xfs_log_grant_wake1(log, tic); spin_lock(&log->l_grant_lock); } if (tic->t_flags & XFS_LOG_PERM_RESERV) @@ -2558,8 +2473,9 @@ redo: if (free_bytes < need_bytes) { if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) xlog_ins_ticketq(&log->l_reserve_headq, tic); - xlog_trace_loggrant(log, tic, - "xlog_grant_log_space: sleep 2"); + + trace_xfs_log_grant_sleep2(log, tic); + spin_unlock(&log->l_grant_lock); xlog_grant_push_ail(log->l_mp, need_bytes); spin_lock(&log->l_grant_lock); @@ -2571,8 +2487,8 @@ redo: if (XLOG_FORCED_SHUTDOWN(log)) goto error_return; - xlog_trace_loggrant(log, tic, - "xlog_grant_log_space: wake 2"); + trace_xfs_log_grant_wake2(log, tic); + goto redo; } else if (tic->t_flags & XLOG_TIC_IN_Q) xlog_del_ticketq(&log->l_reserve_headq, tic); @@ -2592,7 +2508,7 @@ redo: ASSERT(log->l_grant_write_bytes <= BBTOB(BLOCK_LSN(tail_lsn))); } #endif - xlog_trace_loggrant(log, tic, "xlog_grant_log_space: exit"); + trace_xfs_log_grant_exit(log, tic); xlog_verify_grant_head(log, 1); spin_unlock(&log->l_grant_lock); return 0; @@ -2600,7 +2516,9 @@ redo: error_return: if (tic->t_flags & XLOG_TIC_IN_Q) xlog_del_ticketq(&log->l_reserve_headq, tic); - xlog_trace_loggrant(log, tic, "xlog_grant_log_space: err_ret"); + + trace_xfs_log_grant_error(log, tic); + /* * If we are failing, make sure the ticket doesn't have any * current reservations. We don't want to add this back when @@ -2640,7 +2558,8 @@ xlog_regrant_write_log_space(xlog_t *log, #endif spin_lock(&log->l_grant_lock); - xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: enter"); + + trace_xfs_log_regrant_write_enter(log, tic); if (XLOG_FORCED_SHUTDOWN(log)) goto error_return; @@ -2669,8 +2588,8 @@ xlog_regrant_write_log_space(xlog_t *log, if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) xlog_ins_ticketq(&log->l_write_headq, tic); - xlog_trace_loggrant(log, tic, - "xlog_regrant_write_log_space: sleep 1"); + trace_xfs_log_regrant_write_sleep1(log, tic); + spin_unlock(&log->l_grant_lock); xlog_grant_push_ail(log->l_mp, need_bytes); spin_lock(&log->l_grant_lock); @@ -2685,8 +2604,7 @@ xlog_regrant_write_log_space(xlog_t *log, if (XLOG_FORCED_SHUTDOWN(log)) goto error_return; - xlog_trace_loggrant(log, tic, - "xlog_regrant_write_log_space: wake 1"); + trace_xfs_log_regrant_write_wake1(log, tic); } } @@ -2704,6 +2622,8 @@ redo: spin_lock(&log->l_grant_lock); XFS_STATS_INC(xs_sleep_logspace); + trace_xfs_log_regrant_write_sleep2(log, tic); + sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s); /* If we're shutting down, this tic is already off the queue */ @@ -2711,8 +2631,7 @@ redo: if (XLOG_FORCED_SHUTDOWN(log)) goto error_return; - xlog_trace_loggrant(log, tic, - "xlog_regrant_write_log_space: wake 2"); + trace_xfs_log_regrant_write_wake2(log, tic); goto redo; } else if (tic->t_flags & XLOG_TIC_IN_Q) xlog_del_ticketq(&log->l_write_headq, tic); @@ -2727,7 +2646,8 @@ redo: } #endif - xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: exit"); + trace_xfs_log_regrant_write_exit(log, tic); + xlog_verify_grant_head(log, 1); spin_unlock(&log->l_grant_lock); return 0; @@ -2736,7 +2656,9 @@ redo: error_return: if (tic->t_flags & XLOG_TIC_IN_Q) xlog_del_ticketq(&log->l_reserve_headq, tic); - xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: err_ret"); + + trace_xfs_log_regrant_write_error(log, tic); + /* * If we are failing, make sure the ticket doesn't have any * current reservations. We don't want to add this back when @@ -2760,8 +2682,8 @@ STATIC void xlog_regrant_reserve_log_space(xlog_t *log, xlog_ticket_t *ticket) { - xlog_trace_loggrant(log, ticket, - "xlog_regrant_reserve_log_space: enter"); + trace_xfs_log_regrant_reserve_enter(log, ticket); + if (ticket->t_cnt > 0) ticket->t_cnt--; @@ -2769,8 +2691,9 @@ xlog_regrant_reserve_log_space(xlog_t *log, xlog_grant_sub_space(log, ticket->t_curr_res); ticket->t_curr_res = ticket->t_unit_res; xlog_tic_reset_res(ticket); - xlog_trace_loggrant(log, ticket, - "xlog_regrant_reserve_log_space: sub current res"); + + trace_xfs_log_regrant_reserve_sub(log, ticket); + xlog_verify_grant_head(log, 1); /* just return if we still have some of the pre-reserved space */ @@ -2780,8 +2703,9 @@ xlog_regrant_reserve_log_space(xlog_t *log, } xlog_grant_add_space_reserve(log, ticket->t_unit_res); - xlog_trace_loggrant(log, ticket, - "xlog_regrant_reserve_log_space: exit"); + + trace_xfs_log_regrant_reserve_exit(log, ticket); + xlog_verify_grant_head(log, 0); spin_unlock(&log->l_grant_lock); ticket->t_curr_res = ticket->t_unit_res; @@ -2811,11 +2735,11 @@ xlog_ungrant_log_space(xlog_t *log, ticket->t_cnt--; spin_lock(&log->l_grant_lock); - xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: enter"); + trace_xfs_log_ungrant_enter(log, ticket); xlog_grant_sub_space(log, ticket->t_curr_res); - xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: sub current"); + trace_xfs_log_ungrant_sub(log, ticket); /* If this is a permanent reservation ticket, we may be able to free * up more space based on the remaining count. @@ -2825,7 +2749,8 @@ xlog_ungrant_log_space(xlog_t *log, xlog_grant_sub_space(log, ticket->t_unit_res*ticket->t_cnt); } - xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: exit"); + trace_xfs_log_ungrant_exit(log, ticket); + xlog_verify_grant_head(log, 1); spin_unlock(&log->l_grant_lock); xfs_log_move_tail(log->l_mp, 1); diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 679c7c4..d55662d 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -19,7 +19,6 @@ #define __XFS_LOG_PRIV_H__ struct xfs_buf; -struct ktrace; struct log; struct xlog_ticket; struct xfs_buf_cancel; @@ -135,6 +134,12 @@ static inline uint xlog_get_client_id(__be32 i) #define XLOG_TIC_INITED 0x1 /* has been initialized */ #define XLOG_TIC_PERM_RESERV 0x2 /* permanent reservation */ #define XLOG_TIC_IN_Q 0x4 + +#define XLOG_TIC_FLAGS \ + { XLOG_TIC_INITED, "XLOG_TIC_INITED" }, \ + { XLOG_TIC_PERM_RESERV, "XLOG_TIC_PERM_RESERV" }, \ + { XLOG_TIC_IN_Q, "XLOG_TIC_IN_Q" } + #endif /* __KERNEL__ */ #define XLOG_UNMOUNT_TYPE 0x556e /* Un for Unmount */ @@ -361,9 +366,6 @@ typedef struct xlog_in_core { int ic_bwritecnt; unsigned short ic_state; char *ic_datap; /* pointer to iclog data */ -#ifdef XFS_LOG_TRACE - struct ktrace *ic_trace; -#endif /* Callback structures need their own cacheline */ spinlock_t ic_callback_lock ____cacheline_aligned_in_smp; @@ -429,10 +431,6 @@ typedef struct log { int l_grant_write_cycle; int l_grant_write_bytes; -#ifdef XFS_LOG_TRACE - struct ktrace *l_grant_trace; -#endif - /* The following field are used for debugging; need to hold icloglock */ #ifdef DEBUG char *l_iclog_bak[XLOG_MAX_ICLOGS]; @@ -456,12 +454,6 @@ extern void xlog_put_bp(struct xfs_buf *); extern kmem_zone_t *xfs_log_ticket_zone; -/* iclog tracing */ -#define XLOG_TRACE_GRAB_FLUSH 1 -#define XLOG_TRACE_REL_FLUSH 2 -#define XLOG_TRACE_SLEEP_FLUSH 3 -#define XLOG_TRACE_WAKE_FLUSH 4 - /* * Unmount record type is used as a pseudo transaction type for the ticket. * It's value must be outside the range of XFS_TRANS_* values. diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 1ec98ed..abc2034 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -46,6 +46,7 @@ #include "xfs_quota.h" #include "xfs_rw.h" #include "xfs_utils.h" +#include "xfs_trace.h" STATIC int xlog_find_zeroed(xlog_t *, xfs_daddr_t *); STATIC int xlog_clear_stale_blocks(xlog_t *, xfs_lsn_t); diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index bfffd63..eb403b4 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -44,6 +44,8 @@ #include "xfs_quota.h" #include "xfs_fsops.h" #include "xfs_utils.h" +#include "xfs_trace.h" + STATIC void xfs_unmountfs_wait(xfs_mount_t *); diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index 3ec91ac..91bfd60 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h @@ -92,6 +92,14 @@ typedef struct xfs_dqblk { #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) +#define XFS_DQ_FLAGS \ + { XFS_DQ_USER, "USER" }, \ + { XFS_DQ_PROJ, "PROJ" }, \ + { XFS_DQ_GROUP, "GROUP" }, \ + { XFS_DQ_DIRTY, "DIRTY" }, \ + { XFS_DQ_WANT, "WANT" }, \ + { XFS_DQ_INACTIVE, "INACTIVE" } + /* * In the worst case, when both user and group quotas are on, * we can have a max of three dquots changing in a single transaction. diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index b81deea..fc1cda2 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c @@ -39,6 +39,7 @@ #include "xfs_utils.h" #include "xfs_trans_space.h" #include "xfs_vnodeops.h" +#include "xfs_trace.h" /* diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 385f6dc..9e15a11 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -45,6 +45,7 @@ #include "xfs_inode_item.h" #include "xfs_trans_space.h" #include "xfs_utils.h" +#include "xfs_trace.h" /* diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c index 4c199d1..5aa07ca 100644 --- a/fs/xfs/xfs_rw.c +++ b/fs/xfs/xfs_rw.c @@ -44,6 +44,7 @@ #include "xfs_error.h" #include "xfs_buf_item.h" #include "xfs_rw.h" +#include "xfs_trace.h" /* * This is a subroutine for xfs_write() and other writers (xfs_ioctl) @@ -171,7 +172,6 @@ xfs_bioerror( * No need to wait until the buffer is unpinned. * We aren't flushing it. */ - xfs_buftrace("XFS IOERROR", bp); XFS_BUF_ERROR(bp, EIO); /* * We're calling biodone, so delete B_DONE flag. Either way @@ -205,7 +205,6 @@ xfs_bioerror_relse( ASSERT(XFS_BUF_IODONE_FUNC(bp) != xfs_buf_iodone_callbacks); ASSERT(XFS_BUF_IODONE_FUNC(bp) != xlog_iodone); - xfs_buftrace("XFS IOERRELSE", bp); fl = XFS_BUF_BFLAGS(bp); /* * No need to wait until the buffer is unpinned. diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index a0574f5..ca64f33 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -100,6 +100,49 @@ typedef struct xfs_trans_header { #define XFS_TRANS_TYPE_MAX 41 /* new transaction types need to be reflected in xfs_logprint(8) */ +#define XFS_TRANS_TYPES \ + { XFS_TRANS_SETATTR_NOT_SIZE, "SETATTR_NOT_SIZE" }, \ + { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \ + { XFS_TRANS_INACTIVE, "INACTIVE" }, \ + { XFS_TRANS_CREATE, "CREATE" }, \ + { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \ + { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \ + { XFS_TRANS_REMOVE, "REMOVE" }, \ + { XFS_TRANS_LINK, "LINK" }, \ + { XFS_TRANS_RENAME, "RENAME" }, \ + { XFS_TRANS_MKDIR, "MKDIR" }, \ + { XFS_TRANS_RMDIR, "RMDIR" }, \ + { XFS_TRANS_SYMLINK, "SYMLINK" }, \ + { XFS_TRANS_SET_DMATTRS, "SET_DMATTRS" }, \ + { XFS_TRANS_GROWFS, "GROWFS" }, \ + { XFS_TRANS_STRAT_WRITE, "STRAT_WRITE" }, \ + { XFS_TRANS_DIOSTRAT, "DIOSTRAT" }, \ + { XFS_TRANS_WRITEID, "WRITEID" }, \ + { XFS_TRANS_ADDAFORK, "ADDAFORK" }, \ + { XFS_TRANS_ATTRINVAL, "ATTRINVAL" }, \ + { XFS_TRANS_ATRUNCATE, "ATRUNCATE" }, \ + { XFS_TRANS_ATTR_SET, "ATTR_SET" }, \ + { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \ + { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \ + { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \ + { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \ + { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \ + { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \ + { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \ + { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \ + { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \ + { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \ + { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \ + { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \ + { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \ + { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \ + { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \ + { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \ + { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \ + { XFS_TRANS_DUMMY1, "DUMMY1" }, \ + { XFS_TRANS_DUMMY2, "DUMMY2" }, \ + { XLOG_UNMOUNT_REC_TYPE, "UNMOUNT" } + /* * This structure is used to track log items associated with * a transaction. It points to the log item and keeps some @@ -782,6 +825,10 @@ typedef struct xfs_log_item { #define XFS_LI_IN_AIL 0x1 #define XFS_LI_ABORTED 0x2 +#define XFS_LI_FLAGS \ + { XFS_LI_IN_AIL, "IN_AIL" }, \ + { XFS_LI_ABORTED, "ABORTED" } + typedef struct xfs_item_ops { uint (*iop_size)(xfs_log_item_t *); void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index 03a1f70..4913062 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c @@ -38,6 +38,7 @@ #include "xfs_trans_priv.h" #include "xfs_error.h" #include "xfs_rw.h" +#include "xfs_trace.h" STATIC xfs_buf_t *xfs_trans_buf_item_match(xfs_trans_t *, xfs_buftarg_t *, @@ -95,26 +96,23 @@ xfs_trans_get_buf(xfs_trans_t *tp, } if (bp != NULL) { ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); - if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) { - xfs_buftrace("TRANS GET RECUR SHUT", bp); + if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) XFS_BUF_SUPER_STALE(bp); - } + /* * If the buffer is stale then it was binval'ed * since last read. This doesn't matter since the * caller isn't allowed to use the data anyway. */ - else if (XFS_BUF_ISSTALE(bp)) { - xfs_buftrace("TRANS GET RECUR STALE", bp); + else if (XFS_BUF_ISSTALE(bp)) ASSERT(!XFS_BUF_ISDELAYWRITE(bp)); - } + ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); ASSERT(bip != NULL); ASSERT(atomic_read(&bip->bli_refcount) > 0); bip->bli_recur++; - xfs_buftrace("TRANS GET RECUR", bp); - xfs_buf_item_trace("GET RECUR", bip); + trace_xfs_trans_get_buf_recur(bip); return (bp); } @@ -166,8 +164,7 @@ xfs_trans_get_buf(xfs_trans_t *tp, */ XFS_BUF_SET_FSPRIVATE2(bp, tp); - xfs_buftrace("TRANS GET", bp); - xfs_buf_item_trace("GET", bip); + trace_xfs_trans_get_buf(bip); return (bp); } @@ -207,7 +204,7 @@ xfs_trans_getsb(xfs_trans_t *tp, ASSERT(bip != NULL); ASSERT(atomic_read(&bip->bli_refcount) > 0); bip->bli_recur++; - xfs_buf_item_trace("GETSB RECUR", bip); + trace_xfs_trans_getsb_recur(bip); return (bp); } @@ -249,7 +246,7 @@ xfs_trans_getsb(xfs_trans_t *tp, */ XFS_BUF_SET_FSPRIVATE2(bp, tp); - xfs_buf_item_trace("GETSB", bip); + trace_xfs_trans_getsb(bip); return (bp); } @@ -347,7 +344,7 @@ xfs_trans_read_buf( ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); ASSERT((XFS_BUF_ISERROR(bp)) == 0); if (!(XFS_BUF_ISDONE(bp))) { - xfs_buftrace("READ_BUF_INCORE !DONE", bp); + trace_xfs_trans_read_buf_io(bp, _RET_IP_); ASSERT(!XFS_BUF_ISASYNC(bp)); XFS_BUF_READ(bp); xfsbdstrat(tp->t_mountp, bp); @@ -372,7 +369,7 @@ xfs_trans_read_buf( * brelse it either. Just get out. */ if (XFS_FORCED_SHUTDOWN(mp)) { - xfs_buftrace("READ_BUF_INCORE XFSSHUTDN", bp); + trace_xfs_trans_read_buf_shut(bp, _RET_IP_); *bpp = NULL; return XFS_ERROR(EIO); } @@ -382,7 +379,7 @@ xfs_trans_read_buf( bip->bli_recur++; ASSERT(atomic_read(&bip->bli_refcount) > 0); - xfs_buf_item_trace("READ RECUR", bip); + trace_xfs_trans_read_buf_recur(bip); *bpp = bp; return 0; } @@ -402,7 +399,6 @@ xfs_trans_read_buf( } if (XFS_BUF_GETERROR(bp) != 0) { XFS_BUF_SUPER_STALE(bp); - xfs_buftrace("READ ERROR", bp); error = XFS_BUF_GETERROR(bp); xfs_ioerror_alert("xfs_trans_read_buf", mp, @@ -461,8 +457,7 @@ xfs_trans_read_buf( */ XFS_BUF_SET_FSPRIVATE2(bp, tp); - xfs_buftrace("TRANS READ", bp); - xfs_buf_item_trace("READ", bip); + trace_xfs_trans_read_buf(bip); *bpp = bp; return 0; @@ -480,7 +475,7 @@ shutdown_abort: ASSERT((XFS_BUF_BFLAGS(bp) & (XFS_B_STALE|XFS_B_DELWRI)) != (XFS_B_STALE|XFS_B_DELWRI)); - xfs_buftrace("READ_BUF XFSSHUTDN", bp); + trace_xfs_trans_read_buf_shut(bp, _RET_IP_); xfs_buf_relse(bp); *bpp = NULL; return XFS_ERROR(EIO); @@ -546,13 +541,14 @@ xfs_trans_brelse(xfs_trans_t *tp, lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip); ASSERT(lidp != NULL); + trace_xfs_trans_brelse(bip); + /* * If the release is just for a recursive lock, * then decrement the count and return. */ if (bip->bli_recur > 0) { bip->bli_recur--; - xfs_buf_item_trace("RELSE RECUR", bip); return; } @@ -560,10 +556,8 @@ xfs_trans_brelse(xfs_trans_t *tp, * If the buffer is dirty within this transaction, we can't * release it until we commit. */ - if (lidp->lid_flags & XFS_LID_DIRTY) { - xfs_buf_item_trace("RELSE DIRTY", bip); + if (lidp->lid_flags & XFS_LID_DIRTY) return; - } /* * If the buffer has been invalidated, then we can't release @@ -571,13 +565,10 @@ xfs_trans_brelse(xfs_trans_t *tp, * as part of this transaction. This prevents us from pulling * the item from the AIL before we should. */ - if (bip->bli_flags & XFS_BLI_STALE) { - xfs_buf_item_trace("RELSE STALE", bip); + if (bip->bli_flags & XFS_BLI_STALE) return; - } ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED)); - xfs_buf_item_trace("RELSE", bip); /* * Free up the log item descriptor tracking the released item. @@ -674,7 +665,7 @@ xfs_trans_bjoin(xfs_trans_t *tp, */ XFS_BUF_SET_FSPRIVATE2(bp, tp); - xfs_buf_item_trace("BJOIN", bip); + trace_xfs_trans_bjoin(bip); } /* @@ -698,7 +689,7 @@ xfs_trans_bhold(xfs_trans_t *tp, ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL)); ASSERT(atomic_read(&bip->bli_refcount) > 0); bip->bli_flags |= XFS_BLI_HOLD; - xfs_buf_item_trace("BHOLD", bip); + trace_xfs_trans_bhold(bip); } /* @@ -721,7 +712,8 @@ xfs_trans_bhold_release(xfs_trans_t *tp, ASSERT(atomic_read(&bip->bli_refcount) > 0); ASSERT(bip->bli_flags & XFS_BLI_HOLD); bip->bli_flags &= ~XFS_BLI_HOLD; - xfs_buf_item_trace("BHOLD RELEASE", bip); + + trace_xfs_trans_bhold_release(bip); } /* @@ -767,6 +759,8 @@ xfs_trans_log_buf(xfs_trans_t *tp, XFS_BUF_SET_IODONE_FUNC(bp, xfs_buf_iodone_callbacks); bip->bli_item.li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*))xfs_buf_iodone; + trace_xfs_trans_log_buf(bip); + /* * If we invalidated the buffer within this transaction, then * cancel the invalidation now that we're dirtying the buffer @@ -774,7 +768,6 @@ xfs_trans_log_buf(xfs_trans_t *tp, * because we have a reference to the buffer this entire time. */ if (bip->bli_flags & XFS_BLI_STALE) { - xfs_buf_item_trace("BLOG UNSTALE", bip); bip->bli_flags &= ~XFS_BLI_STALE; ASSERT(XFS_BUF_ISSTALE(bp)); XFS_BUF_UNSTALE(bp); @@ -789,7 +782,6 @@ xfs_trans_log_buf(xfs_trans_t *tp, lidp->lid_flags &= ~XFS_LID_BUF_STALE; bip->bli_flags |= XFS_BLI_LOGGED; xfs_buf_item_log(bip, first, last); - xfs_buf_item_trace("BLOG", bip); } @@ -828,6 +820,8 @@ xfs_trans_binval( ASSERT(lidp != NULL); ASSERT(atomic_read(&bip->bli_refcount) > 0); + trace_xfs_trans_binval(bip); + if (bip->bli_flags & XFS_BLI_STALE) { /* * If the buffer is already invalidated, then @@ -840,8 +834,6 @@ xfs_trans_binval( ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL); ASSERT(lidp->lid_flags & XFS_LID_DIRTY); ASSERT(tp->t_flags & XFS_TRANS_DIRTY); - xfs_buftrace("XFS_BINVAL RECUR", bp); - xfs_buf_item_trace("BINVAL RECUR", bip); return; } @@ -875,8 +867,6 @@ xfs_trans_binval( (bip->bli_format.blf_map_size * sizeof(uint))); lidp->lid_flags |= XFS_LID_DIRTY|XFS_LID_BUF_STALE; tp->t_flags |= XFS_TRANS_DIRTY; - xfs_buftrace("XFS_BINVAL", bp); - xfs_buf_item_trace("BINVAL", bip); } /* diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 578f3f5..6558ffd 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -53,6 +53,7 @@ #include "xfs_log_priv.h" #include "xfs_filestream.h" #include "xfs_vnodeops.h" +#include "xfs_trace.h" int xfs_setattr( @@ -1397,7 +1398,6 @@ xfs_lookup( if (error) goto out_free_name; - xfs_itrace_ref(*ipp); return 0; out_free_name: @@ -1543,7 +1543,6 @@ xfs_create( * At this point, we've gotten a newly allocated inode. * It is locked (and joined to the transaction). */ - xfs_itrace_ref(ip); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); /* @@ -2003,9 +2002,6 @@ xfs_remove( if (!is_dir && link_zero && xfs_inode_is_filestream(ip)) xfs_filestream_deassociate(ip); - xfs_itrace_exit(ip); - xfs_itrace_exit(dp); - std_return: if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) { XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, dp, DM_RIGHT_NULL, @@ -2302,7 +2298,6 @@ xfs_symlink( goto error_return; goto error1; } - xfs_itrace_ref(ip); /* * An error after we've joined dp to the transaction will result in the @@ -2845,7 +2840,6 @@ xfs_free_file_space( ioffset = offset & ~(rounding - 1); if (VN_CACHED(VFS_I(ip)) != 0) { - xfs_inval_cached_trace(ip, ioffset, -1, ioffset, -1); error = xfs_flushinval_pages(ip, ioffset, -1, FI_REMAPF_LOCKED); if (error) goto out_unlock_iolock; -- cgit v0.10.2 From ddf9ddacef0989fdeb22e182212a232488f0f3ad Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 13 Jun 2009 07:42:58 -0400 Subject: Blackfin: convert to generic checksum code The Blackfin port only implemented an optimized version of the csum_tcpudp_nofold function, so convert everything else to the new generic code. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index ae6a60f..c0d4445 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -28,6 +28,9 @@ config BLACKFIN select HAVE_OPROFILE select ARCH_WANT_OPTIONAL_GPIOLIB +config GENERIC_CSUM + def_bool y + config GENERIC_BUG def_bool y depends on BUG diff --git a/arch/blackfin/include/asm/checksum.h b/arch/blackfin/include/asm/checksum.h index a23415b..623cc7f 100644 --- a/arch/blackfin/include/asm/checksum.h +++ b/arch/blackfin/include/asm/checksum.h @@ -9,63 +9,12 @@ #define _BFIN_CHECKSUM_H /* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * the same as csum_partial, but copies from src while it - * checksums - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -__wsum csum_partial_copy(const void *src, void *dst, - int len, __wsum sum); - -/* - * the same as csum_partial_copy, but copies from user space. - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *csum_err); - -#define csum_partial_copy_nocheck(src, dst, len, sum) \ - csum_partial_copy((src), (dst), (len), (sum)) - -__sum16 ip_fast_csum(unsigned char *iph, unsigned int ihl); - -/* - * Fold a partial checksum - */ - -static inline __sum16 csum_fold(__wsum sum) -{ - while (sum >> 16) - sum = (sum & 0xffff) + (sum >> 16); - return ((~(sum << 16)) >> 16); -} - -/* * computes the checksum of the TCP/UDP pseudo-header * returns a 16-bit checksum, already complemented */ static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, +__csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, unsigned short proto, __wsum sum) { unsigned int carry; @@ -88,19 +37,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, return (sum); } +#define csum_tcpudp_nofold __csum_tcpudp_nofold -static inline __sum16 -csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ - -extern __sum16 ip_compute_csum(const void *buff, int len); +#include -#endif /* _BFIN_CHECKSUM_H */ +#endif diff --git a/arch/blackfin/lib/Makefile b/arch/blackfin/lib/Makefile index 635288f..42c47dc 100644 --- a/arch/blackfin/lib/Makefile +++ b/arch/blackfin/lib/Makefile @@ -5,7 +5,7 @@ lib-y := \ ashldi3.o ashrdi3.o lshrdi3.o \ muldi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \ - checksum.o memcpy.o memset.o memcmp.o memchr.o memmove.o \ + memcpy.o memset.o memcmp.o memchr.o memmove.o \ strcmp.o strcpy.o strncmp.o strncpy.o \ umulsi3_highpart.o smulsi3_highpart.o \ ins.o outs.o diff --git a/arch/blackfin/lib/checksum.c b/arch/blackfin/lib/checksum.c deleted file mode 100644 index c62969d..0000000 --- a/arch/blackfin/lib/checksum.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2004-2009 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - * - * An implementation of the TCP/IP protocol suite for the LINUX operating - * system. INET is implemented using the BSD Socket interface as the - * means of communication with the user level. - * - */ - -#include -#include -#include - -#ifdef CONFIG_IP_CHECKSUM_L1 -static unsigned short do_csum(const unsigned char *buff, int len)__attribute__((l1_text)); -#endif - -static unsigned short do_csum(const unsigned char *buff, int len) -{ - register unsigned long sum = 0; - int swappem = 0; - - if (1 & (unsigned long)buff) { - sum = *buff << 8; - buff++; - len--; - ++swappem; - } - - while (len > 1) { - sum += *(unsigned short *)buff; - buff += 2; - len -= 2; - } - - if (len > 0) - sum += *buff; - - /* Fold 32-bit sum to 16 bits */ - while (sum >> 16) - sum = (sum & 0xffff) + (sum >> 16); - - if (swappem) - sum = ((sum & 0xff00) >> 8) + ((sum & 0x00ff) << 8); - - return sum; - -} - -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. - */ -__sum16 ip_fast_csum(unsigned char *iph, unsigned int ihl) -{ - return (__force __sum16)~do_csum(iph, ihl * 4); -} -EXPORT_SYMBOL(ip_fast_csum); - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum) -{ - /* - * Just in case we get nasty checksum data... - * Like 0xffff6ec3 in the case of our IPv6 multicast header. - * We fold to begin with, as well as at the end. - */ - sum = (sum & 0xffff) + (sum >> 16); - - sum += do_csum(buff, len); - - sum = (sum & 0xffff) + (sum >> 16); - - return sum; -} -EXPORT_SYMBOL(csum_partial); - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ -__sum16 ip_compute_csum(const void *buff, int len) -{ - return (__force __sum16)~do_csum(buff, len); -} -EXPORT_SYMBOL(ip_compute_csum); - -/* - * copy from fs while checksumming, otherwise like csum_partial - */ - -__wsum -csum_partial_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *csum_err) -{ - if (csum_err) - *csum_err = 0; - memcpy(dst, (__force void *)src, len); - return csum_partial(dst, len, sum); -} -EXPORT_SYMBOL(csum_partial_copy_from_user); - -/* - * copy from ds while checksumming, otherwise like csum_partial - */ - -__wsum csum_partial_copy(const void *src, void *dst, int len, __wsum sum) -{ - memcpy(dst, src, len); - return csum_partial(dst, len, sum); -} -EXPORT_SYMBOL(csum_partial_copy); -- cgit v0.10.2 From 3a022ba9ac12aefe6bbbdda4c9086e21b25b8939 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 23 Jun 2009 13:43:06 +0000 Subject: Blackfin: update defconfigs Signed-off-by: Michael Hennerich Signed-off-by: Cliff Cai Signed-off-by: Yi Li Signed-off-by: Harald Krapfenbauer Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/configs/BF518F-EZBRD_defconfig b/arch/blackfin/configs/BF518F-EZBRD_defconfig index 9905b26..e315594 100644 --- a/arch/blackfin/configs/BF518F-EZBRD_defconfig +++ b/arch/blackfin/configs/BF518F-EZBRD_defconfig @@ -67,6 +67,7 @@ CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y @@ -316,6 +317,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set @@ -438,17 +440,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set -CONFIG_NET_DSA=y -# CONFIG_NET_DSA_TAG_DSA is not set -# CONFIG_NET_DSA_TAG_EDSA is not set -# CONFIG_NET_DSA_TAG_TRAILER is not set -CONFIG_NET_DSA_TAG_STPID=y -# CONFIG_NET_DSA_MV88E6XXX is not set -# CONFIG_NET_DSA_MV88E6060 is not set -# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set -# CONFIG_NET_DSA_MV88E6131 is not set -# CONFIG_NET_DSA_MV88E6123_61_65 is not set -CONFIG_NET_DSA_KSZ8893M=y +# CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set # CONFIG_LLC2 is not set diff --git a/arch/blackfin/configs/BF526-EZBRD_defconfig b/arch/blackfin/configs/BF526-EZBRD_defconfig index 9dc6820..075e0fd 100644 --- a/arch/blackfin/configs/BF526-EZBRD_defconfig +++ b/arch/blackfin/configs/BF526-EZBRD_defconfig @@ -67,6 +67,7 @@ CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y @@ -321,6 +322,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig index 77e35d4..6d1a623 100644 --- a/arch/blackfin/configs/BF527-EZKIT_defconfig +++ b/arch/blackfin/configs/BF527-EZKIT_defconfig @@ -67,6 +67,7 @@ CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y @@ -321,6 +322,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=y # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig index 4c04480..50f9a23 100644 --- a/arch/blackfin/configs/BF533-EZKIT_defconfig +++ b/arch/blackfin/configs/BF533-EZKIT_defconfig @@ -67,6 +67,7 @@ CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y @@ -283,6 +284,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig index c99bbcd..6c60c82 100644 --- a/arch/blackfin/configs/BF533-STAMP_defconfig +++ b/arch/blackfin/configs/BF533-STAMP_defconfig @@ -67,6 +67,7 @@ CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y @@ -283,6 +284,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig index 092ffda..2908595 100644 --- a/arch/blackfin/configs/BF537-STAMP_defconfig +++ b/arch/blackfin/configs/BF537-STAMP_defconfig @@ -67,6 +67,7 @@ CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y @@ -290,6 +291,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set @@ -704,10 +706,7 @@ CONFIG_CONFIG_INPUT_PCF8574=m # # Hardware I/O ports # -CONFIG_SERIO=y -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO is not set # CONFIG_GAMEPORT is not set # diff --git a/arch/blackfin/configs/BF538-EZKIT_defconfig b/arch/blackfin/configs/BF538-EZKIT_defconfig index fa698a8..09ea249 100644 --- a/arch/blackfin/configs/BF538-EZKIT_defconfig +++ b/arch/blackfin/configs/BF538-EZKIT_defconfig @@ -67,6 +67,7 @@ CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y @@ -301,6 +302,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig index f773ad1..eb3e98b 100644 --- a/arch/blackfin/configs/BF548-EZKIT_defconfig +++ b/arch/blackfin/configs/BF548-EZKIT_defconfig @@ -1,22 +1,29 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28.10 -# Thu May 21 05:50:01 2009 +# Linux kernel version: 2.6.31.5 +# Mon Nov 2 22:02:56 2009 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -26,22 +33,40 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -62,17 +87,28 @@ CONFIG_EPOLL=y # CONFIG_TIMERFD is not set # CONFIG_EVENTFD is not set # CONFIG_AIO is not set + +# +# Performance Counters +# CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y -CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -80,11 +116,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -94,13 +127,12 @@ CONFIG_BLOCK=y CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y # CONFIG_IOSCHED_DEADLINE is not set -CONFIG_IOSCHED_CFQ=y +# CONFIG_IOSCHED_CFQ is not set CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set @@ -137,7 +169,7 @@ CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_BF544M is not set # CONFIG_BF547 is not set # CONFIG_BF547M is not set -CONFIG_BF548=y +CONFIG_BF548_std=y # CONFIG_BF548M is not set # CONFIG_BF549 is not set # CONFIG_BF549M is not set @@ -195,7 +227,7 @@ CONFIG_BFIN548_EZKIT=y # # BF548 Specific Configuration # -# CONFIG_DEB_DMA_URGENT is not set +CONFIG_DEB_DMA_URGENT=y # CONFIG_BF548_ATAPI_ALTERNATIVE_PORT is not set # @@ -352,10 +384,11 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set CONFIG_DMA_UNCACHED_2M=y @@ -366,14 +399,13 @@ CONFIG_DMA_UNCACHED_2M=y # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y +# CONFIG_BFIN_L2_ICACHEABLE is not set CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y -CONFIG_BFIN_EXTMEM_WRITEBACK=y -# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set -# CONFIG_BFIN_L2_ICACHEABLE is not set +# CONFIG_BFIN_EXTMEM_WRITEBACK is not set +CONFIG_BFIN_EXTMEM_WRITETHROUGH=y # CONFIG_BFIN_L2_DCACHEABLE is not set # @@ -382,7 +414,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -441,11 +473,6 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -469,13 +496,11 @@ CONFIG_IP_PNP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set -# CONFIG_NETLABEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set @@ -493,7 +518,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -548,14 +576,10 @@ CONFIG_SIR_BFIN_DMA=y # CONFIG_MCS_FIR is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_OLD_REGULATORY=y +# CONFIG_WIRELESS is not set CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_EXT_SYSFS=y -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +CONFIG_LIB80211=m +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -578,6 +602,7 @@ CONFIG_EXTRA_FIRMWARE="" # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set @@ -653,7 +678,6 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_VERIFY_WRITE is not set # CONFIG_MTD_NAND_ECC_SMC is not set # CONFIG_MTD_NAND_MUSEUM_IDS is not set -# CONFIG_MTD_NAND_BFIN is not set CONFIG_MTD_NAND_IDS=y CONFIG_MTD_NAND_BF5XX=y CONFIG_MTD_NAND_BF5XX_HWECC=y @@ -665,6 +689,11 @@ CONFIG_MTD_NAND_BF5XX_HWECC=y # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -682,10 +711,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_AD525X_DPOT is not set # CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -709,10 +748,6 @@ CONFIG_BLK_DEV_SR=m # CONFIG_BLK_DEV_SR_VENDOR is not set # CONFIG_CHR_DEV_SG is not set # CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# # CONFIG_SCSI_MULTI_LUN is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set @@ -729,6 +764,7 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SRP_ATTRS is not set # CONFIG_SCSI_LOWLEVEL is not set # CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set CONFIG_SATA_PMP=y @@ -744,13 +780,34 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set -# CONFIG_PHYLIB is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_SMC91X is not set -CONFIG_SMSC911X=y # CONFIG_DM9000 is not set # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +CONFIG_SMSC911X=y +# CONFIG_DNET is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -759,6 +816,8 @@ CONFIG_SMSC911X=y # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set @@ -771,13 +830,16 @@ CONFIG_LIBERTAS=m # CONFIG_LIBERTAS_USB is not set CONFIG_LIBERTAS_SDIO=m CONFIG_POWEROF2_BLOCKSIZE_ONLY=y +# CONFIG_LIBERTAS_SPI is not set # CONFIG_LIBERTAS_DEBUG is not set # CONFIG_USB_ZD1201 is not set -# CONFIG_USB_NET_RNDIS_WLAN is not set -# CONFIG_IWLWIFI_LEDS is not set # CONFIG_HOSTAP is not set # +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# # USB Network Adapters # # CONFIG_USB_CATC is not set @@ -813,28 +875,31 @@ CONFIG_INPUT_EVBUG=m # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set # CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_KEYBOARD_SUNKBD is not set +CONFIG_KEYBOARD_BFIN=y # CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set # CONFIG_KEYBOARD_GPIO is not set -CONFIG_KEYBOARD_BFIN=y +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_OPENCORES is not set -# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set CONFIG_TOUCHSCREEN_AD7877=m # CONFIG_TOUCHSCREEN_AD7879_I2C is not set # CONFIG_TOUCHSCREEN_AD7879_SPI is not set # CONFIG_TOUCHSCREEN_AD7879 is not set -# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_EETI is not set # CONFIG_TOUCHSCREEN_FUJITSU is not set # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set # CONFIG_TOUCHSCREEN_INEXIO is not set # CONFIG_TOUCHSCREEN_MK712 is not set @@ -844,6 +909,8 @@ CONFIG_TOUCHSCREEN_AD7877=m # CONFIG_TOUCHSCREEN_WM97XX is not set # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set CONFIG_INPUT_MISC=y # CONFIG_INPUT_ATI_REMOTE is not set # CONFIG_INPUT_ATI_REMOTE2 is not set @@ -852,7 +919,11 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_CM109 is not set # CONFIG_INPUT_UINPUT is not set -# CONFIG_CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_BFIN_ROTARY is not set +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_PCF8574 is not set # # Hardware I/O ports @@ -863,16 +934,13 @@ CONFIG_INPUT_MISC=y # # Character devices # -# CONFIG_AD9960 is not set CONFIG_BFIN_DMA_INTERFACE=m # CONFIG_BFIN_PPI is not set # CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BFIN_SPI_ADC is not set CONFIG_BFIN_SPORT=m -# CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_BFIN_TWI_LCD is not set -CONFIG_SIMPLE_GPIO=m CONFIG_VT=y CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_VT_CONSOLE=y @@ -890,6 +958,7 @@ CONFIG_BFIN_JTAG_COMM=m # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -903,6 +972,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set CONFIG_BFIN_OTP=y # CONFIG_BFIN_OTP_WRITE_ENABLE is not set @@ -951,14 +1021,9 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_EEPROM_AT24 is not set -# CONFIG_SENSORS_AD5252 is not set -# CONFIG_EEPROM_LEGACY is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_PCF8575 is not set # CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -975,13 +1040,18 @@ CONFIG_SPI_BFIN=y # CONFIG_SPI_BFIN_LOCK is not set # CONFIG_SPI_BFIN_SPORT is not set # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set @@ -997,6 +1067,7 @@ CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -1038,28 +1109,19 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_UCB1400_CORE is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set # CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -1096,6 +1158,7 @@ CONFIG_FB_BF54X_LQ043=y # CONFIG_FB_VIRTUAL is not set # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -1132,6 +1195,7 @@ CONFIG_SOUND_OSS_CORE=y CONFIG_SND=y CONFIG_SND_TIMER=y CONFIG_SND_PCM=y +CONFIG_SND_JACK=y # CONFIG_SND_SEQUENCER is not set CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=y @@ -1142,6 +1206,11 @@ CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set CONFIG_SND_DRIVERS=y # CONFIG_SND_DUMMY is not set # CONFIG_SND_MTPAV is not set @@ -1152,7 +1221,6 @@ CONFIG_SND_SPI=y # # ALSA Blackfin devices # -# CONFIG_SND_BLACKFIN_AD1836 is not set # CONFIG_SND_BFIN_AD73322 is not set CONFIG_SND_USB=y # CONFIG_SND_USB_AUDIO is not set @@ -1160,15 +1228,17 @@ CONFIG_SND_USB=y CONFIG_SND_SOC=y CONFIG_SND_SOC_AC97_BUS=y # CONFIG_SND_BF5XX_I2S is not set +# CONFIG_SND_BF5XX_TDM is not set CONFIG_SND_BF5XX_AC97=y CONFIG_SND_BF5XX_MMAP_SUPPORT=y # CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set +CONFIG_SND_BF5XX_HAVE_COLD_RESET=y +CONFIG_SND_BF5XX_RESET_GPIO_NUM=19 +CONFIG_SND_BF5XX_SOC_AD1980=y CONFIG_SND_BF5XX_SOC_SPORT=y CONFIG_SND_BF5XX_SOC_AC97=y -CONFIG_SND_BF5XX_SOC_AD1980=y CONFIG_SND_BF5XX_SPORT_NUM=0 -CONFIG_SND_BF5XX_HAVE_COLD_RESET=y -CONFIG_SND_BF5XX_RESET_GPIO_NUM=19 +CONFIG_SND_SOC_I2C_AND_SPI=y # CONFIG_SND_SOC_ALL_CODECS is not set CONFIG_SND_SOC_AD1980=y # CONFIG_SOUND_PRIME is not set @@ -1188,30 +1258,34 @@ CONFIG_USB_HID=y # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y -CONFIG_HID_BRIGHT=y CONFIG_HID_CHERRY=y CONFIG_HID_CHICONY=y CONFIG_HID_CYPRESS=y -CONFIG_HID_DELL=y +# CONFIG_HID_DRAGONRISE is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_KYE is not set CONFIG_HID_GYRATION=y +# CONFIG_HID_KENSINGTON is not set CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set CONFIG_HID_MICROSOFT=y CONFIG_HID_MONTEREY=y +# CONFIG_HID_NTRIG is not set CONFIG_HID_PANTHERLORD=y # CONFIG_PANTHERLORD_FF is not set CONFIG_HID_PETALYNX=y CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y CONFIG_HID_SUNPLUS=y -CONFIG_THRUSTMASTER_FF=m -CONFIG_ZEROPLUS_FF=m +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set @@ -1237,6 +1311,7 @@ CONFIG_USB_MON=y # USB Host Controller Drivers # # CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP1760_HCD is not set # CONFIG_USB_ISP1362_HCD is not set @@ -1267,18 +1342,17 @@ CONFIG_USB_INVENTRA_DMA=y # CONFIG_USB_TMC is not set # -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # # -# see USB_STORAGE Help for more information +# also be needed; see USB_STORAGE Help for more info # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set @@ -1314,7 +1388,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set # CONFIG_USB_IDMOUSE is not set # CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set @@ -1326,6 +1399,13 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_ISIGHTFW is not set # CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +CONFIG_NOP_USB_XCEIV=y CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set # CONFIG_MMC_UNSAFE_RESUME is not set @@ -1380,6 +1460,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers @@ -1411,10 +1492,21 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_BFIN=y # CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set + +# +# TI VLYNQ +# # CONFIG_STAGING is not set # +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_SIGMA is not set + +# # File systems # CONFIG_EXT2_FS=y @@ -1427,9 +1519,11 @@ CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -1439,6 +1533,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # CONFIG_ISO9660_FS=m @@ -1467,10 +1566,7 @@ CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1489,17 +1585,8 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set -CONFIG_YAFFS_FS=m -CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_9BYTE_TAGS is not set -# CONFIG_YAFFS_DOES_ECC is not set -CONFIG_YAFFS_YAFFS2=y -CONFIG_YAFFS_AUTO_YAFFS2=y -# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set -# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set -# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -1508,6 +1595,7 @@ CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y @@ -1522,7 +1610,6 @@ CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m -# CONFIG_SUNRPC_REGISTER_V4 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1596,11 +1683,15 @@ CONFIG_FRAME_WARN=1024 # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1608,16 +1699,21 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_NOMMU_REGIONS is not set # CONFIG_DEBUG_WRITECOUNT is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_FRAME_POINTER is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set @@ -1625,17 +1721,16 @@ CONFIG_DEBUG_INFO=y # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_FAULT_INJECTION is not set - -# -# Tracers -# -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set +# CONFIG_KMEMCHECK is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUG_VERBOSE=y @@ -1657,17 +1752,15 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y CONFIG_EARLY_PRINTK=y CONFIG_CPLB_INFO=y CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options # # CONFIG_KEYS is not set -CONFIG_SECURITY=y +# CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_NETWORK is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set -# CONFIG_SECURITY_ROOTPLUG is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 CONFIG_CRYPTO=y # @@ -1746,6 +1839,7 @@ CONFIG_CRYPTO=y # Compression # # CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set # @@ -1753,11 +1847,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -1767,6 +1863,8 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m +CONFIG_DECOMPRESS_GZIP=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig index 0313cd1..e3ecdcc 100644 --- a/arch/blackfin/configs/BF561-EZKIT_defconfig +++ b/arch/blackfin/configs/BF561-EZKIT_defconfig @@ -1,22 +1,29 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28.10 -# Thu May 21 05:50:01 2009 +# Linux kernel version: 2.6.31.5 +# Mon Nov 2 21:59:31 2009 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -26,22 +33,40 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -62,17 +87,28 @@ CONFIG_EPOLL=y # CONFIG_TIMERFD is not set # CONFIG_EVENTFD is not set # CONFIG_AIO is not set + +# +# Performance Counters +# CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y -CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -80,11 +116,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -94,13 +127,12 @@ CONFIG_BLOCK=y CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y # CONFIG_IOSCHED_DEADLINE is not set -CONFIG_IOSCHED_CFQ=y +# CONFIG_IOSCHED_CFQ is not set CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set @@ -170,6 +202,7 @@ CONFIG_IRQ_SPI_ERROR=7 CONFIG_BFIN561_EZKIT=y # CONFIG_BFIN561_TEPLA is not set # CONFIG_BFIN561_BLUETECHNIX_CM is not set +# CONFIG_BFIN561_ACVILON is not set # # BF561 Specific Configuration @@ -317,10 +350,11 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set @@ -331,14 +365,13 @@ CONFIG_DMA_UNCACHED_1M=y # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y +# CONFIG_BFIN_L2_ICACHEABLE is not set CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set -# CONFIG_BFIN_L2_ICACHEABLE is not set # CONFIG_BFIN_L2_DCACHEABLE is not set # @@ -347,7 +380,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -407,11 +440,6 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -435,13 +463,11 @@ CONFIG_IP_PNP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set -# CONFIG_NETLABEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set @@ -459,7 +485,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -503,13 +532,8 @@ CONFIG_IRTTY_SIR=m # # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_OLD_REGULATORY=y -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -530,6 +554,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set @@ -603,6 +628,11 @@ CONFIG_MTD_PHYSMAP=m # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -619,9 +649,14 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -645,9 +680,11 @@ CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y -# CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -656,6 +693,8 @@ CONFIG_SMC91X=y # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set @@ -664,7 +703,10 @@ CONFIG_SMC91X=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -708,15 +750,12 @@ CONFIG_INPUT_EVDEV=m # # Character devices # -# CONFIG_AD9960 is not set CONFIG_BFIN_DMA_INTERFACE=m # CONFIG_BFIN_PPI is not set # CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BFIN_SPI_ADC is not set # CONFIG_BFIN_SPORT is not set -# CONFIG_BFIN_TIMER_LATENCY is not set -CONFIG_SIMPLE_GPIO=m # CONFIG_VT is not set # CONFIG_DEVKMEM is not set CONFIG_BFIN_JTAG_COMM=m @@ -730,6 +769,7 @@ CONFIG_BFIN_JTAG_COMM=m # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -740,6 +780,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # @@ -763,13 +804,18 @@ CONFIG_SPI_BFIN=y # CONFIG_SPI_BFIN_LOCK is not set # CONFIG_SPI_BFIN_SPORT is not set # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set @@ -782,9 +828,6 @@ CONFIG_GPIO_SYSFS=y # # I2C GPIO expanders: # -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_GPIO_PCF857X is not set # # PCI GPIO expanders: @@ -822,23 +865,9 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set +# CONFIG_EZX_PCAP is not set # CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -862,7 +891,6 @@ CONFIG_HID=m # # Special HID drivers # -CONFIG_HID_COMPAT=y # CONFIG_USB_SUPPORT is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set @@ -870,10 +898,20 @@ CONFIG_HID_COMPAT=y # CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set # CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set + +# +# TI VLYNQ +# # CONFIG_STAGING is not set # +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set + +# # File systems # # CONFIG_EXT2_FS is not set @@ -882,9 +920,11 @@ CONFIG_HID_COMPAT=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -894,6 +934,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # # CONFIG_ISO9660_FS is not set @@ -915,10 +960,7 @@ CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -937,17 +979,8 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set -CONFIG_YAFFS_FS=m -CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_9BYTE_TAGS is not set -# CONFIG_YAFFS_DOES_ECC is not set -CONFIG_YAFFS_YAFFS2=y -CONFIG_YAFFS_AUTO_YAFFS2=y -# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set -# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set -# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -956,6 +989,7 @@ CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y @@ -966,7 +1000,6 @@ CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m -# CONFIG_SUNRPC_REGISTER_V4 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1034,11 +1067,15 @@ CONFIG_FRAME_WARN=1024 # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1046,16 +1083,21 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_NOMMU_REGIONS is not set # CONFIG_DEBUG_WRITECOUNT is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_FRAME_POINTER is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set @@ -1063,17 +1105,19 @@ CONFIG_DEBUG_INFO=y # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_FAULT_INJECTION is not set - -# -# Tracers -# -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_BRANCH_PROFILE_NONE is not set +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set +# CONFIG_KMEMCHECK is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUG_VERBOSE=y @@ -1095,16 +1139,15 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y CONFIG_EARLY_PRINTK=y CONFIG_CPLB_INFO=y CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options # # CONFIG_KEYS is not set -CONFIG_SECURITY=y +# CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_NETWORK is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 CONFIG_CRYPTO=y # @@ -1183,6 +1226,7 @@ CONFIG_CRYPTO=y # Compression # # CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set # @@ -1190,11 +1234,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -1204,6 +1250,8 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m +CONFIG_DECOMPRESS_GZIP=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/configs/BlackStamp_defconfig b/arch/blackfin/configs/BlackStamp_defconfig index 5d944ff..9e65d88 100644 --- a/arch/blackfin/configs/BlackStamp_defconfig +++ b/arch/blackfin/configs/BlackStamp_defconfig @@ -66,6 +66,7 @@ CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y @@ -275,6 +276,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=y # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set diff --git a/arch/blackfin/configs/CM-BF527_defconfig b/arch/blackfin/configs/CM-BF527_defconfig index 648a31d..4432150 100644 --- a/arch/blackfin/configs/CM-BF527_defconfig +++ b/arch/blackfin/configs/CM-BF527_defconfig @@ -1,12 +1,13 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28 +# Linux kernel version: 2.6.30.5 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y @@ -15,6 +16,9 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -25,55 +29,72 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +CONFIG_KERNEL_LZMA=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +# CONFIG_RD_GZIP is not set +# CONFIG_RD_BZIP2 is not set +CONFIG_RD_LZMA=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -# CONFIG_SYSCTL is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y # CONFIG_ELF_CORE is not set -CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y # CONFIG_AIO is not set CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -81,11 +102,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -101,7 +119,6 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_CLASSIC_RCU=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set @@ -265,7 +282,10 @@ CONFIG_HZ=250 # CONFIG_SCHED_HRTICK is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_TICKSOURCE_GPTMR0 is not set +CONFIG_TICKSOURCE_CORETMR=y # CONFIG_CYCLES_CLOCKSOURCE is not set +# CONFIG_GPTMR0_CLOCKSOURCE is not set # CONFIG_NO_HZ is not set # CONFIG_HIGH_RES_TIMERS is not set CONFIG_GENERIC_CLOCKEVENTS_BUILD=y @@ -315,10 +335,12 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=y # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set @@ -329,10 +351,9 @@ CONFIG_DMA_UNCACHED_1M=y # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set @@ -343,7 +364,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -361,7 +382,7 @@ CONFIG_C_AMBEN_ALL=y # EBIU_AMBCTL Control # CONFIG_BANK_0=0x7BB0 -CONFIG_BANK_1=0x5554 +CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 CONFIG_BANK_3=0xFFC0 @@ -386,7 +407,6 @@ CONFIG_BINFMT_ZFLAT=y # # CONFIG_PM is not set CONFIG_ARCH_SUSPEND_POSSIBLE=y -# CONFIG_PM_WAKEUP_BY_GPIO is not set # # CPU Frequency scaling @@ -400,11 +420,6 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -428,7 +443,6 @@ CONFIG_IP_PNP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" @@ -452,7 +466,9 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -463,13 +479,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_OLD_REGULATORY=y -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -484,22 +495,21 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y # CONFIG_MTD_AR7_PARTS is not set # # User Modules And Translation Layers # -CONFIG_MTD_CHAR=m +CONFIG_MTD_CHAR=y CONFIG_MTD_BLKDEVS=y CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set @@ -512,9 +522,9 @@ CONFIG_MTD_BLOCK=y # # RAM/ROM/Flash chip drivers # -# CONFIG_MTD_CFI is not set -CONFIG_MTD_JEDECPROBE=m -CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_MAP_BANK_WIDTH_1=y CONFIG_MTD_MAP_BANK_WIDTH_2=y @@ -526,9 +536,11 @@ CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y # CONFIG_MTD_CFI_I4 is not set # CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set # CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_PSD4256G is not set +CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_RAM=y CONFIG_MTD_ROM=m # CONFIG_MTD_ABSENT is not set @@ -538,7 +550,7 @@ CONFIG_MTD_ROM=m # CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_GPIO_ADDR is not set +CONFIG_MTD_GPIO_ADDR=y # CONFIG_MTD_UCLINUX is not set # CONFIG_MTD_PLATRAM is not set @@ -562,6 +574,11 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -586,12 +603,46 @@ CONFIG_HAVE_IDE=y # SCSI device support # # CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set # CONFIG_MD is not set CONFIG_NETDEVICES=y +CONFIG_COMPAT_NET_DEV_OPS=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_MACVLAN is not set @@ -613,6 +664,9 @@ CONFIG_PHYLIB=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y @@ -623,9 +677,11 @@ CONFIG_BFIN_TX_DESC_NUM=10 CONFIG_BFIN_RX_DESC_NUM=20 CONFIG_BFIN_MAC_RMII=y # CONFIG_SMC91X is not set -# CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -633,6 +689,7 @@ CONFIG_BFIN_MAC_RMII=y # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set @@ -641,7 +698,10 @@ CONFIG_BFIN_MAC_RMII=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # # USB Network Adapters @@ -674,17 +734,13 @@ CONFIG_BFIN_MAC_RMII=y # # Character devices # -# CONFIG_AD9960 is not set -# CONFIG_SPI_ADC_BF533 is not set -# CONFIG_BF5xx_PPIFCD is not set +CONFIG_BFIN_DMA_INTERFACE=m +# CONFIG_BFIN_PPI is not set +# CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set -# CONFIG_BF5xx_PPI is not set -# CONFIG_BF5xx_EPPI is not set +# CONFIG_BFIN_SPI_ADC is not set # CONFIG_BFIN_SPORT is not set -# CONFIG_BFIN_TIMER_LATENCY is not set -# CONFIG_TWI_LCD is not set -CONFIG_BFIN_DMA_INTERFACE=m -CONFIG_SIMPLE_GPIO=m +# CONFIG_BFIN_TWI_LCD is not set # CONFIG_VT is not set # CONFIG_DEVKMEM is not set # CONFIG_BFIN_JTAG_COMM is not set @@ -698,6 +754,7 @@ CONFIG_SIMPLE_GPIO=m # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -710,6 +767,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set CONFIG_BFIN_OTP=y # CONFIG_BFIN_OTP_WRITE_ENABLE is not set @@ -758,13 +816,9 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_AT24 is not set -# CONFIG_SENSORS_AD5252 is not set -# CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_PCF8575 is not set # CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set @@ -772,7 +826,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set CONFIG_SPI=y -# CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y # @@ -780,17 +833,17 @@ CONFIG_SPI_MASTER=y # CONFIG_SPI_BFIN=y # CONFIG_SPI_BFIN_LOCK is not set +# CONFIG_SPI_BFIN_SPORT is not set # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_SPI_AT25 is not set # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y -# CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y # @@ -803,6 +856,7 @@ CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -829,11 +883,13 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADT7462 is not set # CONFIG_SENSORS_ADT7470 is not set # CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ADT7475 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_F71882FG is not set # CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_G760A is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set @@ -849,11 +905,16 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LM95241 is not set # CONFIG_SENSORS_MAX1111 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set @@ -885,6 +946,12 @@ CONFIG_BFIN_WDT=y # USB-based Watchdog Cards # # CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set # # Multifunction device drivers @@ -892,10 +959,14 @@ CONFIG_BFIN_WDT=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set # CONFIG_REGULATOR is not set # @@ -931,20 +1002,20 @@ CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set # CONFIG_USB_ARCH_HAS_EHCI is not set -CONFIG_USB=y +CONFIG_USB=m # CONFIG_USB_DEBUG is not set -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y # # Miscellaneous USB options # -# CONFIG_USB_DEVICEFS is not set -CONFIG_USB_DEVICE_CLASS=y +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set # CONFIG_USB_OTG_WHITELIST is not set CONFIG_USB_OTG_BLACKLIST_HUB=y -CONFIG_USB_MON=y +CONFIG_USB_MON=m # CONFIG_USB_WUSB is not set # CONFIG_USB_WUSB_CBAF is not set @@ -952,24 +1023,24 @@ CONFIG_USB_MON=y # USB Host Controller Drivers # # CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP1760_HCD is not set # CONFIG_USB_ISP1362_HCD is not set # CONFIG_USB_SL811_HCD is not set # CONFIG_USB_R8A66597_HCD is not set # CONFIG_USB_HWA_HCD is not set -CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_HDRC=m CONFIG_USB_MUSB_SOC=y # # Blackfin high speed USB Support # -CONFIG_USB_MUSB_HOST=y -# CONFIG_USB_MUSB_PERIPHERAL is not set +# CONFIG_USB_MUSB_HOST is not set +CONFIG_USB_MUSB_PERIPHERAL=y # CONFIG_USB_MUSB_OTG is not set -CONFIG_USB_MUSB_HDRC_HCD=y +CONFIG_USB_GADGET_MUSB_HDRC=y CONFIG_MUSB_PIO_ONLY=y -CONFIG_MUSB_DMA_POLL=y # CONFIG_USB_MUSB_DEBUG is not set # @@ -981,18 +1052,31 @@ CONFIG_MUSB_DMA_POLL=y # CONFIG_USB_TMC is not set # -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # # -# see USB_STORAGE Help for more information +# also be needed; see USB_STORAGE Help for more info # +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set # CONFIG_USB_LIBUSUAL is not set # # USB Imaging devices # # CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set # # USB port drivers @@ -1013,7 +1097,6 @@ CONFIG_MUSB_DMA_POLL=y # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set # CONFIG_USB_IDMOUSE is not set # CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set @@ -1021,9 +1104,50 @@ CONFIG_MUSB_DMA_POLL=y # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set # CONFIG_USB_VST is not set -# CONFIG_USB_GADGET is not set +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2272 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_G_PRINTER=m +# CONFIG_USB_CDC_COMPOSITE is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set @@ -1090,6 +1214,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_BFIN=y # CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set # CONFIG_STAGING is not set @@ -1102,9 +1227,10 @@ CONFIG_RTC_DRV_BFIN=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -1114,6 +1240,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # # CONFIG_ISO9660_FS is not set @@ -1122,8 +1253,11 @@ CONFIG_INOTIFY_USER=y # # DOS/FAT/NT Filesystems # -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_NTFS_FS is not set # @@ -1135,10 +1269,7 @@ CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1146,9 +1277,19 @@ CONFIG_SYSFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_YAFFS_FS is not set -# CONFIG_JFFS2_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -1157,6 +1298,7 @@ CONFIG_SYSFS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y @@ -1167,7 +1309,6 @@ CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m -# CONFIG_SUNRPC_REGISTER_V4 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1182,9 +1323,9 @@ CONFIG_SMB_FS=m # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -CONFIG_NLS=m +CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set +CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set # CONFIG_NLS_CODEPAGE_850 is not set @@ -1208,7 +1349,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set # CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set +CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -1235,55 +1376,34 @@ CONFIG_FRAME_WARN=1024 # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -# CONFIG_SCHED_DEBUG is not set -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DEBUG_SECTION_MISMATCH=y +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_FRAME_POINTER is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_KGDB_TESTCASE is not set CONFIG_DEBUG_VERBOSE=y -CONFIG_DEBUG_MMRS=y -# CONFIG_DEBUG_HWERR is not set +# CONFIG_DEBUG_MMRS is not set # CONFIG_DEBUG_DOUBLEFAULT is not set CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y @@ -1293,9 +1413,10 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set -# CONFIG_EARLY_PRINTK is not set +CONFIG_EARLY_PRINTK=y # CONFIG_CPLB_INFO is not set CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options @@ -1304,9 +1425,9 @@ CONFIG_ACCESS_CHECK=y CONFIG_SECURITY=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set -# CONFIG_SECURITY_ROOTPLUG is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +# CONFIG_SECURITY_TOMOYO is not set CONFIG_CRYPTO=y # @@ -1385,6 +1506,7 @@ CONFIG_CRYPTO=y # Compression # # CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set # @@ -1392,20 +1514,24 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=y CONFIG_CRC32=y -# CONFIG_CRC7 is not set +CONFIG_CRC7=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_LZMA=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/configs/CM-BF533_defconfig b/arch/blackfin/configs/CM-BF533_defconfig index ae665b9..df56639 100644 --- a/arch/blackfin/configs/CM-BF533_defconfig +++ b/arch/blackfin/configs/CM-BF533_defconfig @@ -1,94 +1,110 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22.16 +# Linux kernel version: 2.6.30.5 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y -CONFIG_SEMAPHORE_SLEEPERS=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_TIME=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +CONFIG_KERNEL_LZMA=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -# CONFIG_SYSCTL is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_RD_GZIP is not set +# CONFIG_RD_BZIP2 is not set +CONFIG_RD_LZMA=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y # CONFIG_UID16 is not set # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set -# CONFIG_HOTPLUG is not set +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y # CONFIG_ELF_CORE is not set CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y CONFIG_EVENTFD=y +CONFIG_AIO=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 -# CONFIG_NP2 is not set +CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set -CONFIG_RT_MUTEXES=y -CONFIG_TINY_SHMEM=y +CONFIG_MMAP_ALLOW_UNINITIALIZED=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_SLOW_WORK is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODULE_FORCE_LOAD is not set +# CONFIG_MODULE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set # # IO Schedulers @@ -96,7 +112,7 @@ CONFIG_BLOCK=y CONFIG_IOSCHED_NOOP=y # CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set -CONFIG_IOSCHED_CFQ=y +# CONFIG_IOSCHED_CFQ is not set # CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set @@ -105,6 +121,7 @@ CONFIG_DEFAULT_IOSCHED="noop" CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +# CONFIG_FREEZER is not set # # Blackfin Processor Options @@ -113,6 +130,10 @@ CONFIG_PREEMPT_NONE=y # # Processor and Board Settings # +# CONFIG_BF512 is not set +# CONFIG_BF514 is not set +# CONFIG_BF516 is not set +# CONFIG_BF518 is not set # CONFIG_BF522 is not set # CONFIG_BF523 is not set # CONFIG_BF524 is not set @@ -125,28 +146,38 @@ CONFIG_BF533=y # CONFIG_BF534 is not set # CONFIG_BF536 is not set # CONFIG_BF537 is not set +# CONFIG_BF538 is not set +# CONFIG_BF539 is not set # CONFIG_BF542 is not set +# CONFIG_BF542M is not set # CONFIG_BF544 is not set +# CONFIG_BF544M is not set # CONFIG_BF547 is not set +# CONFIG_BF547M is not set # CONFIG_BF548 is not set +# CONFIG_BF548M is not set # CONFIG_BF549 is not set +# CONFIG_BF549M is not set # CONFIG_BF561 is not set +CONFIG_BF_REV_MIN=3 +CONFIG_BF_REV_MAX=6 # CONFIG_BF_REV_0_0 is not set # CONFIG_BF_REV_0_1 is not set # CONFIG_BF_REV_0_2 is not set CONFIG_BF_REV_0_3=y # CONFIG_BF_REV_0_4 is not set # CONFIG_BF_REV_0_5 is not set +# CONFIG_BF_REV_0_6 is not set # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set CONFIG_BF53x=y -CONFIG_BFIN_SINGLE_CORE=y CONFIG_MEM_MT48LC16M16A2TG_75=y # CONFIG_BFIN533_EZKIT is not set # CONFIG_BFIN533_STAMP is not set +# CONFIG_BLACKSTAMP is not set CONFIG_BFIN533_BLUETECHNIX_CM=y # CONFIG_H8606_HVSISTEMAS is not set -# CONFIG_GENERIC_BF533_BOARD is not set +# CONFIG_BFIN532_IP0X is not set # # BF533/2/1 Specific Configuration @@ -188,6 +219,7 @@ CONFIG_WDTIMER=13 # Board customizations # # CONFIG_CMDLINE_BOOL is not set +CONFIG_BOOT_LOAD=0x1000 # # Clock/PLL Setup @@ -207,13 +239,20 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_TICKSOURCE_GPTMR0 is not set +CONFIG_TICKSOURCE_CORETMR=y +# CONFIG_CYCLES_CLOCKSOURCE is not set +# CONFIG_GPTMR0_CLOCKSOURCE is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # -# Memory Setup +# Misc # -CONFIG_MAX_MEM_SIZE=32 -CONFIG_MEM_ADD_WIDTH=9 -CONFIG_BOOT_LOAD=0x1000 CONFIG_BFIN_SCRATCH_REG_RETN=y # CONFIG_BFIN_SCRATCH_REG_RETE is not set # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set @@ -240,6 +279,12 @@ CONFIG_IP_CHECKSUM_L1=y CONFIG_CACHELINE_ALIGNED_L1=y CONFIG_SYSCALL_TAB_L1=y CONFIG_CPLB_SWITCH_TAB_L1=y +CONFIG_APP_STACK_L1=y + +# +# Speed Optimizations +# +CONFIG_BFIN_INS_LOWOVERHEAD=y CONFIG_RAMKERNEL=y # CONFIG_ROMKERNEL is not set CONFIG_SELECT_MEMORY_MODEL=y @@ -248,12 +293,16 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 -CONFIG_LARGE_ALLOCS=y +CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 # CONFIG_BFIN_GPTIMERS is not set +# CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y # CONFIG_DMA_UNCACHED_NONE is not set @@ -262,10 +311,9 @@ CONFIG_DMA_UNCACHED_1M=y # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set @@ -276,7 +324,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -301,12 +349,8 @@ CONFIG_BANK_3=0xFFC2 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # -# CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# +# CONFIG_PCCARD is not set # # Executable file formats @@ -315,22 +359,19 @@ CONFIG_BINFMT_ELF_FDPIC=y CONFIG_BINFMT_FLAT=y CONFIG_BINFMT_ZFLAT=y CONFIG_BINFMT_SHARED_FLAT=y +# CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set # # Power management options # # CONFIG_PM is not set -# CONFIG_PM_WAKEUP_BY_GPIO is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y # # CPU Frequency scaling # # CONFIG_CPU_FREQ is not set - -# -# Networking -# CONFIG_NET=y # @@ -339,45 +380,13 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETLABEL is not set +# CONFIG_INET is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set # CONFIG_LLC2 is not set @@ -385,31 +394,23 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# +# CONFIG_PHONET is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -418,20 +419,22 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set # # User Modules And Translation Layers @@ -444,12 +447,15 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers # -# CONFIG_MTD_CFI is not set +CONFIG_MTD_CFI=y # CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_MAP_BANK_WIDTH_1=y CONFIG_MTD_MAP_BANK_WIDTH_2=y CONFIG_MTD_MAP_BANK_WIDTH_4=y @@ -460,6 +466,11 @@ CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y # CONFIG_MTD_CFI_I4 is not set # CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_PSD4256G is not set +CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_RAM=y # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -468,12 +479,16 @@ CONFIG_MTD_RAM=y # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_UCLINUX=y +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_UCLINUX is not set # CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers # +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -489,36 +504,25 @@ CONFIG_MTD_UCLINUX=y # CONFIG_MTD_ONENAND is not set # -# UBI - Unsorted block images +# LPDDR flash memory drivers # -# CONFIG_MTD_UBI is not set +# CONFIG_MTD_LPDDR is not set # -# Parallel port support +# UBI - Unsorted block images # +# CONFIG_MTD_UBI is not set # CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# +CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# +# CONFIG_BLK_DEV_HD is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -526,34 +530,19 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# # CONFIG_MD is not set - -# -# Network device support -# CONFIG_NETDEVICES=y +CONFIG_COMPAT_NET_DEV_OPS=y # CONFIG_DUMMY is not set -# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -CONFIG_SMC91X=y -# CONFIG_SMSC911X is not set -# CONFIG_DM9000 is not set +# CONFIG_VETH is not set +# CONFIG_NET_ETHERNET is not set # CONFIG_NETDEV_1000 is not set -# CONFIG_AX88180 is not set # CONFIG_NETDEV_10000 is not set # @@ -561,22 +550,17 @@ CONFIG_SMC91X=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# # CONFIG_ISDN is not set - -# -# Telephony Support -# # CONFIG_PHONE is not set # @@ -593,16 +577,15 @@ CONFIG_SMC91X=y # # Character devices # -# CONFIG_AD9960 is not set -# CONFIG_SPI_ADC_BF533 is not set -# CONFIG_BF5xx_PFLAGS is not set -# CONFIG_BF5xx_PPIFCD is not set +# CONFIG_BFIN_DMA_INTERFACE is not set +# CONFIG_BFIN_PPI is not set +# CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set -# CONFIG_BF5xx_PPI is not set -CONFIG_BFIN_SPORT=y -# CONFIG_BFIN_TIMER_LATENCY is not set +# CONFIG_BFIN_SPI_ADC is not set +# CONFIG_BFIN_SPORT is not set # CONFIG_VT is not set # CONFIG_DEVKMEM is not set +# CONFIG_BFIN_JTAG_COMM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -613,6 +596,7 @@ CONFIG_BFIN_SPORT=y # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -623,176 +607,141 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # # CAN, the car bus and industrial fieldbus # # CONFIG_CAN4LINUX is not set - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set -# CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set -# CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set - -CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y -CONFIG_GPIOLIB=y -CONFIG_GPIO_SYSFS=y +CONFIG_SPI=y +CONFIG_SPI_MASTER=y # -# SPI support +# SPI Master Controller Drivers # -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set +CONFIG_SPI_BFIN=y +# CONFIG_SPI_BFIN_LOCK is not set +# CONFIG_SPI_BFIN_SPORT is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # -# Dallas's 1-wire bus +# SPI Protocol Masters # +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +# CONFIG_GPIOLIB is not set # CONFIG_W1 is not set -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set # # Multifunction device drivers # +# CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_REGULATOR is not set # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set +# CONFIG_VIDEO_MEDIA is not set # -# Graphics support +# Multimedia drivers # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_DAB is not set # -# Display device support +# Graphics support # -# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set # CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # -# Sound +# Display device support # +# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_SOUND is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set # -# USB support +# MMC/SD/SDIO Card Drivers # -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set -# CONFIG_USB is not set +CONFIG_MMC_BLOCK=y +# CONFIG_MMC_BLOCK_BOUNCE is not set +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set # -# Enable Host or Gadget support to see Inventra options -# - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set -# CONFIG_MMC is not set - -# -# LED devices +# MMC/SD/SDIO Host Controller Drivers # +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_SPI=m +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# +# CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# PBX support -# -# CONFIG_PBX is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_STAGING is not set # # File systems # -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -# CONFIG_EXT2_FS_POSIX_ACL is not set -# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_FS_MBCACHE=y +# CONFIG_EXT4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y # CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # # CONFIG_ISO9660_FS is not set @@ -801,8 +750,11 @@ CONFIG_INOTIFY_USER=y # # DOS/FAT/NT Filesystems # +CONFIG_FAT_FS=y # CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_NTFS_FS is not set # @@ -813,12 +765,8 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -826,60 +774,106 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_YAFFS_FS is not set # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set - -# -# Network File Systems -# -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set +# CONFIG_NILFS2_FS is not set +# CONFIG_NETWORK_FILESYSTEMS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set # # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y # CONFIG_DEBUG_KERNEL is not set -CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_DEBUG_VERBOSE=y CONFIG_DEBUG_MMRS=y +# CONFIG_DEBUG_DOUBLEFAULT is not set CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y @@ -888,34 +882,39 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set -# CONFIG_EARLY_PRINTK is not set +CONFIG_EARLY_PRINTK=y CONFIG_CPLB_INFO=y CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options # # CONFIG_KEYS is not set CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set -CONFIG_SECURITY_CAPABILITIES=y - -# -# Cryptographic options -# +# CONFIG_SECURITY_PATH is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_SECURITY_TOMOYO is not set # CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y -CONFIG_CRC_CCITT=m +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y # CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=y CONFIG_CRC32=y +CONFIG_CRC7=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y +CONFIG_DECOMPRESS_LZMA=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/configs/CM-BF537E_defconfig b/arch/blackfin/configs/CM-BF537E_defconfig index d74b6f4..22e565c 100644 --- a/arch/blackfin/configs/CM-BF537E_defconfig +++ b/arch/blackfin/configs/CM-BF537E_defconfig @@ -1,13 +1,13 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28.10 -# Wed Jun 3 06:27:41 2009 +# Linux kernel version: 2.6.30.5 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y @@ -16,6 +16,9 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -26,21 +29,40 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +CONFIG_KERNEL_LZMA=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set -# CONFIG_BLK_DEV_INITRD is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_RD_GZIP is not set +# CONFIG_RD_BZIP2 is not set +CONFIG_RD_LZMA=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -49,7 +71,8 @@ CONFIG_EMBEDDED=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set -# CONFIG_HOTPLUG is not set +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y # CONFIG_ELF_CORE is not set @@ -65,12 +88,13 @@ CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y -CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -78,11 +102,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -98,7 +119,6 @@ CONFIG_IOSCHED_CFQ=y # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" -CONFIG_CLASSIC_RCU=y CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -181,7 +201,8 @@ CONFIG_IRQ_MEM_DMA1=13 CONFIG_IRQ_WATCH=13 CONFIG_IRQ_SPI=10 # CONFIG_BFIN537_STAMP is not set -CONFIG_BFIN537_BLUETECHNIX_CM=y +CONFIG_BFIN537_BLUETECHNIX_CM_E=y +# CONFIG_BFIN537_BLUETECHNIX_CM_U is not set # CONFIG_BFIN537_BLUETECHNIX_TCM is not set # CONFIG_PNAV10 is not set # CONFIG_CAMSIG_MINOTAUR is not set @@ -283,10 +304,12 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 # CONFIG_BFIN_GPTIMERS is not set # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set @@ -297,10 +320,9 @@ CONFIG_DMA_UNCACHED_1M=y # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set @@ -311,7 +333,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -337,6 +359,7 @@ CONFIG_BANK_3=0xFFC2 # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # # CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set # # Executable file formats @@ -366,11 +389,6 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -394,7 +412,6 @@ CONFIG_IP_PNP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" @@ -418,7 +435,9 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -429,8 +448,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set # CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -441,16 +460,21 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" # CONFIG_SYS_HYPERVISOR is not set # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y # CONFIG_MTD_AR7_PARTS is not set # @@ -486,22 +510,26 @@ CONFIG_MTD_CFI_I2=y CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set # CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_PSD4256G is not set CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_RAM=y -# CONFIG_MTD_ROM is not set +CONFIG_MTD_ROM=m # CONFIG_MTD_ABSENT is not set # # Mapping drivers for chip access # CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set CONFIG_MTD_GPIO_ADDR=y -CONFIG_MTD_UCLINUX=y +# CONFIG_MTD_UCLINUX is not set # CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers # +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -517,6 +545,11 @@ CONFIG_MTD_UCLINUX=y # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -533,9 +566,14 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -549,6 +587,7 @@ CONFIG_HAVE_IDE=y # CONFIG_ATA is not set # CONFIG_MD is not set CONFIG_NETDEVICES=y +CONFIG_COMPAT_NET_DEV_OPS=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_MACVLAN is not set @@ -570,6 +609,9 @@ CONFIG_PHYLIB=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y @@ -580,8 +622,11 @@ CONFIG_BFIN_TX_DESC_NUM=10 CONFIG_BFIN_RX_DESC_NUM=20 # CONFIG_BFIN_MAC_RMII is not set # CONFIG_SMC91X is not set -# CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -598,7 +643,10 @@ CONFIG_BFIN_RX_DESC_NUM=20 # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -622,15 +670,12 @@ CONFIG_BFIN_RX_DESC_NUM=20 # # Character devices # -# CONFIG_AD9960 is not set CONFIG_BFIN_DMA_INTERFACE=m # CONFIG_BFIN_PPI is not set # CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BFIN_SPI_ADC is not set CONFIG_BFIN_SPORT=y -# CONFIG_BFIN_TIMER_LATENCY is not set -# CONFIG_SIMPLE_GPIO is not set # CONFIG_VT is not set # CONFIG_DEVKMEM is not set # CONFIG_BFIN_JTAG_COMM is not set @@ -644,6 +689,7 @@ CONFIG_BFIN_SPORT=y # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -656,6 +702,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # @@ -668,7 +715,23 @@ CONFIG_UNIX98_PTYS=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set -# CONFIG_SPI is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BFIN=y +# CONFIG_SPI_BFIN_LOCK is not set +# CONFIG_SPI_BFIN_SPORT is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y @@ -688,15 +751,21 @@ CONFIG_GPIO_SYSFS=y # # SPI GPIO expanders: # +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ADCXX is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_F71882FG is not set # CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_MAX1111 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set @@ -758,21 +827,74 @@ CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB is not set # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set - -# -# Enable Host or Gadget support to see Inventra options -# - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; -# -# CONFIG_USB_GADGET is not set -# CONFIG_MMC is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +CONFIG_USB_GADGET_NET2272=y +CONFIG_USB_NET2272=m +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +# CONFIG_MMC_BLOCK_BOUNCE is not set +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_SPI=m # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set # CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set # CONFIG_STAGING is not set @@ -789,9 +911,10 @@ CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -801,6 +924,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # # CONFIG_ISO9660_FS is not set @@ -809,8 +937,11 @@ CONFIG_INOTIFY_USER=y # # DOS/FAT/NT Filesystems # -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_NTFS_FS is not set # @@ -822,10 +953,7 @@ CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -833,9 +961,19 @@ CONFIG_SYSFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_YAFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -844,14 +982,70 @@ CONFIG_SYSFS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -# CONFIG_NETWORK_FILESYSTEMS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_NLS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set # CONFIG_DLM is not set # @@ -867,14 +1061,28 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_SECTION_MISMATCH=y # CONFIG_DEBUG_KERNEL is not set -CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y # # Tracers # -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_DEBUG_VERBOSE=y @@ -888,9 +1096,10 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set -# CONFIG_EARLY_PRINTK is not set +CONFIG_EARLY_PRINTK=y CONFIG_CPLB_INFO=y CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options @@ -899,8 +1108,9 @@ CONFIG_ACCESS_CHECK=y CONFIG_SECURITY=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +# CONFIG_SECURITY_TOMOYO is not set CONFIG_CRYPTO=y # @@ -979,6 +1189,7 @@ CONFIG_CRYPTO=y # Compression # # CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set # @@ -986,19 +1197,24 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set -# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_ITU_T=y CONFIG_CRC32=y -# CONFIG_CRC7 is not set +CONFIG_CRC7=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_LZMA=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/configs/CM-BF537U_defconfig b/arch/blackfin/configs/CM-BF537U_defconfig index 7fc8dfa..efcc90d 100644 --- a/arch/blackfin/configs/CM-BF537U_defconfig +++ b/arch/blackfin/configs/CM-BF537U_defconfig @@ -1,94 +1,111 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22.16 +# Linux kernel version: 2.6.30.5 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y -CONFIG_SEMAPHORE_SLEEPERS=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_TIME=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +CONFIG_KERNEL_LZMA=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_RD_GZIP is not set +# CONFIG_RD_BZIP2 is not set +CONFIG_RD_LZMA=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -# CONFIG_SYSCTL is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y # CONFIG_UID16 is not set # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set -# CONFIG_HOTPLUG is not set +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y # CONFIG_ELF_CORE is not set CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y CONFIG_EVENTFD=y +CONFIG_AIO=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 -# CONFIG_NP2 is not set +CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set -CONFIG_RT_MUTEXES=y -CONFIG_TINY_SHMEM=y +CONFIG_MMAP_ALLOW_UNINITIALIZED=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_SLOW_WORK is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set # # IO Schedulers @@ -105,6 +122,7 @@ CONFIG_DEFAULT_IOSCHED="noop" CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +# CONFIG_FREEZER is not set # # Blackfin Processor Options @@ -113,6 +131,10 @@ CONFIG_PREEMPT_NONE=y # # Processor and Board Settings # +# CONFIG_BF512 is not set +# CONFIG_BF514 is not set +# CONFIG_BF516 is not set +# CONFIG_BF518 is not set # CONFIG_BF522 is not set # CONFIG_BF523 is not set # CONFIG_BF524 is not set @@ -125,22 +147,31 @@ CONFIG_PREEMPT_NONE=y # CONFIG_BF534 is not set # CONFIG_BF536 is not set CONFIG_BF537=y +# CONFIG_BF538 is not set +# CONFIG_BF539 is not set # CONFIG_BF542 is not set +# CONFIG_BF542M is not set # CONFIG_BF544 is not set +# CONFIG_BF544M is not set # CONFIG_BF547 is not set +# CONFIG_BF547M is not set # CONFIG_BF548 is not set +# CONFIG_BF548M is not set # CONFIG_BF549 is not set +# CONFIG_BF549M is not set # CONFIG_BF561 is not set +CONFIG_BF_REV_MIN=2 +CONFIG_BF_REV_MAX=3 # CONFIG_BF_REV_0_0 is not set # CONFIG_BF_REV_0_1 is not set CONFIG_BF_REV_0_2=y # CONFIG_BF_REV_0_3 is not set # CONFIG_BF_REV_0_4 is not set # CONFIG_BF_REV_0_5 is not set +# CONFIG_BF_REV_0_6 is not set # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set CONFIG_BF53x=y -CONFIG_BFIN_SINGLE_CORE=y CONFIG_MEM_MT48LC16M16A2TG_75=y CONFIG_IRQ_PLL_WAKEUP=7 CONFIG_IRQ_RTC=8 @@ -150,7 +181,6 @@ CONFIG_IRQ_SPORT0_TX=9 CONFIG_IRQ_SPORT1_RX=9 CONFIG_IRQ_SPORT1_TX=9 CONFIG_IRQ_TWI=10 -CONFIG_IRQ_SPI=10 CONFIG_IRQ_UART0_RX=10 CONFIG_IRQ_UART0_TX=10 CONFIG_IRQ_UART1_RX=10 @@ -169,11 +199,13 @@ CONFIG_IRQ_PORTG_INTB=12 CONFIG_IRQ_MEM_DMA0=13 CONFIG_IRQ_MEM_DMA1=13 CONFIG_IRQ_WATCH=13 +CONFIG_IRQ_SPI=10 # CONFIG_BFIN537_STAMP is not set -CONFIG_BFIN537_BLUETECHNIX_CM=y +# CONFIG_BFIN537_BLUETECHNIX_CM_E is not set +CONFIG_BFIN537_BLUETECHNIX_CM_U=y +# CONFIG_BFIN537_BLUETECHNIX_TCM is not set # CONFIG_PNAV10 is not set # CONFIG_CAMSIG_MINOTAUR is not set -# CONFIG_GENERIC_BF537_BOARD is not set # # BF537 Specific Configuration @@ -196,6 +228,7 @@ CONFIG_IRQ_PROG_INTA=12 # Board customizations # # CONFIG_CMDLINE_BOOL is not set +CONFIG_BOOT_LOAD=0x1000 # # Clock/PLL Setup @@ -215,13 +248,20 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_TICKSOURCE_GPTMR0 is not set +CONFIG_TICKSOURCE_CORETMR=y +# CONFIG_CYCLES_CLOCKSOURCE is not set +# CONFIG_GPTMR0_CLOCKSOURCE is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # -# Memory Setup +# Misc # -CONFIG_MAX_MEM_SIZE=32 -CONFIG_MEM_ADD_WIDTH=9 -CONFIG_BOOT_LOAD=0x1000 CONFIG_BFIN_SCRATCH_REG_RETN=y # CONFIG_BFIN_SCRATCH_REG_RETE is not set # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set @@ -248,6 +288,12 @@ CONFIG_IP_CHECKSUM_L1=y CONFIG_CACHELINE_ALIGNED_L1=y CONFIG_SYSCALL_TAB_L1=y CONFIG_CPLB_SWITCH_TAB_L1=y +CONFIG_APP_STACK_L1=y + +# +# Speed Optimizations +# +CONFIG_BFIN_INS_LOWOVERHEAD=y CONFIG_RAMKERNEL=y # CONFIG_ROMKERNEL is not set CONFIG_SELECT_MEMORY_MODEL=y @@ -256,12 +302,16 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 -CONFIG_LARGE_ALLOCS=y +CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 # CONFIG_BFIN_GPTIMERS is not set +# CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y # CONFIG_DMA_UNCACHED_NONE is not set @@ -270,10 +320,9 @@ CONFIG_DMA_UNCACHED_1M=y # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set @@ -284,7 +333,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -309,12 +358,8 @@ CONFIG_BANK_3=0xFFC2 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # -# CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# +# CONFIG_PCCARD is not set # # Executable file formats @@ -323,22 +368,19 @@ CONFIG_BINFMT_ELF_FDPIC=y CONFIG_BINFMT_FLAT=y CONFIG_BINFMT_ZFLAT=y CONFIG_BINFMT_SHARED_FLAT=y +# CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set # # Power management options # # CONFIG_PM is not set -# CONFIG_PM_WAKEUP_BY_GPIO is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y # # CPU Frequency scaling # # CONFIG_CPU_FREQ is not set - -# -# Networking -# CONFIG_NET=y # @@ -347,10 +389,6 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -369,15 +407,13 @@ CONFIG_IP_FIB_HASH=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set +CONFIG_INET_LRO=y # CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set # CONFIG_NETLABEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set @@ -386,6 +422,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set # CONFIG_LLC2 is not set @@ -395,29 +432,23 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# +# CONFIG_PHONET is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -426,20 +457,22 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set # # User Modules And Translation Layers @@ -452,12 +485,15 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers # -# CONFIG_MTD_CFI is not set +CONFIG_MTD_CFI=y # CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_MAP_BANK_WIDTH_1=y CONFIG_MTD_MAP_BANK_WIDTH_2=y CONFIG_MTD_MAP_BANK_WIDTH_4=y @@ -468,20 +504,29 @@ CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y # CONFIG_MTD_CFI_I4 is not set # CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_PSD4256G is not set +CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_RAM=y -# CONFIG_MTD_ROM is not set +CONFIG_MTD_ROM=m # CONFIG_MTD_ABSENT is not set # # Mapping drivers for chip access # -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_UCLINUX=y +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_GPIO_ADDR=y +# CONFIG_MTD_UCLINUX is not set # CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers # +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -497,36 +542,36 @@ CONFIG_MTD_UCLINUX=y # CONFIG_MTD_ONENAND is not set # -# UBI - Unsorted block images +# LPDDR flash memory drivers # -# CONFIG_MTD_UBI is not set +# CONFIG_MTD_LPDDR is not set # -# Parallel port support +# UBI - Unsorted block images # +# CONFIG_MTD_UBI is not set # CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# +CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_C2PORT is not set # -# Misc devices +# EEPROM support # +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -534,35 +579,20 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# # CONFIG_MD is not set - -# -# Network device support -# CONFIG_NETDEVICES=y +CONFIG_COMPAT_NET_DEV_OPS=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -CONFIG_SMC91X=y -# CONFIG_BFIN_MAC is not set -# CONFIG_SMSC911X is not set -# CONFIG_DM9000 is not set +# CONFIG_VETH is not set +# CONFIG_NET_ETHERNET is not set # CONFIG_NETDEV_1000 is not set -# CONFIG_AX88180 is not set # CONFIG_NETDEV_10000 is not set # @@ -570,22 +600,17 @@ CONFIG_SMC91X=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# # CONFIG_ISDN is not set - -# -# Telephony Support -# # CONFIG_PHONE is not set # @@ -602,16 +627,15 @@ CONFIG_SMC91X=y # # Character devices # -# CONFIG_AD9960 is not set -# CONFIG_SPI_ADC_BF533 is not set -# CONFIG_BF5xx_PFLAGS is not set -# CONFIG_BF5xx_PPIFCD is not set +CONFIG_BFIN_DMA_INTERFACE=m +# CONFIG_BFIN_PPI is not set +# CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set -# CONFIG_BF5xx_PPI is not set +# CONFIG_BFIN_SPI_ADC is not set CONFIG_BFIN_SPORT=y -# CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_VT is not set # CONFIG_DEVKMEM is not set +# CONFIG_BFIN_JTAG_COMM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -622,6 +646,7 @@ CONFIG_BFIN_SPORT=y # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -634,165 +659,201 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # # CAN, the car bus and industrial fieldbus # # CONFIG_CAN4LINUX is not set - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set -# CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set -# CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y # -# TPM devices +# SPI Master Controller Drivers # -# CONFIG_TCG_TPM is not set -# CONFIG_I2C is not set +CONFIG_SPI_BFIN=y +# CONFIG_SPI_BFIN_LOCK is not set +# CONFIG_SPI_BFIN_SPORT is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y # -# SPI support +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: # -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set # -# Dallas's 1-wire bus +# PCI GPIO expanders: # + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set # CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ADCXX is not set # CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set # # Multifunction device drivers # +# CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_REGULATOR is not set # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set +# CONFIG_VIDEO_MEDIA is not set # -# Graphics support +# Multimedia drivers # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_DAB is not set # -# Display device support +# Graphics support # -# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set # CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # -# Sound +# Display device support # +# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_SOUND is not set - -# -# USB support -# +CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set # CONFIG_USB_ARCH_HAS_EHCI is not set # CONFIG_USB is not set -# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set # CONFIG_USB_GADGET_MUSB_HDRC is not set # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set # CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set CONFIG_USB_GADGET_NET2272=y CONFIG_USB_NET2272=y # CONFIG_USB_GADGET_NET2280 is not set -# CONFIG_USB_GADGET_PXA2XX is not set # CONFIG_USB_GADGET_GOKU is not set -# CONFIG_USB_GADGET_LH7A40X is not set -# CONFIG_USB_GADGET_OMAP is not set -# CONFIG_USB_GADGET_AT91 is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set CONFIG_USB_GADGET_DUALSPEED=y # CONFIG_USB_ZERO is not set -# CONFIG_USB_ETH is not set +# CONFIG_USB_AUDIO is not set +CONFIG_USB_ETH=y +CONFIG_USB_ETH_RNDIS=y # CONFIG_USB_GADGETFS is not set # CONFIG_USB_FILE_STORAGE is not set # CONFIG_USB_G_SERIAL is not set # CONFIG_USB_MIDI_GADGET is not set -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set # -# InfiniBand support +# OTG and related infrastructure # +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set # -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# MMC/SD/SDIO Card Drivers # +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set # -# Real Time Clock +# MMC/SD/SDIO Host Controller Drivers # +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_SPI=m +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# PBX support -# -# CONFIG_PBX is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_STAGING is not set # # File systems @@ -802,25 +863,29 @@ CONFIG_EXT2_FS_XATTR=y # CONFIG_EXT2_FS_POSIX_ACL is not set # CONFIG_EXT2_FS_SECURITY is not set # CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set +# CONFIG_EXT4_FS is not set CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y +# CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # # CONFIG_ISO9660_FS is not set @@ -829,8 +894,11 @@ CONFIG_INOTIFY_USER=y # # DOS/FAT/NT Filesystems # -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_NTFS_FS is not set # @@ -841,12 +909,8 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -854,18 +918,29 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_YAFFS_FS is not set -# CONFIG_JFFS2_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set - -# -# Network File Systems -# +# CONFIG_NILFS2_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set @@ -873,41 +948,94 @@ CONFIG_RAMFS=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Distributed Lock Manager -# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set # CONFIG_DLM is not set # -# Profiling support -# -# CONFIG_PROFILING is not set - -# # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y # CONFIG_DEBUG_KERNEL is not set -CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_DEBUG_VERBOSE=y CONFIG_DEBUG_MMRS=y +# CONFIG_DEBUG_DOUBLEFAULT is not set CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y @@ -916,34 +1044,40 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set -# CONFIG_EARLY_PRINTK is not set +CONFIG_EARLY_PRINTK=y CONFIG_CPLB_INFO=y CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options # # CONFIG_KEYS is not set CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set -CONFIG_SECURITY_CAPABILITIES=y - -# -# Cryptographic options -# +# CONFIG_SECURITY_PATH is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_SECURITY_TOMOYO is not set # CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=y CONFIG_CRC32=y +CONFIG_CRC7=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_LZMA=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/configs/CM-BF548_defconfig b/arch/blackfin/configs/CM-BF548_defconfig index acca4e5..7f579cf 100644 --- a/arch/blackfin/configs/CM-BF548_defconfig +++ b/arch/blackfin/configs/CM-BF548_defconfig @@ -1,14 +1,14 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24.4 +# Linux kernel version: 2.6.30.5 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y -CONFIG_SEMAPHORE_SLEEPERS=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y @@ -16,6 +16,9 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -26,79 +29,100 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +CONFIG_KERNEL_LZMA=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set -# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +# CONFIG_RD_GZIP is not set +# CONFIG_RD_BZIP2 is not set +CONFIG_RD_LZMA=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -# CONFIG_SYSCTL is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y -CONFIG_UID16=y +# CONFIG_UID16 is not set # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y # CONFIG_ELF_CORE is not set CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y CONFIG_EVENTFD=y +CONFIG_AIO=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 -# CONFIG_NP2 is not set +CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_SLOW_WORK is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set # # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +# CONFIG_FREEZER is not set # # Blackfin Processor Options @@ -107,6 +131,10 @@ CONFIG_PREEMPT_VOLUNTARY=y # # Processor and Board Settings # +# CONFIG_BF512 is not set +# CONFIG_BF514 is not set +# CONFIG_BF516 is not set +# CONFIG_BF518 is not set # CONFIG_BF522 is not set # CONFIG_BF523 is not set # CONFIG_BF524 is not set @@ -119,19 +147,29 @@ CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_BF534 is not set # CONFIG_BF536 is not set # CONFIG_BF537 is not set +# CONFIG_BF538 is not set +# CONFIG_BF539 is not set # CONFIG_BF542 is not set +# CONFIG_BF542M is not set # CONFIG_BF544 is not set +# CONFIG_BF544M is not set # CONFIG_BF547 is not set -CONFIG_BF548=y +# CONFIG_BF547M is not set +CONFIG_BF548_std=y +# CONFIG_BF548M is not set # CONFIG_BF549 is not set +# CONFIG_BF549M is not set # CONFIG_BF561 is not set +CONFIG_BF_REV_MIN=0 +CONFIG_BF_REV_MAX=2 # CONFIG_BF_REV_0_0 is not set # CONFIG_BF_REV_0_1 is not set -CONFIG_BF_REV_0_2=y +# CONFIG_BF_REV_0_2 is not set # CONFIG_BF_REV_0_3 is not set # CONFIG_BF_REV_0_4 is not set # CONFIG_BF_REV_0_5 is not set -# CONFIG_BF_REV_ANY is not set +# CONFIG_BF_REV_0_6 is not set +CONFIG_BF_REV_ANY=y # CONFIG_BF_REV_NONE is not set CONFIG_BF54x=y CONFIG_IRQ_PLL_WAKEUP=7 @@ -140,15 +178,12 @@ CONFIG_IRQ_SPORT0_RX=9 CONFIG_IRQ_SPORT0_TX=9 CONFIG_IRQ_SPORT1_RX=9 CONFIG_IRQ_SPORT1_TX=9 +CONFIG_IRQ_SPI0=10 CONFIG_IRQ_UART0_RX=10 CONFIG_IRQ_UART0_TX=10 CONFIG_IRQ_UART1_RX=10 CONFIG_IRQ_UART1_TX=10 CONFIG_IRQ_CNT=8 -CONFIG_IRQ_USB_INT0=11 -CONFIG_IRQ_USB_INT1=11 -CONFIG_IRQ_USB_INT2=11 -CONFIG_IRQ_USB_DMA=11 CONFIG_IRQ_TIMER0=11 CONFIG_IRQ_TIMER1=11 CONFIG_IRQ_TIMER2=11 @@ -157,9 +192,21 @@ CONFIG_IRQ_TIMER4=11 CONFIG_IRQ_TIMER5=11 CONFIG_IRQ_TIMER6=11 CONFIG_IRQ_TIMER7=11 +CONFIG_IRQ_USB_INT0=11 +CONFIG_IRQ_USB_INT1=11 +CONFIG_IRQ_USB_INT2=11 +CONFIG_IRQ_USB_DMA=11 CONFIG_IRQ_TIMER8=11 CONFIG_IRQ_TIMER9=11 CONFIG_IRQ_TIMER10=11 +CONFIG_IRQ_SPORT2_RX=9 +CONFIG_IRQ_SPORT2_TX=9 +CONFIG_IRQ_SPORT3_RX=9 +CONFIG_IRQ_SPORT3_TX=9 +CONFIG_IRQ_SPI1=10 +CONFIG_IRQ_SPI2=10 +CONFIG_IRQ_TWI0=11 +CONFIG_IRQ_TWI1=11 # CONFIG_BFIN548_EZKIT is not set CONFIG_BFIN548_BLUETECHNIX_CM=y @@ -167,6 +214,7 @@ CONFIG_BFIN548_BLUETECHNIX_CM=y # BF548 Specific Configuration # # CONFIG_DEB_DMA_URGENT is not set +# CONFIG_BF548_ATAPI_ALTERNATIVE_PORT is not set # # Interrupt Priority Assignment @@ -182,7 +230,6 @@ CONFIG_IRQ_SPORT1_ERR=7 CONFIG_IRQ_SPI0_ERR=7 CONFIG_IRQ_UART0_ERR=7 CONFIG_IRQ_EPPI0=8 -CONFIG_IRQ_SPI0=10 CONFIG_IRQ_PINT0=12 CONFIG_IRQ_PINT1=12 CONFIG_IRQ_MDMAS0=13 @@ -197,18 +244,10 @@ CONFIG_IRQ_SPI2_ERR=7 CONFIG_IRQ_UART1_ERR=7 CONFIG_IRQ_UART2_ERR=7 CONFIG_IRQ_CAN0_ERR=7 -CONFIG_IRQ_SPORT2_RX=9 -CONFIG_IRQ_SPORT2_TX=9 -CONFIG_IRQ_SPORT3_RX=9 -CONFIG_IRQ_SPORT3_TX=9 CONFIG_IRQ_EPPI1=9 CONFIG_IRQ_EPPI2=9 -CONFIG_IRQ_SPI1=10 -CONFIG_IRQ_SPI2=10 CONFIG_IRQ_ATAPI_RX=10 CONFIG_IRQ_ATAPI_TX=10 -CONFIG_IRQ_TWI0=11 -CONFIG_IRQ_TWI1=11 CONFIG_IRQ_CAN0_RX=11 CONFIG_IRQ_CAN0_TX=11 CONFIG_IRQ_MDMAS2=13 @@ -255,6 +294,7 @@ CONFIG_PINT3_ASSIGN=0x02020303 # Board customizations # # CONFIG_CMDLINE_BOOL is not set +CONFIG_BOOT_LOAD=0x1000 # # Clock/PLL Setup @@ -274,16 +314,12 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set # CONFIG_GENERIC_TIME is not set -# CONFIG_TICK_ONESHOT is not set # -# Memory Setup +# Misc # -CONFIG_MAX_MEM_SIZE=64 -# CONFIG_MEM_MT46V32M16_6T is not set -CONFIG_MEM_MT46V32M16_5B=y -CONFIG_BOOT_LOAD=0x1000 CONFIG_BFIN_SCRATCH_REG_RETN=y # CONFIG_BFIN_SCRATCH_REG_RETE is not set # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set @@ -310,6 +346,12 @@ CONFIG_ACCESS_OK_L1=y CONFIG_CACHELINE_ALIGNED_L1=y # CONFIG_SYSCALL_TAB_L1 is not set # CONFIG_CPLB_SWITCH_TAB_L1 is not set +CONFIG_APP_STACK_L1=y + +# +# Speed Optimizations +# +CONFIG_BFIN_INS_LOWOVERHEAD=y CONFIG_RAMKERNEL=y # CONFIG_ROMKERNEL is not set CONFIG_SELECT_MEMORY_MODEL=y @@ -318,13 +360,16 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 # CONFIG_BFIN_GPTIMERS is not set +# CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y # CONFIG_DMA_UNCACHED_NONE is not set @@ -333,14 +378,13 @@ CONFIG_DMA_UNCACHED_1M=y # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y +# CONFIG_BFIN_L2_ICACHEABLE is not set CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y -CONFIG_BFIN_EXTMEM_WRITEBACK=y -# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set -# CONFIG_BFIN_L2_ICACHEABLE is not set +# CONFIG_BFIN_EXTMEM_WRITEBACK +CONFIG_BFIN_EXTMEM_WRITETHROUGH=y # CONFIG_BFIN_L2_DCACHEABLE is not set # @@ -349,7 +393,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -369,7 +413,7 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x5554 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0x99B2 +CONFIG_BANK_3=0x99B3 CONFIG_EBIU_MBSCTLVAL=0x0 CONFIG_EBIU_MODEVAL=0x1 CONFIG_EBIU_FCTLVAL=0x6 @@ -377,7 +421,6 @@ CONFIG_EBIU_FCTLVAL=0x6 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # -# CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set # CONFIG_PCCARD is not set @@ -388,23 +431,19 @@ CONFIG_BINFMT_ELF_FDPIC=y CONFIG_BINFMT_FLAT=y CONFIG_BINFMT_ZFLAT=y # CONFIG_BINFMT_SHARED_FLAT is not set +# CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set # # Power management options # # CONFIG_PM is not set -CONFIG_SUSPEND_UP_POSSIBLE=y -# CONFIG_PM_WAKEUP_BY_GPIO is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y # # CPU Frequency scaling # # CONFIG_CPU_FREQ is not set - -# -# Networking -# CONFIG_NET=y # @@ -417,6 +456,7 @@ CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -435,19 +475,16 @@ CONFIG_IP_PNP=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m # CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set # CONFIG_NETLABEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set @@ -456,6 +493,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set # CONFIG_LLC2 is not set @@ -465,24 +503,21 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -501,10 +536,12 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set # # User Modules And Translation Layers @@ -539,6 +576,7 @@ CONFIG_MTD_CFI_I2=y CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set # CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_PSD4256G is not set CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_RAM=y # CONFIG_MTD_ROM is not set @@ -549,9 +587,8 @@ CONFIG_MTD_RAM=y # CONFIG_MTD_COMPLEX_MAPPINGS=y CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x20000000 -CONFIG_MTD_PHYSMAP_LEN=0 -CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_GPIO_ADDR is not set # CONFIG_MTD_UCLINUX is not set # CONFIG_MTD_PLATRAM is not set @@ -575,6 +612,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -587,31 +629,31 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # # SCSI device support # # CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y +CONFIG_SCSI=m CONFIG_SCSI_DMA=y # CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set -# CONFIG_SCSI_PROC_FS is not set +CONFIG_SCSI_PROC_FS=y # # SCSI support type (disk, tape, CD-ROM) # -CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SD=m # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_BLK_DEV_SR is not set # CONFIG_CHR_DEV_SG is not set # CONFIG_CHR_DEV_SCH is not set @@ -632,29 +674,54 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set # CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set # CONFIG_MD is not set CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set +CONFIG_COMPAT_NET_DEV_OPS=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set -# CONFIG_PHYLIB is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_SMC91X is not set -CONFIG_SMSC911X=y # CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +CONFIG_SMSC911X=y +# CONFIG_DNET is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set @@ -666,6 +733,10 @@ CONFIG_SMSC911X=y # CONFIG_WLAN_80211 is not set # +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# # USB Network Adapters # # CONFIG_USB_CATC is not set @@ -676,7 +747,6 @@ CONFIG_SMSC911X=y # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -711,6 +781,7 @@ CONFIG_INPUT_KEYBOARD=y # CONFIG_KEYBOARD_GPIO is not set # CONFIG_KEYBOARD_BFIN is not set # CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_ADP5588 is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set @@ -726,19 +797,16 @@ CONFIG_INPUT_KEYBOARD=y # # Character devices # -# CONFIG_AD9960 is not set -# CONFIG_SPI_ADC_BF533 is not set -# CONFIG_BF5xx_PPIFCD is not set +CONFIG_BFIN_DMA_INTERFACE=m +# CONFIG_BFIN_PPI is not set +# CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set -# CONFIG_BF5xx_PPI is not set -CONFIG_BFIN_OTP=y -# CONFIG_BFIN_OTP_WRITE_ENABLE is not set +# CONFIG_BFIN_SPI_ADC is not set # CONFIG_BFIN_SPORT is not set -# CONFIG_BFIN_TIMER_LATENCY is not set -# CONFIG_TWI_LCD is not set -# CONFIG_SIMPLE_GPIO is not set +# CONFIG_BFIN_TWI_LCD is not set # CONFIG_VT is not set -# CONFIG_DEVKMEM is not set +CONFIG_DEVKMEM=y +# CONFIG_BFIN_JTAG_COMM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -749,10 +817,11 @@ CONFIG_BFIN_OTP=y # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y -CONFIG_SERIAL_BFIN_DMA=y -# CONFIG_SERIAL_BFIN_PIO is not set +# CONFIG_SERIAL_BFIN_DMA is not set +CONFIG_SERIAL_BFIN_PIO=y # CONFIG_SERIAL_BFIN_UART0 is not set CONFIG_SERIAL_BFIN_UART1=y # CONFIG_BFIN_UART1_CTSRTS is not set @@ -762,7 +831,10 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set +CONFIG_BFIN_OTP=y +# CONFIG_BFIN_OTP_WRITE_ENABLE is not set # # CAN, the car bus and industrial fieldbus @@ -770,61 +842,53 @@ CONFIG_UNIX98_PTYS=y # CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set -# CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y # -# I2C Algorithms +# I2C Hardware Bus support # -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set # -# I2C Hardware Bus support +# I2C system bus drivers (mostly embedded / system-on-chip) # CONFIG_I2C_BLACKFIN_TWI=y -CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 +CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 # CONFIG_I2C_GPIO is not set # CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_STUB is not set # CONFIG_I2C_TINY_USB is not set # +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# # Miscellaneous I2C Chip support # -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set # CONFIG_DS1682 is not set -# CONFIG_SENSORS_AD5252 is not set -# CONFIG_EEPROM_LEGACY is not set # CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCF8575 is not set -# CONFIG_SENSORS_PCA9543 is not set +# CONFIG_PCF8575 is not set # CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set - -CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y -CONFIG_GPIOLIB=y -CONFIG_GPIO_SYSFS=y - -# -# SPI support -# CONFIG_SPI=y CONFIG_SPI_MASTER=y @@ -832,64 +896,23 @@ CONFIG_SPI_MASTER=y # SPI Master Controller Drivers # CONFIG_SPI_BFIN=y +# CONFIG_SPI_BFIN_LOCK is not set +# CONFIG_SPI_BFIN_SPORT is not set # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +# CONFIG_GPIOLIB is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM70 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -903,25 +926,43 @@ CONFIG_BFIN_WDT=y # USB-based Watchdog Cards # # CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # # Multifunction device drivers # +# CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_REGULATOR is not set # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# # CONFIG_DAB is not set -# CONFIG_USB_DABUSB is not set # # Graphics support @@ -935,80 +976,75 @@ CONFIG_SSB_POSSIBLE=y # Display device support # # CONFIG_DISPLAY_SUPPORT is not set - -# -# Sound -# # CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set +# CONFIG_HID_SUPPORT is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set # CONFIG_USB_ARCH_HAS_EHCI is not set -CONFIG_USB=y +CONFIG_USB=m # CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set # # Miscellaneous USB options # -# CONFIG_USB_DEVICEFS is not set -CONFIG_USB_DEVICE_CLASS=y +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=m +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set # # USB Host Controller Drivers # +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1362_HCD is not set # CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set # CONFIG_USB_SL811_HCD is not set # CONFIG_USB_R8A66597_HCD is not set -CONFIG_USB_MUSB_HDRC=y +# CONFIG_USB_HWA_HCD is not set +CONFIG_USB_MUSB_HDRC=m CONFIG_USB_MUSB_SOC=y # -# Blackfin BF54x, BF525 and BF527 high speed USB support +# Blackfin high speed USB Support # -CONFIG_USB_MUSB_HOST=y -# CONFIG_USB_MUSB_PERIPHERAL is not set +# CONFIG_USB_MUSB_HOST is not set +CONFIG_USB_MUSB_PERIPHERAL=y # CONFIG_USB_MUSB_OTG is not set -CONFIG_USB_MUSB_HDRC_HCD=y +CONFIG_USB_GADGET_MUSB_HDRC=y # CONFIG_MUSB_PIO_ONLY is not set -# CONFIG_USB_INVENTRA_DMA is not set +CONFIG_USB_INVENTRA_DMA=y # CONFIG_USB_TI_CPPI_DMA is not set -CONFIG_USB_MUSB_LOGLEVEL=0 +# CONFIG_USB_MUSB_DEBUG is not set # # USB Device Class drivers # # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # # -# may also be needed; see USB_STORAGE Help for more information +# also be needed; see USB_STORAGE Help for more info # -CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set @@ -1016,6 +1052,7 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_ALAUDA is not set # CONFIG_USB_STORAGE_ONETOUCH is not set # CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set # CONFIG_USB_LIBUSUAL is not set # @@ -1023,15 +1060,10 @@ CONFIG_USB_STORAGE=y # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set -CONFIG_USB_MON=y # # USB port drivers # - -# -# USB Serial Converter support -# # CONFIG_USB_SERIAL is not set # @@ -1040,7 +1072,7 @@ CONFIG_USB_MON=y # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set # CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_SEVSEG is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set @@ -1048,7 +1080,6 @@ CONFIG_USB_MON=y # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set # CONFIG_USB_IDMOUSE is not set # CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set @@ -1056,38 +1087,75 @@ CONFIG_USB_MON=y # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_IOWARRIOR is not set - -# -# USB DSL modem support -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set -CONFIG_MMC=y +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2272 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set +CONFIG_USB_ETH=m +# CONFIG_USB_ETH_RNDIS is not set +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_G_PRINTER=m +# CONFIG_USB_CDC_COMPOSITE is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=m # CONFIG_MMC_DEBUG is not set # CONFIG_MMC_UNSAFE_RESUME is not set # -# MMC/SD Card Drivers +# MMC/SD/SDIO Card Drivers # -CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK=m CONFIG_MMC_BLOCK_BOUNCE=y # CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set # -# MMC/SD Host Controller Drivers +# MMC/SD/SDIO Host Controller Drivers # -CONFIG_SDH_BFIN=y +# CONFIG_MMC_SDHCI is not set +CONFIG_SDH_BFIN=m +# CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND is not set +# CONFIG_SDH_BFIN_ENABLE_SDIO_IRQ is not set # CONFIG_MMC_SPI is not set -# CONFIG_SPI_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=m +CONFIG_RTC_CLASS=m # # RTC interfaces @@ -1111,66 +1179,74 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set # # SPI RTC drivers # -# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set # CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set # # Platform RTC drivers # +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_V3020 is not set # # on-CPU RTC drivers # -CONFIG_RTC_DRV_BFIN=y - -# -# Userspace I/O -# +CONFIG_RTC_DRV_BFIN=m +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set - -# -# PBX support -# -# CONFIG_PBX is not set +# CONFIG_STAGING is not set # # File systems # -# CONFIG_EXT2_FS is not set +CONFIG_EXT2_FS=m +# CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set +# CONFIG_EXT4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y # CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y +# CONFIG_ISO9660_FS is not set # CONFIG_UDF_FS is not set # @@ -1194,10 +1270,7 @@ CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1205,17 +1278,7 @@ CONFIG_SYSFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -CONFIG_YAFFS_FS=m -CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_DOES_ECC is not set -CONFIG_YAFFS_YAFFS2=y -CONFIG_YAFFS_AUTO_YAFFS2=y -# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set -CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 -# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set -# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y -CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y # CONFIG_JFFS2_FS_WBUF_VERIFY is not set @@ -1227,34 +1290,30 @@ CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set -# CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y +# CONFIG_NFSD is not set CONFIG_LOCKD=m CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=m CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m -# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y -CONFIG_SMB_NLS_REMOTE="cp437" -CONFIG_CIFS=y +# CONFIG_SMB_FS is not set +CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set # CONFIG_CIFS_WEAK_PW_HASH is not set # CONFIG_CIFS_XATTR is not set @@ -1267,24 +1326,8 @@ CONFIG_CIFS=y # # Partition Types # -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set +# CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_SYSV68_PARTITION is not set CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_NLS_CODEPAGE_437=m @@ -1326,9 +1369,6 @@ CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m CONFIG_NLS_UTF8=m # CONFIG_DLM is not set -CONFIG_INSTRUMENTATION=y -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set # # Kernel hacking @@ -1336,14 +1376,39 @@ CONFIG_INSTRUMENTATION=y # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y # CONFIG_DEBUG_KERNEL is not set -CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set -CONFIG_DEBUG_MMRS=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_DEBUG_VERBOSE=y +# CONFIG_DEBUG_MMRS is not set +# CONFIG_DEBUG_DOUBLEFAULT is not set CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y @@ -1352,33 +1417,125 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set -# CONFIG_EARLY_PRINTK is not set +CONFIG_EARLY_PRINTK=y CONFIG_CPLB_INFO=y CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options # # CONFIG_KEYS is not set CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set -# CONFIG_SECURITY_CAPABILITIES is not set -# CONFIG_SECURITY_ROOTPLUG is not set -# CONFIG_CRYPTO is not set +# CONFIG_SECURITY_PATH is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_SECURITY_TOMOYO is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=m -CONFIG_PLIST=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_LZMA=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/configs/CM-BF561_defconfig b/arch/blackfin/configs/CM-BF561_defconfig index bae4ee6..a6df01d 100644 --- a/arch/blackfin/configs/CM-BF561_defconfig +++ b/arch/blackfin/configs/CM-BF561_defconfig @@ -1,15 +1,14 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24.4 -# Tue Apr 1 10:50:11 2008 +# Linux kernel version: 2.6.30.5 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y -CONFIG_SEMAPHORE_SLEEPERS=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y @@ -17,6 +16,9 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -27,62 +29,83 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +CONFIG_KERNEL_LZMA=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set -# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_RD_GZIP is not set +# CONFIG_RD_BZIP2 is not set +CONFIG_RD_LZMA=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -# CONFIG_SYSCTL is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y # CONFIG_UID16 is not set # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set -# CONFIG_HOTPLUG is not set +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y # CONFIG_ELF_CORE is not set CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set -CONFIG_ANON_INODES=y CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_EVENTFD=y +# CONFIG_SIGNALFD is not set +# CONFIG_TIMERFD is not set +# CONFIG_EVENTFD is not set +# CONFIG_AIO is not set CONFIG_VM_EVENT_COUNTERS=y -CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 -# CONFIG_NP2 is not set +CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_SLOW_WORK is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set # # IO Schedulers @@ -99,6 +122,7 @@ CONFIG_DEFAULT_IOSCHED="noop" CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +# CONFIG_FREEZER is not set # # Blackfin Processor Options @@ -107,6 +131,10 @@ CONFIG_PREEMPT_NONE=y # # Processor and Board Settings # +# CONFIG_BF512 is not set +# CONFIG_BF514 is not set +# CONFIG_BF516 is not set +# CONFIG_BF518 is not set # CONFIG_BF522 is not set # CONFIG_BF523 is not set # CONFIG_BF524 is not set @@ -119,30 +147,47 @@ CONFIG_PREEMPT_NONE=y # CONFIG_BF534 is not set # CONFIG_BF536 is not set # CONFIG_BF537 is not set +# CONFIG_BF538 is not set +# CONFIG_BF539 is not set # CONFIG_BF542 is not set +# CONFIG_BF542M is not set # CONFIG_BF544 is not set +# CONFIG_BF544M is not set # CONFIG_BF547 is not set +# CONFIG_BF547M is not set # CONFIG_BF548 is not set +# CONFIG_BF548M is not set # CONFIG_BF549 is not set +# CONFIG_BF549M is not set CONFIG_BF561=y +# CONFIG_SMP is not set +CONFIG_BF_REV_MIN=3 +CONFIG_BF_REV_MAX=5 # CONFIG_BF_REV_0_0 is not set # CONFIG_BF_REV_0_1 is not set # CONFIG_BF_REV_0_2 is not set CONFIG_BF_REV_0_3=y # CONFIG_BF_REV_0_4 is not set # CONFIG_BF_REV_0_5 is not set +# CONFIG_BF_REV_0_6 is not set # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set -CONFIG_BFIN_DUAL_CORE=y CONFIG_MEM_MT48LC8M32B2B5_7=y CONFIG_IRQ_PLL_WAKEUP=7 CONFIG_IRQ_SPORT0_ERROR=7 CONFIG_IRQ_SPORT1_ERROR=7 +CONFIG_IRQ_TIMER0=10 +CONFIG_IRQ_TIMER1=10 +CONFIG_IRQ_TIMER2=10 +CONFIG_IRQ_TIMER3=10 +CONFIG_IRQ_TIMER4=10 +CONFIG_IRQ_TIMER5=10 +CONFIG_IRQ_TIMER6=10 +CONFIG_IRQ_TIMER7=10 CONFIG_IRQ_SPI_ERROR=7 # CONFIG_BFIN561_EZKIT is not set # CONFIG_BFIN561_TEPLA is not set CONFIG_BFIN561_BLUETECHNIX_CM=y -# CONFIG_GENERIC_BF561_BOARD is not set # # BF561 Specific Configuration @@ -151,12 +196,7 @@ CONFIG_BFIN561_BLUETECHNIX_CM=y # # Core B Support # - -# -# Core B Support -# CONFIG_BF561_COREB=y -# CONFIG_BF561_COREB_RESET is not set # # Interrupt Priority Assignment @@ -196,14 +236,6 @@ CONFIG_IRQ_DMA2_8=9 CONFIG_IRQ_DMA2_9=9 CONFIG_IRQ_DMA2_10=9 CONFIG_IRQ_DMA2_11=9 -CONFIG_IRQ_TIMER0=10 -CONFIG_IRQ_TIMER1=10 -CONFIG_IRQ_TIMER2=10 -CONFIG_IRQ_TIMER3=10 -CONFIG_IRQ_TIMER4=10 -CONFIG_IRQ_TIMER5=10 -CONFIG_IRQ_TIMER6=10 -CONFIG_IRQ_TIMER7=10 CONFIG_IRQ_TIMER8=10 CONFIG_IRQ_TIMER9=10 CONFIG_IRQ_TIMER10=10 @@ -226,6 +258,7 @@ CONFIG_IRQ_WDTIMER=13 # Board customizations # # CONFIG_CMDLINE_BOOL is not set +CONFIG_BOOT_LOAD=0x1000 # # Clock/PLL Setup @@ -245,19 +278,20 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_TICKSOURCE_GPTMR0 is not set +CONFIG_TICKSOURCE_CORETMR=y # CONFIG_CYCLES_CLOCKSOURCE is not set -# CONFIG_TICK_ONESHOT is not set +# CONFIG_GPTMR0_CLOCKSOURCE is not set # CONFIG_NO_HZ is not set # CONFIG_HIGH_RES_TIMERS is not set CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # -# Memory Setup +# Misc # -CONFIG_MAX_MEM_SIZE=32 -CONFIG_BOOT_LOAD=0x1000 CONFIG_BFIN_SCRATCH_REG_RETN=y # CONFIG_BFIN_SCRATCH_REG_RETE is not set # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set @@ -284,6 +318,12 @@ CONFIG_IP_CHECKSUM_L1=y CONFIG_CACHELINE_ALIGNED_L1=y CONFIG_SYSCALL_TAB_L1=y CONFIG_CPLB_SWITCH_TAB_L1=y +CONFIG_APP_STACK_L1=y + +# +# Speed Optimizations +# +CONFIG_BFIN_INS_LOWOVERHEAD=y CONFIG_RAMKERNEL=y # CONFIG_ROMKERNEL is not set CONFIG_SELECT_MEMORY_MODEL=y @@ -292,14 +332,16 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y -CONFIG_LARGE_ALLOCS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 # CONFIG_BFIN_GPTIMERS is not set +# CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y # CONFIG_DMA_UNCACHED_NONE is not set @@ -308,15 +350,16 @@ CONFIG_DMA_UNCACHED_1M=y # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y +# CONFIG_BFIN_L2_ICACHEABLE is not set CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y -CONFIG_BFIN_EXTMEM_WRITEBACK=y -# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set -# CONFIG_BFIN_L2_ICACHEABLE is not set +# CONFIG_BFIN_EXTMEM_WRITEBACK is not set +CONFIG_BFIN_EXTMEM_WRITETHROUGH=y # CONFIG_BFIN_L2_DCACHEABLE is not set +# CONFIG_BFIN_L2_WRITEBACK is not set +# CONFIG_BFIN_L2_WRITETHROUGH is not set # # Memory Protection Unit @@ -324,7 +367,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -353,8 +396,8 @@ CONFIG_BANK_3=0xFFC2 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # -# CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set # # Executable file formats @@ -363,18 +406,19 @@ CONFIG_BINFMT_ELF_FDPIC=y CONFIG_BINFMT_FLAT=y CONFIG_BINFMT_ZFLAT=y CONFIG_BINFMT_SHARED_FLAT=y +# CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set # # Power management options # # CONFIG_PM is not set -CONFIG_SUSPEND_UP_POSSIBLE=y -# CONFIG_PM_WAKEUP_BY_GPIO is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y # -# Networking +# CPU Frequency scaling # +# CONFIG_CPU_FREQ is not set CONFIG_NET=y # @@ -383,10 +427,6 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -407,14 +447,11 @@ CONFIG_IP_FIB_HASH=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set # CONFIG_NETLABEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set @@ -423,6 +460,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set # CONFIG_LLC2 is not set @@ -432,24 +470,21 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -460,16 +495,22 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" # CONFIG_SYS_HYPERVISOR is not set # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set # # User Modules And Translation Layers @@ -487,8 +528,10 @@ CONFIG_MTD_BLOCK=y # # RAM/ROM/Flash chip drivers # -# CONFIG_MTD_CFI is not set +CONFIG_MTD_CFI=y # CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_MAP_BANK_WIDTH_1=y CONFIG_MTD_MAP_BANK_WIDTH_2=y CONFIG_MTD_MAP_BANK_WIDTH_4=y @@ -499,20 +542,29 @@ CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y # CONFIG_MTD_CFI_I4 is not set # CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_PSD4256G is not set +CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_RAM=y -# CONFIG_MTD_ROM is not set +CONFIG_MTD_ROM=m # CONFIG_MTD_ABSENT is not set # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_UCLINUX=y +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_UCLINUX is not set # CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers # +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -528,6 +580,11 @@ CONFIG_MTD_UCLINUX=y # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -539,14 +596,21 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT25 is not set # CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set -# CONFIG_BFIN_IDE_ADDRESS_MAPPING_MODE0 is not set -# CONFIG_BFIN_IDE_ADDRESS_MAPPING_MODE1 is not set # # SCSI device support @@ -558,26 +622,50 @@ CONFIG_MISC_DEVICES=y # CONFIG_ATA is not set # CONFIG_MD is not set CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set +CONFIG_COMPAT_NET_DEV_OPS=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set -# CONFIG_PHYLIB is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y -CONFIG_SMC91X=y -# CONFIG_SMSC911X is not set +# CONFIG_SMC91X is not set # CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +CONFIG_SMSC911X=m +# CONFIG_DNET is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_NETDEV_1000 is not set -# CONFIG_AX88180 is not set # CONFIG_NETDEV_10000 is not set # @@ -585,10 +673,13 @@ CONFIG_SMC91X=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -609,16 +700,15 @@ CONFIG_SMC91X=y # # Character devices # -# CONFIG_AD9960 is not set -# CONFIG_SPI_ADC_BF533 is not set -# CONFIG_BF5xx_PPIFCD is not set +CONFIG_BFIN_DMA_INTERFACE=m +# CONFIG_BFIN_PPI is not set +# CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set -# CONFIG_BF5xx_PPI is not set +# CONFIG_BFIN_SPI_ADC is not set # CONFIG_BFIN_SPORT is not set -# CONFIG_BFIN_TIMER_LATENCY is not set -# CONFIG_SIMPLE_GPIO is not set # CONFIG_VT is not set # CONFIG_DEVKMEM is not set +# CONFIG_BFIN_JTAG_COMM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -629,6 +719,7 @@ CONFIG_SMC91X=y # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -639,6 +730,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # @@ -647,54 +739,100 @@ CONFIG_UNIX98_PTYS=y # CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set -# CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BFIN=y +# CONFIG_SPI_BFIN_LOCK is not set +# CONFIG_SPI_BFIN_SPORT is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y # -# SPI support +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# + # -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ADCXX is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_F71882FG is not set # CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_MAX1111 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set # CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # # Multifunction device drivers # +# CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_REGULATOR is not set # # Multimedia devices # + +# +# Multimedia core support +# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# # CONFIG_DAB is not set # @@ -709,42 +847,85 @@ CONFIG_SSB_POSSIBLE=y # Display device support # # CONFIG_DISPLAY_SUPPORT is not set - -# -# Sound -# # CONFIG_SOUND is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set # CONFIG_USB_ARCH_HAS_EHCI is not set # CONFIG_USB is not set - -# -# Enable Host or Gadget support to see Inventra options -# - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set -# CONFIG_MMC is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +CONFIG_USB_GADGET_NET2272=y +CONFIG_USB_NET2272=m +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_G_PRINTER=m +# CONFIG_USB_CDC_COMPOSITE is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_SPI=m +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set - -# -# Userspace I/O -# +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set - -# -# PBX support -# -# CONFIG_PBX is not set +# CONFIG_STAGING is not set # # File systems @@ -754,25 +935,29 @@ CONFIG_EXT2_FS_XATTR=y # CONFIG_EXT2_FS_POSIX_ACL is not set # CONFIG_EXT2_FS_SECURITY is not set # CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set +# CONFIG_EXT4_FS is not set CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y +# CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # # CONFIG_ISO9660_FS is not set @@ -781,8 +966,11 @@ CONFIG_INOTIFY_USER=y # # DOS/FAT/NT Filesystems # -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_NTFS_FS is not set # @@ -794,10 +982,7 @@ CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -805,14 +990,28 @@ CONFIG_SYSFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_YAFFS_FS is not set -# CONFIG_JFFS2_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set @@ -827,11 +1026,47 @@ CONFIG_NETWORK_FILESYSTEMS=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_NLS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set # CONFIG_DLM is not set -CONFIG_INSTRUMENTATION=y -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set # # Kernel hacking @@ -839,14 +1074,40 @@ CONFIG_INSTRUMENTATION=y # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y # CONFIG_DEBUG_KERNEL is not set -CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_DEBUG_VERBOSE=y CONFIG_DEBUG_MMRS=y +# CONFIG_DEBUG_DOUBLEFAULT is not set CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y @@ -855,33 +1116,40 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set -# CONFIG_EARLY_PRINTK is not set -# CONFIG_DUAL_CORE_TEST_MODULE is not set +CONFIG_EARLY_PRINTK=y CONFIG_CPLB_INFO=y CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options # # CONFIG_KEYS is not set CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set -CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY_PATH is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_SECURITY_TOMOYO is not set # CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=y CONFIG_CRC32=y -# CONFIG_CRC7 is not set +CONFIG_CRC7=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_LZMA=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/configs/H8606_defconfig b/arch/blackfin/configs/H8606_defconfig index a6a7c8e..bc7fae3 100644 --- a/arch/blackfin/configs/H8606_defconfig +++ b/arch/blackfin/configs/H8606_defconfig @@ -67,6 +67,7 @@ CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y CONFIG_RT_MUTEXES=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 @@ -249,6 +250,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_LARGE_ALLOCS=y +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=y # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y diff --git a/arch/blackfin/configs/IP0X_defconfig b/arch/blackfin/configs/IP0X_defconfig index 1ec9ae2..a7e49d6 100644 --- a/arch/blackfin/configs/IP0X_defconfig +++ b/arch/blackfin/configs/IP0X_defconfig @@ -68,6 +68,7 @@ CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y CONFIG_RT_MUTEXES=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 @@ -261,6 +262,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_LARGE_ALLOCS=y +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 # CONFIG_BFIN_GPTIMERS is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y diff --git a/arch/blackfin/configs/PNAV-10_defconfig b/arch/blackfin/configs/PNAV-10_defconfig index ff377fa..67d1276 100644 --- a/arch/blackfin/configs/PNAV-10_defconfig +++ b/arch/blackfin/configs/PNAV-10_defconfig @@ -63,6 +63,7 @@ CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y @@ -285,6 +286,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=y # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set diff --git a/arch/blackfin/configs/SRV1_defconfig b/arch/blackfin/configs/SRV1_defconfig index 814f9ca..52bfa6b 100644 --- a/arch/blackfin/configs/SRV1_defconfig +++ b/arch/blackfin/configs/SRV1_defconfig @@ -72,6 +72,7 @@ CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y CONFIG_RT_MUTEXES=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 @@ -271,6 +272,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_LARGE_ALLOCS=y +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_DMA_UNCACHED_2M=y # CONFIG_DMA_UNCACHED_1M is not set # CONFIG_DMA_UNCACHED_NONE is not set @@ -700,7 +702,7 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_YEALINK is not set CONFIG_INPUT_UINPUT=y # CONFIG_BF53X_PFBUTTONS is not set -# CONFIG_TWI_KEYPAD is not set +# CONFIG_INPUT_PCF8574 is not set # # Hardware I/O ports diff --git a/arch/blackfin/configs/TCM-BF537_defconfig b/arch/blackfin/configs/TCM-BF537_defconfig index 375e75a..60adfad 100644 --- a/arch/blackfin/configs/TCM-BF537_defconfig +++ b/arch/blackfin/configs/TCM-BF537_defconfig @@ -1,13 +1,13 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28-rc2 -# Tue Jan 6 09:22:17 2009 +# Linux kernel version: 2.6.30.5 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y @@ -16,6 +16,9 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -26,49 +29,72 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +CONFIG_KERNEL_LZMA=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set -# CONFIG_BLK_DEV_INITRD is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_RD_GZIP is not set +# CONFIG_RD_BZIP2 is not set +CONFIG_RD_LZMA=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -# CONFIG_SYSCTL is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y # CONFIG_UID16 is not set # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set -# CONFIG_HOTPLUG is not set +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y # CONFIG_ELF_CORE is not set -CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y # CONFIG_AIO is not set CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -76,11 +102,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -96,7 +119,6 @@ CONFIG_IOSCHED_CFQ=y # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" -CONFIG_CLASSIC_RCU=y CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -128,10 +150,15 @@ CONFIG_BF537=y # CONFIG_BF538 is not set # CONFIG_BF539 is not set # CONFIG_BF542 is not set +# CONFIG_BF542M is not set # CONFIG_BF544 is not set +# CONFIG_BF544M is not set # CONFIG_BF547 is not set +# CONFIG_BF547M is not set # CONFIG_BF548 is not set +# CONFIG_BF548M is not set # CONFIG_BF549 is not set +# CONFIG_BF549M is not set # CONFIG_BF561 is not set CONFIG_BF_REV_MIN=2 CONFIG_BF_REV_MAX=3 @@ -173,11 +200,11 @@ CONFIG_IRQ_MEM_DMA1=13 CONFIG_IRQ_WATCH=13 CONFIG_IRQ_SPI=10 # CONFIG_BFIN537_STAMP is not set -# CONFIG_BFIN537_BLUETECHNIX_CM is not set +# CONFIG_BFIN537_BLUETECHNIX_CM_E is not set +# CONFIG_BFIN537_BLUETECHNIX_CM_U is not set CONFIG_BFIN537_BLUETECHNIX_TCM=y # CONFIG_PNAV10 is not set # CONFIG_CAMSIG_MINOTAUR is not set -# CONFIG_GENERIC_BF537_BOARD is not set # # BF537 Specific Configuration @@ -223,7 +250,10 @@ CONFIG_HZ=250 # CONFIG_SCHED_HRTICK is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_TICKSOURCE_GPTMR0 is not set +CONFIG_TICKSOURCE_CORETMR=y # CONFIG_CYCLES_CLOCKSOURCE is not set +# CONFIG_GPTMR0_CLOCKSOURCE is not set # CONFIG_NO_HZ is not set # CONFIG_HIGH_RES_TIMERS is not set CONFIG_GENERIC_CLOCKEVENTS_BUILD=y @@ -273,10 +303,12 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 # CONFIG_BFIN_GPTIMERS is not set # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set @@ -287,10 +319,9 @@ CONFIG_DMA_UNCACHED_1M=y # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set @@ -301,7 +332,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -327,6 +358,7 @@ CONFIG_BANK_3=0xFFC2 # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # # CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set # # Executable file formats @@ -343,13 +375,83 @@ CONFIG_BINFMT_SHARED_FLAT=y # # CONFIG_PM is not set CONFIG_ARCH_SUSPEND_POSSIBLE=y -# CONFIG_PM_WAKEUP_BY_GPIO is not set # # CPU Frequency scaling # # CONFIG_CPU_FREQ is not set -# CONFIG_NET is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -358,15 +460,21 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" # CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y # CONFIG_MTD_AR7_PARTS is not set # @@ -402,9 +510,10 @@ CONFIG_MTD_CFI_I2=y CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set # CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_PSD4256G is not set CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_RAM=y -# CONFIG_MTD_ROM is not set +CONFIG_MTD_ROM=m # CONFIG_MTD_ABSENT is not set # @@ -413,7 +522,7 @@ CONFIG_MTD_RAM=y CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_PHYSMAP is not set CONFIG_MTD_GPIO_ADDR=y -CONFIG_MTD_UCLINUX=y +# CONFIG_MTD_UCLINUX is not set # CONFIG_MTD_PLATRAM is not set # @@ -436,6 +545,11 @@ CONFIG_MTD_UCLINUX=y # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -443,15 +557,23 @@ CONFIG_MTD_UCLINUX=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -464,6 +586,74 @@ CONFIG_HAVE_IDE=y # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set # CONFIG_MD is not set +CONFIG_NETDEVICES=y +CONFIG_COMPAT_NET_DEV_OPS=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_BFIN_MAC=y +CONFIG_BFIN_MAC_USE_L1=y +CONFIG_BFIN_TX_DESC_NUM=10 +CONFIG_BFIN_RX_DESC_NUM=20 +# CONFIG_BFIN_MAC_RMII is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set # CONFIG_PHONE is not set # @@ -480,15 +670,12 @@ CONFIG_HAVE_IDE=y # # Character devices # -# CONFIG_AD9960 is not set -# CONFIG_SPI_ADC_BF533 is not set -# CONFIG_BF5xx_PPIFCD is not set +CONFIG_BFIN_DMA_INTERFACE=m +# CONFIG_BFIN_PPI is not set +# CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set -# CONFIG_BF5xx_PPI is not set +# CONFIG_BFIN_SPI_ADC is not set CONFIG_BFIN_SPORT=y -# CONFIG_BFIN_TIMER_LATENCY is not set -CONFIG_BFIN_DMA_INTERFACE=m -# CONFIG_SIMPLE_GPIO is not set # CONFIG_VT is not set # CONFIG_DEVKMEM is not set # CONFIG_BFIN_JTAG_COMM is not set @@ -502,6 +689,7 @@ CONFIG_BFIN_DMA_INTERFACE=m # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -514,6 +702,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # @@ -534,39 +723,17 @@ CONFIG_SPI_MASTER=y # CONFIG_SPI_BFIN=y # CONFIG_SPI_BFIN_LOCK is not set +# CONFIG_SPI_BFIN_SPORT is not set # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y -CONFIG_GPIOLIB=y -# CONFIG_DEBUG_GPIO is not set -CONFIG_GPIO_SYSFS=y - -# -# Memory mapped GPIO expanders: -# - -# -# I2C GPIO expanders: -# -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_GPIO_PCF857X is not set - -# -# PCI GPIO expanders: -# - -# -# SPI GPIO expanders: -# -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIOLIB is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -580,6 +747,12 @@ CONFIG_WATCHDOG=y # # CONFIG_SOFT_WATCHDOG is not set CONFIG_BFIN_WDT=y +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set # # Multifunction device drivers @@ -588,7 +761,7 @@ CONFIG_BFIN_WDT=y # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set -# CONFIG_MFD_WM8400 is not set +# CONFIG_REGULATOR is not set # # Multimedia devices @@ -598,6 +771,7 @@ CONFIG_BFIN_WDT=y # Multimedia core support # # CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set # CONFIG_VIDEO_MEDIA is not set # @@ -618,13 +792,81 @@ CONFIG_BFIN_WDT=y # # CONFIG_DISPLAY_SUPPORT is not set # CONFIG_SOUND is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_MMC is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +CONFIG_USB_GADGET_NET2272=y +CONFIG_USB_NET2272=y +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +CONFIG_USB_ETH=y +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_SPI=m # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set # CONFIG_RTC_CLASS is not set # CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set # CONFIG_STAGING is not set @@ -641,8 +883,10 @@ CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -652,6 +896,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # # CONFIG_ISO9660_FS is not set @@ -660,8 +909,11 @@ CONFIG_INOTIFY_USER=y # # DOS/FAT/NT Filesystems # -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_NTFS_FS is not set # @@ -673,10 +925,7 @@ CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -684,9 +933,19 @@ CONFIG_SYSFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_YAFFS_FS is not set -# CONFIG_JFFS2_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -695,13 +954,62 @@ CONFIG_SYSFS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_NLS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set # # Kernel hacking @@ -714,12 +1022,30 @@ CONFIG_FRAME_WARN=1024 # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y # CONFIG_DEBUG_KERNEL is not set -CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_SYSCTL_SYSCALL_CHECK is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_DEBUG_VERBOSE=y @@ -733,9 +1059,10 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set -# CONFIG_EARLY_PRINTK is not set +CONFIG_EARLY_PRINTK=y CONFIG_CPLB_INFO=y CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options @@ -744,20 +1071,110 @@ CONFIG_ACCESS_CHECK=y # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set -# CONFIG_CRYPTO is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines # +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set -# CONFIG_CRC_ITU_T is not set -# CONFIG_CRC32 is not set -# CONFIG_CRC7 is not set +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +CONFIG_CRC7=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_LZMA=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y -- cgit v0.10.2 From f7036d649c88ad14b482b2787ffb1063c8a719d7 Mon Sep 17 00:00:00 2001 From: Yi Li Date: Tue, 15 Sep 2009 02:08:50 +0000 Subject: Blackfin: fix gptimer0 clock source compile warning Some of the clocksource prototypes were updated, but the gptimer0 func was missed in the process. Not a big issue as the argument is ignored, but we should fix the compile warning anyways. Signed-off-by: Yi Li Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index 359cfb1..a54e569 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c @@ -108,7 +108,7 @@ void __init setup_gptimer0(void) enable_gptimers(TIMER0bit); } -static cycle_t bfin_read_gptimer0(void) +static cycle_t bfin_read_gptimer0(struct clocksource *cs) { return bfin_read_TIMER0_COUNTER(); } -- cgit v0.10.2 From ceb33be95afcfbc4079af334835a345288f9f6ca Mon Sep 17 00:00:00 2001 From: Yi Li Date: Tue, 15 Sep 2009 06:50:51 +0000 Subject: Blackfin: unify sched_clock() handling between clock sources Currently sched_clock() is only defined when using CYCLES as a clock source. Declare sched_clock() in common code and mark it with notrace to prevent invoking sched_clock() recursively (because ftrace uses sched_clock() to record time). Signed-off-by: Yi Li Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index a54e569..2855f0f 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c @@ -22,8 +22,6 @@ #include #include -#if defined(CONFIG_CYCLES_CLOCKSOURCE) - /* Accelerators for sched_clock() * convert from cycles(64bits) => nanoseconds (64bits) * basic equation: @@ -46,20 +44,23 @@ * -johnstul@us.ibm.com "math is hard, lets go shopping!" */ -static unsigned long cyc2ns_scale; #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ -static inline void set_cyc2ns_scale(unsigned long cpu_khz) +static inline unsigned long cyc2ns_scale(unsigned long cpu_khz) { - cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR) / cpu_khz; + return (1000000 << CYC2NS_SCALE_FACTOR) / cpu_khz; } -static inline unsigned long long cycles_2_ns(cycle_t cyc) +static inline unsigned long long cycles_2_ns(cycle_t cyc, unsigned long cyc2ns_scale) { return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; } -static cycle_t bfin_read_cycles(struct clocksource *cs) +#if defined(CONFIG_CYCLES_CLOCKSOURCE) + +static unsigned long cycles_cyc2ns_scale; + +static notrace cycle_t bfin_read_cycles(struct clocksource *cs) { return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod); } @@ -73,14 +74,14 @@ static struct clocksource bfin_cs_cycles = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -unsigned long long sched_clock(void) +static inline unsigned long long bfin_cs_cycles_sched_clock(void) { - return cycles_2_ns(bfin_read_cycles(&bfin_cs_cycles)); + return cycles_2_ns(bfin_read_cycles(&bfin_cs_cycles), cycles_cyc2ns_scale); } static int __init bfin_cs_cycles_init(void) { - set_cyc2ns_scale(get_cclk() / 1000); + cycles_cyc2ns_scale = cyc2ns_scale(get_cclk() / 1000); bfin_cs_cycles.mult = \ clocksource_hz2mult(get_cclk(), bfin_cs_cycles.shift); @@ -96,6 +97,8 @@ static int __init bfin_cs_cycles_init(void) #ifdef CONFIG_GPTMR0_CLOCKSOURCE +unsigned long gptimer0_cyc2ns_scale; + void __init setup_gptimer0(void) { disable_gptimers(TIMER0bit); @@ -122,8 +125,15 @@ static struct clocksource bfin_cs_gptimer0 = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +static inline unsigned long long bfin_cs_gptimer0_sched_clock(void) +{ + return cycles_2_ns(bfin_read_TIMER0_COUNTER(), gptimer0_cyc2ns_scale); +} + static int __init bfin_cs_gptimer0_init(void) { + gptimer0_cyc2ns_scale = cyc2ns_scale(get_sclk() / 1000); + setup_gptimer0(); bfin_cs_gptimer0.mult = \ @@ -138,6 +148,19 @@ static int __init bfin_cs_gptimer0_init(void) # define bfin_cs_gptimer0_init() #endif + +#if defined(CONFIG_GPTMR0_CLOCKSOURCE) || defined(CONFIG_CYCLES_CLOCKSOURCE) +/* prefer to use cycles since it has higher rating */ +notrace unsigned long long sched_clock(void) +{ +#if defined(CONFIG_CYCLES_CLOCKSOURCE) + return bfin_cs_cycles_sched_clock(); +#else + return bfin_cs_gptimer0_sched_clock(); +#endif +} +#endif + #ifdef CONFIG_CORE_TIMER_IRQ_L1 __attribute__((l1_text)) #endif -- cgit v0.10.2 From 298571249a1990cd3c6c6ab40250a4a9c18ab5d1 Mon Sep 17 00:00:00 2001 From: Yi Li Date: Tue, 15 Sep 2009 08:55:47 +0000 Subject: Blackfin: use common code for cycle->nanosecond conversion No point in redefining things that common code already does for us. Also use CYC2NS_SCALE_FACTOR to better reflect reality and for better precision. Signed-off-by: Yi Li Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index 2855f0f..eef5283 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c @@ -46,20 +46,8 @@ #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ -static inline unsigned long cyc2ns_scale(unsigned long cpu_khz) -{ - return (1000000 << CYC2NS_SCALE_FACTOR) / cpu_khz; -} - -static inline unsigned long long cycles_2_ns(cycle_t cyc, unsigned long cyc2ns_scale) -{ - return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; -} - #if defined(CONFIG_CYCLES_CLOCKSOURCE) -static unsigned long cycles_cyc2ns_scale; - static notrace cycle_t bfin_read_cycles(struct clocksource *cs) { return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod); @@ -70,19 +58,17 @@ static struct clocksource bfin_cs_cycles = { .rating = 400, .read = bfin_read_cycles, .mask = CLOCKSOURCE_MASK(64), - .shift = 22, + .shift = CYC2NS_SCALE_FACTOR, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; static inline unsigned long long bfin_cs_cycles_sched_clock(void) { - return cycles_2_ns(bfin_read_cycles(&bfin_cs_cycles), cycles_cyc2ns_scale); + return cyc2ns(&bfin_cs_cycles, bfin_read_cycles(&bfin_cs_cycles)); } static int __init bfin_cs_cycles_init(void) { - cycles_cyc2ns_scale = cyc2ns_scale(get_cclk() / 1000); - bfin_cs_cycles.mult = \ clocksource_hz2mult(get_cclk(), bfin_cs_cycles.shift); @@ -97,8 +83,6 @@ static int __init bfin_cs_cycles_init(void) #ifdef CONFIG_GPTMR0_CLOCKSOURCE -unsigned long gptimer0_cyc2ns_scale; - void __init setup_gptimer0(void) { disable_gptimers(TIMER0bit); @@ -121,19 +105,17 @@ static struct clocksource bfin_cs_gptimer0 = { .rating = 350, .read = bfin_read_gptimer0, .mask = CLOCKSOURCE_MASK(32), - .shift = 22, + .shift = CYC2NS_SCALE_FACTOR, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; static inline unsigned long long bfin_cs_gptimer0_sched_clock(void) { - return cycles_2_ns(bfin_read_TIMER0_COUNTER(), gptimer0_cyc2ns_scale); + return cyc2ns(&bfin_cs_gptimer0, bfin_read_TIMER0_COUNTER()); } static int __init bfin_cs_gptimer0_init(void) { - gptimer0_cyc2ns_scale = cyc2ns_scale(get_sclk() / 1000); - setup_gptimer0(); bfin_cs_gptimer0.mult = \ -- cgit v0.10.2 From 89e84eeace5924f29a4f8f25cce9fcb083969974 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 16 Sep 2009 04:36:29 +0000 Subject: Blackfin: add some bounds checking to peripheral_request The requested peripheral is turned into an index into some state arrays, so make sure the calculated index doesn't exceed the index. This occurs when using bogus pin values or the define headers are screwed up. Now we'll notice right away that something needs fixing instead of trying to track down random memory corruption. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 22705ee..c4161e0 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -762,6 +762,8 @@ int peripheral_request(unsigned short per, const char *label) if (!(per & P_DEFINED)) return -ENODEV; + BUG_ON(ident >= MAX_RESOURCES); + local_irq_save_hw(flags); /* If a pin can be muxed as either GPIO or peripheral, make -- cgit v0.10.2 From ddcd7cb857cdf2a29c30125f71cb5d4d6744c99b Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 22 Sep 2009 15:36:55 +0000 Subject: Blackfin: clean up bf537-lq035 board resources Now that the driver has been updated, convert the board resources to the new i2c framework for managing slaves. For boards that don't actually hook up to this hardware, simply drop the resources altogether. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index f09665f..45db07b 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -688,12 +688,6 @@ static struct platform_device bfin_spi0_device = { }; #endif /* spi master and devices */ -#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) -static struct platform_device bfin_fb_device = { - .name = "bf537-lq035", -}; -#endif - #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) static struct resource bfin_uart_resources[] = { #ifdef CONFIG_SERIAL_BFIN_UART0 @@ -957,10 +951,6 @@ static struct platform_device *stamp_devices[] __initdata = { &bfin_spi0_device, #endif -#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) - &bfin_fb_device, -#endif - #if defined(CONFIG_FB_BFIN_T350MCQB) || defined(CONFIG_FB_BFIN_T350MCQB_MODULE) &bf52x_t350mcqb_device, #endif diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c index 43f43a0..26a04f0 100644 --- a/arch/blackfin/mach-bf533/boards/H8606.c +++ b/arch/blackfin/mach-bf533/boards/H8606.c @@ -258,12 +258,6 @@ static struct platform_device bfin_spi0_device = { }; #endif /* spi master and devices */ -#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) -static struct platform_device bfin_fb_device = { - .name = "bf537-fb", -}; -#endif - #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) static struct resource bfin_uart_resources[] = { { diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index 82f70ef..6d68dcf 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c @@ -321,12 +321,6 @@ static struct platform_device bfin_spi0_device = { }; #endif /* spi master and devices */ -#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) -static struct platform_device bfin_fb_device = { - .name = "bf537-fb", -}; -#endif - #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) static struct resource bfin_uart_resources[] = { { diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index c46baa5..6a09b71 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1462,6 +1462,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { I2C_BOARD_INFO("bfin-adv7393", 0x2B), }, #endif +#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) + { + I2C_BOARD_INFO("bf537-lq035-ad5280", 0x2C), + }, +#endif }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) -- cgit v0.10.2 From cb5ae60f7a0b21b936c022a2e7f9303c60665233 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Wed, 23 Sep 2009 11:32:52 +0000 Subject: Blackfin: convert DMA code to a proper bitmap Rather than using our own data structures that basically boil down to a bitmap, use the standard bitmap functions. Reported-by: Paul Mundt Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c index e74e74d..be81572 100644 --- a/arch/blackfin/kernel/dma-mapping.c +++ b/arch/blackfin/kernel/dma-mapping.c @@ -19,7 +19,7 @@ #include static spinlock_t dma_page_lock; -static unsigned int *dma_page; +static unsigned long *dma_page; static unsigned int dma_pages; static unsigned long dma_base; static unsigned long dma_size; @@ -30,7 +30,7 @@ void dma_alloc_init(unsigned long start, unsigned long end) spin_lock_init(&dma_page_lock); dma_initialized = 0; - dma_page = (unsigned int *)__get_free_page(GFP_KERNEL); + dma_page = (unsigned long *)__get_free_page(GFP_KERNEL); memset(dma_page, 0, PAGE_SIZE); dma_base = PAGE_ALIGN(start); dma_size = PAGE_ALIGN(end) - PAGE_ALIGN(start); @@ -58,10 +58,11 @@ static unsigned long __alloc_dma_pages(unsigned int pages) spin_lock_irqsave(&dma_page_lock, flags); for (i = 0; i < dma_pages;) { - if (dma_page[i++] == 0) { + if (test_bit(i++, dma_page) == 0) { if (++count == pages) { while (count--) - dma_page[--i] = 1; + __set_bit(--i, dma_page); + ret = dma_base + (i << PAGE_SHIFT); break; } @@ -84,9 +85,9 @@ static void __free_dma_pages(unsigned long addr, unsigned int pages) } spin_lock_irqsave(&dma_page_lock, flags); - for (i = page; i < page + pages; i++) { - dma_page[i] = 0; - } + for (i = page; i < page + pages; i++) + __clear_bit(i, dma_page); + spin_unlock_irqrestore(&dma_page_lock, flags); } -- cgit v0.10.2 From 13048f8866390a26a7b657e0ca28100e2660063a Mon Sep 17 00:00:00 2001 From: Bernd Schmidt Date: Wed, 23 Sep 2009 16:47:16 +0000 Subject: Blackfin: improve async bank access checking (for cross-banks & XIP) The access_ok() function did not accept ranges within the async banks which made it impossible to do XIP in flash. Fixing that also showed that the current bfin_mem_access_type() code did not work with accesses that spanned async banks (like a file system). So split out and fix the async bank checks so that all these scenarios work as expected. Signed-off-by: Bernd Schmidt Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 4587642..a577238 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -332,12 +332,58 @@ int in_mem_const(unsigned long addr, unsigned long size, { return in_mem_const_off(addr, size, 0, const_addr, const_size); } -#define IN_ASYNC(bnum, bctlnum) \ +#define ASYNC_ENABLED(bnum, bctlnum) \ ({ \ - (bfin_read_EBIU_AMGCTL() & 0xe) < ((bnum + 1) << 1) ? -EFAULT : \ - bfin_read_EBIU_AMBCTL##bctlnum() & B##bnum##RDYEN ? -EFAULT : \ - BFIN_MEM_ACCESS_CORE; \ + (bfin_read_EBIU_AMGCTL() & 0xe) < ((bnum + 1) << 1) ? 0 : \ + bfin_read_EBIU_AMBCTL##bctlnum() & B##bnum##RDYEN ? 0 : \ + 1; \ }) +/* + * We can't read EBIU banks that aren't enabled or we end up hanging + * on the access to the async space. Make sure we validate accesses + * that cross async banks too. + * 0 - found, but unusable + * 1 - found & usable + * 2 - not found + */ +static +int in_async(unsigned long addr, unsigned long size) +{ + if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE) { + if (!ASYNC_ENABLED(0, 0)) + return 0; + if (addr + size <= ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE) + return 1; + size -= ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE - addr; + addr = ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE; + } + if (addr >= ASYNC_BANK1_BASE && addr < ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE) { + if (!ASYNC_ENABLED(1, 0)) + return 0; + if (addr + size <= ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE) + return 1; + size -= ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE - addr; + addr = ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE; + } + if (addr >= ASYNC_BANK2_BASE && addr < ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE) { + if (!ASYNC_ENABLED(2, 1)) + return 0; + if (addr + size <= ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE) + return 1; + size -= ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE - addr; + addr = ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE; + } + if (addr >= ASYNC_BANK3_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) { + if (ASYNC_ENABLED(3, 1)) + return 0; + if (addr + size <= ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) + return 1; + return 0; + } + + /* not within async bounds */ + return 2; +} int bfin_mem_access_type(unsigned long addr, unsigned long size) { @@ -374,17 +420,11 @@ int bfin_mem_access_type(unsigned long addr, unsigned long size) if (addr >= SYSMMR_BASE) return BFIN_MEM_ACCESS_CORE_ONLY; - /* We can't read EBIU banks that aren't enabled or we end up hanging - * on the access to the async space. - */ - if (in_mem_const(addr, size, ASYNC_BANK0_BASE, ASYNC_BANK0_SIZE)) - return IN_ASYNC(0, 0); - if (in_mem_const(addr, size, ASYNC_BANK1_BASE, ASYNC_BANK1_SIZE)) - return IN_ASYNC(1, 0); - if (in_mem_const(addr, size, ASYNC_BANK2_BASE, ASYNC_BANK2_SIZE)) - return IN_ASYNC(2, 1); - if (in_mem_const(addr, size, ASYNC_BANK3_BASE, ASYNC_BANK3_SIZE)) - return IN_ASYNC(3, 1); + switch (in_async(addr, size)) { + case 0: return -EFAULT; + case 1: return BFIN_MEM_ACCESS_CORE; + case 2: /* fall through */; + } if (in_mem_const(addr, size, BOOT_ROM_START, BOOT_ROM_LENGTH)) return BFIN_MEM_ACCESS_CORE; @@ -401,6 +441,8 @@ __attribute__((l1_text)) /* Return 1 if access to memory range is OK, 0 otherwise */ int _access_ok(unsigned long addr, unsigned long size) { + int aret; + if (size == 0) return 1; /* Check that things do not wrap around */ @@ -450,6 +492,11 @@ int _access_ok(unsigned long addr, unsigned long size) if (in_mem_const(addr, size, COREB_L1_DATA_B_START, COREB_L1_DATA_B_LENGTH)) return 1; #endif + + aret = in_async(addr, size); + if (aret < 2) + return aret; + if (in_mem_const_off(addr, size, _ebss_l2 - _stext_l2, L2_START, L2_LENGTH)) return 1; -- cgit v0.10.2 From 5cd82a6d58cb14c3a5d08ed171229de7adc3deac Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 23 Sep 2009 20:34:48 +0000 Subject: Blackfin: calculate on-chip lengths at link time rather than run time Since the link sizes never change at runtime, push the calculation out to the linker script to save some useless calculation costs. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/sections.h b/arch/blackfin/include/asm/sections.h index 1f5381f..42f6c53 100644 --- a/arch/blackfin/include/asm/sections.h +++ b/arch/blackfin/include/asm/sections.h @@ -13,10 +13,18 @@ extern unsigned long memory_mtd_start, memory_mtd_end, mtd_size; extern unsigned long _ramstart, _ramend, _rambase; extern unsigned long memory_start, memory_end, physical_mem_end; -extern char _stext_l1[], _etext_l1[], _sdata_l1[], _edata_l1[], _sbss_l1[], - _ebss_l1[], _l1_lma_start[], _sdata_b_l1[], _sbss_b_l1[], _ebss_b_l1[], - _stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[], _sbss_l2[], - _ebss_l2[], _l2_lma_start[]; +/* + * The weak markings on the lengths might seem weird, but this is required + * in order to make gcc accept the fact that these may actually have a value + * of 0 (since they aren't actually addresses, but sizes of sections). + */ +extern char _stext_l1[], _etext_l1[], _text_l1_lma[], __weak _text_l1_len[]; +extern char _sdata_l1[], _edata_l1[], _sbss_l1[], _ebss_l1[], + _data_l1_lma[], __weak _data_l1_len[]; +extern char _sdata_b_l1[], _edata_b_l1[], _sbss_b_l1[], _ebss_b_l1[], + _data_b_l1_lma[], __weak _data_b_l1_len[]; +extern char _stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[], + _sbss_l2[], _ebss_l2[], _l2_lma[], __weak _l2_len[]; #include diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index c202a44..5fda774 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -178,10 +178,10 @@ void __init bfin_cache_init(void) void __init bfin_relocate_l1_mem(void) { - unsigned long l1_code_length; - unsigned long l1_data_a_length; - unsigned long l1_data_b_length; - unsigned long l2_length; + unsigned long text_l1_len = (unsigned long)_text_l1_len; + unsigned long data_l1_len = (unsigned long)_data_l1_len; + unsigned long data_b_l1_len = (unsigned long)_data_b_l1_len; + unsigned long l2_len = (unsigned long)_l2_len; early_shadow_stamp(); @@ -201,30 +201,23 @@ void __init bfin_relocate_l1_mem(void) blackfin_dma_early_init(); - /* if necessary, copy _stext_l1 to _etext_l1 to L1 instruction SRAM */ - l1_code_length = _etext_l1 - _stext_l1; - if (l1_code_length) - early_dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length); + /* if necessary, copy L1 text to L1 instruction SRAM */ + if (L1_CODE_LENGTH && text_l1_len) + early_dma_memcpy(_stext_l1, _text_l1_lma, text_l1_len); - /* if necessary, copy _sdata_l1 to _sbss_l1 to L1 data bank A SRAM */ - l1_data_a_length = _sbss_l1 - _sdata_l1; - if (l1_data_a_length) - early_dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length); + /* if necessary, copy L1 data to L1 data bank A SRAM */ + if (L1_DATA_A_LENGTH && data_l1_len) + early_dma_memcpy(_sdata_l1, _data_l1_lma, data_l1_len); - /* if necessary, copy _sdata_b_l1 to _sbss_b_l1 to L1 data bank B SRAM */ - l1_data_b_length = _sbss_b_l1 - _sdata_b_l1; - if (l1_data_b_length) - early_dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + - l1_data_a_length, l1_data_b_length); + /* if necessary, copy L1 data B to L1 data bank B SRAM */ + if (L1_DATA_B_LENGTH && data_b_l1_len) + early_dma_memcpy(_sdata_b_l1, _data_b_l1_lma, data_b_l1_len); early_dma_memcpy_done(); - /* if necessary, copy _stext_l2 to _edata_l2 to L2 SRAM */ - if (L2_LENGTH != 0) { - l2_length = _sbss_l2 - _stext_l2; - if (l2_length) - memcpy(_stext_l2, _l2_lma_start, l2_length); - } + /* if necessary, copy L2 text/data to L2 SRAM */ + if (L2_LENGTH && l2_len) + memcpy(_stext_l2, _l2_lma, l2_len); } /* add_memory_region to memmap */ diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index 10e1253..01682ee 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S @@ -123,8 +123,6 @@ SECTIONS EXIT_DATA } - __l1_lma_start = .; - .text_l1 L1_CODE_START : AT(LOADADDR(.exit.data) + SIZEOF(.exit.data)) { . = ALIGN(4); @@ -136,9 +134,11 @@ SECTIONS . = ALIGN(4); __etext_l1 = .; } - ASSERT (SIZEOF(.text_l1) <= L1_CODE_LENGTH, "L1 text overflow!") + __text_l1_lma = LOADADDR(.text_l1); + __text_l1_len = SIZEOF(.text_l1); + ASSERT (__text_l1_len <= L1_CODE_LENGTH, "L1 text overflow!") - .data_l1 L1_DATA_A_START : AT(LOADADDR(.text_l1) + SIZEOF(.text_l1)) + .data_l1 L1_DATA_A_START : AT(__text_l1_lma + __text_l1_len) { . = ALIGN(4); __sdata_l1 = .; @@ -154,9 +154,11 @@ SECTIONS . = ALIGN(4); __ebss_l1 = .; } - ASSERT (SIZEOF(.data_l1) <= L1_DATA_A_LENGTH, "L1 data A overflow!") + __data_l1_lma = LOADADDR(.data_l1); + __data_l1_len = SIZEOF(.data_l1); + ASSERT (__data_l1_len <= L1_DATA_A_LENGTH, "L1 data A overflow!") - .data_b_l1 L1_DATA_B_START : AT(LOADADDR(.data_l1) + SIZEOF(.data_l1)) + .data_b_l1 L1_DATA_B_START : AT(__data_l1_lma + __data_l1_len) { . = ALIGN(4); __sdata_b_l1 = .; @@ -169,11 +171,11 @@ SECTIONS . = ALIGN(4); __ebss_b_l1 = .; } - ASSERT (SIZEOF(.data_b_l1) <= L1_DATA_B_LENGTH, "L1 data B overflow!") - - __l2_lma_start = LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1); + __data_b_l1_lma = LOADADDR(.data_b_l1); + __data_b_l1_len = SIZEOF(.data_b_l1); + ASSERT (__data_b_l1_len <= L1_DATA_B_LENGTH, "L1 data B overflow!") - .text_data_l2 L2_START : AT(LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1)) + .text_data_l2 L2_START : AT(__data_b_l1_lma + __data_b_l1_len) { . = ALIGN(4); __stext_l2 = .; @@ -195,12 +197,14 @@ SECTIONS . = ALIGN(4); __ebss_l2 = .; } - ASSERT (SIZEOF(.text_data_l2) <= L2_LENGTH, "L2 overflow!") + __l2_lma = LOADADDR(.text_data_l2); + __l2_len = SIZEOF(.text_data_l2); + ASSERT (__l2_len <= L2_LENGTH, "L2 overflow!") /* Force trailing alignment of our init section so that when we * free our init memory, we don't leave behind a partial page. */ - . = LOADADDR(.text_data_l2) + SIZEOF(.text_data_l2); + . = __l2_lma + __l2_len; . = ALIGN(PAGE_SIZE); ___init_end = .; -- cgit v0.10.2 From 21b03cfe4c50fd586bfebd06d852457c07f60c2b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 24 Sep 2009 05:44:36 +0000 Subject: Blackfin: clean up isp1362 board resources Drop the CONFIG_USB_ISP1362_BFIN_GPIO_IRQ Kconfig as it never made it into mainline and it was a bad interface into the board resources. For boards that actually used this, replace it with an actual IRQ define. For boards that didn't, simply drop the resources. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c index f1996b1..40b9934 100644 --- a/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c @@ -15,9 +15,6 @@ #include #include #include -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -#include -#endif #include #include #include @@ -317,45 +314,6 @@ static struct platform_device sl811_hcd_device = { }; #endif -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -static struct resource isp1362_hcd_resources[] = { - { - .start = 0x20360000, - .end = 0x20360000, - .flags = IORESOURCE_MEM, - }, { - .start = 0x20360004, - .end = 0x20360004, - .flags = IORESOURCE_MEM, - }, { - .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, - .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct isp1362_platform_data isp1362_priv = { - .sel15Kres = 1, - .clknotstop = 0, - .oc_enable = 0, - .int_act_high = 0, - .int_edge_triggered = 0, - .remote_wakeup_connected = 0, - .no_power_switching = 1, - .power_switching_mode = 0, -}; - -static struct platform_device isp1362_hcd_device = { - .name = "isp1362-hcd", - .id = 0, - .dev = { - .platform_data = &isp1362_priv, - }, - .num_resources = ARRAY_SIZE(isp1362_hcd_resources), - .resource = isp1362_hcd_resources, -}; -#endif - #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) static struct platform_device bfin_mii_bus = { .name = "bfin_mii_bus", @@ -841,10 +799,6 @@ static struct platform_device *cmbf527_devices[] __initdata = { &sl811_hcd_device, #endif -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) - &isp1362_hcd_device, -#endif - #if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) &bfin_isp1760_device, #endif diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 45db07b..6ffbefc 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -13,9 +13,6 @@ #include #include #include -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -#include -#endif #include #include #include @@ -373,45 +370,6 @@ static struct platform_device sl811_hcd_device = { }; #endif -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -static struct resource isp1362_hcd_resources[] = { - { - .start = 0x20360000, - .end = 0x20360000, - .flags = IORESOURCE_MEM, - }, { - .start = 0x20360004, - .end = 0x20360004, - .flags = IORESOURCE_MEM, - }, { - .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, - .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct isp1362_platform_data isp1362_priv = { - .sel15Kres = 1, - .clknotstop = 0, - .oc_enable = 0, - .int_act_high = 0, - .int_edge_triggered = 0, - .remote_wakeup_connected = 0, - .no_power_switching = 1, - .power_switching_mode = 0, -}; - -static struct platform_device isp1362_hcd_device = { - .name = "isp1362-hcd", - .id = 0, - .dev = { - .platform_data = &isp1362_priv, - }, - .num_resources = ARRAY_SIZE(isp1362_hcd_resources), - .resource = isp1362_hcd_resources, -}; -#endif - #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) static struct platform_device bfin_mii_bus = { .name = "bfin_mii_bus", @@ -918,10 +876,6 @@ static struct platform_device *stamp_devices[] __initdata = { &sl811_hcd_device, #endif -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) - &isp1362_hcd_device, -#endif - #if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) &bfin_isp1760_device, #endif diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c index 9ba2904..4e0afda 100644 --- a/arch/blackfin/mach-bf537/boards/pnav10.c +++ b/arch/blackfin/mach-bf537/boards/pnav10.c @@ -13,9 +13,6 @@ #include #include #include -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -#include -#endif #include #include #include @@ -147,45 +144,6 @@ static struct platform_device sl811_hcd_device = { }; #endif -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -static struct resource isp1362_hcd_resources[] = { - { - .start = 0x20360000, - .end = 0x20360000, - .flags = IORESOURCE_MEM, - }, { - .start = 0x20360004, - .end = 0x20360004, - .flags = IORESOURCE_MEM, - }, { - .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, - .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct isp1362_platform_data isp1362_priv = { - .sel15Kres = 1, - .clknotstop = 0, - .oc_enable = 0, - .int_act_high = 0, - .int_edge_triggered = 0, - .remote_wakeup_connected = 0, - .no_power_switching = 1, - .power_switching_mode = 0, -}; - -static struct platform_device isp1362_hcd_device = { - .name = "isp1362-hcd", - .id = 0, - .dev = { - .platform_data = &isp1362_priv, - }, - .num_resources = ARRAY_SIZE(isp1362_hcd_resources), - .resource = isp1362_hcd_resources, -}; -#endif - #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) static struct platform_device bfin_mii_bus = { .name = "bfin_mii_bus", @@ -492,10 +450,6 @@ static struct platform_device *stamp_devices[] __initdata = { &sl811_hcd_device, #endif -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) - &isp1362_hcd_device, -#endif - #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) &smc91x_device, #endif diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 6a09b71..514d994 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -272,8 +272,8 @@ static struct resource isp1362_hcd_resources[] = { .end = 0x20360004, .flags = IORESOURCE_MEM, }, { - .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, - .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, + .start = IRQ_PF3, + .end = IRQ_PF3, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, }, }; -- cgit v0.10.2 From d887a1ce285f03c689bb4fbbaf574160bb484c3e Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 25 Sep 2009 09:03:21 +0000 Subject: Blackfin: cpufreq: use a constant latency PLL_LOCKCNT applies only to the PLL programming sequence which does not apply to core and system clock dividers. Writes to PLL_DIV to change the CSEL/SSEL dividers take effect immediately. There is still overhead in software in writing the new dividers, so just use a value of 50us as this should be good enough. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c index 0150650..3d18d2b 100644 --- a/arch/blackfin/mach-common/cpufreq.c +++ b/arch/blackfin/mach-common/cpufreq.c @@ -138,7 +138,8 @@ static int __init __bfin_cpu_init(struct cpufreq_policy *policy) dpm_state_table[index].tscale); } - policy->cpuinfo.transition_latency = (bfin_read_PLL_LOCKCNT() / (sclk / 1000000)) * 1000; + policy->cpuinfo.transition_latency = 50000; /* 50us assumed */ + /*Now ,only support one cpu */ policy->cur = cclk; cpufreq_frequency_table_get_attr(bfin_freq_table, policy->cpu); -- cgit v0.10.2 From 46fe23ac39a0cdc4272946c1e3f9ff4fd5765a5b Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Mon, 28 Sep 2009 09:23:05 +0000 Subject: Blackfin: add C define of trace_buffer_init() Have the C API trace funcs match the assembly API trace funcs. Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/trace.h b/arch/blackfin/include/asm/trace.h index 609ad3c..dc0aa55 100644 --- a/arch/blackfin/include/asm/trace.h +++ b/arch/blackfin/include/asm/trace.h @@ -28,6 +28,8 @@ extern unsigned long software_trace_buff[]; #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON +#define trace_buffer_init() bfin_write_TBUFCTL(BFIN_TRACE_INIT) + #define trace_buffer_save(x) \ do { \ (x) = bfin_read_TBUFCTL(); \ -- cgit v0.10.2 From 621dd2474399237ca556a54037c3b8557e80d021 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 28 Sep 2009 12:23:41 +0000 Subject: Blackfin: bf538: add support for extended GPIO banks The GPIOs on ports C/D/E on the BF538/BF539 do not behave the same way as the other ports on the part and the same way as all other Blackfin parts. The MMRs are programmed slightly different and they cannot be used to generate interrupts or wakeup a sleeping system. Since these guys don't fit into the existing code, create a simple gpiolib driver for them. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h index 5b44d05..539468a 100644 --- a/arch/blackfin/include/asm/gpio.h +++ b/arch/blackfin/include/asm/gpio.h @@ -159,6 +159,11 @@ struct gpio_port_t { }; #endif +#ifdef BFIN_SPECIAL_GPIO_BANKS +void bfin_special_gpio_free(unsigned gpio); +int bfin_special_gpio_request(unsigned gpio, const char *label); +#endif + #ifdef CONFIG_PM unsigned int bfin_pm_standby_setup(void); diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index c4161e0..a174596 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -100,6 +100,12 @@ u8 pmux_offset[][16] = { }; # endif +#elif defined(BF538_FAMILY) +static unsigned short * const port_fer[] = { + (unsigned short *) PORTCIO_FER, + (unsigned short *) PORTDIO_FER, + (unsigned short *) PORTEIO_FER, +}; #endif static unsigned short reserved_gpio_map[GPIO_BANK_NUM]; @@ -163,6 +169,27 @@ static int cmp_label(unsigned short ident, const char *label) static void port_setup(unsigned gpio, unsigned short usage) { +#if defined(BF538_FAMILY) + /* + * BF538/9 Port C,D and E are special. + * Inverted PORT_FER polarity on CDE and no PORF_FER on F + * Regular PORT F GPIOs are handled here, CDE are exclusively + * managed by GPIOLIB + */ + + if (gpio < MAX_BLACKFIN_GPIOS || gpio >= MAX_RESOURCES) + return; + + gpio -= MAX_BLACKFIN_GPIOS; + + if (usage == GPIO_USAGE) + *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); + else + *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio); + SSYNC(); + return; +#endif + if (check_gpio(gpio)) return; @@ -981,6 +1008,76 @@ void bfin_gpio_free(unsigned gpio) } EXPORT_SYMBOL(bfin_gpio_free); +#ifdef BFIN_SPECIAL_GPIO_BANKS +static unsigned short reserved_special_gpio_map[gpio_bank(MAX_RESOURCES)]; + +int bfin_special_gpio_request(unsigned gpio, const char *label) +{ + unsigned long flags; + + local_irq_save_hw(flags); + + /* + * Allow that the identical GPIO can + * be requested from the same driver twice + * Do nothing and return - + */ + + if (cmp_label(gpio, label) == 0) { + local_irq_restore_hw(flags); + return 0; + } + + if (unlikely(reserved_special_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + local_irq_restore_hw(flags); + printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n", + gpio, get_label(gpio)); + + return -EBUSY; + } + if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + local_irq_restore_hw(flags); + printk(KERN_ERR + "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n", + gpio, get_label(gpio)); + + return -EBUSY; + } + + reserved_special_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); + reserved_peri_map[gpio_bank(gpio)] |= gpio_bit(gpio); + + set_label(gpio, label); + local_irq_restore_hw(flags); + port_setup(gpio, GPIO_USAGE); + + return 0; +} +EXPORT_SYMBOL(bfin_special_gpio_request); + +void bfin_special_gpio_free(unsigned gpio) +{ + unsigned long flags; + + might_sleep(); + + local_irq_save_hw(flags); + + if (unlikely(!(reserved_special_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { + gpio_error(gpio); + local_irq_restore_hw(flags); + return; + } + + reserved_special_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); + reserved_peri_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); + set_label(gpio, "free"); + local_irq_restore_hw(flags); +} +EXPORT_SYMBOL(bfin_special_gpio_free); +#endif + + int bfin_gpio_irq_request(unsigned gpio, const char *label) { unsigned long flags; diff --git a/arch/blackfin/mach-bf538/Makefile b/arch/blackfin/mach-bf538/Makefile index 8cd2719..c0be54f 100644 --- a/arch/blackfin/mach-bf538/Makefile +++ b/arch/blackfin/mach-bf538/Makefile @@ -3,3 +3,4 @@ # obj-y := ints-priority.o dma.o +obj-$(CONFIG_GPIOLIB) += ext-gpio.o diff --git a/arch/blackfin/mach-bf538/ext-gpio.c b/arch/blackfin/mach-bf538/ext-gpio.c new file mode 100644 index 0000000..180b125 --- /dev/null +++ b/arch/blackfin/mach-bf538/ext-gpio.c @@ -0,0 +1,123 @@ +/* + * GPIOLIB interface for BF538/9 PORT C, D, and E GPIOs + * + * Copyright 2009 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include + +#define DEFINE_REG(reg, off) \ +static inline u16 read_##reg(void __iomem *port) \ + { return bfin_read16(port + off); } \ +static inline void write_##reg(void __iomem *port, u16 v) \ + { bfin_write16(port + off, v); } + +DEFINE_REG(PORTIO, 0x00) +DEFINE_REG(PORTIO_CLEAR, 0x10) +DEFINE_REG(PORTIO_SET, 0x20) +DEFINE_REG(PORTIO_DIR, 0x40) +DEFINE_REG(PORTIO_INEN, 0x50) + +static void __iomem *gpio_chip_to_mmr(struct gpio_chip *chip) +{ + switch (chip->base) { + default: /* not really needed, but keeps gcc happy */ + case GPIO_PC0: return (void __iomem *)PORTCIO; + case GPIO_PD0: return (void __iomem *)PORTDIO; + case GPIO_PE0: return (void __iomem *)PORTEIO; + } +} + +static int bf538_gpio_get_value(struct gpio_chip *chip, unsigned gpio) +{ + void __iomem *port = gpio_chip_to_mmr(chip); + return !!(read_PORTIO(port) & (1u << gpio)); +} + +static void bf538_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value) +{ + void __iomem *port = gpio_chip_to_mmr(chip); + if (value) + write_PORTIO_SET(port, (1u << gpio)); + else + write_PORTIO_CLEAR(port, (1u << gpio)); +} + +static int bf538_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) +{ + void __iomem *port = gpio_chip_to_mmr(chip); + write_PORTIO_DIR(port, read_PORTIO_DIR(port) & ~(1u << gpio)); + write_PORTIO_INEN(port, read_PORTIO_INEN(port) | (1u << gpio)); + return 0; +} + +static int bf538_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) +{ + void __iomem *port = gpio_chip_to_mmr(chip); + write_PORTIO_INEN(port, read_PORTIO_INEN(port) & ~(1u << gpio)); + bf538_gpio_set_value(port, gpio, value); + write_PORTIO_DIR(port, read_PORTIO_DIR(port) | (1u << gpio)); + return 0; +} + +static int bf538_gpio_request(struct gpio_chip *chip, unsigned gpio) +{ + return bfin_special_gpio_request(chip->base + gpio, chip->label); +} + +static void bf538_gpio_free(struct gpio_chip *chip, unsigned gpio) +{ + return bfin_special_gpio_free(chip->base + gpio); +} + +/* We don't set the irq fields as these banks cannot generate interrupts */ + +static struct gpio_chip bf538_portc_chip = { + .label = "GPIO-PC", + .direction_input = bf538_gpio_direction_input, + .get = bf538_gpio_get_value, + .direction_output = bf538_gpio_direction_output, + .set = bf538_gpio_set_value, + .request = bf538_gpio_request, + .free = bf538_gpio_free, + .base = GPIO_PC0, + .ngpio = GPIO_PC9 - GPIO_PC0 + 1, +}; + +static struct gpio_chip bf538_portd_chip = { + .label = "GPIO-PD", + .direction_input = bf538_gpio_direction_input, + .get = bf538_gpio_get_value, + .direction_output = bf538_gpio_direction_output, + .set = bf538_gpio_set_value, + .request = bf538_gpio_request, + .free = bf538_gpio_free, + .base = GPIO_PD0, + .ngpio = GPIO_PD13 - GPIO_PD0 + 1, +}; + +static struct gpio_chip bf538_porte_chip = { + .label = "GPIO-PE", + .direction_input = bf538_gpio_direction_input, + .get = bf538_gpio_get_value, + .direction_output = bf538_gpio_direction_output, + .set = bf538_gpio_set_value, + .request = bf538_gpio_request, + .free = bf538_gpio_free, + .base = GPIO_PE0, + .ngpio = GPIO_PE15 - GPIO_PE0 + 1, +}; + +static int __init bf538_extgpio_setup(void) +{ + return gpiochip_add(&bf538_portc_chip) | + gpiochip_add(&bf538_portd_chip) | + gpiochip_add(&bf538_porte_chip); +} +arch_initcall(bf538_extgpio_setup); diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h index 5f6c34d..1f1aeab 100644 --- a/arch/blackfin/mach-bf538/include/mach/defBF539.h +++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h @@ -468,31 +468,31 @@ /* General-Purpose Ports (0xFFC01500 - 0xFFC015FF) */ /* GPIO Port C Register Names */ -#define GPIO_C_CNFG 0xFFC01500 /* GPIO Pin Port C Configuration Register */ -#define GPIO_C_D 0xFFC01510 /* GPIO Pin Port C Data Register */ -#define GPIO_C_C 0xFFC01520 /* Clear GPIO Pin Port C Register */ -#define GPIO_C_S 0xFFC01530 /* Set GPIO Pin Port C Register */ -#define GPIO_C_T 0xFFC01540 /* Toggle GPIO Pin Port C Register */ -#define GPIO_C_DIR 0xFFC01550 /* GPIO Pin Port C Direction Register */ -#define GPIO_C_INEN 0xFFC01560 /* GPIO Pin Port C Input Enable Register */ +#define PORTCIO_FER 0xFFC01500 /* GPIO Pin Port C Configuration Register */ +#define PORTCIO 0xFFC01510 /* GPIO Pin Port C Data Register */ +#define PORTCIO_CLEAR 0xFFC01520 /* Clear GPIO Pin Port C Register */ +#define PORTCIO_SET 0xFFC01530 /* Set GPIO Pin Port C Register */ +#define PORTCIO_TOGGLE 0xFFC01540 /* Toggle GPIO Pin Port C Register */ +#define PORTCIO_DIR 0xFFC01550 /* GPIO Pin Port C Direction Register */ +#define PORTCIO_INEN 0xFFC01560 /* GPIO Pin Port C Input Enable Register */ /* GPIO Port D Register Names */ -#define GPIO_D_CNFG 0xFFC01504 /* GPIO Pin Port D Configuration Register */ -#define GPIO_D_D 0xFFC01514 /* GPIO Pin Port D Data Register */ -#define GPIO_D_C 0xFFC01524 /* Clear GPIO Pin Port D Register */ -#define GPIO_D_S 0xFFC01534 /* Set GPIO Pin Port D Register */ -#define GPIO_D_T 0xFFC01544 /* Toggle GPIO Pin Port D Register */ -#define GPIO_D_DIR 0xFFC01554 /* GPIO Pin Port D Direction Register */ -#define GPIO_D_INEN 0xFFC01564 /* GPIO Pin Port D Input Enable Register */ +#define PORTDIO_FER 0xFFC01504 /* GPIO Pin Port D Configuration Register */ +#define PORTDIO 0xFFC01514 /* GPIO Pin Port D Data Register */ +#define PORTDIO_CLEAR 0xFFC01524 /* Clear GPIO Pin Port D Register */ +#define PORTDIO_SET 0xFFC01534 /* Set GPIO Pin Port D Register */ +#define PORTDIO_TOGGLE 0xFFC01544 /* Toggle GPIO Pin Port D Register */ +#define PORTDIO_DIR 0xFFC01554 /* GPIO Pin Port D Direction Register */ +#define PORTDIO_INEN 0xFFC01564 /* GPIO Pin Port D Input Enable Register */ /* GPIO Port E Register Names */ -#define GPIO_E_CNFG 0xFFC01508 /* GPIO Pin Port E Configuration Register */ -#define GPIO_E_D 0xFFC01518 /* GPIO Pin Port E Data Register */ -#define GPIO_E_C 0xFFC01528 /* Clear GPIO Pin Port E Register */ -#define GPIO_E_S 0xFFC01538 /* Set GPIO Pin Port E Register */ -#define GPIO_E_T 0xFFC01548 /* Toggle GPIO Pin Port E Register */ -#define GPIO_E_DIR 0xFFC01558 /* GPIO Pin Port E Direction Register */ -#define GPIO_E_INEN 0xFFC01568 /* GPIO Pin Port E Input Enable Register */ +#define PORTEIO_FER 0xFFC01508 /* GPIO Pin Port E Configuration Register */ +#define PORTEIO 0xFFC01518 /* GPIO Pin Port E Data Register */ +#define PORTEIO_CLEAR 0xFFC01528 /* Clear GPIO Pin Port E Register */ +#define PORTEIO_SET 0xFFC01538 /* Set GPIO Pin Port E Register */ +#define PORTEIO_TOGGLE 0xFFC01548 /* Toggle GPIO Pin Port E Register */ +#define PORTEIO_DIR 0xFFC01558 /* GPIO Pin Port E Direction Register */ +#define PORTEIO_INEN 0xFFC01568 /* GPIO Pin Port E Input Enable Register */ /* DMA Controller 1 Traffic Control Registers (0xFFC01B00 - 0xFFC01BFF) */ diff --git a/arch/blackfin/mach-bf538/include/mach/gpio.h b/arch/blackfin/mach-bf538/include/mach/gpio.h index 295c78a..0c346fb 100644 --- a/arch/blackfin/mach-bf538/include/mach/gpio.h +++ b/arch/blackfin/mach-bf538/include/mach/gpio.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Analog Devices Inc. + * Copyright (C) 2008-2009 Analog Devices Inc. * Licensed under the GPL-2 or later. */ @@ -7,11 +7,8 @@ #ifndef _MACH_GPIO_H_ #define _MACH_GPIO_H_ - /* FIXME: - * For now only support PORTF GPIOs. - * PORT C,D and E are for peripheral usage only - */ #define MAX_BLACKFIN_GPIOS 16 +#define BFIN_SPECIAL_GPIO_BANKS 3 #define GPIO_PF0 0 /* PF */ #define GPIO_PF1 1 diff --git a/arch/blackfin/mach-bf538/include/mach/portmux.h b/arch/blackfin/mach-bf538/include/mach/portmux.h index 6121cf8..0083ba1 100644 --- a/arch/blackfin/mach-bf538/include/mach/portmux.h +++ b/arch/blackfin/mach-bf538/include/mach/portmux.h @@ -7,7 +7,7 @@ #ifndef _MACH_PORTMUX_H_ #define _MACH_PORTMUX_H_ -#define MAX_RESOURCES MAX_BLACKFIN_GPIOS +#define MAX_RESOURCES 64 #define P_TMR2 (P_DONTCARE) #define P_TMR1 (P_DONTCARE) diff --git a/arch/blackfin/mach-common/dpmc_modes.S b/arch/blackfin/mach-common/dpmc_modes.S index 8009a51..b037168 100644 --- a/arch/blackfin/mach-common/dpmc_modes.S +++ b/arch/blackfin/mach-common/dpmc_modes.S @@ -404,6 +404,21 @@ ENTRY(_do_hibernate) PM_SYS_PUSH(EBIU_FCTL) #endif +#ifdef PORTCIO_FER + PM_SYS_PUSH16(PORTCIO_DIR) + PM_SYS_PUSH16(PORTCIO_INEN) + PM_SYS_PUSH16(PORTCIO) + PM_SYS_PUSH16(PORTCIO_FER) + PM_SYS_PUSH16(PORTDIO_DIR) + PM_SYS_PUSH16(PORTDIO_INEN) + PM_SYS_PUSH16(PORTDIO) + PM_SYS_PUSH16(PORTDIO_FER) + PM_SYS_PUSH16(PORTEIO_DIR) + PM_SYS_PUSH16(PORTEIO_INEN) + PM_SYS_PUSH16(PORTEIO) + PM_SYS_PUSH16(PORTEIO_FER) +#endif + PM_SYS_PUSH16(SYSCR) /* Save Core MMRs */ @@ -716,6 +731,21 @@ ENTRY(_do_hibernate) P0.L = lo(PLL_CTL); PM_SYS_POP16(SYSCR) +#ifdef PORTCIO_FER + PM_SYS_POP16(PORTEIO_FER) + PM_SYS_POP16(PORTEIO) + PM_SYS_POP16(PORTEIO_INEN) + PM_SYS_POP16(PORTEIO_DIR) + PM_SYS_POP16(PORTDIO_FER) + PM_SYS_POP16(PORTDIO) + PM_SYS_POP16(PORTDIO_INEN) + PM_SYS_POP16(PORTDIO_DIR) + PM_SYS_POP16(PORTCIO_FER) + PM_SYS_POP16(PORTCIO) + PM_SYS_POP16(PORTCIO_INEN) + PM_SYS_POP16(PORTCIO_DIR) +#endif + #ifdef EBIU_FCTL PM_SYS_POP(EBIU_FCTL) PM_SYS_POP(EBIU_MODE) -- cgit v0.10.2 From 6e3647554e2bf7d7a898ccfc35941adbecd888e7 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Tue, 29 Sep 2009 03:01:40 +0000 Subject: Blackfin: bf537-stamp: need io.h for writeb() funcs Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 514d994..f02f20f 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include -- cgit v0.10.2 From b6357116c4ef06633ee92dfcb0b8ae058f367c77 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 30 Sep 2009 01:21:13 +0000 Subject: Blackfin: BF51x/BF52x: fill out bfin_clear_PPI_STATUS() All the arches define a helper macro to make things easy for driver code. Reported-by: Frank Van Hooft Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h index 1d970df..d2d0533 100644 --- a/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h +++ b/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h @@ -844,6 +844,7 @@ #define bfin_write_PPI_CONTROL(val) bfin_write16(PPI_CONTROL, val) #define bfin_read_PPI_STATUS() bfin_read16(PPI_STATUS) #define bfin_write_PPI_STATUS(val) bfin_write16(PPI_STATUS, val) +#define bfin_clear_PPI_STATUS() bfin_write_PPI_STATUS(0xFFFF) #define bfin_read_PPI_DELAY() bfin_read16(PPI_DELAY) #define bfin_write_PPI_DELAY(val) bfin_write16(PPI_DELAY, val) #define bfin_read_PPI_COUNT() bfin_read16(PPI_COUNT) diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h index 7014dde..b6b99bb 100644 --- a/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h +++ b/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h @@ -844,6 +844,7 @@ #define bfin_write_PPI_CONTROL(val) bfin_write16(PPI_CONTROL, val) #define bfin_read_PPI_STATUS() bfin_read16(PPI_STATUS) #define bfin_write_PPI_STATUS(val) bfin_write16(PPI_STATUS, val) +#define bfin_clear_PPI_STATUS() bfin_write_PPI_STATUS(0xFFFF) #define bfin_read_PPI_DELAY() bfin_read16(PPI_DELAY) #define bfin_write_PPI_DELAY(val) bfin_write16(PPI_DELAY, val) #define bfin_read_PPI_COUNT() bfin_read16(PPI_COUNT) -- cgit v0.10.2 From 872d024b40550fcbd3327386e4c891e815d3922a Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 6 Oct 2009 04:49:07 +0000 Subject: Blackfin: pull in firmware Kconfig Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index c0d4445..af44a06 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -1277,6 +1277,8 @@ source "net/Kconfig" source "drivers/Kconfig" +source "drivers/firmware/Kconfig" + source "fs/Kconfig" source "arch/blackfin/Kconfig.debug" -- cgit v0.10.2 From bbc51e97d336e0d0461b13bbe4ccdbe768695f5a Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 9 Oct 2009 07:34:00 +0000 Subject: Blackfin: push down asm/ includes and out of bfin-global.h Avoid including unnecessary headers all the time as well as circular includes with core requirements. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/bfin-global.h b/arch/blackfin/include/asm/bfin-global.h index 10064f9..741c021 100644 --- a/arch/blackfin/include/asm/bfin-global.h +++ b/arch/blackfin/include/asm/bfin-global.h @@ -11,9 +11,6 @@ #ifndef __ASSEMBLY__ -#include -#include -#include #include #include @@ -35,6 +32,7 @@ extern unsigned long get_sclk(void); extern unsigned long sclk_to_usecs(unsigned long sclk); extern unsigned long usecs_to_sclk(unsigned long usecs); +struct pt_regs; extern void dump_bfin_process(struct pt_regs *regs); extern void dump_bfin_mem(struct pt_regs *regs); extern void dump_bfin_trace_buffer(void); diff --git a/arch/blackfin/include/asm/cacheflush.h b/arch/blackfin/include/asm/cacheflush.h index 417eaac..2666ff8 100644 --- a/arch/blackfin/include/asm/cacheflush.h +++ b/arch/blackfin/include/asm/cacheflush.h @@ -10,6 +10,7 @@ #define _BLACKFIN_CACHEFLUSH_H #include /* for SSYNC() */ +#include /* for _ramend */ extern void blackfin_icache_flush_range(unsigned long start_address, unsigned long end_address); extern void blackfin_dcache_flush_range(unsigned long start_address, unsigned long end_address); diff --git a/arch/blackfin/include/asm/uaccess.h b/arch/blackfin/include/asm/uaccess.h index c03b853..1c0d190 100644 --- a/arch/blackfin/include/asm/uaccess.h +++ b/arch/blackfin/include/asm/uaccess.h @@ -17,9 +17,7 @@ #include #include -#ifdef CONFIG_ACCESS_CHECK -# include -#endif +#include #define get_ds() (KERNEL_DS) #define get_fs() (current_thread_info()->addr_limit) diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c index be81572..755a0f4 100644 --- a/arch/blackfin/kernel/dma-mapping.c +++ b/arch/blackfin/kernel/dma-mapping.c @@ -17,6 +17,7 @@ #include #include #include +#include static spinlock_t dma_page_lock; static unsigned long *dma_page; -- cgit v0.10.2 From adfc046740b4161cbb1f0a3ea0d4200e21113489 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 9 Oct 2009 07:37:03 +0000 Subject: Blackfin: update bfin_rotary defines The driver was moved during the merge process, so update the defines to match the new location. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 6ffbefc..1c2ec24 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -802,7 +802,7 @@ static struct platform_device bfin_device_gpiokeys = { }; #endif -#if defined(CONFIG_JOYSTICK_BFIN_ROTARY) || defined(CONFIG_JOYSTICK_BFIN_ROTARY_MODULE) +#if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE) #include #include @@ -935,7 +935,7 @@ static struct platform_device *stamp_devices[] __initdata = { &bfin_device_gpiokeys, #endif -#if defined(CONFIG_JOYSTICK_BFIN_ROTARY) || defined(CONFIG_JOYSTICK_BFIN_ROTARY_MODULE) +#if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE) &bfin_rotary_device, #endif diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 1a5286b..e926d39 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -154,7 +154,7 @@ static struct platform_device bf54x_kpad_device = { }; #endif -#if defined(CONFIG_JOYSTICK_BFIN_ROTARY) || defined(CONFIG_JOYSTICK_BFIN_ROTARY_MODULE) +#if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE) #include static struct bfin_rotary_platform_data bfin_rotary_data = { @@ -974,7 +974,7 @@ static struct platform_device *ezkit_devices[] __initdata = { &bf54x_kpad_device, #endif -#if defined(CONFIG_JOYSTICK_BFIN_ROTARY) || defined(CONFIG_JOYSTICK_BFIN_ROTARY_MODULE) +#if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE) &bfin_rotary_device, #endif -- cgit v0.10.2 From d2e015d65fc692475b8513259d6afacd2cded8e8 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 9 Oct 2009 22:18:12 +0000 Subject: Blackfin: convert DMA mutex to an atomic and drop redundant code The DMA channel status field was encoding redundant info wrt the DMA MMR config register, and it was doing an incomplete job of checking all DMA channels (some drivers write directly to the config register). So drop the tristate field in favor of a binary atomic field. This simplifies the code in general, removes the implicit need for sleeping, and forces the suspend code to handle all channels properly. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index c9a5962..e3c0dfa 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -19,11 +20,6 @@ * Generic DMA Declarations * ****************************************************************************/ -enum dma_chan_status { - DMA_CHANNEL_FREE, - DMA_CHANNEL_REQUESTED, - DMA_CHANNEL_ENABLED, -}; /*------------------------- * config reg bits value @@ -104,11 +100,9 @@ struct dma_register { }; -struct mutex; struct dma_channel { - struct mutex dmalock; const char *device_id; - enum dma_chan_status chan_status; + atomic_t chan_status; volatile struct dma_register *regs; struct dmasg *sg; /* large mode descriptor */ unsigned int irq; @@ -220,24 +214,19 @@ static inline void set_dma_sg(unsigned int channel, struct dmasg *sg, int ndsize static inline int dma_channel_active(unsigned int channel) { - if (dma_ch[channel].chan_status == DMA_CHANNEL_FREE) - return 0; - else - return 1; + return atomic_read(&dma_ch[channel].chan_status); } static inline void disable_dma(unsigned int channel) { dma_ch[channel].regs->cfg &= ~DMAEN; SSYNC(); - dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED; } static inline void enable_dma(unsigned int channel) { dma_ch[channel].regs->curr_x_count = 0; dma_ch[channel].regs->curr_y_count = 0; dma_ch[channel].regs->cfg |= DMAEN; - dma_ch[channel].chan_status = DMA_CHANNEL_ENABLED; } void free_dma(unsigned int channel); int request_dma(unsigned int channel, const char *device_id); diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index 3946aff..639dcee 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -37,9 +37,8 @@ static int __init blackfin_dma_init(void) printk(KERN_INFO "Blackfin DMA Controller\n"); for (i = 0; i < MAX_DMA_CHANNELS; i++) { - dma_ch[i].chan_status = DMA_CHANNEL_FREE; + atomic_set(&dma_ch[i].chan_status, 0); dma_ch[i].regs = dma_io_base_addr[i]; - mutex_init(&(dma_ch[i].dmalock)); } /* Mark MEMDMA Channel 0 as requested since we're using it internally */ request_dma(CH_MEM_STREAM0_DEST, "Blackfin dma_memcpy"); @@ -60,7 +59,7 @@ static int proc_dma_show(struct seq_file *m, void *v) int i; for (i = 0; i < MAX_DMA_CHANNELS; ++i) - if (dma_ch[i].chan_status != DMA_CHANNEL_FREE) + if (dma_channel_active(i)) seq_printf(m, "%2d: %s\n", i, dma_ch[i].device_id); return 0; @@ -107,20 +106,11 @@ int request_dma(unsigned int channel, const char *device_id) } #endif - mutex_lock(&(dma_ch[channel].dmalock)); - - if ((dma_ch[channel].chan_status == DMA_CHANNEL_REQUESTED) - || (dma_ch[channel].chan_status == DMA_CHANNEL_ENABLED)) { - mutex_unlock(&(dma_ch[channel].dmalock)); + if (atomic_cmpxchg(&dma_ch[channel].chan_status, 0, 1)) { pr_debug("DMA CHANNEL IN USE \n"); return -EBUSY; - } else { - dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED; - pr_debug("DMA CHANNEL IS ALLOCATED \n"); } - mutex_unlock(&(dma_ch[channel].dmalock)); - #ifdef CONFIG_BF54x if (channel >= CH_UART2_RX && channel <= CH_UART3_TX) { unsigned int per_map; @@ -149,7 +139,7 @@ EXPORT_SYMBOL(request_dma); int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data) { BUG_ON(channel >= MAX_DMA_CHANNELS || - dma_ch[channel].chan_status == DMA_CHANNEL_FREE); + !atomic_read(&dma_ch[channel].chan_status)); if (callback != NULL) { int ret; @@ -184,7 +174,7 @@ void free_dma(unsigned int channel) { pr_debug("freedma() : BEGIN \n"); BUG_ON(channel >= MAX_DMA_CHANNELS || - dma_ch[channel].chan_status == DMA_CHANNEL_FREE); + !atomic_read(&dma_ch[channel].chan_status)); /* Halt the DMA */ disable_dma(channel); @@ -194,9 +184,7 @@ void free_dma(unsigned int channel) free_irq(dma_ch[channel].irq, dma_ch[channel].data); /* Clear the DMA Variable in the Channel */ - mutex_lock(&(dma_ch[channel].dmalock)); - dma_ch[channel].chan_status = DMA_CHANNEL_FREE; - mutex_unlock(&(dma_ch[channel].dmalock)); + atomic_set(&dma_ch[channel].chan_status, 0); pr_debug("freedma() : END \n"); } @@ -210,13 +198,14 @@ int blackfin_dma_suspend(void) { int i; - for (i = 0; i < MAX_DMA_SUSPEND_CHANNELS; ++i) { - if (dma_ch[i].chan_status == DMA_CHANNEL_ENABLED) { + for (i = 0; i < MAX_DMA_CHANNELS; ++i) { + if (dma_ch[i].regs->cfg & DMAEN) { printk(KERN_ERR "DMA Channel %d failed to suspend\n", i); return -EBUSY; } - dma_ch[i].saved_peripheral_map = dma_ch[i].regs->peripheral_map; + if (i < MAX_DMA_SUSPEND_CHANNELS) + dma_ch[i].saved_peripheral_map = dma_ch[i].regs->peripheral_map; } return 0; -- cgit v0.10.2 From 17a1b5e3748f2d890d24c7eb3b1c11de2e0b9a00 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 13 Oct 2009 12:50:05 +0000 Subject: Blackfin: coreb: switched to unlocked_ioctl We don't need the BKL and now people will stop looking at this. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c index 1e60a92..deb2271 100644 --- a/arch/blackfin/mach-bf561/coreb.c +++ b/arch/blackfin/mach-bf561/coreb.c @@ -22,8 +22,8 @@ #define CMD_COREB_STOP 3 #define CMD_COREB_RESET 4 -static int -coreb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static long +coreb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int ret = 0; @@ -49,8 +49,8 @@ coreb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned l } static const struct file_operations coreb_fops = { - .owner = THIS_MODULE, - .ioctl = coreb_ioctl, + .owner = THIS_MODULE, + .unlocked_ioctl = coreb_ioctl, }; static struct miscdevice coreb_dev = { -- cgit v0.10.2 From aaa225e0aa96691964a5f0518c3c16b954d400cb Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Wed, 14 Oct 2009 13:43:53 +0000 Subject: Blackfin: punt cache lock documentation The cache lock code was unused and punted, so punt the documentation too. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/Documentation/blackfin/00-INDEX b/Documentation/blackfin/00-INDEX index d6840a9..c34e124 100644 --- a/Documentation/blackfin/00-INDEX +++ b/Documentation/blackfin/00-INDEX @@ -1,9 +1,6 @@ 00-INDEX - This file -cache-lock.txt - - HOWTO for blackfin cache locking. - cachefeatures.txt - Supported cache features. diff --git a/Documentation/blackfin/cache-lock.txt b/Documentation/blackfin/cache-lock.txt deleted file mode 100644 index 88ba1e6..0000000 --- a/Documentation/blackfin/cache-lock.txt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * File: Documentation/blackfin/cache-lock.txt - * Based on: - * Author: - * - * Created: - * Description: This file contains the simple DMA Implementation for Blackfin - * - * Rev: $Id: cache-lock.txt 2384 2006-11-01 04:12:43Z magicyang $ - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - */ - -How to lock your code in cache in uClinux/blackfin --------------------------------------------------- - -There are only a few steps required to lock your code into the cache. -Currently you can lock the code by Way. - -Below are the interface provided for locking the cache. - - -1. cache_grab_lock(int Ways); - -This function grab the lock for locking your code into the cache specified -by Ways. - - -2. cache_lock(int Ways); - -This function should be called after your critical code has been executed. -Once the critical code exits, the code is now loaded into the cache. This -function locks the code into the cache. - - -So, the example sequence will be: - - cache_grab_lock(WAY0_L); /* Grab the lock */ - - critical_code(); /* Execute the code of interest */ - - cache_lock(WAY0_L); /* Lock the cache */ - -Where WAY0_L signifies WAY0 locking. diff --git a/Documentation/blackfin/cachefeatures.txt b/Documentation/blackfin/cachefeatures.txt index 0fbec23..75de51f 100644 --- a/Documentation/blackfin/cachefeatures.txt +++ b/Documentation/blackfin/cachefeatures.txt @@ -41,16 +41,6 @@ icplb_flush(); dcplb_flush(); - - Locking the cache. - - cache_grab_lock(); - cache_lock(); - - Please refer linux-2.6.x/Documentation/blackfin/cache-lock.txt for how to - lock the cache. - - Locking the cache is optional feature. - - Miscellaneous cache functions. flush_cache_all(); -- cgit v0.10.2 From 5da8a3dc480f0424e7bcb9e41b140b1e70c5fdfb Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 15 Oct 2009 04:22:21 +0000 Subject: Blackfin: rename BF542 host dma defines All the other BF54x parts had these defines renamed to avoid collision, but it looks the BF542 was missed somehow. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf548/include/mach/defBF544.h b/arch/blackfin/mach-bf548/include/mach/defBF544.h index 39f588d..f916c52 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF544.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF544.h @@ -624,9 +624,9 @@ #define DMA_READY 0x1 /* DMA Ready */ #define FIFOFULL 0x2 /* FIFO Full */ #define FIFOEMPTY 0x4 /* FIFO Empty */ -#define COMPLETE 0x8 /* DMA Complete */ +#define DMA_COMPLETE 0x8 /* DMA Complete */ #define HSHK 0x10 /* Host Handshake */ -#define TIMEOUT 0x20 /* Host Timeout */ +#define HSTIMEOUT 0x20 /* Host Timeout */ #define HIRQ 0x40 /* Host Interrupt Request */ #define ALLOW_CNFG 0x80 /* Allow New Configuration */ #define DMA_DIR 0x100 /* DMA Direction */ -- cgit v0.10.2 From 4ed250a563203efd98db05905839269e145785d5 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 20 Oct 2009 18:31:46 +0000 Subject: Blackfin: fix some BF547 header copy & paste typos Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF547.h b/arch/blackfin/mach-bf548/include/mach/cdefBF547.h index 4234215..bc650e6 100644 --- a/arch/blackfin/mach-bf548/include/mach/cdefBF547.h +++ b/arch/blackfin/mach-bf548/include/mach/cdefBF547.h @@ -4,21 +4,21 @@ * Licensed under the GPL-2 or later. */ -#ifndef _CDEF_BF548_H -#define _CDEF_BF548_H +#ifndef _CDEF_BF547_H +#define _CDEF_BF547_H /* include all Core registers and bit definitions */ -#include "defBF548.h" +#include "defBF547.h" /* include core sbfin_read_()ecific register pointer definitions */ #include -/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF548 */ +/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF547 */ /* include cdefBF54x_base.h for the set of #defines that are common to all ADSP-BF54x bfin_read_()rocessors */ #include "cdefBF54x_base.h" -/* The following are the #defines needed by ADSP-BF548 that are not in the common header */ +/* The following are the #defines needed by ADSP-BF547 that are not in the common header */ /* Timer Registers */ @@ -805,4 +805,4 @@ #define bfin_read_HMDMA1_BCOUNT() bfin_read16(HMDMA1_BCOUNT) #define bfin_write_HMDMA1_BCOUNT(val) bfin_write16(HMDMA1_BCOUNT, val) -#endif /* _CDEF_BF548_H */ +#endif /* _CDEF_BF547_H */ diff --git a/arch/blackfin/mach-bf548/include/mach/defBF547.h b/arch/blackfin/mach-bf548/include/mach/defBF547.h index c4dcf30..72c3436 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF547.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF547.h @@ -4,18 +4,18 @@ * Licensed under the ADI BSD license or the GPL-2 (or later) */ -#ifndef _DEF_BF548_H -#define _DEF_BF548_H +#ifndef _DEF_BF547_H +#define _DEF_BF547_H /* Include all Core registers and bit definitions */ #include -/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF548 */ +/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF547 */ /* Include defBF54x_base.h for the set of #defines that are common to all ADSP-BF54x processors */ #include "defBF54x_base.h" -/* The following are the #defines needed by ADSP-BF548 that are not in the common header */ +/* The following are the #defines needed by ADSP-BF547 that are not in the common header */ /* Timer Registers */ @@ -1217,4 +1217,4 @@ /* ******************************************* */ -#endif /* _DEF_BF548_H */ +#endif /* _DEF_BF547_H */ -- cgit v0.10.2 From 60883e28b3dc6a85fca6f45f2306599523657a49 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 20 Oct 2009 17:30:58 +0000 Subject: Blackfin: unify BF547/8/9 headers No point in duplicating entire lists when we can simply tail into other parts for most of the MMRs. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF548.h b/arch/blackfin/mach-bf548/include/mach/cdefBF548.h index df84180..3523e08 100644 --- a/arch/blackfin/mach-bf548/include/mach/cdefBF548.h +++ b/arch/blackfin/mach-bf548/include/mach/cdefBF548.h @@ -18,165 +18,8 @@ /* include cdefBF54x_base.h for the set of #defines that are common to all ADSP-BF54x bfin_read_()rocessors */ #include "cdefBF54x_base.h" -/* The following are the #defines needed by ADSP-BF548 that are not in the common header */ - -/* Timer Registers */ - -#define bfin_read_TIMER8_CONFIG() bfin_read16(TIMER8_CONFIG) -#define bfin_write_TIMER8_CONFIG(val) bfin_write16(TIMER8_CONFIG, val) -#define bfin_read_TIMER8_COUNTER() bfin_read32(TIMER8_COUNTER) -#define bfin_write_TIMER8_COUNTER(val) bfin_write32(TIMER8_COUNTER, val) -#define bfin_read_TIMER8_PERIOD() bfin_read32(TIMER8_PERIOD) -#define bfin_write_TIMER8_PERIOD(val) bfin_write32(TIMER8_PERIOD, val) -#define bfin_read_TIMER8_WIDTH() bfin_read32(TIMER8_WIDTH) -#define bfin_write_TIMER8_WIDTH(val) bfin_write32(TIMER8_WIDTH, val) -#define bfin_read_TIMER9_CONFIG() bfin_read16(TIMER9_CONFIG) -#define bfin_write_TIMER9_CONFIG(val) bfin_write16(TIMER9_CONFIG, val) -#define bfin_read_TIMER9_COUNTER() bfin_read32(TIMER9_COUNTER) -#define bfin_write_TIMER9_COUNTER(val) bfin_write32(TIMER9_COUNTER, val) -#define bfin_read_TIMER9_PERIOD() bfin_read32(TIMER9_PERIOD) -#define bfin_write_TIMER9_PERIOD(val) bfin_write32(TIMER9_PERIOD, val) -#define bfin_read_TIMER9_WIDTH() bfin_read32(TIMER9_WIDTH) -#define bfin_write_TIMER9_WIDTH(val) bfin_write32(TIMER9_WIDTH, val) -#define bfin_read_TIMER10_CONFIG() bfin_read16(TIMER10_CONFIG) -#define bfin_write_TIMER10_CONFIG(val) bfin_write16(TIMER10_CONFIG, val) -#define bfin_read_TIMER10_COUNTER() bfin_read32(TIMER10_COUNTER) -#define bfin_write_TIMER10_COUNTER(val) bfin_write32(TIMER10_COUNTER, val) -#define bfin_read_TIMER10_PERIOD() bfin_read32(TIMER10_PERIOD) -#define bfin_write_TIMER10_PERIOD(val) bfin_write32(TIMER10_PERIOD, val) -#define bfin_read_TIMER10_WIDTH() bfin_read32(TIMER10_WIDTH) -#define bfin_write_TIMER10_WIDTH(val) bfin_write32(TIMER10_WIDTH, val) - -/* Timer Groubfin_read_() of 3 */ - -#define bfin_read_TIMER_ENABLE1() bfin_read16(TIMER_ENABLE1) -#define bfin_write_TIMER_ENABLE1(val) bfin_write16(TIMER_ENABLE1, val) -#define bfin_read_TIMER_DISABLE1() bfin_read16(TIMER_DISABLE1) -#define bfin_write_TIMER_DISABLE1(val) bfin_write16(TIMER_DISABLE1, val) -#define bfin_read_TIMER_STATUS1() bfin_read32(TIMER_STATUS1) -#define bfin_write_TIMER_STATUS1(val) bfin_write32(TIMER_STATUS1, val) - -/* SPORT0 Registers */ - -#define bfin_read_SPORT0_TCR1() bfin_read16(SPORT0_TCR1) -#define bfin_write_SPORT0_TCR1(val) bfin_write16(SPORT0_TCR1, val) -#define bfin_read_SPORT0_TCR2() bfin_read16(SPORT0_TCR2) -#define bfin_write_SPORT0_TCR2(val) bfin_write16(SPORT0_TCR2, val) -#define bfin_read_SPORT0_TCLKDIV() bfin_read16(SPORT0_TCLKDIV) -#define bfin_write_SPORT0_TCLKDIV(val) bfin_write16(SPORT0_TCLKDIV, val) -#define bfin_read_SPORT0_TFSDIV() bfin_read16(SPORT0_TFSDIV) -#define bfin_write_SPORT0_TFSDIV(val) bfin_write16(SPORT0_TFSDIV, val) -#define bfin_read_SPORT0_TX() bfin_read32(SPORT0_TX) -#define bfin_write_SPORT0_TX(val) bfin_write32(SPORT0_TX, val) -#define bfin_read_SPORT0_RX() bfin_read32(SPORT0_RX) -#define bfin_write_SPORT0_RX(val) bfin_write32(SPORT0_RX, val) -#define bfin_read_SPORT0_RCR1() bfin_read16(SPORT0_RCR1) -#define bfin_write_SPORT0_RCR1(val) bfin_write16(SPORT0_RCR1, val) -#define bfin_read_SPORT0_RCR2() bfin_read16(SPORT0_RCR2) -#define bfin_write_SPORT0_RCR2(val) bfin_write16(SPORT0_RCR2, val) -#define bfin_read_SPORT0_RCLKDIV() bfin_read16(SPORT0_RCLKDIV) -#define bfin_write_SPORT0_RCLKDIV(val) bfin_write16(SPORT0_RCLKDIV, val) -#define bfin_read_SPORT0_RFSDIV() bfin_read16(SPORT0_RFSDIV) -#define bfin_write_SPORT0_RFSDIV(val) bfin_write16(SPORT0_RFSDIV, val) -#define bfin_read_SPORT0_STAT() bfin_read16(SPORT0_STAT) -#define bfin_write_SPORT0_STAT(val) bfin_write16(SPORT0_STAT, val) -#define bfin_read_SPORT0_CHNL() bfin_read16(SPORT0_CHNL) -#define bfin_write_SPORT0_CHNL(val) bfin_write16(SPORT0_CHNL, val) -#define bfin_read_SPORT0_MCMC1() bfin_read16(SPORT0_MCMC1) -#define bfin_write_SPORT0_MCMC1(val) bfin_write16(SPORT0_MCMC1, val) -#define bfin_read_SPORT0_MCMC2() bfin_read16(SPORT0_MCMC2) -#define bfin_write_SPORT0_MCMC2(val) bfin_write16(SPORT0_MCMC2, val) -#define bfin_read_SPORT0_MTCS0() bfin_read32(SPORT0_MTCS0) -#define bfin_write_SPORT0_MTCS0(val) bfin_write32(SPORT0_MTCS0, val) -#define bfin_read_SPORT0_MTCS1() bfin_read32(SPORT0_MTCS1) -#define bfin_write_SPORT0_MTCS1(val) bfin_write32(SPORT0_MTCS1, val) -#define bfin_read_SPORT0_MTCS2() bfin_read32(SPORT0_MTCS2) -#define bfin_write_SPORT0_MTCS2(val) bfin_write32(SPORT0_MTCS2, val) -#define bfin_read_SPORT0_MTCS3() bfin_read32(SPORT0_MTCS3) -#define bfin_write_SPORT0_MTCS3(val) bfin_write32(SPORT0_MTCS3, val) -#define bfin_read_SPORT0_MRCS0() bfin_read32(SPORT0_MRCS0) -#define bfin_write_SPORT0_MRCS0(val) bfin_write32(SPORT0_MRCS0, val) -#define bfin_read_SPORT0_MRCS1() bfin_read32(SPORT0_MRCS1) -#define bfin_write_SPORT0_MRCS1(val) bfin_write32(SPORT0_MRCS1, val) -#define bfin_read_SPORT0_MRCS2() bfin_read32(SPORT0_MRCS2) -#define bfin_write_SPORT0_MRCS2(val) bfin_write32(SPORT0_MRCS2, val) -#define bfin_read_SPORT0_MRCS3() bfin_read32(SPORT0_MRCS3) -#define bfin_write_SPORT0_MRCS3(val) bfin_write32(SPORT0_MRCS3, val) - -/* EPPI0 Registers */ - -#define bfin_read_EPPI0_STATUS() bfin_read16(EPPI0_STATUS) -#define bfin_write_EPPI0_STATUS(val) bfin_write16(EPPI0_STATUS, val) -#define bfin_read_EPPI0_HCOUNT() bfin_read16(EPPI0_HCOUNT) -#define bfin_write_EPPI0_HCOUNT(val) bfin_write16(EPPI0_HCOUNT, val) -#define bfin_read_EPPI0_HDELAY() bfin_read16(EPPI0_HDELAY) -#define bfin_write_EPPI0_HDELAY(val) bfin_write16(EPPI0_HDELAY, val) -#define bfin_read_EPPI0_VCOUNT() bfin_read16(EPPI0_VCOUNT) -#define bfin_write_EPPI0_VCOUNT(val) bfin_write16(EPPI0_VCOUNT, val) -#define bfin_read_EPPI0_VDELAY() bfin_read16(EPPI0_VDELAY) -#define bfin_write_EPPI0_VDELAY(val) bfin_write16(EPPI0_VDELAY, val) -#define bfin_read_EPPI0_FRAME() bfin_read16(EPPI0_FRAME) -#define bfin_write_EPPI0_FRAME(val) bfin_write16(EPPI0_FRAME, val) -#define bfin_read_EPPI0_LINE() bfin_read16(EPPI0_LINE) -#define bfin_write_EPPI0_LINE(val) bfin_write16(EPPI0_LINE, val) -#define bfin_read_EPPI0_CLKDIV() bfin_read16(EPPI0_CLKDIV) -#define bfin_write_EPPI0_CLKDIV(val) bfin_write16(EPPI0_CLKDIV, val) -#define bfin_read_EPPI0_CONTROL() bfin_read32(EPPI0_CONTROL) -#define bfin_write_EPPI0_CONTROL(val) bfin_write32(EPPI0_CONTROL, val) -#define bfin_read_EPPI0_FS1W_HBL() bfin_read32(EPPI0_FS1W_HBL) -#define bfin_write_EPPI0_FS1W_HBL(val) bfin_write32(EPPI0_FS1W_HBL, val) -#define bfin_read_EPPI0_FS1P_AVPL() bfin_read32(EPPI0_FS1P_AVPL) -#define bfin_write_EPPI0_FS1P_AVPL(val) bfin_write32(EPPI0_FS1P_AVPL, val) -#define bfin_read_EPPI0_FS2W_LVB() bfin_read32(EPPI0_FS2W_LVB) -#define bfin_write_EPPI0_FS2W_LVB(val) bfin_write32(EPPI0_FS2W_LVB, val) -#define bfin_read_EPPI0_FS2P_LAVF() bfin_read32(EPPI0_FS2P_LAVF) -#define bfin_write_EPPI0_FS2P_LAVF(val) bfin_write32(EPPI0_FS2P_LAVF, val) -#define bfin_read_EPPI0_CLIP() bfin_read32(EPPI0_CLIP) -#define bfin_write_EPPI0_CLIP(val) bfin_write32(EPPI0_CLIP, val) - -/* UART2 Registers */ - -#define bfin_read_UART2_DLL() bfin_read16(UART2_DLL) -#define bfin_write_UART2_DLL(val) bfin_write16(UART2_DLL, val) -#define bfin_read_UART2_DLH() bfin_read16(UART2_DLH) -#define bfin_write_UART2_DLH(val) bfin_write16(UART2_DLH, val) -#define bfin_read_UART2_GCTL() bfin_read16(UART2_GCTL) -#define bfin_write_UART2_GCTL(val) bfin_write16(UART2_GCTL, val) -#define bfin_read_UART2_LCR() bfin_read16(UART2_LCR) -#define bfin_write_UART2_LCR(val) bfin_write16(UART2_LCR, val) -#define bfin_read_UART2_MCR() bfin_read16(UART2_MCR) -#define bfin_write_UART2_MCR(val) bfin_write16(UART2_MCR, val) -#define bfin_read_UART2_LSR() bfin_read16(UART2_LSR) -#define bfin_write_UART2_LSR(val) bfin_write16(UART2_LSR, val) -#define bfin_read_UART2_MSR() bfin_read16(UART2_MSR) -#define bfin_write_UART2_MSR(val) bfin_write16(UART2_MSR, val) -#define bfin_read_UART2_SCR() bfin_read16(UART2_SCR) -#define bfin_write_UART2_SCR(val) bfin_write16(UART2_SCR, val) -#define bfin_read_UART2_IER_SET() bfin_read16(UART2_IER_SET) -#define bfin_write_UART2_IER_SET(val) bfin_write16(UART2_IER_SET, val) -#define bfin_read_UART2_IER_CLEAR() bfin_read16(UART2_IER_CLEAR) -#define bfin_write_UART2_IER_CLEAR(val) bfin_write16(UART2_IER_CLEAR, val) -#define bfin_read_UART2_RBR() bfin_read16(UART2_RBR) -#define bfin_write_UART2_RBR(val) bfin_write16(UART2_RBR, val) - -/* Two Wire Interface Registers (TWI1) */ - -/* SPI2 Registers */ - -#define bfin_read_SPI2_CTL() bfin_read16(SPI2_CTL) -#define bfin_write_SPI2_CTL(val) bfin_write16(SPI2_CTL, val) -#define bfin_read_SPI2_FLG() bfin_read16(SPI2_FLG) -#define bfin_write_SPI2_FLG(val) bfin_write16(SPI2_FLG, val) -#define bfin_read_SPI2_STAT() bfin_read16(SPI2_STAT) -#define bfin_write_SPI2_STAT(val) bfin_write16(SPI2_STAT, val) -#define bfin_read_SPI2_TDBR() bfin_read16(SPI2_TDBR) -#define bfin_write_SPI2_TDBR(val) bfin_write16(SPI2_TDBR, val) -#define bfin_read_SPI2_RDBR() bfin_read16(SPI2_RDBR) -#define bfin_write_SPI2_RDBR(val) bfin_write16(SPI2_RDBR, val) -#define bfin_read_SPI2_BAUD() bfin_read16(SPI2_BAUD) -#define bfin_write_SPI2_BAUD(val) bfin_write16(SPI2_BAUD, val) -#define bfin_read_SPI2_SHADOW() bfin_read16(SPI2_SHADOW) -#define bfin_write_SPI2_SHADOW(val) bfin_write16(SPI2_SHADOW, val) +/* The BF548 is like the BF547, but has additional CANs */ +#include "cdefBF547.h" /* CAN Controller 1 Config 1 Registers */ @@ -923,631 +766,4 @@ #define bfin_read_CAN1_MB31_ID1() bfin_read16(CAN1_MB31_ID1) #define bfin_write_CAN1_MB31_ID1(val) bfin_write16(CAN1_MB31_ID1, val) -/* ATAPI Registers */ - -#define bfin_read_ATAPI_CONTROL() bfin_read16(ATAPI_CONTROL) -#define bfin_write_ATAPI_CONTROL(val) bfin_write16(ATAPI_CONTROL, val) -#define bfin_read_ATAPI_STATUS() bfin_read16(ATAPI_STATUS) -#define bfin_write_ATAPI_STATUS(val) bfin_write16(ATAPI_STATUS, val) -#define bfin_read_ATAPI_DEV_ADDR() bfin_read16(ATAPI_DEV_ADDR) -#define bfin_write_ATAPI_DEV_ADDR(val) bfin_write16(ATAPI_DEV_ADDR, val) -#define bfin_read_ATAPI_DEV_TXBUF() bfin_read16(ATAPI_DEV_TXBUF) -#define bfin_write_ATAPI_DEV_TXBUF(val) bfin_write16(ATAPI_DEV_TXBUF, val) -#define bfin_read_ATAPI_DEV_RXBUF() bfin_read16(ATAPI_DEV_RXBUF) -#define bfin_write_ATAPI_DEV_RXBUF(val) bfin_write16(ATAPI_DEV_RXBUF, val) -#define bfin_read_ATAPI_INT_MASK() bfin_read16(ATAPI_INT_MASK) -#define bfin_write_ATAPI_INT_MASK(val) bfin_write16(ATAPI_INT_MASK, val) -#define bfin_read_ATAPI_INT_STATUS() bfin_read16(ATAPI_INT_STATUS) -#define bfin_write_ATAPI_INT_STATUS(val) bfin_write16(ATAPI_INT_STATUS, val) -#define bfin_read_ATAPI_XFER_LEN() bfin_read16(ATAPI_XFER_LEN) -#define bfin_write_ATAPI_XFER_LEN(val) bfin_write16(ATAPI_XFER_LEN, val) -#define bfin_read_ATAPI_LINE_STATUS() bfin_read16(ATAPI_LINE_STATUS) -#define bfin_write_ATAPI_LINE_STATUS(val) bfin_write16(ATAPI_LINE_STATUS, val) -#define bfin_read_ATAPI_SM_STATE() bfin_read16(ATAPI_SM_STATE) -#define bfin_write_ATAPI_SM_STATE(val) bfin_write16(ATAPI_SM_STATE, val) -#define bfin_read_ATAPI_TERMINATE() bfin_read16(ATAPI_TERMINATE) -#define bfin_write_ATAPI_TERMINATE(val) bfin_write16(ATAPI_TERMINATE, val) -#define bfin_read_ATAPI_PIO_TFRCNT() bfin_read16(ATAPI_PIO_TFRCNT) -#define bfin_write_ATAPI_PIO_TFRCNT(val) bfin_write16(ATAPI_PIO_TFRCNT, val) -#define bfin_read_ATAPI_DMA_TFRCNT() bfin_read16(ATAPI_DMA_TFRCNT) -#define bfin_write_ATAPI_DMA_TFRCNT(val) bfin_write16(ATAPI_DMA_TFRCNT, val) -#define bfin_read_ATAPI_UMAIN_TFRCNT() bfin_read16(ATAPI_UMAIN_TFRCNT) -#define bfin_write_ATAPI_UMAIN_TFRCNT(val) bfin_write16(ATAPI_UMAIN_TFRCNT, val) -#define bfin_read_ATAPI_UDMAOUT_TFRCNT() bfin_read16(ATAPI_UDMAOUT_TFRCNT) -#define bfin_write_ATAPI_UDMAOUT_TFRCNT(val) bfin_write16(ATAPI_UDMAOUT_TFRCNT, val) -#define bfin_read_ATAPI_REG_TIM_0() bfin_read16(ATAPI_REG_TIM_0) -#define bfin_write_ATAPI_REG_TIM_0(val) bfin_write16(ATAPI_REG_TIM_0, val) -#define bfin_read_ATAPI_PIO_TIM_0() bfin_read16(ATAPI_PIO_TIM_0) -#define bfin_write_ATAPI_PIO_TIM_0(val) bfin_write16(ATAPI_PIO_TIM_0, val) -#define bfin_read_ATAPI_PIO_TIM_1() bfin_read16(ATAPI_PIO_TIM_1) -#define bfin_write_ATAPI_PIO_TIM_1(val) bfin_write16(ATAPI_PIO_TIM_1, val) -#define bfin_read_ATAPI_MULTI_TIM_0() bfin_read16(ATAPI_MULTI_TIM_0) -#define bfin_write_ATAPI_MULTI_TIM_0(val) bfin_write16(ATAPI_MULTI_TIM_0, val) -#define bfin_read_ATAPI_MULTI_TIM_1() bfin_read16(ATAPI_MULTI_TIM_1) -#define bfin_write_ATAPI_MULTI_TIM_1(val) bfin_write16(ATAPI_MULTI_TIM_1, val) -#define bfin_read_ATAPI_MULTI_TIM_2() bfin_read16(ATAPI_MULTI_TIM_2) -#define bfin_write_ATAPI_MULTI_TIM_2(val) bfin_write16(ATAPI_MULTI_TIM_2, val) -#define bfin_read_ATAPI_ULTRA_TIM_0() bfin_read16(ATAPI_ULTRA_TIM_0) -#define bfin_write_ATAPI_ULTRA_TIM_0(val) bfin_write16(ATAPI_ULTRA_TIM_0, val) -#define bfin_read_ATAPI_ULTRA_TIM_1() bfin_read16(ATAPI_ULTRA_TIM_1) -#define bfin_write_ATAPI_ULTRA_TIM_1(val) bfin_write16(ATAPI_ULTRA_TIM_1, val) -#define bfin_read_ATAPI_ULTRA_TIM_2() bfin_read16(ATAPI_ULTRA_TIM_2) -#define bfin_write_ATAPI_ULTRA_TIM_2(val) bfin_write16(ATAPI_ULTRA_TIM_2, val) -#define bfin_read_ATAPI_ULTRA_TIM_3() bfin_read16(ATAPI_ULTRA_TIM_3) -#define bfin_write_ATAPI_ULTRA_TIM_3(val) bfin_write16(ATAPI_ULTRA_TIM_3, val) - -/* SDH Registers */ - -#define bfin_read_SDH_PWR_CTL() bfin_read16(SDH_PWR_CTL) -#define bfin_write_SDH_PWR_CTL(val) bfin_write16(SDH_PWR_CTL, val) -#define bfin_read_SDH_CLK_CTL() bfin_read16(SDH_CLK_CTL) -#define bfin_write_SDH_CLK_CTL(val) bfin_write16(SDH_CLK_CTL, val) -#define bfin_read_SDH_ARGUMENT() bfin_read32(SDH_ARGUMENT) -#define bfin_write_SDH_ARGUMENT(val) bfin_write32(SDH_ARGUMENT, val) -#define bfin_read_SDH_COMMAND() bfin_read16(SDH_COMMAND) -#define bfin_write_SDH_COMMAND(val) bfin_write16(SDH_COMMAND, val) -#define bfin_read_SDH_RESP_CMD() bfin_read16(SDH_RESP_CMD) -#define bfin_write_SDH_RESP_CMD(val) bfin_write16(SDH_RESP_CMD, val) -#define bfin_read_SDH_RESPONSE0() bfin_read32(SDH_RESPONSE0) -#define bfin_write_SDH_RESPONSE0(val) bfin_write32(SDH_RESPONSE0, val) -#define bfin_read_SDH_RESPONSE1() bfin_read32(SDH_RESPONSE1) -#define bfin_write_SDH_RESPONSE1(val) bfin_write32(SDH_RESPONSE1, val) -#define bfin_read_SDH_RESPONSE2() bfin_read32(SDH_RESPONSE2) -#define bfin_write_SDH_RESPONSE2(val) bfin_write32(SDH_RESPONSE2, val) -#define bfin_read_SDH_RESPONSE3() bfin_read32(SDH_RESPONSE3) -#define bfin_write_SDH_RESPONSE3(val) bfin_write32(SDH_RESPONSE3, val) -#define bfin_read_SDH_DATA_TIMER() bfin_read32(SDH_DATA_TIMER) -#define bfin_write_SDH_DATA_TIMER(val) bfin_write32(SDH_DATA_TIMER, val) -#define bfin_read_SDH_DATA_LGTH() bfin_read16(SDH_DATA_LGTH) -#define bfin_write_SDH_DATA_LGTH(val) bfin_write16(SDH_DATA_LGTH, val) -#define bfin_read_SDH_DATA_CTL() bfin_read16(SDH_DATA_CTL) -#define bfin_write_SDH_DATA_CTL(val) bfin_write16(SDH_DATA_CTL, val) -#define bfin_read_SDH_DATA_CNT() bfin_read16(SDH_DATA_CNT) -#define bfin_write_SDH_DATA_CNT(val) bfin_write16(SDH_DATA_CNT, val) -#define bfin_read_SDH_STATUS() bfin_read32(SDH_STATUS) -#define bfin_write_SDH_STATUS(val) bfin_write32(SDH_STATUS, val) -#define bfin_read_SDH_STATUS_CLR() bfin_read16(SDH_STATUS_CLR) -#define bfin_write_SDH_STATUS_CLR(val) bfin_write16(SDH_STATUS_CLR, val) -#define bfin_read_SDH_MASK0() bfin_read32(SDH_MASK0) -#define bfin_write_SDH_MASK0(val) bfin_write32(SDH_MASK0, val) -#define bfin_read_SDH_MASK1() bfin_read32(SDH_MASK1) -#define bfin_write_SDH_MASK1(val) bfin_write32(SDH_MASK1, val) -#define bfin_read_SDH_FIFO_CNT() bfin_read16(SDH_FIFO_CNT) -#define bfin_write_SDH_FIFO_CNT(val) bfin_write16(SDH_FIFO_CNT, val) -#define bfin_read_SDH_FIFO() bfin_read32(SDH_FIFO) -#define bfin_write_SDH_FIFO(val) bfin_write32(SDH_FIFO, val) -#define bfin_read_SDH_E_STATUS() bfin_read16(SDH_E_STATUS) -#define bfin_write_SDH_E_STATUS(val) bfin_write16(SDH_E_STATUS, val) -#define bfin_read_SDH_E_MASK() bfin_read16(SDH_E_MASK) -#define bfin_write_SDH_E_MASK(val) bfin_write16(SDH_E_MASK, val) -#define bfin_read_SDH_CFG() bfin_read16(SDH_CFG) -#define bfin_write_SDH_CFG(val) bfin_write16(SDH_CFG, val) -#define bfin_read_SDH_RD_WAIT_EN() bfin_read16(SDH_RD_WAIT_EN) -#define bfin_write_SDH_RD_WAIT_EN(val) bfin_write16(SDH_RD_WAIT_EN, val) -#define bfin_read_SDH_PID0() bfin_read16(SDH_PID0) -#define bfin_write_SDH_PID0(val) bfin_write16(SDH_PID0, val) -#define bfin_read_SDH_PID1() bfin_read16(SDH_PID1) -#define bfin_write_SDH_PID1(val) bfin_write16(SDH_PID1, val) -#define bfin_read_SDH_PID2() bfin_read16(SDH_PID2) -#define bfin_write_SDH_PID2(val) bfin_write16(SDH_PID2, val) -#define bfin_read_SDH_PID3() bfin_read16(SDH_PID3) -#define bfin_write_SDH_PID3(val) bfin_write16(SDH_PID3, val) -#define bfin_read_SDH_PID4() bfin_read16(SDH_PID4) -#define bfin_write_SDH_PID4(val) bfin_write16(SDH_PID4, val) -#define bfin_read_SDH_PID5() bfin_read16(SDH_PID5) -#define bfin_write_SDH_PID5(val) bfin_write16(SDH_PID5, val) -#define bfin_read_SDH_PID6() bfin_read16(SDH_PID6) -#define bfin_write_SDH_PID6(val) bfin_write16(SDH_PID6, val) -#define bfin_read_SDH_PID7() bfin_read16(SDH_PID7) -#define bfin_write_SDH_PID7(val) bfin_write16(SDH_PID7, val) - -/* HOST Port Registers */ - -#define bfin_read_HOST_CONTROL() bfin_read16(HOST_CONTROL) -#define bfin_write_HOST_CONTROL(val) bfin_write16(HOST_CONTROL, val) -#define bfin_read_HOST_STATUS() bfin_read16(HOST_STATUS) -#define bfin_write_HOST_STATUS(val) bfin_write16(HOST_STATUS, val) -#define bfin_read_HOST_TIMEOUT() bfin_read16(HOST_TIMEOUT) -#define bfin_write_HOST_TIMEOUT(val) bfin_write16(HOST_TIMEOUT, val) - -/* USB Control Registers */ - -#define bfin_read_USB_FADDR() bfin_read16(USB_FADDR) -#define bfin_write_USB_FADDR(val) bfin_write16(USB_FADDR, val) -#define bfin_read_USB_POWER() bfin_read16(USB_POWER) -#define bfin_write_USB_POWER(val) bfin_write16(USB_POWER, val) -#define bfin_read_USB_INTRTX() bfin_read16(USB_INTRTX) -#define bfin_write_USB_INTRTX(val) bfin_write16(USB_INTRTX, val) -#define bfin_read_USB_INTRRX() bfin_read16(USB_INTRRX) -#define bfin_write_USB_INTRRX(val) bfin_write16(USB_INTRRX, val) -#define bfin_read_USB_INTRTXE() bfin_read16(USB_INTRTXE) -#define bfin_write_USB_INTRTXE(val) bfin_write16(USB_INTRTXE, val) -#define bfin_read_USB_INTRRXE() bfin_read16(USB_INTRRXE) -#define bfin_write_USB_INTRRXE(val) bfin_write16(USB_INTRRXE, val) -#define bfin_read_USB_INTRUSB() bfin_read16(USB_INTRUSB) -#define bfin_write_USB_INTRUSB(val) bfin_write16(USB_INTRUSB, val) -#define bfin_read_USB_INTRUSBE() bfin_read16(USB_INTRUSBE) -#define bfin_write_USB_INTRUSBE(val) bfin_write16(USB_INTRUSBE, val) -#define bfin_read_USB_FRAME() bfin_read16(USB_FRAME) -#define bfin_write_USB_FRAME(val) bfin_write16(USB_FRAME, val) -#define bfin_read_USB_INDEX() bfin_read16(USB_INDEX) -#define bfin_write_USB_INDEX(val) bfin_write16(USB_INDEX, val) -#define bfin_read_USB_TESTMODE() bfin_read16(USB_TESTMODE) -#define bfin_write_USB_TESTMODE(val) bfin_write16(USB_TESTMODE, val) -#define bfin_read_USB_GLOBINTR() bfin_read16(USB_GLOBINTR) -#define bfin_write_USB_GLOBINTR(val) bfin_write16(USB_GLOBINTR, val) -#define bfin_read_USB_GLOBAL_CTL() bfin_read16(USB_GLOBAL_CTL) -#define bfin_write_USB_GLOBAL_CTL(val) bfin_write16(USB_GLOBAL_CTL, val) - -/* USB Packet Control Registers */ - -#define bfin_read_USB_TX_MAX_PACKET() bfin_read16(USB_TX_MAX_PACKET) -#define bfin_write_USB_TX_MAX_PACKET(val) bfin_write16(USB_TX_MAX_PACKET, val) -#define bfin_read_USB_CSR0() bfin_read16(USB_CSR0) -#define bfin_write_USB_CSR0(val) bfin_write16(USB_CSR0, val) -#define bfin_read_USB_TXCSR() bfin_read16(USB_TXCSR) -#define bfin_write_USB_TXCSR(val) bfin_write16(USB_TXCSR, val) -#define bfin_read_USB_RX_MAX_PACKET() bfin_read16(USB_RX_MAX_PACKET) -#define bfin_write_USB_RX_MAX_PACKET(val) bfin_write16(USB_RX_MAX_PACKET, val) -#define bfin_read_USB_RXCSR() bfin_read16(USB_RXCSR) -#define bfin_write_USB_RXCSR(val) bfin_write16(USB_RXCSR, val) -#define bfin_read_USB_COUNT0() bfin_read16(USB_COUNT0) -#define bfin_write_USB_COUNT0(val) bfin_write16(USB_COUNT0, val) -#define bfin_read_USB_RXCOUNT() bfin_read16(USB_RXCOUNT) -#define bfin_write_USB_RXCOUNT(val) bfin_write16(USB_RXCOUNT, val) -#define bfin_read_USB_TXTYPE() bfin_read16(USB_TXTYPE) -#define bfin_write_USB_TXTYPE(val) bfin_write16(USB_TXTYPE, val) -#define bfin_read_USB_NAKLIMIT0() bfin_read16(USB_NAKLIMIT0) -#define bfin_write_USB_NAKLIMIT0(val) bfin_write16(USB_NAKLIMIT0, val) -#define bfin_read_USB_TXINTERVAL() bfin_read16(USB_TXINTERVAL) -#define bfin_write_USB_TXINTERVAL(val) bfin_write16(USB_TXINTERVAL, val) -#define bfin_read_USB_RXTYPE() bfin_read16(USB_RXTYPE) -#define bfin_write_USB_RXTYPE(val) bfin_write16(USB_RXTYPE, val) -#define bfin_read_USB_RXINTERVAL() bfin_read16(USB_RXINTERVAL) -#define bfin_write_USB_RXINTERVAL(val) bfin_write16(USB_RXINTERVAL, val) -#define bfin_read_USB_TXCOUNT() bfin_read16(USB_TXCOUNT) -#define bfin_write_USB_TXCOUNT(val) bfin_write16(USB_TXCOUNT, val) - -/* USB Endbfin_read_()oint FIFO Registers */ - -#define bfin_read_USB_EP0_FIFO() bfin_read16(USB_EP0_FIFO) -#define bfin_write_USB_EP0_FIFO(val) bfin_write16(USB_EP0_FIFO, val) -#define bfin_read_USB_EP1_FIFO() bfin_read16(USB_EP1_FIFO) -#define bfin_write_USB_EP1_FIFO(val) bfin_write16(USB_EP1_FIFO, val) -#define bfin_read_USB_EP2_FIFO() bfin_read16(USB_EP2_FIFO) -#define bfin_write_USB_EP2_FIFO(val) bfin_write16(USB_EP2_FIFO, val) -#define bfin_read_USB_EP3_FIFO() bfin_read16(USB_EP3_FIFO) -#define bfin_write_USB_EP3_FIFO(val) bfin_write16(USB_EP3_FIFO, val) -#define bfin_read_USB_EP4_FIFO() bfin_read16(USB_EP4_FIFO) -#define bfin_write_USB_EP4_FIFO(val) bfin_write16(USB_EP4_FIFO, val) -#define bfin_read_USB_EP5_FIFO() bfin_read16(USB_EP5_FIFO) -#define bfin_write_USB_EP5_FIFO(val) bfin_write16(USB_EP5_FIFO, val) -#define bfin_read_USB_EP6_FIFO() bfin_read16(USB_EP6_FIFO) -#define bfin_write_USB_EP6_FIFO(val) bfin_write16(USB_EP6_FIFO, val) -#define bfin_read_USB_EP7_FIFO() bfin_read16(USB_EP7_FIFO) -#define bfin_write_USB_EP7_FIFO(val) bfin_write16(USB_EP7_FIFO, val) - -/* USB OTG Control Registers */ - -#define bfin_read_USB_OTG_DEV_CTL() bfin_read16(USB_OTG_DEV_CTL) -#define bfin_write_USB_OTG_DEV_CTL(val) bfin_write16(USB_OTG_DEV_CTL, val) -#define bfin_read_USB_OTG_VBUS_IRQ() bfin_read16(USB_OTG_VBUS_IRQ) -#define bfin_write_USB_OTG_VBUS_IRQ(val) bfin_write16(USB_OTG_VBUS_IRQ, val) -#define bfin_read_USB_OTG_VBUS_MASK() bfin_read16(USB_OTG_VBUS_MASK) -#define bfin_write_USB_OTG_VBUS_MASK(val) bfin_write16(USB_OTG_VBUS_MASK, val) - -/* USB Phy Control Registers */ - -#define bfin_read_USB_LINKINFO() bfin_read16(USB_LINKINFO) -#define bfin_write_USB_LINKINFO(val) bfin_write16(USB_LINKINFO, val) -#define bfin_read_USB_VPLEN() bfin_read16(USB_VPLEN) -#define bfin_write_USB_VPLEN(val) bfin_write16(USB_VPLEN, val) -#define bfin_read_USB_HS_EOF1() bfin_read16(USB_HS_EOF1) -#define bfin_write_USB_HS_EOF1(val) bfin_write16(USB_HS_EOF1, val) -#define bfin_read_USB_FS_EOF1() bfin_read16(USB_FS_EOF1) -#define bfin_write_USB_FS_EOF1(val) bfin_write16(USB_FS_EOF1, val) -#define bfin_read_USB_LS_EOF1() bfin_read16(USB_LS_EOF1) -#define bfin_write_USB_LS_EOF1(val) bfin_write16(USB_LS_EOF1, val) - -/* (APHY_CNTRL is for ADI usage only) */ - -#define bfin_read_USB_APHY_CNTRL() bfin_read16(USB_APHY_CNTRL) -#define bfin_write_USB_APHY_CNTRL(val) bfin_write16(USB_APHY_CNTRL, val) - -/* (APHY_CALIB is for ADI usage only) */ - -#define bfin_read_USB_APHY_CALIB() bfin_read16(USB_APHY_CALIB) -#define bfin_write_USB_APHY_CALIB(val) bfin_write16(USB_APHY_CALIB, val) -#define bfin_read_USB_APHY_CNTRL2() bfin_read16(USB_APHY_CNTRL2) -#define bfin_write_USB_APHY_CNTRL2(val) bfin_write16(USB_APHY_CNTRL2, val) - -/* (PHY_TEST is for ADI usage only) */ - -#define bfin_read_USB_PHY_TEST() bfin_read16(USB_PHY_TEST) -#define bfin_write_USB_PHY_TEST(val) bfin_write16(USB_PHY_TEST, val) -#define bfin_read_USB_PLLOSC_CTRL() bfin_read16(USB_PLLOSC_CTRL) -#define bfin_write_USB_PLLOSC_CTRL(val) bfin_write16(USB_PLLOSC_CTRL, val) -#define bfin_read_USB_SRP_CLKDIV() bfin_read16(USB_SRP_CLKDIV) -#define bfin_write_USB_SRP_CLKDIV(val) bfin_write16(USB_SRP_CLKDIV, val) - -/* USB Endbfin_read_()oint 0 Control Registers */ - -#define bfin_read_USB_EP_NI0_TXMAXP() bfin_read16(USB_EP_NI0_TXMAXP) -#define bfin_write_USB_EP_NI0_TXMAXP(val) bfin_write16(USB_EP_NI0_TXMAXP, val) -#define bfin_read_USB_EP_NI0_TXCSR() bfin_read16(USB_EP_NI0_TXCSR) -#define bfin_write_USB_EP_NI0_TXCSR(val) bfin_write16(USB_EP_NI0_TXCSR, val) -#define bfin_read_USB_EP_NI0_RXMAXP() bfin_read16(USB_EP_NI0_RXMAXP) -#define bfin_write_USB_EP_NI0_RXMAXP(val) bfin_write16(USB_EP_NI0_RXMAXP, val) -#define bfin_read_USB_EP_NI0_RXCSR() bfin_read16(USB_EP_NI0_RXCSR) -#define bfin_write_USB_EP_NI0_RXCSR(val) bfin_write16(USB_EP_NI0_RXCSR, val) -#define bfin_read_USB_EP_NI0_RXCOUNT() bfin_read16(USB_EP_NI0_RXCOUNT) -#define bfin_write_USB_EP_NI0_RXCOUNT(val) bfin_write16(USB_EP_NI0_RXCOUNT, val) -#define bfin_read_USB_EP_NI0_TXTYPE() bfin_read16(USB_EP_NI0_TXTYPE) -#define bfin_write_USB_EP_NI0_TXTYPE(val) bfin_write16(USB_EP_NI0_TXTYPE, val) -#define bfin_read_USB_EP_NI0_TXINTERVAL() bfin_read16(USB_EP_NI0_TXINTERVAL) -#define bfin_write_USB_EP_NI0_TXINTERVAL(val) bfin_write16(USB_EP_NI0_TXINTERVAL, val) -#define bfin_read_USB_EP_NI0_RXTYPE() bfin_read16(USB_EP_NI0_RXTYPE) -#define bfin_write_USB_EP_NI0_RXTYPE(val) bfin_write16(USB_EP_NI0_RXTYPE, val) -#define bfin_read_USB_EP_NI0_RXINTERVAL() bfin_read16(USB_EP_NI0_RXINTERVAL) -#define bfin_write_USB_EP_NI0_RXINTERVAL(val) bfin_write16(USB_EP_NI0_RXINTERVAL, val) - -/* USB Endbfin_read_()oint 1 Control Registers */ - -#define bfin_read_USB_EP_NI0_TXCOUNT() bfin_read16(USB_EP_NI0_TXCOUNT) -#define bfin_write_USB_EP_NI0_TXCOUNT(val) bfin_write16(USB_EP_NI0_TXCOUNT, val) -#define bfin_read_USB_EP_NI1_TXMAXP() bfin_read16(USB_EP_NI1_TXMAXP) -#define bfin_write_USB_EP_NI1_TXMAXP(val) bfin_write16(USB_EP_NI1_TXMAXP, val) -#define bfin_read_USB_EP_NI1_TXCSR() bfin_read16(USB_EP_NI1_TXCSR) -#define bfin_write_USB_EP_NI1_TXCSR(val) bfin_write16(USB_EP_NI1_TXCSR, val) -#define bfin_read_USB_EP_NI1_RXMAXP() bfin_read16(USB_EP_NI1_RXMAXP) -#define bfin_write_USB_EP_NI1_RXMAXP(val) bfin_write16(USB_EP_NI1_RXMAXP, val) -#define bfin_read_USB_EP_NI1_RXCSR() bfin_read16(USB_EP_NI1_RXCSR) -#define bfin_write_USB_EP_NI1_RXCSR(val) bfin_write16(USB_EP_NI1_RXCSR, val) -#define bfin_read_USB_EP_NI1_RXCOUNT() bfin_read16(USB_EP_NI1_RXCOUNT) -#define bfin_write_USB_EP_NI1_RXCOUNT(val) bfin_write16(USB_EP_NI1_RXCOUNT, val) -#define bfin_read_USB_EP_NI1_TXTYPE() bfin_read16(USB_EP_NI1_TXTYPE) -#define bfin_write_USB_EP_NI1_TXTYPE(val) bfin_write16(USB_EP_NI1_TXTYPE, val) -#define bfin_read_USB_EP_NI1_TXINTERVAL() bfin_read16(USB_EP_NI1_TXINTERVAL) -#define bfin_write_USB_EP_NI1_TXINTERVAL(val) bfin_write16(USB_EP_NI1_TXINTERVAL, val) -#define bfin_read_USB_EP_NI1_RXTYPE() bfin_read16(USB_EP_NI1_RXTYPE) -#define bfin_write_USB_EP_NI1_RXTYPE(val) bfin_write16(USB_EP_NI1_RXTYPE, val) -#define bfin_read_USB_EP_NI1_RXINTERVAL() bfin_read16(USB_EP_NI1_RXINTERVAL) -#define bfin_write_USB_EP_NI1_RXINTERVAL(val) bfin_write16(USB_EP_NI1_RXINTERVAL, val) - -/* USB Endbfin_read_()oint 2 Control Registers */ - -#define bfin_read_USB_EP_NI1_TXCOUNT() bfin_read16(USB_EP_NI1_TXCOUNT) -#define bfin_write_USB_EP_NI1_TXCOUNT(val) bfin_write16(USB_EP_NI1_TXCOUNT, val) -#define bfin_read_USB_EP_NI2_TXMAXP() bfin_read16(USB_EP_NI2_TXMAXP) -#define bfin_write_USB_EP_NI2_TXMAXP(val) bfin_write16(USB_EP_NI2_TXMAXP, val) -#define bfin_read_USB_EP_NI2_TXCSR() bfin_read16(USB_EP_NI2_TXCSR) -#define bfin_write_USB_EP_NI2_TXCSR(val) bfin_write16(USB_EP_NI2_TXCSR, val) -#define bfin_read_USB_EP_NI2_RXMAXP() bfin_read16(USB_EP_NI2_RXMAXP) -#define bfin_write_USB_EP_NI2_RXMAXP(val) bfin_write16(USB_EP_NI2_RXMAXP, val) -#define bfin_read_USB_EP_NI2_RXCSR() bfin_read16(USB_EP_NI2_RXCSR) -#define bfin_write_USB_EP_NI2_RXCSR(val) bfin_write16(USB_EP_NI2_RXCSR, val) -#define bfin_read_USB_EP_NI2_RXCOUNT() bfin_read16(USB_EP_NI2_RXCOUNT) -#define bfin_write_USB_EP_NI2_RXCOUNT(val) bfin_write16(USB_EP_NI2_RXCOUNT, val) -#define bfin_read_USB_EP_NI2_TXTYPE() bfin_read16(USB_EP_NI2_TXTYPE) -#define bfin_write_USB_EP_NI2_TXTYPE(val) bfin_write16(USB_EP_NI2_TXTYPE, val) -#define bfin_read_USB_EP_NI2_TXINTERVAL() bfin_read16(USB_EP_NI2_TXINTERVAL) -#define bfin_write_USB_EP_NI2_TXINTERVAL(val) bfin_write16(USB_EP_NI2_TXINTERVAL, val) -#define bfin_read_USB_EP_NI2_RXTYPE() bfin_read16(USB_EP_NI2_RXTYPE) -#define bfin_write_USB_EP_NI2_RXTYPE(val) bfin_write16(USB_EP_NI2_RXTYPE, val) -#define bfin_read_USB_EP_NI2_RXINTERVAL() bfin_read16(USB_EP_NI2_RXINTERVAL) -#define bfin_write_USB_EP_NI2_RXINTERVAL(val) bfin_write16(USB_EP_NI2_RXINTERVAL, val) - -/* USB Endbfin_read_()oint 3 Control Registers */ - -#define bfin_read_USB_EP_NI2_TXCOUNT() bfin_read16(USB_EP_NI2_TXCOUNT) -#define bfin_write_USB_EP_NI2_TXCOUNT(val) bfin_write16(USB_EP_NI2_TXCOUNT, val) -#define bfin_read_USB_EP_NI3_TXMAXP() bfin_read16(USB_EP_NI3_TXMAXP) -#define bfin_write_USB_EP_NI3_TXMAXP(val) bfin_write16(USB_EP_NI3_TXMAXP, val) -#define bfin_read_USB_EP_NI3_TXCSR() bfin_read16(USB_EP_NI3_TXCSR) -#define bfin_write_USB_EP_NI3_TXCSR(val) bfin_write16(USB_EP_NI3_TXCSR, val) -#define bfin_read_USB_EP_NI3_RXMAXP() bfin_read16(USB_EP_NI3_RXMAXP) -#define bfin_write_USB_EP_NI3_RXMAXP(val) bfin_write16(USB_EP_NI3_RXMAXP, val) -#define bfin_read_USB_EP_NI3_RXCSR() bfin_read16(USB_EP_NI3_RXCSR) -#define bfin_write_USB_EP_NI3_RXCSR(val) bfin_write16(USB_EP_NI3_RXCSR, val) -#define bfin_read_USB_EP_NI3_RXCOUNT() bfin_read16(USB_EP_NI3_RXCOUNT) -#define bfin_write_USB_EP_NI3_RXCOUNT(val) bfin_write16(USB_EP_NI3_RXCOUNT, val) -#define bfin_read_USB_EP_NI3_TXTYPE() bfin_read16(USB_EP_NI3_TXTYPE) -#define bfin_write_USB_EP_NI3_TXTYPE(val) bfin_write16(USB_EP_NI3_TXTYPE, val) -#define bfin_read_USB_EP_NI3_TXINTERVAL() bfin_read16(USB_EP_NI3_TXINTERVAL) -#define bfin_write_USB_EP_NI3_TXINTERVAL(val) bfin_write16(USB_EP_NI3_TXINTERVAL, val) -#define bfin_read_USB_EP_NI3_RXTYPE() bfin_read16(USB_EP_NI3_RXTYPE) -#define bfin_write_USB_EP_NI3_RXTYPE(val) bfin_write16(USB_EP_NI3_RXTYPE, val) -#define bfin_read_USB_EP_NI3_RXINTERVAL() bfin_read16(USB_EP_NI3_RXINTERVAL) -#define bfin_write_USB_EP_NI3_RXINTERVAL(val) bfin_write16(USB_EP_NI3_RXINTERVAL, val) - -/* USB Endbfin_read_()oint 4 Control Registers */ - -#define bfin_read_USB_EP_NI3_TXCOUNT() bfin_read16(USB_EP_NI3_TXCOUNT) -#define bfin_write_USB_EP_NI3_TXCOUNT(val) bfin_write16(USB_EP_NI3_TXCOUNT, val) -#define bfin_read_USB_EP_NI4_TXMAXP() bfin_read16(USB_EP_NI4_TXMAXP) -#define bfin_write_USB_EP_NI4_TXMAXP(val) bfin_write16(USB_EP_NI4_TXMAXP, val) -#define bfin_read_USB_EP_NI4_TXCSR() bfin_read16(USB_EP_NI4_TXCSR) -#define bfin_write_USB_EP_NI4_TXCSR(val) bfin_write16(USB_EP_NI4_TXCSR, val) -#define bfin_read_USB_EP_NI4_RXMAXP() bfin_read16(USB_EP_NI4_RXMAXP) -#define bfin_write_USB_EP_NI4_RXMAXP(val) bfin_write16(USB_EP_NI4_RXMAXP, val) -#define bfin_read_USB_EP_NI4_RXCSR() bfin_read16(USB_EP_NI4_RXCSR) -#define bfin_write_USB_EP_NI4_RXCSR(val) bfin_write16(USB_EP_NI4_RXCSR, val) -#define bfin_read_USB_EP_NI4_RXCOUNT() bfin_read16(USB_EP_NI4_RXCOUNT) -#define bfin_write_USB_EP_NI4_RXCOUNT(val) bfin_write16(USB_EP_NI4_RXCOUNT, val) -#define bfin_read_USB_EP_NI4_TXTYPE() bfin_read16(USB_EP_NI4_TXTYPE) -#define bfin_write_USB_EP_NI4_TXTYPE(val) bfin_write16(USB_EP_NI4_TXTYPE, val) -#define bfin_read_USB_EP_NI4_TXINTERVAL() bfin_read16(USB_EP_NI4_TXINTERVAL) -#define bfin_write_USB_EP_NI4_TXINTERVAL(val) bfin_write16(USB_EP_NI4_TXINTERVAL, val) -#define bfin_read_USB_EP_NI4_RXTYPE() bfin_read16(USB_EP_NI4_RXTYPE) -#define bfin_write_USB_EP_NI4_RXTYPE(val) bfin_write16(USB_EP_NI4_RXTYPE, val) -#define bfin_read_USB_EP_NI4_RXINTERVAL() bfin_read16(USB_EP_NI4_RXINTERVAL) -#define bfin_write_USB_EP_NI4_RXINTERVAL(val) bfin_write16(USB_EP_NI4_RXINTERVAL, val) - -/* USB Endbfin_read_()oint 5 Control Registers */ - -#define bfin_read_USB_EP_NI4_TXCOUNT() bfin_read16(USB_EP_NI4_TXCOUNT) -#define bfin_write_USB_EP_NI4_TXCOUNT(val) bfin_write16(USB_EP_NI4_TXCOUNT, val) -#define bfin_read_USB_EP_NI5_TXMAXP() bfin_read16(USB_EP_NI5_TXMAXP) -#define bfin_write_USB_EP_NI5_TXMAXP(val) bfin_write16(USB_EP_NI5_TXMAXP, val) -#define bfin_read_USB_EP_NI5_TXCSR() bfin_read16(USB_EP_NI5_TXCSR) -#define bfin_write_USB_EP_NI5_TXCSR(val) bfin_write16(USB_EP_NI5_TXCSR, val) -#define bfin_read_USB_EP_NI5_RXMAXP() bfin_read16(USB_EP_NI5_RXMAXP) -#define bfin_write_USB_EP_NI5_RXMAXP(val) bfin_write16(USB_EP_NI5_RXMAXP, val) -#define bfin_read_USB_EP_NI5_RXCSR() bfin_read16(USB_EP_NI5_RXCSR) -#define bfin_write_USB_EP_NI5_RXCSR(val) bfin_write16(USB_EP_NI5_RXCSR, val) -#define bfin_read_USB_EP_NI5_RXCOUNT() bfin_read16(USB_EP_NI5_RXCOUNT) -#define bfin_write_USB_EP_NI5_RXCOUNT(val) bfin_write16(USB_EP_NI5_RXCOUNT, val) -#define bfin_read_USB_EP_NI5_TXTYPE() bfin_read16(USB_EP_NI5_TXTYPE) -#define bfin_write_USB_EP_NI5_TXTYPE(val) bfin_write16(USB_EP_NI5_TXTYPE, val) -#define bfin_read_USB_EP_NI5_TXINTERVAL() bfin_read16(USB_EP_NI5_TXINTERVAL) -#define bfin_write_USB_EP_NI5_TXINTERVAL(val) bfin_write16(USB_EP_NI5_TXINTERVAL, val) -#define bfin_read_USB_EP_NI5_RXTYPE() bfin_read16(USB_EP_NI5_RXTYPE) -#define bfin_write_USB_EP_NI5_RXTYPE(val) bfin_write16(USB_EP_NI5_RXTYPE, val) -#define bfin_read_USB_EP_NI5_RXINTERVAL() bfin_read16(USB_EP_NI5_RXINTERVAL) -#define bfin_write_USB_EP_NI5_RXINTERVAL(val) bfin_write16(USB_EP_NI5_RXINTERVAL, val) - -/* USB Endbfin_read_()oint 6 Control Registers */ - -#define bfin_read_USB_EP_NI5_TXCOUNT() bfin_read16(USB_EP_NI5_TXCOUNT) -#define bfin_write_USB_EP_NI5_TXCOUNT(val) bfin_write16(USB_EP_NI5_TXCOUNT, val) -#define bfin_read_USB_EP_NI6_TXMAXP() bfin_read16(USB_EP_NI6_TXMAXP) -#define bfin_write_USB_EP_NI6_TXMAXP(val) bfin_write16(USB_EP_NI6_TXMAXP, val) -#define bfin_read_USB_EP_NI6_TXCSR() bfin_read16(USB_EP_NI6_TXCSR) -#define bfin_write_USB_EP_NI6_TXCSR(val) bfin_write16(USB_EP_NI6_TXCSR, val) -#define bfin_read_USB_EP_NI6_RXMAXP() bfin_read16(USB_EP_NI6_RXMAXP) -#define bfin_write_USB_EP_NI6_RXMAXP(val) bfin_write16(USB_EP_NI6_RXMAXP, val) -#define bfin_read_USB_EP_NI6_RXCSR() bfin_read16(USB_EP_NI6_RXCSR) -#define bfin_write_USB_EP_NI6_RXCSR(val) bfin_write16(USB_EP_NI6_RXCSR, val) -#define bfin_read_USB_EP_NI6_RXCOUNT() bfin_read16(USB_EP_NI6_RXCOUNT) -#define bfin_write_USB_EP_NI6_RXCOUNT(val) bfin_write16(USB_EP_NI6_RXCOUNT, val) -#define bfin_read_USB_EP_NI6_TXTYPE() bfin_read16(USB_EP_NI6_TXTYPE) -#define bfin_write_USB_EP_NI6_TXTYPE(val) bfin_write16(USB_EP_NI6_TXTYPE, val) -#define bfin_read_USB_EP_NI6_TXINTERVAL() bfin_read16(USB_EP_NI6_TXINTERVAL) -#define bfin_write_USB_EP_NI6_TXINTERVAL(val) bfin_write16(USB_EP_NI6_TXINTERVAL, val) -#define bfin_read_USB_EP_NI6_RXTYPE() bfin_read16(USB_EP_NI6_RXTYPE) -#define bfin_write_USB_EP_NI6_RXTYPE(val) bfin_write16(USB_EP_NI6_RXTYPE, val) -#define bfin_read_USB_EP_NI6_RXINTERVAL() bfin_read16(USB_EP_NI6_RXINTERVAL) -#define bfin_write_USB_EP_NI6_RXINTERVAL(val) bfin_write16(USB_EP_NI6_RXINTERVAL, val) - -/* USB Endbfin_read_()oint 7 Control Registers */ - -#define bfin_read_USB_EP_NI6_TXCOUNT() bfin_read16(USB_EP_NI6_TXCOUNT) -#define bfin_write_USB_EP_NI6_TXCOUNT(val) bfin_write16(USB_EP_NI6_TXCOUNT, val) -#define bfin_read_USB_EP_NI7_TXMAXP() bfin_read16(USB_EP_NI7_TXMAXP) -#define bfin_write_USB_EP_NI7_TXMAXP(val) bfin_write16(USB_EP_NI7_TXMAXP, val) -#define bfin_read_USB_EP_NI7_TXCSR() bfin_read16(USB_EP_NI7_TXCSR) -#define bfin_write_USB_EP_NI7_TXCSR(val) bfin_write16(USB_EP_NI7_TXCSR, val) -#define bfin_read_USB_EP_NI7_RXMAXP() bfin_read16(USB_EP_NI7_RXMAXP) -#define bfin_write_USB_EP_NI7_RXMAXP(val) bfin_write16(USB_EP_NI7_RXMAXP, val) -#define bfin_read_USB_EP_NI7_RXCSR() bfin_read16(USB_EP_NI7_RXCSR) -#define bfin_write_USB_EP_NI7_RXCSR(val) bfin_write16(USB_EP_NI7_RXCSR, val) -#define bfin_read_USB_EP_NI7_RXCOUNT() bfin_read16(USB_EP_NI7_RXCOUNT) -#define bfin_write_USB_EP_NI7_RXCOUNT(val) bfin_write16(USB_EP_NI7_RXCOUNT, val) -#define bfin_read_USB_EP_NI7_TXTYPE() bfin_read16(USB_EP_NI7_TXTYPE) -#define bfin_write_USB_EP_NI7_TXTYPE(val) bfin_write16(USB_EP_NI7_TXTYPE, val) -#define bfin_read_USB_EP_NI7_TXINTERVAL() bfin_read16(USB_EP_NI7_TXINTERVAL) -#define bfin_write_USB_EP_NI7_TXINTERVAL(val) bfin_write16(USB_EP_NI7_TXINTERVAL, val) -#define bfin_read_USB_EP_NI7_RXTYPE() bfin_read16(USB_EP_NI7_RXTYPE) -#define bfin_write_USB_EP_NI7_RXTYPE(val) bfin_write16(USB_EP_NI7_RXTYPE, val) -#define bfin_read_USB_EP_NI7_RXINTERVAL() bfin_read16(USB_EP_NI7_RXINTERVAL) -#define bfin_write_USB_EP_NI7_RXINTERVAL(val) bfin_write16(USB_EP_NI7_RXINTERVAL, val) -#define bfin_read_USB_EP_NI7_TXCOUNT() bfin_read16(USB_EP_NI7_TXCOUNT) -#define bfin_write_USB_EP_NI7_TXCOUNT(val) bfin_write16(USB_EP_NI7_TXCOUNT, val) -#define bfin_read_USB_DMA_INTERRUPT() bfin_read16(USB_DMA_INTERRUPT) -#define bfin_write_USB_DMA_INTERRUPT(val) bfin_write16(USB_DMA_INTERRUPT, val) - -/* USB Channel 0 Config Registers */ - -#define bfin_read_USB_DMA0CONTROL() bfin_read16(USB_DMA0CONTROL) -#define bfin_write_USB_DMA0CONTROL(val) bfin_write16(USB_DMA0CONTROL, val) -#define bfin_read_USB_DMA0ADDRLOW() bfin_read16(USB_DMA0ADDRLOW) -#define bfin_write_USB_DMA0ADDRLOW(val) bfin_write16(USB_DMA0ADDRLOW, val) -#define bfin_read_USB_DMA0ADDRHIGH() bfin_read16(USB_DMA0ADDRHIGH) -#define bfin_write_USB_DMA0ADDRHIGH(val) bfin_write16(USB_DMA0ADDRHIGH, val) -#define bfin_read_USB_DMA0COUNTLOW() bfin_read16(USB_DMA0COUNTLOW) -#define bfin_write_USB_DMA0COUNTLOW(val) bfin_write16(USB_DMA0COUNTLOW, val) -#define bfin_read_USB_DMA0COUNTHIGH() bfin_read16(USB_DMA0COUNTHIGH) -#define bfin_write_USB_DMA0COUNTHIGH(val) bfin_write16(USB_DMA0COUNTHIGH, val) - -/* USB Channel 1 Config Registers */ - -#define bfin_read_USB_DMA1CONTROL() bfin_read16(USB_DMA1CONTROL) -#define bfin_write_USB_DMA1CONTROL(val) bfin_write16(USB_DMA1CONTROL, val) -#define bfin_read_USB_DMA1ADDRLOW() bfin_read16(USB_DMA1ADDRLOW) -#define bfin_write_USB_DMA1ADDRLOW(val) bfin_write16(USB_DMA1ADDRLOW, val) -#define bfin_read_USB_DMA1ADDRHIGH() bfin_read16(USB_DMA1ADDRHIGH) -#define bfin_write_USB_DMA1ADDRHIGH(val) bfin_write16(USB_DMA1ADDRHIGH, val) -#define bfin_read_USB_DMA1COUNTLOW() bfin_read16(USB_DMA1COUNTLOW) -#define bfin_write_USB_DMA1COUNTLOW(val) bfin_write16(USB_DMA1COUNTLOW, val) -#define bfin_read_USB_DMA1COUNTHIGH() bfin_read16(USB_DMA1COUNTHIGH) -#define bfin_write_USB_DMA1COUNTHIGH(val) bfin_write16(USB_DMA1COUNTHIGH, val) - -/* USB Channel 2 Config Registers */ - -#define bfin_read_USB_DMA2CONTROL() bfin_read16(USB_DMA2CONTROL) -#define bfin_write_USB_DMA2CONTROL(val) bfin_write16(USB_DMA2CONTROL, val) -#define bfin_read_USB_DMA2ADDRLOW() bfin_read16(USB_DMA2ADDRLOW) -#define bfin_write_USB_DMA2ADDRLOW(val) bfin_write16(USB_DMA2ADDRLOW, val) -#define bfin_read_USB_DMA2ADDRHIGH() bfin_read16(USB_DMA2ADDRHIGH) -#define bfin_write_USB_DMA2ADDRHIGH(val) bfin_write16(USB_DMA2ADDRHIGH, val) -#define bfin_read_USB_DMA2COUNTLOW() bfin_read16(USB_DMA2COUNTLOW) -#define bfin_write_USB_DMA2COUNTLOW(val) bfin_write16(USB_DMA2COUNTLOW, val) -#define bfin_read_USB_DMA2COUNTHIGH() bfin_read16(USB_DMA2COUNTHIGH) -#define bfin_write_USB_DMA2COUNTHIGH(val) bfin_write16(USB_DMA2COUNTHIGH, val) - -/* USB Channel 3 Config Registers */ - -#define bfin_read_USB_DMA3CONTROL() bfin_read16(USB_DMA3CONTROL) -#define bfin_write_USB_DMA3CONTROL(val) bfin_write16(USB_DMA3CONTROL, val) -#define bfin_read_USB_DMA3ADDRLOW() bfin_read16(USB_DMA3ADDRLOW) -#define bfin_write_USB_DMA3ADDRLOW(val) bfin_write16(USB_DMA3ADDRLOW, val) -#define bfin_read_USB_DMA3ADDRHIGH() bfin_read16(USB_DMA3ADDRHIGH) -#define bfin_write_USB_DMA3ADDRHIGH(val) bfin_write16(USB_DMA3ADDRHIGH, val) -#define bfin_read_USB_DMA3COUNTLOW() bfin_read16(USB_DMA3COUNTLOW) -#define bfin_write_USB_DMA3COUNTLOW(val) bfin_write16(USB_DMA3COUNTLOW, val) -#define bfin_read_USB_DMA3COUNTHIGH() bfin_read16(USB_DMA3COUNTHIGH) -#define bfin_write_USB_DMA3COUNTHIGH(val) bfin_write16(USB_DMA3COUNTHIGH, val) - -/* USB Channel 4 Config Registers */ - -#define bfin_read_USB_DMA4CONTROL() bfin_read16(USB_DMA4CONTROL) -#define bfin_write_USB_DMA4CONTROL(val) bfin_write16(USB_DMA4CONTROL, val) -#define bfin_read_USB_DMA4ADDRLOW() bfin_read16(USB_DMA4ADDRLOW) -#define bfin_write_USB_DMA4ADDRLOW(val) bfin_write16(USB_DMA4ADDRLOW, val) -#define bfin_read_USB_DMA4ADDRHIGH() bfin_read16(USB_DMA4ADDRHIGH) -#define bfin_write_USB_DMA4ADDRHIGH(val) bfin_write16(USB_DMA4ADDRHIGH, val) -#define bfin_read_USB_DMA4COUNTLOW() bfin_read16(USB_DMA4COUNTLOW) -#define bfin_write_USB_DMA4COUNTLOW(val) bfin_write16(USB_DMA4COUNTLOW, val) -#define bfin_read_USB_DMA4COUNTHIGH() bfin_read16(USB_DMA4COUNTHIGH) -#define bfin_write_USB_DMA4COUNTHIGH(val) bfin_write16(USB_DMA4COUNTHIGH, val) - -/* USB Channel 5 Config Registers */ - -#define bfin_read_USB_DMA5CONTROL() bfin_read16(USB_DMA5CONTROL) -#define bfin_write_USB_DMA5CONTROL(val) bfin_write16(USB_DMA5CONTROL, val) -#define bfin_read_USB_DMA5ADDRLOW() bfin_read16(USB_DMA5ADDRLOW) -#define bfin_write_USB_DMA5ADDRLOW(val) bfin_write16(USB_DMA5ADDRLOW, val) -#define bfin_read_USB_DMA5ADDRHIGH() bfin_read16(USB_DMA5ADDRHIGH) -#define bfin_write_USB_DMA5ADDRHIGH(val) bfin_write16(USB_DMA5ADDRHIGH, val) -#define bfin_read_USB_DMA5COUNTLOW() bfin_read16(USB_DMA5COUNTLOW) -#define bfin_write_USB_DMA5COUNTLOW(val) bfin_write16(USB_DMA5COUNTLOW, val) -#define bfin_read_USB_DMA5COUNTHIGH() bfin_read16(USB_DMA5COUNTHIGH) -#define bfin_write_USB_DMA5COUNTHIGH(val) bfin_write16(USB_DMA5COUNTHIGH, val) - -/* USB Channel 6 Config Registers */ - -#define bfin_read_USB_DMA6CONTROL() bfin_read16(USB_DMA6CONTROL) -#define bfin_write_USB_DMA6CONTROL(val) bfin_write16(USB_DMA6CONTROL, val) -#define bfin_read_USB_DMA6ADDRLOW() bfin_read16(USB_DMA6ADDRLOW) -#define bfin_write_USB_DMA6ADDRLOW(val) bfin_write16(USB_DMA6ADDRLOW, val) -#define bfin_read_USB_DMA6ADDRHIGH() bfin_read16(USB_DMA6ADDRHIGH) -#define bfin_write_USB_DMA6ADDRHIGH(val) bfin_write16(USB_DMA6ADDRHIGH, val) -#define bfin_read_USB_DMA6COUNTLOW() bfin_read16(USB_DMA6COUNTLOW) -#define bfin_write_USB_DMA6COUNTLOW(val) bfin_write16(USB_DMA6COUNTLOW, val) -#define bfin_read_USB_DMA6COUNTHIGH() bfin_read16(USB_DMA6COUNTHIGH) -#define bfin_write_USB_DMA6COUNTHIGH(val) bfin_write16(USB_DMA6COUNTHIGH, val) - -/* USB Channel 7 Config Registers */ - -#define bfin_read_USB_DMA7CONTROL() bfin_read16(USB_DMA7CONTROL) -#define bfin_write_USB_DMA7CONTROL(val) bfin_write16(USB_DMA7CONTROL, val) -#define bfin_read_USB_DMA7ADDRLOW() bfin_read16(USB_DMA7ADDRLOW) -#define bfin_write_USB_DMA7ADDRLOW(val) bfin_write16(USB_DMA7ADDRLOW, val) -#define bfin_read_USB_DMA7ADDRHIGH() bfin_read16(USB_DMA7ADDRHIGH) -#define bfin_write_USB_DMA7ADDRHIGH(val) bfin_write16(USB_DMA7ADDRHIGH, val) -#define bfin_read_USB_DMA7COUNTLOW() bfin_read16(USB_DMA7COUNTLOW) -#define bfin_write_USB_DMA7COUNTLOW(val) bfin_write16(USB_DMA7COUNTLOW, val) -#define bfin_read_USB_DMA7COUNTHIGH() bfin_read16(USB_DMA7COUNTHIGH) -#define bfin_write_USB_DMA7COUNTHIGH(val) bfin_write16(USB_DMA7COUNTHIGH, val) - -/* Keybfin_read_()ad Registers */ - -#define bfin_read_KPAD_CTL() bfin_read16(KPAD_CTL) -#define bfin_write_KPAD_CTL(val) bfin_write16(KPAD_CTL, val) -#define bfin_read_KPAD_PRESCALE() bfin_read16(KPAD_PRESCALE) -#define bfin_write_KPAD_PRESCALE(val) bfin_write16(KPAD_PRESCALE, val) -#define bfin_read_KPAD_MSEL() bfin_read16(KPAD_MSEL) -#define bfin_write_KPAD_MSEL(val) bfin_write16(KPAD_MSEL, val) -#define bfin_read_KPAD_ROWCOL() bfin_read16(KPAD_ROWCOL) -#define bfin_write_KPAD_ROWCOL(val) bfin_write16(KPAD_ROWCOL, val) -#define bfin_read_KPAD_STAT() bfin_read16(KPAD_STAT) -#define bfin_write_KPAD_STAT(val) bfin_write16(KPAD_STAT, val) -#define bfin_read_KPAD_SOFTEVAL() bfin_read16(KPAD_SOFTEVAL) -#define bfin_write_KPAD_SOFTEVAL(val) bfin_write16(KPAD_SOFTEVAL, val) - -/* Pixel Combfin_read_()ositor (PIXC) Registers */ - -#define bfin_read_PIXC_CTL() bfin_read16(PIXC_CTL) -#define bfin_write_PIXC_CTL(val) bfin_write16(PIXC_CTL, val) -#define bfin_read_PIXC_PPL() bfin_read16(PIXC_PPL) -#define bfin_write_PIXC_PPL(val) bfin_write16(PIXC_PPL, val) -#define bfin_read_PIXC_LPF() bfin_read16(PIXC_LPF) -#define bfin_write_PIXC_LPF(val) bfin_write16(PIXC_LPF, val) -#define bfin_read_PIXC_AHSTART() bfin_read16(PIXC_AHSTART) -#define bfin_write_PIXC_AHSTART(val) bfin_write16(PIXC_AHSTART, val) -#define bfin_read_PIXC_AHEND() bfin_read16(PIXC_AHEND) -#define bfin_write_PIXC_AHEND(val) bfin_write16(PIXC_AHEND, val) -#define bfin_read_PIXC_AVSTART() bfin_read16(PIXC_AVSTART) -#define bfin_write_PIXC_AVSTART(val) bfin_write16(PIXC_AVSTART, val) -#define bfin_read_PIXC_AVEND() bfin_read16(PIXC_AVEND) -#define bfin_write_PIXC_AVEND(val) bfin_write16(PIXC_AVEND, val) -#define bfin_read_PIXC_ATRANSP() bfin_read16(PIXC_ATRANSP) -#define bfin_write_PIXC_ATRANSP(val) bfin_write16(PIXC_ATRANSP, val) -#define bfin_read_PIXC_BHSTART() bfin_read16(PIXC_BHSTART) -#define bfin_write_PIXC_BHSTART(val) bfin_write16(PIXC_BHSTART, val) -#define bfin_read_PIXC_BHEND() bfin_read16(PIXC_BHEND) -#define bfin_write_PIXC_BHEND(val) bfin_write16(PIXC_BHEND, val) -#define bfin_read_PIXC_BVSTART() bfin_read16(PIXC_BVSTART) -#define bfin_write_PIXC_BVSTART(val) bfin_write16(PIXC_BVSTART, val) -#define bfin_read_PIXC_BVEND() bfin_read16(PIXC_BVEND) -#define bfin_write_PIXC_BVEND(val) bfin_write16(PIXC_BVEND, val) -#define bfin_read_PIXC_BTRANSP() bfin_read16(PIXC_BTRANSP) -#define bfin_write_PIXC_BTRANSP(val) bfin_write16(PIXC_BTRANSP, val) -#define bfin_read_PIXC_INTRSTAT() bfin_read16(PIXC_INTRSTAT) -#define bfin_write_PIXC_INTRSTAT(val) bfin_write16(PIXC_INTRSTAT, val) -#define bfin_read_PIXC_RYCON() bfin_read32(PIXC_RYCON) -#define bfin_write_PIXC_RYCON(val) bfin_write32(PIXC_RYCON, val) -#define bfin_read_PIXC_GUCON() bfin_read32(PIXC_GUCON) -#define bfin_write_PIXC_GUCON(val) bfin_write32(PIXC_GUCON, val) -#define bfin_read_PIXC_BVCON() bfin_read32(PIXC_BVCON) -#define bfin_write_PIXC_BVCON(val) bfin_write32(PIXC_BVCON, val) -#define bfin_read_PIXC_CCBIAS() bfin_read32(PIXC_CCBIAS) -#define bfin_write_PIXC_CCBIAS(val) bfin_write32(PIXC_CCBIAS, val) -#define bfin_read_PIXC_TC() bfin_read32(PIXC_TC) -#define bfin_write_PIXC_TC(val) bfin_write32(PIXC_TC, val) - -/* Handshake MDMA 0 Registers */ - -#define bfin_read_HMDMA0_CONTROL() bfin_read16(HMDMA0_CONTROL) -#define bfin_write_HMDMA0_CONTROL(val) bfin_write16(HMDMA0_CONTROL, val) -#define bfin_read_HMDMA0_ECINIT() bfin_read16(HMDMA0_ECINIT) -#define bfin_write_HMDMA0_ECINIT(val) bfin_write16(HMDMA0_ECINIT, val) -#define bfin_read_HMDMA0_BCINIT() bfin_read16(HMDMA0_BCINIT) -#define bfin_write_HMDMA0_BCINIT(val) bfin_write16(HMDMA0_BCINIT, val) -#define bfin_read_HMDMA0_ECURGENT() bfin_read16(HMDMA0_ECURGENT) -#define bfin_write_HMDMA0_ECURGENT(val) bfin_write16(HMDMA0_ECURGENT, val) -#define bfin_read_HMDMA0_ECOVERFLOW() bfin_read16(HMDMA0_ECOVERFLOW) -#define bfin_write_HMDMA0_ECOVERFLOW(val) bfin_write16(HMDMA0_ECOVERFLOW, val) -#define bfin_read_HMDMA0_ECOUNT() bfin_read16(HMDMA0_ECOUNT) -#define bfin_write_HMDMA0_ECOUNT(val) bfin_write16(HMDMA0_ECOUNT, val) -#define bfin_read_HMDMA0_BCOUNT() bfin_read16(HMDMA0_BCOUNT) -#define bfin_write_HMDMA0_BCOUNT(val) bfin_write16(HMDMA0_BCOUNT, val) - -/* Handshake MDMA 1 Registers */ - -#define bfin_read_HMDMA1_CONTROL() bfin_read16(HMDMA1_CONTROL) -#define bfin_write_HMDMA1_CONTROL(val) bfin_write16(HMDMA1_CONTROL, val) -#define bfin_read_HMDMA1_ECINIT() bfin_read16(HMDMA1_ECINIT) -#define bfin_write_HMDMA1_ECINIT(val) bfin_write16(HMDMA1_ECINIT, val) -#define bfin_read_HMDMA1_BCINIT() bfin_read16(HMDMA1_BCINIT) -#define bfin_write_HMDMA1_BCINIT(val) bfin_write16(HMDMA1_BCINIT, val) -#define bfin_read_HMDMA1_ECURGENT() bfin_read16(HMDMA1_ECURGENT) -#define bfin_write_HMDMA1_ECURGENT(val) bfin_write16(HMDMA1_ECURGENT, val) -#define bfin_read_HMDMA1_ECOVERFLOW() bfin_read16(HMDMA1_ECOVERFLOW) -#define bfin_write_HMDMA1_ECOVERFLOW(val) bfin_write16(HMDMA1_ECOVERFLOW, val) -#define bfin_read_HMDMA1_ECOUNT() bfin_read16(HMDMA1_ECOUNT) -#define bfin_write_HMDMA1_ECOUNT(val) bfin_write16(HMDMA1_ECOUNT, val) -#define bfin_read_HMDMA1_BCOUNT() bfin_read16(HMDMA1_BCOUNT) -#define bfin_write_HMDMA1_BCOUNT(val) bfin_write16(HMDMA1_BCOUNT, val) - #endif /* _CDEF_BF548_H */ diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF549.h b/arch/blackfin/mach-bf548/include/mach/cdefBF549.h index 34c84c7..80201ed 100644 --- a/arch/blackfin/mach-bf548/include/mach/cdefBF549.h +++ b/arch/blackfin/mach-bf548/include/mach/cdefBF549.h @@ -18,165 +18,8 @@ /* include cdefBF54x_base.h for the set of #defines that are common to all ADSP-BF54x bfin_read_()rocessors */ #include "cdefBF54x_base.h" -/* The following are the #defines needed by ADSP-BF549 that are not in the common header */ - -/* Timer Registers */ - -#define bfin_read_TIMER8_CONFIG() bfin_read16(TIMER8_CONFIG) -#define bfin_write_TIMER8_CONFIG(val) bfin_write16(TIMER8_CONFIG, val) -#define bfin_read_TIMER8_COUNTER() bfin_read32(TIMER8_COUNTER) -#define bfin_write_TIMER8_COUNTER(val) bfin_write32(TIMER8_COUNTER, val) -#define bfin_read_TIMER8_PERIOD() bfin_read32(TIMER8_PERIOD) -#define bfin_write_TIMER8_PERIOD(val) bfin_write32(TIMER8_PERIOD, val) -#define bfin_read_TIMER8_WIDTH() bfin_read32(TIMER8_WIDTH) -#define bfin_write_TIMER8_WIDTH(val) bfin_write32(TIMER8_WIDTH, val) -#define bfin_read_TIMER9_CONFIG() bfin_read16(TIMER9_CONFIG) -#define bfin_write_TIMER9_CONFIG(val) bfin_write16(TIMER9_CONFIG, val) -#define bfin_read_TIMER9_COUNTER() bfin_read32(TIMER9_COUNTER) -#define bfin_write_TIMER9_COUNTER(val) bfin_write32(TIMER9_COUNTER, val) -#define bfin_read_TIMER9_PERIOD() bfin_read32(TIMER9_PERIOD) -#define bfin_write_TIMER9_PERIOD(val) bfin_write32(TIMER9_PERIOD, val) -#define bfin_read_TIMER9_WIDTH() bfin_read32(TIMER9_WIDTH) -#define bfin_write_TIMER9_WIDTH(val) bfin_write32(TIMER9_WIDTH, val) -#define bfin_read_TIMER10_CONFIG() bfin_read16(TIMER10_CONFIG) -#define bfin_write_TIMER10_CONFIG(val) bfin_write16(TIMER10_CONFIG, val) -#define bfin_read_TIMER10_COUNTER() bfin_read32(TIMER10_COUNTER) -#define bfin_write_TIMER10_COUNTER(val) bfin_write32(TIMER10_COUNTER, val) -#define bfin_read_TIMER10_PERIOD() bfin_read32(TIMER10_PERIOD) -#define bfin_write_TIMER10_PERIOD(val) bfin_write32(TIMER10_PERIOD, val) -#define bfin_read_TIMER10_WIDTH() bfin_read32(TIMER10_WIDTH) -#define bfin_write_TIMER10_WIDTH(val) bfin_write32(TIMER10_WIDTH, val) - -/* Timer Groubfin_read_() of 3 */ - -#define bfin_read_TIMER_ENABLE1() bfin_read16(TIMER_ENABLE1) -#define bfin_write_TIMER_ENABLE1(val) bfin_write16(TIMER_ENABLE1, val) -#define bfin_read_TIMER_DISABLE1() bfin_read16(TIMER_DISABLE1) -#define bfin_write_TIMER_DISABLE1(val) bfin_write16(TIMER_DISABLE1, val) -#define bfin_read_TIMER_STATUS1() bfin_read32(TIMER_STATUS1) -#define bfin_write_TIMER_STATUS1(val) bfin_write32(TIMER_STATUS1, val) - -/* SPORT0 Registers */ - -#define bfin_read_SPORT0_TCR1() bfin_read16(SPORT0_TCR1) -#define bfin_write_SPORT0_TCR1(val) bfin_write16(SPORT0_TCR1, val) -#define bfin_read_SPORT0_TCR2() bfin_read16(SPORT0_TCR2) -#define bfin_write_SPORT0_TCR2(val) bfin_write16(SPORT0_TCR2, val) -#define bfin_read_SPORT0_TCLKDIV() bfin_read16(SPORT0_TCLKDIV) -#define bfin_write_SPORT0_TCLKDIV(val) bfin_write16(SPORT0_TCLKDIV, val) -#define bfin_read_SPORT0_TFSDIV() bfin_read16(SPORT0_TFSDIV) -#define bfin_write_SPORT0_TFSDIV(val) bfin_write16(SPORT0_TFSDIV, val) -#define bfin_read_SPORT0_TX() bfin_read32(SPORT0_TX) -#define bfin_write_SPORT0_TX(val) bfin_write32(SPORT0_TX, val) -#define bfin_read_SPORT0_RX() bfin_read32(SPORT0_RX) -#define bfin_write_SPORT0_RX(val) bfin_write32(SPORT0_RX, val) -#define bfin_read_SPORT0_RCR1() bfin_read16(SPORT0_RCR1) -#define bfin_write_SPORT0_RCR1(val) bfin_write16(SPORT0_RCR1, val) -#define bfin_read_SPORT0_RCR2() bfin_read16(SPORT0_RCR2) -#define bfin_write_SPORT0_RCR2(val) bfin_write16(SPORT0_RCR2, val) -#define bfin_read_SPORT0_RCLKDIV() bfin_read16(SPORT0_RCLKDIV) -#define bfin_write_SPORT0_RCLKDIV(val) bfin_write16(SPORT0_RCLKDIV, val) -#define bfin_read_SPORT0_RFSDIV() bfin_read16(SPORT0_RFSDIV) -#define bfin_write_SPORT0_RFSDIV(val) bfin_write16(SPORT0_RFSDIV, val) -#define bfin_read_SPORT0_STAT() bfin_read16(SPORT0_STAT) -#define bfin_write_SPORT0_STAT(val) bfin_write16(SPORT0_STAT, val) -#define bfin_read_SPORT0_CHNL() bfin_read16(SPORT0_CHNL) -#define bfin_write_SPORT0_CHNL(val) bfin_write16(SPORT0_CHNL, val) -#define bfin_read_SPORT0_MCMC1() bfin_read16(SPORT0_MCMC1) -#define bfin_write_SPORT0_MCMC1(val) bfin_write16(SPORT0_MCMC1, val) -#define bfin_read_SPORT0_MCMC2() bfin_read16(SPORT0_MCMC2) -#define bfin_write_SPORT0_MCMC2(val) bfin_write16(SPORT0_MCMC2, val) -#define bfin_read_SPORT0_MTCS0() bfin_read32(SPORT0_MTCS0) -#define bfin_write_SPORT0_MTCS0(val) bfin_write32(SPORT0_MTCS0, val) -#define bfin_read_SPORT0_MTCS1() bfin_read32(SPORT0_MTCS1) -#define bfin_write_SPORT0_MTCS1(val) bfin_write32(SPORT0_MTCS1, val) -#define bfin_read_SPORT0_MTCS2() bfin_read32(SPORT0_MTCS2) -#define bfin_write_SPORT0_MTCS2(val) bfin_write32(SPORT0_MTCS2, val) -#define bfin_read_SPORT0_MTCS3() bfin_read32(SPORT0_MTCS3) -#define bfin_write_SPORT0_MTCS3(val) bfin_write32(SPORT0_MTCS3, val) -#define bfin_read_SPORT0_MRCS0() bfin_read32(SPORT0_MRCS0) -#define bfin_write_SPORT0_MRCS0(val) bfin_write32(SPORT0_MRCS0, val) -#define bfin_read_SPORT0_MRCS1() bfin_read32(SPORT0_MRCS1) -#define bfin_write_SPORT0_MRCS1(val) bfin_write32(SPORT0_MRCS1, val) -#define bfin_read_SPORT0_MRCS2() bfin_read32(SPORT0_MRCS2) -#define bfin_write_SPORT0_MRCS2(val) bfin_write32(SPORT0_MRCS2, val) -#define bfin_read_SPORT0_MRCS3() bfin_read32(SPORT0_MRCS3) -#define bfin_write_SPORT0_MRCS3(val) bfin_write32(SPORT0_MRCS3, val) - -/* EPPI0 Registers */ - -#define bfin_read_EPPI0_STATUS() bfin_read16(EPPI0_STATUS) -#define bfin_write_EPPI0_STATUS(val) bfin_write16(EPPI0_STATUS, val) -#define bfin_read_EPPI0_HCOUNT() bfin_read16(EPPI0_HCOUNT) -#define bfin_write_EPPI0_HCOUNT(val) bfin_write16(EPPI0_HCOUNT, val) -#define bfin_read_EPPI0_HDELAY() bfin_read16(EPPI0_HDELAY) -#define bfin_write_EPPI0_HDELAY(val) bfin_write16(EPPI0_HDELAY, val) -#define bfin_read_EPPI0_VCOUNT() bfin_read16(EPPI0_VCOUNT) -#define bfin_write_EPPI0_VCOUNT(val) bfin_write16(EPPI0_VCOUNT, val) -#define bfin_read_EPPI0_VDELAY() bfin_read16(EPPI0_VDELAY) -#define bfin_write_EPPI0_VDELAY(val) bfin_write16(EPPI0_VDELAY, val) -#define bfin_read_EPPI0_FRAME() bfin_read16(EPPI0_FRAME) -#define bfin_write_EPPI0_FRAME(val) bfin_write16(EPPI0_FRAME, val) -#define bfin_read_EPPI0_LINE() bfin_read16(EPPI0_LINE) -#define bfin_write_EPPI0_LINE(val) bfin_write16(EPPI0_LINE, val) -#define bfin_read_EPPI0_CLKDIV() bfin_read16(EPPI0_CLKDIV) -#define bfin_write_EPPI0_CLKDIV(val) bfin_write16(EPPI0_CLKDIV, val) -#define bfin_read_EPPI0_CONTROL() bfin_read32(EPPI0_CONTROL) -#define bfin_write_EPPI0_CONTROL(val) bfin_write32(EPPI0_CONTROL, val) -#define bfin_read_EPPI0_FS1W_HBL() bfin_read32(EPPI0_FS1W_HBL) -#define bfin_write_EPPI0_FS1W_HBL(val) bfin_write32(EPPI0_FS1W_HBL, val) -#define bfin_read_EPPI0_FS1P_AVPL() bfin_read32(EPPI0_FS1P_AVPL) -#define bfin_write_EPPI0_FS1P_AVPL(val) bfin_write32(EPPI0_FS1P_AVPL, val) -#define bfin_read_EPPI0_FS2W_LVB() bfin_read32(EPPI0_FS2W_LVB) -#define bfin_write_EPPI0_FS2W_LVB(val) bfin_write32(EPPI0_FS2W_LVB, val) -#define bfin_read_EPPI0_FS2P_LAVF() bfin_read32(EPPI0_FS2P_LAVF) -#define bfin_write_EPPI0_FS2P_LAVF(val) bfin_write32(EPPI0_FS2P_LAVF, val) -#define bfin_read_EPPI0_CLIP() bfin_read32(EPPI0_CLIP) -#define bfin_write_EPPI0_CLIP(val) bfin_write32(EPPI0_CLIP, val) - -/* UART2 Registers */ - -#define bfin_read_UART2_DLL() bfin_read16(UART2_DLL) -#define bfin_write_UART2_DLL(val) bfin_write16(UART2_DLL, val) -#define bfin_read_UART2_DLH() bfin_read16(UART2_DLH) -#define bfin_write_UART2_DLH(val) bfin_write16(UART2_DLH, val) -#define bfin_read_UART2_GCTL() bfin_read16(UART2_GCTL) -#define bfin_write_UART2_GCTL(val) bfin_write16(UART2_GCTL, val) -#define bfin_read_UART2_LCR() bfin_read16(UART2_LCR) -#define bfin_write_UART2_LCR(val) bfin_write16(UART2_LCR, val) -#define bfin_read_UART2_MCR() bfin_read16(UART2_MCR) -#define bfin_write_UART2_MCR(val) bfin_write16(UART2_MCR, val) -#define bfin_read_UART2_LSR() bfin_read16(UART2_LSR) -#define bfin_write_UART2_LSR(val) bfin_write16(UART2_LSR, val) -#define bfin_read_UART2_MSR() bfin_read16(UART2_MSR) -#define bfin_write_UART2_MSR(val) bfin_write16(UART2_MSR, val) -#define bfin_read_UART2_SCR() bfin_read16(UART2_SCR) -#define bfin_write_UART2_SCR(val) bfin_write16(UART2_SCR, val) -#define bfin_read_UART2_IER_SET() bfin_read16(UART2_IER_SET) -#define bfin_write_UART2_IER_SET(val) bfin_write16(UART2_IER_SET, val) -#define bfin_read_UART2_IER_CLEAR() bfin_read16(UART2_IER_CLEAR) -#define bfin_write_UART2_IER_CLEAR(val) bfin_write16(UART2_IER_CLEAR, val) -#define bfin_read_UART2_RBR() bfin_read16(UART2_RBR) -#define bfin_write_UART2_RBR(val) bfin_write16(UART2_RBR, val) - -/* Two Wire Interface Registers (TWI1) */ - -/* SPI2 Registers */ - -#define bfin_read_SPI2_CTL() bfin_read16(SPI2_CTL) -#define bfin_write_SPI2_CTL(val) bfin_write16(SPI2_CTL, val) -#define bfin_read_SPI2_FLG() bfin_read16(SPI2_FLG) -#define bfin_write_SPI2_FLG(val) bfin_write16(SPI2_FLG, val) -#define bfin_read_SPI2_STAT() bfin_read16(SPI2_STAT) -#define bfin_write_SPI2_STAT(val) bfin_write16(SPI2_STAT, val) -#define bfin_read_SPI2_TDBR() bfin_read16(SPI2_TDBR) -#define bfin_write_SPI2_TDBR(val) bfin_write16(SPI2_TDBR, val) -#define bfin_read_SPI2_RDBR() bfin_read16(SPI2_RDBR) -#define bfin_write_SPI2_RDBR(val) bfin_write16(SPI2_RDBR, val) -#define bfin_read_SPI2_BAUD() bfin_read16(SPI2_BAUD) -#define bfin_write_SPI2_BAUD(val) bfin_write16(SPI2_BAUD, val) -#define bfin_read_SPI2_SHADOW() bfin_read16(SPI2_SHADOW) -#define bfin_write_SPI2_SHADOW(val) bfin_write16(SPI2_SHADOW, val) +/* The BF549 is like the BF544, but has MXVR */ +#include "cdefBF547.h" /* MXVR Registers */ @@ -464,1376 +307,4 @@ #define bfin_read_MXVR_SCLK_CNT() bfin_read16(MXVR_SCLK_CNT) #define bfin_write_MXVR_SCLK_CNT(val) bfin_write16(MXVR_SCLK_CNT, val) -/* CAN Controller 1 Config 1 Registers */ - -#define bfin_read_CAN1_MC1() bfin_read16(CAN1_MC1) -#define bfin_write_CAN1_MC1(val) bfin_write16(CAN1_MC1, val) -#define bfin_read_CAN1_MD1() bfin_read16(CAN1_MD1) -#define bfin_write_CAN1_MD1(val) bfin_write16(CAN1_MD1, val) -#define bfin_read_CAN1_TRS1() bfin_read16(CAN1_TRS1) -#define bfin_write_CAN1_TRS1(val) bfin_write16(CAN1_TRS1, val) -#define bfin_read_CAN1_TRR1() bfin_read16(CAN1_TRR1) -#define bfin_write_CAN1_TRR1(val) bfin_write16(CAN1_TRR1, val) -#define bfin_read_CAN1_TA1() bfin_read16(CAN1_TA1) -#define bfin_write_CAN1_TA1(val) bfin_write16(CAN1_TA1, val) -#define bfin_read_CAN1_AA1() bfin_read16(CAN1_AA1) -#define bfin_write_CAN1_AA1(val) bfin_write16(CAN1_AA1, val) -#define bfin_read_CAN1_RMP1() bfin_read16(CAN1_RMP1) -#define bfin_write_CAN1_RMP1(val) bfin_write16(CAN1_RMP1, val) -#define bfin_read_CAN1_RML1() bfin_read16(CAN1_RML1) -#define bfin_write_CAN1_RML1(val) bfin_write16(CAN1_RML1, val) -#define bfin_read_CAN1_MBTIF1() bfin_read16(CAN1_MBTIF1) -#define bfin_write_CAN1_MBTIF1(val) bfin_write16(CAN1_MBTIF1, val) -#define bfin_read_CAN1_MBRIF1() bfin_read16(CAN1_MBRIF1) -#define bfin_write_CAN1_MBRIF1(val) bfin_write16(CAN1_MBRIF1, val) -#define bfin_read_CAN1_MBIM1() bfin_read16(CAN1_MBIM1) -#define bfin_write_CAN1_MBIM1(val) bfin_write16(CAN1_MBIM1, val) -#define bfin_read_CAN1_RFH1() bfin_read16(CAN1_RFH1) -#define bfin_write_CAN1_RFH1(val) bfin_write16(CAN1_RFH1, val) -#define bfin_read_CAN1_OPSS1() bfin_read16(CAN1_OPSS1) -#define bfin_write_CAN1_OPSS1(val) bfin_write16(CAN1_OPSS1, val) - -/* CAN Controller 1 Config 2 Registers */ - -#define bfin_read_CAN1_MC2() bfin_read16(CAN1_MC2) -#define bfin_write_CAN1_MC2(val) bfin_write16(CAN1_MC2, val) -#define bfin_read_CAN1_MD2() bfin_read16(CAN1_MD2) -#define bfin_write_CAN1_MD2(val) bfin_write16(CAN1_MD2, val) -#define bfin_read_CAN1_TRS2() bfin_read16(CAN1_TRS2) -#define bfin_write_CAN1_TRS2(val) bfin_write16(CAN1_TRS2, val) -#define bfin_read_CAN1_TRR2() bfin_read16(CAN1_TRR2) -#define bfin_write_CAN1_TRR2(val) bfin_write16(CAN1_TRR2, val) -#define bfin_read_CAN1_TA2() bfin_read16(CAN1_TA2) -#define bfin_write_CAN1_TA2(val) bfin_write16(CAN1_TA2, val) -#define bfin_read_CAN1_AA2() bfin_read16(CAN1_AA2) -#define bfin_write_CAN1_AA2(val) bfin_write16(CAN1_AA2, val) -#define bfin_read_CAN1_RMP2() bfin_read16(CAN1_RMP2) -#define bfin_write_CAN1_RMP2(val) bfin_write16(CAN1_RMP2, val) -#define bfin_read_CAN1_RML2() bfin_read16(CAN1_RML2) -#define bfin_write_CAN1_RML2(val) bfin_write16(CAN1_RML2, val) -#define bfin_read_CAN1_MBTIF2() bfin_read16(CAN1_MBTIF2) -#define bfin_write_CAN1_MBTIF2(val) bfin_write16(CAN1_MBTIF2, val) -#define bfin_read_CAN1_MBRIF2() bfin_read16(CAN1_MBRIF2) -#define bfin_write_CAN1_MBRIF2(val) bfin_write16(CAN1_MBRIF2, val) -#define bfin_read_CAN1_MBIM2() bfin_read16(CAN1_MBIM2) -#define bfin_write_CAN1_MBIM2(val) bfin_write16(CAN1_MBIM2, val) -#define bfin_read_CAN1_RFH2() bfin_read16(CAN1_RFH2) -#define bfin_write_CAN1_RFH2(val) bfin_write16(CAN1_RFH2, val) -#define bfin_read_CAN1_OPSS2() bfin_read16(CAN1_OPSS2) -#define bfin_write_CAN1_OPSS2(val) bfin_write16(CAN1_OPSS2, val) - -/* CAN Controller 1 Clock/Interrubfin_read_()t/Counter Registers */ - -#define bfin_read_CAN1_CLOCK() bfin_read16(CAN1_CLOCK) -#define bfin_write_CAN1_CLOCK(val) bfin_write16(CAN1_CLOCK, val) -#define bfin_read_CAN1_TIMING() bfin_read16(CAN1_TIMING) -#define bfin_write_CAN1_TIMING(val) bfin_write16(CAN1_TIMING, val) -#define bfin_read_CAN1_DEBUG() bfin_read16(CAN1_DEBUG) -#define bfin_write_CAN1_DEBUG(val) bfin_write16(CAN1_DEBUG, val) -#define bfin_read_CAN1_STATUS() bfin_read16(CAN1_STATUS) -#define bfin_write_CAN1_STATUS(val) bfin_write16(CAN1_STATUS, val) -#define bfin_read_CAN1_CEC() bfin_read16(CAN1_CEC) -#define bfin_write_CAN1_CEC(val) bfin_write16(CAN1_CEC, val) -#define bfin_read_CAN1_GIS() bfin_read16(CAN1_GIS) -#define bfin_write_CAN1_GIS(val) bfin_write16(CAN1_GIS, val) -#define bfin_read_CAN1_GIM() bfin_read16(CAN1_GIM) -#define bfin_write_CAN1_GIM(val) bfin_write16(CAN1_GIM, val) -#define bfin_read_CAN1_GIF() bfin_read16(CAN1_GIF) -#define bfin_write_CAN1_GIF(val) bfin_write16(CAN1_GIF, val) -#define bfin_read_CAN1_CONTROL() bfin_read16(CAN1_CONTROL) -#define bfin_write_CAN1_CONTROL(val) bfin_write16(CAN1_CONTROL, val) -#define bfin_read_CAN1_INTR() bfin_read16(CAN1_INTR) -#define bfin_write_CAN1_INTR(val) bfin_write16(CAN1_INTR, val) -#define bfin_read_CAN1_MBTD() bfin_read16(CAN1_MBTD) -#define bfin_write_CAN1_MBTD(val) bfin_write16(CAN1_MBTD, val) -#define bfin_read_CAN1_EWR() bfin_read16(CAN1_EWR) -#define bfin_write_CAN1_EWR(val) bfin_write16(CAN1_EWR, val) -#define bfin_read_CAN1_ESR() bfin_read16(CAN1_ESR) -#define bfin_write_CAN1_ESR(val) bfin_write16(CAN1_ESR, val) -#define bfin_read_CAN1_UCCNT() bfin_read16(CAN1_UCCNT) -#define bfin_write_CAN1_UCCNT(val) bfin_write16(CAN1_UCCNT, val) -#define bfin_read_CAN1_UCRC() bfin_read16(CAN1_UCRC) -#define bfin_write_CAN1_UCRC(val) bfin_write16(CAN1_UCRC, val) -#define bfin_read_CAN1_UCCNF() bfin_read16(CAN1_UCCNF) -#define bfin_write_CAN1_UCCNF(val) bfin_write16(CAN1_UCCNF, val) - -/* CAN Controller 1 Mailbox Accebfin_read_()tance Registers */ - -#define bfin_read_CAN1_AM00L() bfin_read16(CAN1_AM00L) -#define bfin_write_CAN1_AM00L(val) bfin_write16(CAN1_AM00L, val) -#define bfin_read_CAN1_AM00H() bfin_read16(CAN1_AM00H) -#define bfin_write_CAN1_AM00H(val) bfin_write16(CAN1_AM00H, val) -#define bfin_read_CAN1_AM01L() bfin_read16(CAN1_AM01L) -#define bfin_write_CAN1_AM01L(val) bfin_write16(CAN1_AM01L, val) -#define bfin_read_CAN1_AM01H() bfin_read16(CAN1_AM01H) -#define bfin_write_CAN1_AM01H(val) bfin_write16(CAN1_AM01H, val) -#define bfin_read_CAN1_AM02L() bfin_read16(CAN1_AM02L) -#define bfin_write_CAN1_AM02L(val) bfin_write16(CAN1_AM02L, val) -#define bfin_read_CAN1_AM02H() bfin_read16(CAN1_AM02H) -#define bfin_write_CAN1_AM02H(val) bfin_write16(CAN1_AM02H, val) -#define bfin_read_CAN1_AM03L() bfin_read16(CAN1_AM03L) -#define bfin_write_CAN1_AM03L(val) bfin_write16(CAN1_AM03L, val) -#define bfin_read_CAN1_AM03H() bfin_read16(CAN1_AM03H) -#define bfin_write_CAN1_AM03H(val) bfin_write16(CAN1_AM03H, val) -#define bfin_read_CAN1_AM04L() bfin_read16(CAN1_AM04L) -#define bfin_write_CAN1_AM04L(val) bfin_write16(CAN1_AM04L, val) -#define bfin_read_CAN1_AM04H() bfin_read16(CAN1_AM04H) -#define bfin_write_CAN1_AM04H(val) bfin_write16(CAN1_AM04H, val) -#define bfin_read_CAN1_AM05L() bfin_read16(CAN1_AM05L) -#define bfin_write_CAN1_AM05L(val) bfin_write16(CAN1_AM05L, val) -#define bfin_read_CAN1_AM05H() bfin_read16(CAN1_AM05H) -#define bfin_write_CAN1_AM05H(val) bfin_write16(CAN1_AM05H, val) -#define bfin_read_CAN1_AM06L() bfin_read16(CAN1_AM06L) -#define bfin_write_CAN1_AM06L(val) bfin_write16(CAN1_AM06L, val) -#define bfin_read_CAN1_AM06H() bfin_read16(CAN1_AM06H) -#define bfin_write_CAN1_AM06H(val) bfin_write16(CAN1_AM06H, val) -#define bfin_read_CAN1_AM07L() bfin_read16(CAN1_AM07L) -#define bfin_write_CAN1_AM07L(val) bfin_write16(CAN1_AM07L, val) -#define bfin_read_CAN1_AM07H() bfin_read16(CAN1_AM07H) -#define bfin_write_CAN1_AM07H(val) bfin_write16(CAN1_AM07H, val) -#define bfin_read_CAN1_AM08L() bfin_read16(CAN1_AM08L) -#define bfin_write_CAN1_AM08L(val) bfin_write16(CAN1_AM08L, val) -#define bfin_read_CAN1_AM08H() bfin_read16(CAN1_AM08H) -#define bfin_write_CAN1_AM08H(val) bfin_write16(CAN1_AM08H, val) -#define bfin_read_CAN1_AM09L() bfin_read16(CAN1_AM09L) -#define bfin_write_CAN1_AM09L(val) bfin_write16(CAN1_AM09L, val) -#define bfin_read_CAN1_AM09H() bfin_read16(CAN1_AM09H) -#define bfin_write_CAN1_AM09H(val) bfin_write16(CAN1_AM09H, val) -#define bfin_read_CAN1_AM10L() bfin_read16(CAN1_AM10L) -#define bfin_write_CAN1_AM10L(val) bfin_write16(CAN1_AM10L, val) -#define bfin_read_CAN1_AM10H() bfin_read16(CAN1_AM10H) -#define bfin_write_CAN1_AM10H(val) bfin_write16(CAN1_AM10H, val) -#define bfin_read_CAN1_AM11L() bfin_read16(CAN1_AM11L) -#define bfin_write_CAN1_AM11L(val) bfin_write16(CAN1_AM11L, val) -#define bfin_read_CAN1_AM11H() bfin_read16(CAN1_AM11H) -#define bfin_write_CAN1_AM11H(val) bfin_write16(CAN1_AM11H, val) -#define bfin_read_CAN1_AM12L() bfin_read16(CAN1_AM12L) -#define bfin_write_CAN1_AM12L(val) bfin_write16(CAN1_AM12L, val) -#define bfin_read_CAN1_AM12H() bfin_read16(CAN1_AM12H) -#define bfin_write_CAN1_AM12H(val) bfin_write16(CAN1_AM12H, val) -#define bfin_read_CAN1_AM13L() bfin_read16(CAN1_AM13L) -#define bfin_write_CAN1_AM13L(val) bfin_write16(CAN1_AM13L, val) -#define bfin_read_CAN1_AM13H() bfin_read16(CAN1_AM13H) -#define bfin_write_CAN1_AM13H(val) bfin_write16(CAN1_AM13H, val) -#define bfin_read_CAN1_AM14L() bfin_read16(CAN1_AM14L) -#define bfin_write_CAN1_AM14L(val) bfin_write16(CAN1_AM14L, val) -#define bfin_read_CAN1_AM14H() bfin_read16(CAN1_AM14H) -#define bfin_write_CAN1_AM14H(val) bfin_write16(CAN1_AM14H, val) -#define bfin_read_CAN1_AM15L() bfin_read16(CAN1_AM15L) -#define bfin_write_CAN1_AM15L(val) bfin_write16(CAN1_AM15L, val) -#define bfin_read_CAN1_AM15H() bfin_read16(CAN1_AM15H) -#define bfin_write_CAN1_AM15H(val) bfin_write16(CAN1_AM15H, val) - -/* CAN Controller 1 Mailbox Accebfin_read_()tance Registers */ - -#define bfin_read_CAN1_AM16L() bfin_read16(CAN1_AM16L) -#define bfin_write_CAN1_AM16L(val) bfin_write16(CAN1_AM16L, val) -#define bfin_read_CAN1_AM16H() bfin_read16(CAN1_AM16H) -#define bfin_write_CAN1_AM16H(val) bfin_write16(CAN1_AM16H, val) -#define bfin_read_CAN1_AM17L() bfin_read16(CAN1_AM17L) -#define bfin_write_CAN1_AM17L(val) bfin_write16(CAN1_AM17L, val) -#define bfin_read_CAN1_AM17H() bfin_read16(CAN1_AM17H) -#define bfin_write_CAN1_AM17H(val) bfin_write16(CAN1_AM17H, val) -#define bfin_read_CAN1_AM18L() bfin_read16(CAN1_AM18L) -#define bfin_write_CAN1_AM18L(val) bfin_write16(CAN1_AM18L, val) -#define bfin_read_CAN1_AM18H() bfin_read16(CAN1_AM18H) -#define bfin_write_CAN1_AM18H(val) bfin_write16(CAN1_AM18H, val) -#define bfin_read_CAN1_AM19L() bfin_read16(CAN1_AM19L) -#define bfin_write_CAN1_AM19L(val) bfin_write16(CAN1_AM19L, val) -#define bfin_read_CAN1_AM19H() bfin_read16(CAN1_AM19H) -#define bfin_write_CAN1_AM19H(val) bfin_write16(CAN1_AM19H, val) -#define bfin_read_CAN1_AM20L() bfin_read16(CAN1_AM20L) -#define bfin_write_CAN1_AM20L(val) bfin_write16(CAN1_AM20L, val) -#define bfin_read_CAN1_AM20H() bfin_read16(CAN1_AM20H) -#define bfin_write_CAN1_AM20H(val) bfin_write16(CAN1_AM20H, val) -#define bfin_read_CAN1_AM21L() bfin_read16(CAN1_AM21L) -#define bfin_write_CAN1_AM21L(val) bfin_write16(CAN1_AM21L, val) -#define bfin_read_CAN1_AM21H() bfin_read16(CAN1_AM21H) -#define bfin_write_CAN1_AM21H(val) bfin_write16(CAN1_AM21H, val) -#define bfin_read_CAN1_AM22L() bfin_read16(CAN1_AM22L) -#define bfin_write_CAN1_AM22L(val) bfin_write16(CAN1_AM22L, val) -#define bfin_read_CAN1_AM22H() bfin_read16(CAN1_AM22H) -#define bfin_write_CAN1_AM22H(val) bfin_write16(CAN1_AM22H, val) -#define bfin_read_CAN1_AM23L() bfin_read16(CAN1_AM23L) -#define bfin_write_CAN1_AM23L(val) bfin_write16(CAN1_AM23L, val) -#define bfin_read_CAN1_AM23H() bfin_read16(CAN1_AM23H) -#define bfin_write_CAN1_AM23H(val) bfin_write16(CAN1_AM23H, val) -#define bfin_read_CAN1_AM24L() bfin_read16(CAN1_AM24L) -#define bfin_write_CAN1_AM24L(val) bfin_write16(CAN1_AM24L, val) -#define bfin_read_CAN1_AM24H() bfin_read16(CAN1_AM24H) -#define bfin_write_CAN1_AM24H(val) bfin_write16(CAN1_AM24H, val) -#define bfin_read_CAN1_AM25L() bfin_read16(CAN1_AM25L) -#define bfin_write_CAN1_AM25L(val) bfin_write16(CAN1_AM25L, val) -#define bfin_read_CAN1_AM25H() bfin_read16(CAN1_AM25H) -#define bfin_write_CAN1_AM25H(val) bfin_write16(CAN1_AM25H, val) -#define bfin_read_CAN1_AM26L() bfin_read16(CAN1_AM26L) -#define bfin_write_CAN1_AM26L(val) bfin_write16(CAN1_AM26L, val) -#define bfin_read_CAN1_AM26H() bfin_read16(CAN1_AM26H) -#define bfin_write_CAN1_AM26H(val) bfin_write16(CAN1_AM26H, val) -#define bfin_read_CAN1_AM27L() bfin_read16(CAN1_AM27L) -#define bfin_write_CAN1_AM27L(val) bfin_write16(CAN1_AM27L, val) -#define bfin_read_CAN1_AM27H() bfin_read16(CAN1_AM27H) -#define bfin_write_CAN1_AM27H(val) bfin_write16(CAN1_AM27H, val) -#define bfin_read_CAN1_AM28L() bfin_read16(CAN1_AM28L) -#define bfin_write_CAN1_AM28L(val) bfin_write16(CAN1_AM28L, val) -#define bfin_read_CAN1_AM28H() bfin_read16(CAN1_AM28H) -#define bfin_write_CAN1_AM28H(val) bfin_write16(CAN1_AM28H, val) -#define bfin_read_CAN1_AM29L() bfin_read16(CAN1_AM29L) -#define bfin_write_CAN1_AM29L(val) bfin_write16(CAN1_AM29L, val) -#define bfin_read_CAN1_AM29H() bfin_read16(CAN1_AM29H) -#define bfin_write_CAN1_AM29H(val) bfin_write16(CAN1_AM29H, val) -#define bfin_read_CAN1_AM30L() bfin_read16(CAN1_AM30L) -#define bfin_write_CAN1_AM30L(val) bfin_write16(CAN1_AM30L, val) -#define bfin_read_CAN1_AM30H() bfin_read16(CAN1_AM30H) -#define bfin_write_CAN1_AM30H(val) bfin_write16(CAN1_AM30H, val) -#define bfin_read_CAN1_AM31L() bfin_read16(CAN1_AM31L) -#define bfin_write_CAN1_AM31L(val) bfin_write16(CAN1_AM31L, val) -#define bfin_read_CAN1_AM31H() bfin_read16(CAN1_AM31H) -#define bfin_write_CAN1_AM31H(val) bfin_write16(CAN1_AM31H, val) - -/* CAN Controller 1 Mailbox Data Registers */ - -#define bfin_read_CAN1_MB00_DATA0() bfin_read16(CAN1_MB00_DATA0) -#define bfin_write_CAN1_MB00_DATA0(val) bfin_write16(CAN1_MB00_DATA0, val) -#define bfin_read_CAN1_MB00_DATA1() bfin_read16(CAN1_MB00_DATA1) -#define bfin_write_CAN1_MB00_DATA1(val) bfin_write16(CAN1_MB00_DATA1, val) -#define bfin_read_CAN1_MB00_DATA2() bfin_read16(CAN1_MB00_DATA2) -#define bfin_write_CAN1_MB00_DATA2(val) bfin_write16(CAN1_MB00_DATA2, val) -#define bfin_read_CAN1_MB00_DATA3() bfin_read16(CAN1_MB00_DATA3) -#define bfin_write_CAN1_MB00_DATA3(val) bfin_write16(CAN1_MB00_DATA3, val) -#define bfin_read_CAN1_MB00_LENGTH() bfin_read16(CAN1_MB00_LENGTH) -#define bfin_write_CAN1_MB00_LENGTH(val) bfin_write16(CAN1_MB00_LENGTH, val) -#define bfin_read_CAN1_MB00_TIMESTAMP() bfin_read16(CAN1_MB00_TIMESTAMP) -#define bfin_write_CAN1_MB00_TIMESTAMP(val) bfin_write16(CAN1_MB00_TIMESTAMP, val) -#define bfin_read_CAN1_MB00_ID0() bfin_read16(CAN1_MB00_ID0) -#define bfin_write_CAN1_MB00_ID0(val) bfin_write16(CAN1_MB00_ID0, val) -#define bfin_read_CAN1_MB00_ID1() bfin_read16(CAN1_MB00_ID1) -#define bfin_write_CAN1_MB00_ID1(val) bfin_write16(CAN1_MB00_ID1, val) -#define bfin_read_CAN1_MB01_DATA0() bfin_read16(CAN1_MB01_DATA0) -#define bfin_write_CAN1_MB01_DATA0(val) bfin_write16(CAN1_MB01_DATA0, val) -#define bfin_read_CAN1_MB01_DATA1() bfin_read16(CAN1_MB01_DATA1) -#define bfin_write_CAN1_MB01_DATA1(val) bfin_write16(CAN1_MB01_DATA1, val) -#define bfin_read_CAN1_MB01_DATA2() bfin_read16(CAN1_MB01_DATA2) -#define bfin_write_CAN1_MB01_DATA2(val) bfin_write16(CAN1_MB01_DATA2, val) -#define bfin_read_CAN1_MB01_DATA3() bfin_read16(CAN1_MB01_DATA3) -#define bfin_write_CAN1_MB01_DATA3(val) bfin_write16(CAN1_MB01_DATA3, val) -#define bfin_read_CAN1_MB01_LENGTH() bfin_read16(CAN1_MB01_LENGTH) -#define bfin_write_CAN1_MB01_LENGTH(val) bfin_write16(CAN1_MB01_LENGTH, val) -#define bfin_read_CAN1_MB01_TIMESTAMP() bfin_read16(CAN1_MB01_TIMESTAMP) -#define bfin_write_CAN1_MB01_TIMESTAMP(val) bfin_write16(CAN1_MB01_TIMESTAMP, val) -#define bfin_read_CAN1_MB01_ID0() bfin_read16(CAN1_MB01_ID0) -#define bfin_write_CAN1_MB01_ID0(val) bfin_write16(CAN1_MB01_ID0, val) -#define bfin_read_CAN1_MB01_ID1() bfin_read16(CAN1_MB01_ID1) -#define bfin_write_CAN1_MB01_ID1(val) bfin_write16(CAN1_MB01_ID1, val) -#define bfin_read_CAN1_MB02_DATA0() bfin_read16(CAN1_MB02_DATA0) -#define bfin_write_CAN1_MB02_DATA0(val) bfin_write16(CAN1_MB02_DATA0, val) -#define bfin_read_CAN1_MB02_DATA1() bfin_read16(CAN1_MB02_DATA1) -#define bfin_write_CAN1_MB02_DATA1(val) bfin_write16(CAN1_MB02_DATA1, val) -#define bfin_read_CAN1_MB02_DATA2() bfin_read16(CAN1_MB02_DATA2) -#define bfin_write_CAN1_MB02_DATA2(val) bfin_write16(CAN1_MB02_DATA2, val) -#define bfin_read_CAN1_MB02_DATA3() bfin_read16(CAN1_MB02_DATA3) -#define bfin_write_CAN1_MB02_DATA3(val) bfin_write16(CAN1_MB02_DATA3, val) -#define bfin_read_CAN1_MB02_LENGTH() bfin_read16(CAN1_MB02_LENGTH) -#define bfin_write_CAN1_MB02_LENGTH(val) bfin_write16(CAN1_MB02_LENGTH, val) -#define bfin_read_CAN1_MB02_TIMESTAMP() bfin_read16(CAN1_MB02_TIMESTAMP) -#define bfin_write_CAN1_MB02_TIMESTAMP(val) bfin_write16(CAN1_MB02_TIMESTAMP, val) -#define bfin_read_CAN1_MB02_ID0() bfin_read16(CAN1_MB02_ID0) -#define bfin_write_CAN1_MB02_ID0(val) bfin_write16(CAN1_MB02_ID0, val) -#define bfin_read_CAN1_MB02_ID1() bfin_read16(CAN1_MB02_ID1) -#define bfin_write_CAN1_MB02_ID1(val) bfin_write16(CAN1_MB02_ID1, val) -#define bfin_read_CAN1_MB03_DATA0() bfin_read16(CAN1_MB03_DATA0) -#define bfin_write_CAN1_MB03_DATA0(val) bfin_write16(CAN1_MB03_DATA0, val) -#define bfin_read_CAN1_MB03_DATA1() bfin_read16(CAN1_MB03_DATA1) -#define bfin_write_CAN1_MB03_DATA1(val) bfin_write16(CAN1_MB03_DATA1, val) -#define bfin_read_CAN1_MB03_DATA2() bfin_read16(CAN1_MB03_DATA2) -#define bfin_write_CAN1_MB03_DATA2(val) bfin_write16(CAN1_MB03_DATA2, val) -#define bfin_read_CAN1_MB03_DATA3() bfin_read16(CAN1_MB03_DATA3) -#define bfin_write_CAN1_MB03_DATA3(val) bfin_write16(CAN1_MB03_DATA3, val) -#define bfin_read_CAN1_MB03_LENGTH() bfin_read16(CAN1_MB03_LENGTH) -#define bfin_write_CAN1_MB03_LENGTH(val) bfin_write16(CAN1_MB03_LENGTH, val) -#define bfin_read_CAN1_MB03_TIMESTAMP() bfin_read16(CAN1_MB03_TIMESTAMP) -#define bfin_write_CAN1_MB03_TIMESTAMP(val) bfin_write16(CAN1_MB03_TIMESTAMP, val) -#define bfin_read_CAN1_MB03_ID0() bfin_read16(CAN1_MB03_ID0) -#define bfin_write_CAN1_MB03_ID0(val) bfin_write16(CAN1_MB03_ID0, val) -#define bfin_read_CAN1_MB03_ID1() bfin_read16(CAN1_MB03_ID1) -#define bfin_write_CAN1_MB03_ID1(val) bfin_write16(CAN1_MB03_ID1, val) -#define bfin_read_CAN1_MB04_DATA0() bfin_read16(CAN1_MB04_DATA0) -#define bfin_write_CAN1_MB04_DATA0(val) bfin_write16(CAN1_MB04_DATA0, val) -#define bfin_read_CAN1_MB04_DATA1() bfin_read16(CAN1_MB04_DATA1) -#define bfin_write_CAN1_MB04_DATA1(val) bfin_write16(CAN1_MB04_DATA1, val) -#define bfin_read_CAN1_MB04_DATA2() bfin_read16(CAN1_MB04_DATA2) -#define bfin_write_CAN1_MB04_DATA2(val) bfin_write16(CAN1_MB04_DATA2, val) -#define bfin_read_CAN1_MB04_DATA3() bfin_read16(CAN1_MB04_DATA3) -#define bfin_write_CAN1_MB04_DATA3(val) bfin_write16(CAN1_MB04_DATA3, val) -#define bfin_read_CAN1_MB04_LENGTH() bfin_read16(CAN1_MB04_LENGTH) -#define bfin_write_CAN1_MB04_LENGTH(val) bfin_write16(CAN1_MB04_LENGTH, val) -#define bfin_read_CAN1_MB04_TIMESTAMP() bfin_read16(CAN1_MB04_TIMESTAMP) -#define bfin_write_CAN1_MB04_TIMESTAMP(val) bfin_write16(CAN1_MB04_TIMESTAMP, val) -#define bfin_read_CAN1_MB04_ID0() bfin_read16(CAN1_MB04_ID0) -#define bfin_write_CAN1_MB04_ID0(val) bfin_write16(CAN1_MB04_ID0, val) -#define bfin_read_CAN1_MB04_ID1() bfin_read16(CAN1_MB04_ID1) -#define bfin_write_CAN1_MB04_ID1(val) bfin_write16(CAN1_MB04_ID1, val) -#define bfin_read_CAN1_MB05_DATA0() bfin_read16(CAN1_MB05_DATA0) -#define bfin_write_CAN1_MB05_DATA0(val) bfin_write16(CAN1_MB05_DATA0, val) -#define bfin_read_CAN1_MB05_DATA1() bfin_read16(CAN1_MB05_DATA1) -#define bfin_write_CAN1_MB05_DATA1(val) bfin_write16(CAN1_MB05_DATA1, val) -#define bfin_read_CAN1_MB05_DATA2() bfin_read16(CAN1_MB05_DATA2) -#define bfin_write_CAN1_MB05_DATA2(val) bfin_write16(CAN1_MB05_DATA2, val) -#define bfin_read_CAN1_MB05_DATA3() bfin_read16(CAN1_MB05_DATA3) -#define bfin_write_CAN1_MB05_DATA3(val) bfin_write16(CAN1_MB05_DATA3, val) -#define bfin_read_CAN1_MB05_LENGTH() bfin_read16(CAN1_MB05_LENGTH) -#define bfin_write_CAN1_MB05_LENGTH(val) bfin_write16(CAN1_MB05_LENGTH, val) -#define bfin_read_CAN1_MB05_TIMESTAMP() bfin_read16(CAN1_MB05_TIMESTAMP) -#define bfin_write_CAN1_MB05_TIMESTAMP(val) bfin_write16(CAN1_MB05_TIMESTAMP, val) -#define bfin_read_CAN1_MB05_ID0() bfin_read16(CAN1_MB05_ID0) -#define bfin_write_CAN1_MB05_ID0(val) bfin_write16(CAN1_MB05_ID0, val) -#define bfin_read_CAN1_MB05_ID1() bfin_read16(CAN1_MB05_ID1) -#define bfin_write_CAN1_MB05_ID1(val) bfin_write16(CAN1_MB05_ID1, val) -#define bfin_read_CAN1_MB06_DATA0() bfin_read16(CAN1_MB06_DATA0) -#define bfin_write_CAN1_MB06_DATA0(val) bfin_write16(CAN1_MB06_DATA0, val) -#define bfin_read_CAN1_MB06_DATA1() bfin_read16(CAN1_MB06_DATA1) -#define bfin_write_CAN1_MB06_DATA1(val) bfin_write16(CAN1_MB06_DATA1, val) -#define bfin_read_CAN1_MB06_DATA2() bfin_read16(CAN1_MB06_DATA2) -#define bfin_write_CAN1_MB06_DATA2(val) bfin_write16(CAN1_MB06_DATA2, val) -#define bfin_read_CAN1_MB06_DATA3() bfin_read16(CAN1_MB06_DATA3) -#define bfin_write_CAN1_MB06_DATA3(val) bfin_write16(CAN1_MB06_DATA3, val) -#define bfin_read_CAN1_MB06_LENGTH() bfin_read16(CAN1_MB06_LENGTH) -#define bfin_write_CAN1_MB06_LENGTH(val) bfin_write16(CAN1_MB06_LENGTH, val) -#define bfin_read_CAN1_MB06_TIMESTAMP() bfin_read16(CAN1_MB06_TIMESTAMP) -#define bfin_write_CAN1_MB06_TIMESTAMP(val) bfin_write16(CAN1_MB06_TIMESTAMP, val) -#define bfin_read_CAN1_MB06_ID0() bfin_read16(CAN1_MB06_ID0) -#define bfin_write_CAN1_MB06_ID0(val) bfin_write16(CAN1_MB06_ID0, val) -#define bfin_read_CAN1_MB06_ID1() bfin_read16(CAN1_MB06_ID1) -#define bfin_write_CAN1_MB06_ID1(val) bfin_write16(CAN1_MB06_ID1, val) -#define bfin_read_CAN1_MB07_DATA0() bfin_read16(CAN1_MB07_DATA0) -#define bfin_write_CAN1_MB07_DATA0(val) bfin_write16(CAN1_MB07_DATA0, val) -#define bfin_read_CAN1_MB07_DATA1() bfin_read16(CAN1_MB07_DATA1) -#define bfin_write_CAN1_MB07_DATA1(val) bfin_write16(CAN1_MB07_DATA1, val) -#define bfin_read_CAN1_MB07_DATA2() bfin_read16(CAN1_MB07_DATA2) -#define bfin_write_CAN1_MB07_DATA2(val) bfin_write16(CAN1_MB07_DATA2, val) -#define bfin_read_CAN1_MB07_DATA3() bfin_read16(CAN1_MB07_DATA3) -#define bfin_write_CAN1_MB07_DATA3(val) bfin_write16(CAN1_MB07_DATA3, val) -#define bfin_read_CAN1_MB07_LENGTH() bfin_read16(CAN1_MB07_LENGTH) -#define bfin_write_CAN1_MB07_LENGTH(val) bfin_write16(CAN1_MB07_LENGTH, val) -#define bfin_read_CAN1_MB07_TIMESTAMP() bfin_read16(CAN1_MB07_TIMESTAMP) -#define bfin_write_CAN1_MB07_TIMESTAMP(val) bfin_write16(CAN1_MB07_TIMESTAMP, val) -#define bfin_read_CAN1_MB07_ID0() bfin_read16(CAN1_MB07_ID0) -#define bfin_write_CAN1_MB07_ID0(val) bfin_write16(CAN1_MB07_ID0, val) -#define bfin_read_CAN1_MB07_ID1() bfin_read16(CAN1_MB07_ID1) -#define bfin_write_CAN1_MB07_ID1(val) bfin_write16(CAN1_MB07_ID1, val) -#define bfin_read_CAN1_MB08_DATA0() bfin_read16(CAN1_MB08_DATA0) -#define bfin_write_CAN1_MB08_DATA0(val) bfin_write16(CAN1_MB08_DATA0, val) -#define bfin_read_CAN1_MB08_DATA1() bfin_read16(CAN1_MB08_DATA1) -#define bfin_write_CAN1_MB08_DATA1(val) bfin_write16(CAN1_MB08_DATA1, val) -#define bfin_read_CAN1_MB08_DATA2() bfin_read16(CAN1_MB08_DATA2) -#define bfin_write_CAN1_MB08_DATA2(val) bfin_write16(CAN1_MB08_DATA2, val) -#define bfin_read_CAN1_MB08_DATA3() bfin_read16(CAN1_MB08_DATA3) -#define bfin_write_CAN1_MB08_DATA3(val) bfin_write16(CAN1_MB08_DATA3, val) -#define bfin_read_CAN1_MB08_LENGTH() bfin_read16(CAN1_MB08_LENGTH) -#define bfin_write_CAN1_MB08_LENGTH(val) bfin_write16(CAN1_MB08_LENGTH, val) -#define bfin_read_CAN1_MB08_TIMESTAMP() bfin_read16(CAN1_MB08_TIMESTAMP) -#define bfin_write_CAN1_MB08_TIMESTAMP(val) bfin_write16(CAN1_MB08_TIMESTAMP, val) -#define bfin_read_CAN1_MB08_ID0() bfin_read16(CAN1_MB08_ID0) -#define bfin_write_CAN1_MB08_ID0(val) bfin_write16(CAN1_MB08_ID0, val) -#define bfin_read_CAN1_MB08_ID1() bfin_read16(CAN1_MB08_ID1) -#define bfin_write_CAN1_MB08_ID1(val) bfin_write16(CAN1_MB08_ID1, val) -#define bfin_read_CAN1_MB09_DATA0() bfin_read16(CAN1_MB09_DATA0) -#define bfin_write_CAN1_MB09_DATA0(val) bfin_write16(CAN1_MB09_DATA0, val) -#define bfin_read_CAN1_MB09_DATA1() bfin_read16(CAN1_MB09_DATA1) -#define bfin_write_CAN1_MB09_DATA1(val) bfin_write16(CAN1_MB09_DATA1, val) -#define bfin_read_CAN1_MB09_DATA2() bfin_read16(CAN1_MB09_DATA2) -#define bfin_write_CAN1_MB09_DATA2(val) bfin_write16(CAN1_MB09_DATA2, val) -#define bfin_read_CAN1_MB09_DATA3() bfin_read16(CAN1_MB09_DATA3) -#define bfin_write_CAN1_MB09_DATA3(val) bfin_write16(CAN1_MB09_DATA3, val) -#define bfin_read_CAN1_MB09_LENGTH() bfin_read16(CAN1_MB09_LENGTH) -#define bfin_write_CAN1_MB09_LENGTH(val) bfin_write16(CAN1_MB09_LENGTH, val) -#define bfin_read_CAN1_MB09_TIMESTAMP() bfin_read16(CAN1_MB09_TIMESTAMP) -#define bfin_write_CAN1_MB09_TIMESTAMP(val) bfin_write16(CAN1_MB09_TIMESTAMP, val) -#define bfin_read_CAN1_MB09_ID0() bfin_read16(CAN1_MB09_ID0) -#define bfin_write_CAN1_MB09_ID0(val) bfin_write16(CAN1_MB09_ID0, val) -#define bfin_read_CAN1_MB09_ID1() bfin_read16(CAN1_MB09_ID1) -#define bfin_write_CAN1_MB09_ID1(val) bfin_write16(CAN1_MB09_ID1, val) -#define bfin_read_CAN1_MB10_DATA0() bfin_read16(CAN1_MB10_DATA0) -#define bfin_write_CAN1_MB10_DATA0(val) bfin_write16(CAN1_MB10_DATA0, val) -#define bfin_read_CAN1_MB10_DATA1() bfin_read16(CAN1_MB10_DATA1) -#define bfin_write_CAN1_MB10_DATA1(val) bfin_write16(CAN1_MB10_DATA1, val) -#define bfin_read_CAN1_MB10_DATA2() bfin_read16(CAN1_MB10_DATA2) -#define bfin_write_CAN1_MB10_DATA2(val) bfin_write16(CAN1_MB10_DATA2, val) -#define bfin_read_CAN1_MB10_DATA3() bfin_read16(CAN1_MB10_DATA3) -#define bfin_write_CAN1_MB10_DATA3(val) bfin_write16(CAN1_MB10_DATA3, val) -#define bfin_read_CAN1_MB10_LENGTH() bfin_read16(CAN1_MB10_LENGTH) -#define bfin_write_CAN1_MB10_LENGTH(val) bfin_write16(CAN1_MB10_LENGTH, val) -#define bfin_read_CAN1_MB10_TIMESTAMP() bfin_read16(CAN1_MB10_TIMESTAMP) -#define bfin_write_CAN1_MB10_TIMESTAMP(val) bfin_write16(CAN1_MB10_TIMESTAMP, val) -#define bfin_read_CAN1_MB10_ID0() bfin_read16(CAN1_MB10_ID0) -#define bfin_write_CAN1_MB10_ID0(val) bfin_write16(CAN1_MB10_ID0, val) -#define bfin_read_CAN1_MB10_ID1() bfin_read16(CAN1_MB10_ID1) -#define bfin_write_CAN1_MB10_ID1(val) bfin_write16(CAN1_MB10_ID1, val) -#define bfin_read_CAN1_MB11_DATA0() bfin_read16(CAN1_MB11_DATA0) -#define bfin_write_CAN1_MB11_DATA0(val) bfin_write16(CAN1_MB11_DATA0, val) -#define bfin_read_CAN1_MB11_DATA1() bfin_read16(CAN1_MB11_DATA1) -#define bfin_write_CAN1_MB11_DATA1(val) bfin_write16(CAN1_MB11_DATA1, val) -#define bfin_read_CAN1_MB11_DATA2() bfin_read16(CAN1_MB11_DATA2) -#define bfin_write_CAN1_MB11_DATA2(val) bfin_write16(CAN1_MB11_DATA2, val) -#define bfin_read_CAN1_MB11_DATA3() bfin_read16(CAN1_MB11_DATA3) -#define bfin_write_CAN1_MB11_DATA3(val) bfin_write16(CAN1_MB11_DATA3, val) -#define bfin_read_CAN1_MB11_LENGTH() bfin_read16(CAN1_MB11_LENGTH) -#define bfin_write_CAN1_MB11_LENGTH(val) bfin_write16(CAN1_MB11_LENGTH, val) -#define bfin_read_CAN1_MB11_TIMESTAMP() bfin_read16(CAN1_MB11_TIMESTAMP) -#define bfin_write_CAN1_MB11_TIMESTAMP(val) bfin_write16(CAN1_MB11_TIMESTAMP, val) -#define bfin_read_CAN1_MB11_ID0() bfin_read16(CAN1_MB11_ID0) -#define bfin_write_CAN1_MB11_ID0(val) bfin_write16(CAN1_MB11_ID0, val) -#define bfin_read_CAN1_MB11_ID1() bfin_read16(CAN1_MB11_ID1) -#define bfin_write_CAN1_MB11_ID1(val) bfin_write16(CAN1_MB11_ID1, val) -#define bfin_read_CAN1_MB12_DATA0() bfin_read16(CAN1_MB12_DATA0) -#define bfin_write_CAN1_MB12_DATA0(val) bfin_write16(CAN1_MB12_DATA0, val) -#define bfin_read_CAN1_MB12_DATA1() bfin_read16(CAN1_MB12_DATA1) -#define bfin_write_CAN1_MB12_DATA1(val) bfin_write16(CAN1_MB12_DATA1, val) -#define bfin_read_CAN1_MB12_DATA2() bfin_read16(CAN1_MB12_DATA2) -#define bfin_write_CAN1_MB12_DATA2(val) bfin_write16(CAN1_MB12_DATA2, val) -#define bfin_read_CAN1_MB12_DATA3() bfin_read16(CAN1_MB12_DATA3) -#define bfin_write_CAN1_MB12_DATA3(val) bfin_write16(CAN1_MB12_DATA3, val) -#define bfin_read_CAN1_MB12_LENGTH() bfin_read16(CAN1_MB12_LENGTH) -#define bfin_write_CAN1_MB12_LENGTH(val) bfin_write16(CAN1_MB12_LENGTH, val) -#define bfin_read_CAN1_MB12_TIMESTAMP() bfin_read16(CAN1_MB12_TIMESTAMP) -#define bfin_write_CAN1_MB12_TIMESTAMP(val) bfin_write16(CAN1_MB12_TIMESTAMP, val) -#define bfin_read_CAN1_MB12_ID0() bfin_read16(CAN1_MB12_ID0) -#define bfin_write_CAN1_MB12_ID0(val) bfin_write16(CAN1_MB12_ID0, val) -#define bfin_read_CAN1_MB12_ID1() bfin_read16(CAN1_MB12_ID1) -#define bfin_write_CAN1_MB12_ID1(val) bfin_write16(CAN1_MB12_ID1, val) -#define bfin_read_CAN1_MB13_DATA0() bfin_read16(CAN1_MB13_DATA0) -#define bfin_write_CAN1_MB13_DATA0(val) bfin_write16(CAN1_MB13_DATA0, val) -#define bfin_read_CAN1_MB13_DATA1() bfin_read16(CAN1_MB13_DATA1) -#define bfin_write_CAN1_MB13_DATA1(val) bfin_write16(CAN1_MB13_DATA1, val) -#define bfin_read_CAN1_MB13_DATA2() bfin_read16(CAN1_MB13_DATA2) -#define bfin_write_CAN1_MB13_DATA2(val) bfin_write16(CAN1_MB13_DATA2, val) -#define bfin_read_CAN1_MB13_DATA3() bfin_read16(CAN1_MB13_DATA3) -#define bfin_write_CAN1_MB13_DATA3(val) bfin_write16(CAN1_MB13_DATA3, val) -#define bfin_read_CAN1_MB13_LENGTH() bfin_read16(CAN1_MB13_LENGTH) -#define bfin_write_CAN1_MB13_LENGTH(val) bfin_write16(CAN1_MB13_LENGTH, val) -#define bfin_read_CAN1_MB13_TIMESTAMP() bfin_read16(CAN1_MB13_TIMESTAMP) -#define bfin_write_CAN1_MB13_TIMESTAMP(val) bfin_write16(CAN1_MB13_TIMESTAMP, val) -#define bfin_read_CAN1_MB13_ID0() bfin_read16(CAN1_MB13_ID0) -#define bfin_write_CAN1_MB13_ID0(val) bfin_write16(CAN1_MB13_ID0, val) -#define bfin_read_CAN1_MB13_ID1() bfin_read16(CAN1_MB13_ID1) -#define bfin_write_CAN1_MB13_ID1(val) bfin_write16(CAN1_MB13_ID1, val) -#define bfin_read_CAN1_MB14_DATA0() bfin_read16(CAN1_MB14_DATA0) -#define bfin_write_CAN1_MB14_DATA0(val) bfin_write16(CAN1_MB14_DATA0, val) -#define bfin_read_CAN1_MB14_DATA1() bfin_read16(CAN1_MB14_DATA1) -#define bfin_write_CAN1_MB14_DATA1(val) bfin_write16(CAN1_MB14_DATA1, val) -#define bfin_read_CAN1_MB14_DATA2() bfin_read16(CAN1_MB14_DATA2) -#define bfin_write_CAN1_MB14_DATA2(val) bfin_write16(CAN1_MB14_DATA2, val) -#define bfin_read_CAN1_MB14_DATA3() bfin_read16(CAN1_MB14_DATA3) -#define bfin_write_CAN1_MB14_DATA3(val) bfin_write16(CAN1_MB14_DATA3, val) -#define bfin_read_CAN1_MB14_LENGTH() bfin_read16(CAN1_MB14_LENGTH) -#define bfin_write_CAN1_MB14_LENGTH(val) bfin_write16(CAN1_MB14_LENGTH, val) -#define bfin_read_CAN1_MB14_TIMESTAMP() bfin_read16(CAN1_MB14_TIMESTAMP) -#define bfin_write_CAN1_MB14_TIMESTAMP(val) bfin_write16(CAN1_MB14_TIMESTAMP, val) -#define bfin_read_CAN1_MB14_ID0() bfin_read16(CAN1_MB14_ID0) -#define bfin_write_CAN1_MB14_ID0(val) bfin_write16(CAN1_MB14_ID0, val) -#define bfin_read_CAN1_MB14_ID1() bfin_read16(CAN1_MB14_ID1) -#define bfin_write_CAN1_MB14_ID1(val) bfin_write16(CAN1_MB14_ID1, val) -#define bfin_read_CAN1_MB15_DATA0() bfin_read16(CAN1_MB15_DATA0) -#define bfin_write_CAN1_MB15_DATA0(val) bfin_write16(CAN1_MB15_DATA0, val) -#define bfin_read_CAN1_MB15_DATA1() bfin_read16(CAN1_MB15_DATA1) -#define bfin_write_CAN1_MB15_DATA1(val) bfin_write16(CAN1_MB15_DATA1, val) -#define bfin_read_CAN1_MB15_DATA2() bfin_read16(CAN1_MB15_DATA2) -#define bfin_write_CAN1_MB15_DATA2(val) bfin_write16(CAN1_MB15_DATA2, val) -#define bfin_read_CAN1_MB15_DATA3() bfin_read16(CAN1_MB15_DATA3) -#define bfin_write_CAN1_MB15_DATA3(val) bfin_write16(CAN1_MB15_DATA3, val) -#define bfin_read_CAN1_MB15_LENGTH() bfin_read16(CAN1_MB15_LENGTH) -#define bfin_write_CAN1_MB15_LENGTH(val) bfin_write16(CAN1_MB15_LENGTH, val) -#define bfin_read_CAN1_MB15_TIMESTAMP() bfin_read16(CAN1_MB15_TIMESTAMP) -#define bfin_write_CAN1_MB15_TIMESTAMP(val) bfin_write16(CAN1_MB15_TIMESTAMP, val) -#define bfin_read_CAN1_MB15_ID0() bfin_read16(CAN1_MB15_ID0) -#define bfin_write_CAN1_MB15_ID0(val) bfin_write16(CAN1_MB15_ID0, val) -#define bfin_read_CAN1_MB15_ID1() bfin_read16(CAN1_MB15_ID1) -#define bfin_write_CAN1_MB15_ID1(val) bfin_write16(CAN1_MB15_ID1, val) - -/* CAN Controller 1 Mailbox Data Registers */ - -#define bfin_read_CAN1_MB16_DATA0() bfin_read16(CAN1_MB16_DATA0) -#define bfin_write_CAN1_MB16_DATA0(val) bfin_write16(CAN1_MB16_DATA0, val) -#define bfin_read_CAN1_MB16_DATA1() bfin_read16(CAN1_MB16_DATA1) -#define bfin_write_CAN1_MB16_DATA1(val) bfin_write16(CAN1_MB16_DATA1, val) -#define bfin_read_CAN1_MB16_DATA2() bfin_read16(CAN1_MB16_DATA2) -#define bfin_write_CAN1_MB16_DATA2(val) bfin_write16(CAN1_MB16_DATA2, val) -#define bfin_read_CAN1_MB16_DATA3() bfin_read16(CAN1_MB16_DATA3) -#define bfin_write_CAN1_MB16_DATA3(val) bfin_write16(CAN1_MB16_DATA3, val) -#define bfin_read_CAN1_MB16_LENGTH() bfin_read16(CAN1_MB16_LENGTH) -#define bfin_write_CAN1_MB16_LENGTH(val) bfin_write16(CAN1_MB16_LENGTH, val) -#define bfin_read_CAN1_MB16_TIMESTAMP() bfin_read16(CAN1_MB16_TIMESTAMP) -#define bfin_write_CAN1_MB16_TIMESTAMP(val) bfin_write16(CAN1_MB16_TIMESTAMP, val) -#define bfin_read_CAN1_MB16_ID0() bfin_read16(CAN1_MB16_ID0) -#define bfin_write_CAN1_MB16_ID0(val) bfin_write16(CAN1_MB16_ID0, val) -#define bfin_read_CAN1_MB16_ID1() bfin_read16(CAN1_MB16_ID1) -#define bfin_write_CAN1_MB16_ID1(val) bfin_write16(CAN1_MB16_ID1, val) -#define bfin_read_CAN1_MB17_DATA0() bfin_read16(CAN1_MB17_DATA0) -#define bfin_write_CAN1_MB17_DATA0(val) bfin_write16(CAN1_MB17_DATA0, val) -#define bfin_read_CAN1_MB17_DATA1() bfin_read16(CAN1_MB17_DATA1) -#define bfin_write_CAN1_MB17_DATA1(val) bfin_write16(CAN1_MB17_DATA1, val) -#define bfin_read_CAN1_MB17_DATA2() bfin_read16(CAN1_MB17_DATA2) -#define bfin_write_CAN1_MB17_DATA2(val) bfin_write16(CAN1_MB17_DATA2, val) -#define bfin_read_CAN1_MB17_DATA3() bfin_read16(CAN1_MB17_DATA3) -#define bfin_write_CAN1_MB17_DATA3(val) bfin_write16(CAN1_MB17_DATA3, val) -#define bfin_read_CAN1_MB17_LENGTH() bfin_read16(CAN1_MB17_LENGTH) -#define bfin_write_CAN1_MB17_LENGTH(val) bfin_write16(CAN1_MB17_LENGTH, val) -#define bfin_read_CAN1_MB17_TIMESTAMP() bfin_read16(CAN1_MB17_TIMESTAMP) -#define bfin_write_CAN1_MB17_TIMESTAMP(val) bfin_write16(CAN1_MB17_TIMESTAMP, val) -#define bfin_read_CAN1_MB17_ID0() bfin_read16(CAN1_MB17_ID0) -#define bfin_write_CAN1_MB17_ID0(val) bfin_write16(CAN1_MB17_ID0, val) -#define bfin_read_CAN1_MB17_ID1() bfin_read16(CAN1_MB17_ID1) -#define bfin_write_CAN1_MB17_ID1(val) bfin_write16(CAN1_MB17_ID1, val) -#define bfin_read_CAN1_MB18_DATA0() bfin_read16(CAN1_MB18_DATA0) -#define bfin_write_CAN1_MB18_DATA0(val) bfin_write16(CAN1_MB18_DATA0, val) -#define bfin_read_CAN1_MB18_DATA1() bfin_read16(CAN1_MB18_DATA1) -#define bfin_write_CAN1_MB18_DATA1(val) bfin_write16(CAN1_MB18_DATA1, val) -#define bfin_read_CAN1_MB18_DATA2() bfin_read16(CAN1_MB18_DATA2) -#define bfin_write_CAN1_MB18_DATA2(val) bfin_write16(CAN1_MB18_DATA2, val) -#define bfin_read_CAN1_MB18_DATA3() bfin_read16(CAN1_MB18_DATA3) -#define bfin_write_CAN1_MB18_DATA3(val) bfin_write16(CAN1_MB18_DATA3, val) -#define bfin_read_CAN1_MB18_LENGTH() bfin_read16(CAN1_MB18_LENGTH) -#define bfin_write_CAN1_MB18_LENGTH(val) bfin_write16(CAN1_MB18_LENGTH, val) -#define bfin_read_CAN1_MB18_TIMESTAMP() bfin_read16(CAN1_MB18_TIMESTAMP) -#define bfin_write_CAN1_MB18_TIMESTAMP(val) bfin_write16(CAN1_MB18_TIMESTAMP, val) -#define bfin_read_CAN1_MB18_ID0() bfin_read16(CAN1_MB18_ID0) -#define bfin_write_CAN1_MB18_ID0(val) bfin_write16(CAN1_MB18_ID0, val) -#define bfin_read_CAN1_MB18_ID1() bfin_read16(CAN1_MB18_ID1) -#define bfin_write_CAN1_MB18_ID1(val) bfin_write16(CAN1_MB18_ID1, val) -#define bfin_read_CAN1_MB19_DATA0() bfin_read16(CAN1_MB19_DATA0) -#define bfin_write_CAN1_MB19_DATA0(val) bfin_write16(CAN1_MB19_DATA0, val) -#define bfin_read_CAN1_MB19_DATA1() bfin_read16(CAN1_MB19_DATA1) -#define bfin_write_CAN1_MB19_DATA1(val) bfin_write16(CAN1_MB19_DATA1, val) -#define bfin_read_CAN1_MB19_DATA2() bfin_read16(CAN1_MB19_DATA2) -#define bfin_write_CAN1_MB19_DATA2(val) bfin_write16(CAN1_MB19_DATA2, val) -#define bfin_read_CAN1_MB19_DATA3() bfin_read16(CAN1_MB19_DATA3) -#define bfin_write_CAN1_MB19_DATA3(val) bfin_write16(CAN1_MB19_DATA3, val) -#define bfin_read_CAN1_MB19_LENGTH() bfin_read16(CAN1_MB19_LENGTH) -#define bfin_write_CAN1_MB19_LENGTH(val) bfin_write16(CAN1_MB19_LENGTH, val) -#define bfin_read_CAN1_MB19_TIMESTAMP() bfin_read16(CAN1_MB19_TIMESTAMP) -#define bfin_write_CAN1_MB19_TIMESTAMP(val) bfin_write16(CAN1_MB19_TIMESTAMP, val) -#define bfin_read_CAN1_MB19_ID0() bfin_read16(CAN1_MB19_ID0) -#define bfin_write_CAN1_MB19_ID0(val) bfin_write16(CAN1_MB19_ID0, val) -#define bfin_read_CAN1_MB19_ID1() bfin_read16(CAN1_MB19_ID1) -#define bfin_write_CAN1_MB19_ID1(val) bfin_write16(CAN1_MB19_ID1, val) -#define bfin_read_CAN1_MB20_DATA0() bfin_read16(CAN1_MB20_DATA0) -#define bfin_write_CAN1_MB20_DATA0(val) bfin_write16(CAN1_MB20_DATA0, val) -#define bfin_read_CAN1_MB20_DATA1() bfin_read16(CAN1_MB20_DATA1) -#define bfin_write_CAN1_MB20_DATA1(val) bfin_write16(CAN1_MB20_DATA1, val) -#define bfin_read_CAN1_MB20_DATA2() bfin_read16(CAN1_MB20_DATA2) -#define bfin_write_CAN1_MB20_DATA2(val) bfin_write16(CAN1_MB20_DATA2, val) -#define bfin_read_CAN1_MB20_DATA3() bfin_read16(CAN1_MB20_DATA3) -#define bfin_write_CAN1_MB20_DATA3(val) bfin_write16(CAN1_MB20_DATA3, val) -#define bfin_read_CAN1_MB20_LENGTH() bfin_read16(CAN1_MB20_LENGTH) -#define bfin_write_CAN1_MB20_LENGTH(val) bfin_write16(CAN1_MB20_LENGTH, val) -#define bfin_read_CAN1_MB20_TIMESTAMP() bfin_read16(CAN1_MB20_TIMESTAMP) -#define bfin_write_CAN1_MB20_TIMESTAMP(val) bfin_write16(CAN1_MB20_TIMESTAMP, val) -#define bfin_read_CAN1_MB20_ID0() bfin_read16(CAN1_MB20_ID0) -#define bfin_write_CAN1_MB20_ID0(val) bfin_write16(CAN1_MB20_ID0, val) -#define bfin_read_CAN1_MB20_ID1() bfin_read16(CAN1_MB20_ID1) -#define bfin_write_CAN1_MB20_ID1(val) bfin_write16(CAN1_MB20_ID1, val) -#define bfin_read_CAN1_MB21_DATA0() bfin_read16(CAN1_MB21_DATA0) -#define bfin_write_CAN1_MB21_DATA0(val) bfin_write16(CAN1_MB21_DATA0, val) -#define bfin_read_CAN1_MB21_DATA1() bfin_read16(CAN1_MB21_DATA1) -#define bfin_write_CAN1_MB21_DATA1(val) bfin_write16(CAN1_MB21_DATA1, val) -#define bfin_read_CAN1_MB21_DATA2() bfin_read16(CAN1_MB21_DATA2) -#define bfin_write_CAN1_MB21_DATA2(val) bfin_write16(CAN1_MB21_DATA2, val) -#define bfin_read_CAN1_MB21_DATA3() bfin_read16(CAN1_MB21_DATA3) -#define bfin_write_CAN1_MB21_DATA3(val) bfin_write16(CAN1_MB21_DATA3, val) -#define bfin_read_CAN1_MB21_LENGTH() bfin_read16(CAN1_MB21_LENGTH) -#define bfin_write_CAN1_MB21_LENGTH(val) bfin_write16(CAN1_MB21_LENGTH, val) -#define bfin_read_CAN1_MB21_TIMESTAMP() bfin_read16(CAN1_MB21_TIMESTAMP) -#define bfin_write_CAN1_MB21_TIMESTAMP(val) bfin_write16(CAN1_MB21_TIMESTAMP, val) -#define bfin_read_CAN1_MB21_ID0() bfin_read16(CAN1_MB21_ID0) -#define bfin_write_CAN1_MB21_ID0(val) bfin_write16(CAN1_MB21_ID0, val) -#define bfin_read_CAN1_MB21_ID1() bfin_read16(CAN1_MB21_ID1) -#define bfin_write_CAN1_MB21_ID1(val) bfin_write16(CAN1_MB21_ID1, val) -#define bfin_read_CAN1_MB22_DATA0() bfin_read16(CAN1_MB22_DATA0) -#define bfin_write_CAN1_MB22_DATA0(val) bfin_write16(CAN1_MB22_DATA0, val) -#define bfin_read_CAN1_MB22_DATA1() bfin_read16(CAN1_MB22_DATA1) -#define bfin_write_CAN1_MB22_DATA1(val) bfin_write16(CAN1_MB22_DATA1, val) -#define bfin_read_CAN1_MB22_DATA2() bfin_read16(CAN1_MB22_DATA2) -#define bfin_write_CAN1_MB22_DATA2(val) bfin_write16(CAN1_MB22_DATA2, val) -#define bfin_read_CAN1_MB22_DATA3() bfin_read16(CAN1_MB22_DATA3) -#define bfin_write_CAN1_MB22_DATA3(val) bfin_write16(CAN1_MB22_DATA3, val) -#define bfin_read_CAN1_MB22_LENGTH() bfin_read16(CAN1_MB22_LENGTH) -#define bfin_write_CAN1_MB22_LENGTH(val) bfin_write16(CAN1_MB22_LENGTH, val) -#define bfin_read_CAN1_MB22_TIMESTAMP() bfin_read16(CAN1_MB22_TIMESTAMP) -#define bfin_write_CAN1_MB22_TIMESTAMP(val) bfin_write16(CAN1_MB22_TIMESTAMP, val) -#define bfin_read_CAN1_MB22_ID0() bfin_read16(CAN1_MB22_ID0) -#define bfin_write_CAN1_MB22_ID0(val) bfin_write16(CAN1_MB22_ID0, val) -#define bfin_read_CAN1_MB22_ID1() bfin_read16(CAN1_MB22_ID1) -#define bfin_write_CAN1_MB22_ID1(val) bfin_write16(CAN1_MB22_ID1, val) -#define bfin_read_CAN1_MB23_DATA0() bfin_read16(CAN1_MB23_DATA0) -#define bfin_write_CAN1_MB23_DATA0(val) bfin_write16(CAN1_MB23_DATA0, val) -#define bfin_read_CAN1_MB23_DATA1() bfin_read16(CAN1_MB23_DATA1) -#define bfin_write_CAN1_MB23_DATA1(val) bfin_write16(CAN1_MB23_DATA1, val) -#define bfin_read_CAN1_MB23_DATA2() bfin_read16(CAN1_MB23_DATA2) -#define bfin_write_CAN1_MB23_DATA2(val) bfin_write16(CAN1_MB23_DATA2, val) -#define bfin_read_CAN1_MB23_DATA3() bfin_read16(CAN1_MB23_DATA3) -#define bfin_write_CAN1_MB23_DATA3(val) bfin_write16(CAN1_MB23_DATA3, val) -#define bfin_read_CAN1_MB23_LENGTH() bfin_read16(CAN1_MB23_LENGTH) -#define bfin_write_CAN1_MB23_LENGTH(val) bfin_write16(CAN1_MB23_LENGTH, val) -#define bfin_read_CAN1_MB23_TIMESTAMP() bfin_read16(CAN1_MB23_TIMESTAMP) -#define bfin_write_CAN1_MB23_TIMESTAMP(val) bfin_write16(CAN1_MB23_TIMESTAMP, val) -#define bfin_read_CAN1_MB23_ID0() bfin_read16(CAN1_MB23_ID0) -#define bfin_write_CAN1_MB23_ID0(val) bfin_write16(CAN1_MB23_ID0, val) -#define bfin_read_CAN1_MB23_ID1() bfin_read16(CAN1_MB23_ID1) -#define bfin_write_CAN1_MB23_ID1(val) bfin_write16(CAN1_MB23_ID1, val) -#define bfin_read_CAN1_MB24_DATA0() bfin_read16(CAN1_MB24_DATA0) -#define bfin_write_CAN1_MB24_DATA0(val) bfin_write16(CAN1_MB24_DATA0, val) -#define bfin_read_CAN1_MB24_DATA1() bfin_read16(CAN1_MB24_DATA1) -#define bfin_write_CAN1_MB24_DATA1(val) bfin_write16(CAN1_MB24_DATA1, val) -#define bfin_read_CAN1_MB24_DATA2() bfin_read16(CAN1_MB24_DATA2) -#define bfin_write_CAN1_MB24_DATA2(val) bfin_write16(CAN1_MB24_DATA2, val) -#define bfin_read_CAN1_MB24_DATA3() bfin_read16(CAN1_MB24_DATA3) -#define bfin_write_CAN1_MB24_DATA3(val) bfin_write16(CAN1_MB24_DATA3, val) -#define bfin_read_CAN1_MB24_LENGTH() bfin_read16(CAN1_MB24_LENGTH) -#define bfin_write_CAN1_MB24_LENGTH(val) bfin_write16(CAN1_MB24_LENGTH, val) -#define bfin_read_CAN1_MB24_TIMESTAMP() bfin_read16(CAN1_MB24_TIMESTAMP) -#define bfin_write_CAN1_MB24_TIMESTAMP(val) bfin_write16(CAN1_MB24_TIMESTAMP, val) -#define bfin_read_CAN1_MB24_ID0() bfin_read16(CAN1_MB24_ID0) -#define bfin_write_CAN1_MB24_ID0(val) bfin_write16(CAN1_MB24_ID0, val) -#define bfin_read_CAN1_MB24_ID1() bfin_read16(CAN1_MB24_ID1) -#define bfin_write_CAN1_MB24_ID1(val) bfin_write16(CAN1_MB24_ID1, val) -#define bfin_read_CAN1_MB25_DATA0() bfin_read16(CAN1_MB25_DATA0) -#define bfin_write_CAN1_MB25_DATA0(val) bfin_write16(CAN1_MB25_DATA0, val) -#define bfin_read_CAN1_MB25_DATA1() bfin_read16(CAN1_MB25_DATA1) -#define bfin_write_CAN1_MB25_DATA1(val) bfin_write16(CAN1_MB25_DATA1, val) -#define bfin_read_CAN1_MB25_DATA2() bfin_read16(CAN1_MB25_DATA2) -#define bfin_write_CAN1_MB25_DATA2(val) bfin_write16(CAN1_MB25_DATA2, val) -#define bfin_read_CAN1_MB25_DATA3() bfin_read16(CAN1_MB25_DATA3) -#define bfin_write_CAN1_MB25_DATA3(val) bfin_write16(CAN1_MB25_DATA3, val) -#define bfin_read_CAN1_MB25_LENGTH() bfin_read16(CAN1_MB25_LENGTH) -#define bfin_write_CAN1_MB25_LENGTH(val) bfin_write16(CAN1_MB25_LENGTH, val) -#define bfin_read_CAN1_MB25_TIMESTAMP() bfin_read16(CAN1_MB25_TIMESTAMP) -#define bfin_write_CAN1_MB25_TIMESTAMP(val) bfin_write16(CAN1_MB25_TIMESTAMP, val) -#define bfin_read_CAN1_MB25_ID0() bfin_read16(CAN1_MB25_ID0) -#define bfin_write_CAN1_MB25_ID0(val) bfin_write16(CAN1_MB25_ID0, val) -#define bfin_read_CAN1_MB25_ID1() bfin_read16(CAN1_MB25_ID1) -#define bfin_write_CAN1_MB25_ID1(val) bfin_write16(CAN1_MB25_ID1, val) -#define bfin_read_CAN1_MB26_DATA0() bfin_read16(CAN1_MB26_DATA0) -#define bfin_write_CAN1_MB26_DATA0(val) bfin_write16(CAN1_MB26_DATA0, val) -#define bfin_read_CAN1_MB26_DATA1() bfin_read16(CAN1_MB26_DATA1) -#define bfin_write_CAN1_MB26_DATA1(val) bfin_write16(CAN1_MB26_DATA1, val) -#define bfin_read_CAN1_MB26_DATA2() bfin_read16(CAN1_MB26_DATA2) -#define bfin_write_CAN1_MB26_DATA2(val) bfin_write16(CAN1_MB26_DATA2, val) -#define bfin_read_CAN1_MB26_DATA3() bfin_read16(CAN1_MB26_DATA3) -#define bfin_write_CAN1_MB26_DATA3(val) bfin_write16(CAN1_MB26_DATA3, val) -#define bfin_read_CAN1_MB26_LENGTH() bfin_read16(CAN1_MB26_LENGTH) -#define bfin_write_CAN1_MB26_LENGTH(val) bfin_write16(CAN1_MB26_LENGTH, val) -#define bfin_read_CAN1_MB26_TIMESTAMP() bfin_read16(CAN1_MB26_TIMESTAMP) -#define bfin_write_CAN1_MB26_TIMESTAMP(val) bfin_write16(CAN1_MB26_TIMESTAMP, val) -#define bfin_read_CAN1_MB26_ID0() bfin_read16(CAN1_MB26_ID0) -#define bfin_write_CAN1_MB26_ID0(val) bfin_write16(CAN1_MB26_ID0, val) -#define bfin_read_CAN1_MB26_ID1() bfin_read16(CAN1_MB26_ID1) -#define bfin_write_CAN1_MB26_ID1(val) bfin_write16(CAN1_MB26_ID1, val) -#define bfin_read_CAN1_MB27_DATA0() bfin_read16(CAN1_MB27_DATA0) -#define bfin_write_CAN1_MB27_DATA0(val) bfin_write16(CAN1_MB27_DATA0, val) -#define bfin_read_CAN1_MB27_DATA1() bfin_read16(CAN1_MB27_DATA1) -#define bfin_write_CAN1_MB27_DATA1(val) bfin_write16(CAN1_MB27_DATA1, val) -#define bfin_read_CAN1_MB27_DATA2() bfin_read16(CAN1_MB27_DATA2) -#define bfin_write_CAN1_MB27_DATA2(val) bfin_write16(CAN1_MB27_DATA2, val) -#define bfin_read_CAN1_MB27_DATA3() bfin_read16(CAN1_MB27_DATA3) -#define bfin_write_CAN1_MB27_DATA3(val) bfin_write16(CAN1_MB27_DATA3, val) -#define bfin_read_CAN1_MB27_LENGTH() bfin_read16(CAN1_MB27_LENGTH) -#define bfin_write_CAN1_MB27_LENGTH(val) bfin_write16(CAN1_MB27_LENGTH, val) -#define bfin_read_CAN1_MB27_TIMESTAMP() bfin_read16(CAN1_MB27_TIMESTAMP) -#define bfin_write_CAN1_MB27_TIMESTAMP(val) bfin_write16(CAN1_MB27_TIMESTAMP, val) -#define bfin_read_CAN1_MB27_ID0() bfin_read16(CAN1_MB27_ID0) -#define bfin_write_CAN1_MB27_ID0(val) bfin_write16(CAN1_MB27_ID0, val) -#define bfin_read_CAN1_MB27_ID1() bfin_read16(CAN1_MB27_ID1) -#define bfin_write_CAN1_MB27_ID1(val) bfin_write16(CAN1_MB27_ID1, val) -#define bfin_read_CAN1_MB28_DATA0() bfin_read16(CAN1_MB28_DATA0) -#define bfin_write_CAN1_MB28_DATA0(val) bfin_write16(CAN1_MB28_DATA0, val) -#define bfin_read_CAN1_MB28_DATA1() bfin_read16(CAN1_MB28_DATA1) -#define bfin_write_CAN1_MB28_DATA1(val) bfin_write16(CAN1_MB28_DATA1, val) -#define bfin_read_CAN1_MB28_DATA2() bfin_read16(CAN1_MB28_DATA2) -#define bfin_write_CAN1_MB28_DATA2(val) bfin_write16(CAN1_MB28_DATA2, val) -#define bfin_read_CAN1_MB28_DATA3() bfin_read16(CAN1_MB28_DATA3) -#define bfin_write_CAN1_MB28_DATA3(val) bfin_write16(CAN1_MB28_DATA3, val) -#define bfin_read_CAN1_MB28_LENGTH() bfin_read16(CAN1_MB28_LENGTH) -#define bfin_write_CAN1_MB28_LENGTH(val) bfin_write16(CAN1_MB28_LENGTH, val) -#define bfin_read_CAN1_MB28_TIMESTAMP() bfin_read16(CAN1_MB28_TIMESTAMP) -#define bfin_write_CAN1_MB28_TIMESTAMP(val) bfin_write16(CAN1_MB28_TIMESTAMP, val) -#define bfin_read_CAN1_MB28_ID0() bfin_read16(CAN1_MB28_ID0) -#define bfin_write_CAN1_MB28_ID0(val) bfin_write16(CAN1_MB28_ID0, val) -#define bfin_read_CAN1_MB28_ID1() bfin_read16(CAN1_MB28_ID1) -#define bfin_write_CAN1_MB28_ID1(val) bfin_write16(CAN1_MB28_ID1, val) -#define bfin_read_CAN1_MB29_DATA0() bfin_read16(CAN1_MB29_DATA0) -#define bfin_write_CAN1_MB29_DATA0(val) bfin_write16(CAN1_MB29_DATA0, val) -#define bfin_read_CAN1_MB29_DATA1() bfin_read16(CAN1_MB29_DATA1) -#define bfin_write_CAN1_MB29_DATA1(val) bfin_write16(CAN1_MB29_DATA1, val) -#define bfin_read_CAN1_MB29_DATA2() bfin_read16(CAN1_MB29_DATA2) -#define bfin_write_CAN1_MB29_DATA2(val) bfin_write16(CAN1_MB29_DATA2, val) -#define bfin_read_CAN1_MB29_DATA3() bfin_read16(CAN1_MB29_DATA3) -#define bfin_write_CAN1_MB29_DATA3(val) bfin_write16(CAN1_MB29_DATA3, val) -#define bfin_read_CAN1_MB29_LENGTH() bfin_read16(CAN1_MB29_LENGTH) -#define bfin_write_CAN1_MB29_LENGTH(val) bfin_write16(CAN1_MB29_LENGTH, val) -#define bfin_read_CAN1_MB29_TIMESTAMP() bfin_read16(CAN1_MB29_TIMESTAMP) -#define bfin_write_CAN1_MB29_TIMESTAMP(val) bfin_write16(CAN1_MB29_TIMESTAMP, val) -#define bfin_read_CAN1_MB29_ID0() bfin_read16(CAN1_MB29_ID0) -#define bfin_write_CAN1_MB29_ID0(val) bfin_write16(CAN1_MB29_ID0, val) -#define bfin_read_CAN1_MB29_ID1() bfin_read16(CAN1_MB29_ID1) -#define bfin_write_CAN1_MB29_ID1(val) bfin_write16(CAN1_MB29_ID1, val) -#define bfin_read_CAN1_MB30_DATA0() bfin_read16(CAN1_MB30_DATA0) -#define bfin_write_CAN1_MB30_DATA0(val) bfin_write16(CAN1_MB30_DATA0, val) -#define bfin_read_CAN1_MB30_DATA1() bfin_read16(CAN1_MB30_DATA1) -#define bfin_write_CAN1_MB30_DATA1(val) bfin_write16(CAN1_MB30_DATA1, val) -#define bfin_read_CAN1_MB30_DATA2() bfin_read16(CAN1_MB30_DATA2) -#define bfin_write_CAN1_MB30_DATA2(val) bfin_write16(CAN1_MB30_DATA2, val) -#define bfin_read_CAN1_MB30_DATA3() bfin_read16(CAN1_MB30_DATA3) -#define bfin_write_CAN1_MB30_DATA3(val) bfin_write16(CAN1_MB30_DATA3, val) -#define bfin_read_CAN1_MB30_LENGTH() bfin_read16(CAN1_MB30_LENGTH) -#define bfin_write_CAN1_MB30_LENGTH(val) bfin_write16(CAN1_MB30_LENGTH, val) -#define bfin_read_CAN1_MB30_TIMESTAMP() bfin_read16(CAN1_MB30_TIMESTAMP) -#define bfin_write_CAN1_MB30_TIMESTAMP(val) bfin_write16(CAN1_MB30_TIMESTAMP, val) -#define bfin_read_CAN1_MB30_ID0() bfin_read16(CAN1_MB30_ID0) -#define bfin_write_CAN1_MB30_ID0(val) bfin_write16(CAN1_MB30_ID0, val) -#define bfin_read_CAN1_MB30_ID1() bfin_read16(CAN1_MB30_ID1) -#define bfin_write_CAN1_MB30_ID1(val) bfin_write16(CAN1_MB30_ID1, val) -#define bfin_read_CAN1_MB31_DATA0() bfin_read16(CAN1_MB31_DATA0) -#define bfin_write_CAN1_MB31_DATA0(val) bfin_write16(CAN1_MB31_DATA0, val) -#define bfin_read_CAN1_MB31_DATA1() bfin_read16(CAN1_MB31_DATA1) -#define bfin_write_CAN1_MB31_DATA1(val) bfin_write16(CAN1_MB31_DATA1, val) -#define bfin_read_CAN1_MB31_DATA2() bfin_read16(CAN1_MB31_DATA2) -#define bfin_write_CAN1_MB31_DATA2(val) bfin_write16(CAN1_MB31_DATA2, val) -#define bfin_read_CAN1_MB31_DATA3() bfin_read16(CAN1_MB31_DATA3) -#define bfin_write_CAN1_MB31_DATA3(val) bfin_write16(CAN1_MB31_DATA3, val) -#define bfin_read_CAN1_MB31_LENGTH() bfin_read16(CAN1_MB31_LENGTH) -#define bfin_write_CAN1_MB31_LENGTH(val) bfin_write16(CAN1_MB31_LENGTH, val) -#define bfin_read_CAN1_MB31_TIMESTAMP() bfin_read16(CAN1_MB31_TIMESTAMP) -#define bfin_write_CAN1_MB31_TIMESTAMP(val) bfin_write16(CAN1_MB31_TIMESTAMP, val) -#define bfin_read_CAN1_MB31_ID0() bfin_read16(CAN1_MB31_ID0) -#define bfin_write_CAN1_MB31_ID0(val) bfin_write16(CAN1_MB31_ID0, val) -#define bfin_read_CAN1_MB31_ID1() bfin_read16(CAN1_MB31_ID1) -#define bfin_write_CAN1_MB31_ID1(val) bfin_write16(CAN1_MB31_ID1, val) - -/* ATAPI Registers */ - -#define bfin_read_ATAPI_CONTROL() bfin_read16(ATAPI_CONTROL) -#define bfin_write_ATAPI_CONTROL(val) bfin_write16(ATAPI_CONTROL, val) -#define bfin_read_ATAPI_STATUS() bfin_read16(ATAPI_STATUS) -#define bfin_write_ATAPI_STATUS(val) bfin_write16(ATAPI_STATUS, val) -#define bfin_read_ATAPI_DEV_ADDR() bfin_read16(ATAPI_DEV_ADDR) -#define bfin_write_ATAPI_DEV_ADDR(val) bfin_write16(ATAPI_DEV_ADDR, val) -#define bfin_read_ATAPI_DEV_TXBUF() bfin_read16(ATAPI_DEV_TXBUF) -#define bfin_write_ATAPI_DEV_TXBUF(val) bfin_write16(ATAPI_DEV_TXBUF, val) -#define bfin_read_ATAPI_DEV_RXBUF() bfin_read16(ATAPI_DEV_RXBUF) -#define bfin_write_ATAPI_DEV_RXBUF(val) bfin_write16(ATAPI_DEV_RXBUF, val) -#define bfin_read_ATAPI_INT_MASK() bfin_read16(ATAPI_INT_MASK) -#define bfin_write_ATAPI_INT_MASK(val) bfin_write16(ATAPI_INT_MASK, val) -#define bfin_read_ATAPI_INT_STATUS() bfin_read16(ATAPI_INT_STATUS) -#define bfin_write_ATAPI_INT_STATUS(val) bfin_write16(ATAPI_INT_STATUS, val) -#define bfin_read_ATAPI_XFER_LEN() bfin_read16(ATAPI_XFER_LEN) -#define bfin_write_ATAPI_XFER_LEN(val) bfin_write16(ATAPI_XFER_LEN, val) -#define bfin_read_ATAPI_LINE_STATUS() bfin_read16(ATAPI_LINE_STATUS) -#define bfin_write_ATAPI_LINE_STATUS(val) bfin_write16(ATAPI_LINE_STATUS, val) -#define bfin_read_ATAPI_SM_STATE() bfin_read16(ATAPI_SM_STATE) -#define bfin_write_ATAPI_SM_STATE(val) bfin_write16(ATAPI_SM_STATE, val) -#define bfin_read_ATAPI_TERMINATE() bfin_read16(ATAPI_TERMINATE) -#define bfin_write_ATAPI_TERMINATE(val) bfin_write16(ATAPI_TERMINATE, val) -#define bfin_read_ATAPI_PIO_TFRCNT() bfin_read16(ATAPI_PIO_TFRCNT) -#define bfin_write_ATAPI_PIO_TFRCNT(val) bfin_write16(ATAPI_PIO_TFRCNT, val) -#define bfin_read_ATAPI_DMA_TFRCNT() bfin_read16(ATAPI_DMA_TFRCNT) -#define bfin_write_ATAPI_DMA_TFRCNT(val) bfin_write16(ATAPI_DMA_TFRCNT, val) -#define bfin_read_ATAPI_UMAIN_TFRCNT() bfin_read16(ATAPI_UMAIN_TFRCNT) -#define bfin_write_ATAPI_UMAIN_TFRCNT(val) bfin_write16(ATAPI_UMAIN_TFRCNT, val) -#define bfin_read_ATAPI_UDMAOUT_TFRCNT() bfin_read16(ATAPI_UDMAOUT_TFRCNT) -#define bfin_write_ATAPI_UDMAOUT_TFRCNT(val) bfin_write16(ATAPI_UDMAOUT_TFRCNT, val) -#define bfin_read_ATAPI_REG_TIM_0() bfin_read16(ATAPI_REG_TIM_0) -#define bfin_write_ATAPI_REG_TIM_0(val) bfin_write16(ATAPI_REG_TIM_0, val) -#define bfin_read_ATAPI_PIO_TIM_0() bfin_read16(ATAPI_PIO_TIM_0) -#define bfin_write_ATAPI_PIO_TIM_0(val) bfin_write16(ATAPI_PIO_TIM_0, val) -#define bfin_read_ATAPI_PIO_TIM_1() bfin_read16(ATAPI_PIO_TIM_1) -#define bfin_write_ATAPI_PIO_TIM_1(val) bfin_write16(ATAPI_PIO_TIM_1, val) -#define bfin_read_ATAPI_MULTI_TIM_0() bfin_read16(ATAPI_MULTI_TIM_0) -#define bfin_write_ATAPI_MULTI_TIM_0(val) bfin_write16(ATAPI_MULTI_TIM_0, val) -#define bfin_read_ATAPI_MULTI_TIM_1() bfin_read16(ATAPI_MULTI_TIM_1) -#define bfin_write_ATAPI_MULTI_TIM_1(val) bfin_write16(ATAPI_MULTI_TIM_1, val) -#define bfin_read_ATAPI_MULTI_TIM_2() bfin_read16(ATAPI_MULTI_TIM_2) -#define bfin_write_ATAPI_MULTI_TIM_2(val) bfin_write16(ATAPI_MULTI_TIM_2, val) -#define bfin_read_ATAPI_ULTRA_TIM_0() bfin_read16(ATAPI_ULTRA_TIM_0) -#define bfin_write_ATAPI_ULTRA_TIM_0(val) bfin_write16(ATAPI_ULTRA_TIM_0, val) -#define bfin_read_ATAPI_ULTRA_TIM_1() bfin_read16(ATAPI_ULTRA_TIM_1) -#define bfin_write_ATAPI_ULTRA_TIM_1(val) bfin_write16(ATAPI_ULTRA_TIM_1, val) -#define bfin_read_ATAPI_ULTRA_TIM_2() bfin_read16(ATAPI_ULTRA_TIM_2) -#define bfin_write_ATAPI_ULTRA_TIM_2(val) bfin_write16(ATAPI_ULTRA_TIM_2, val) -#define bfin_read_ATAPI_ULTRA_TIM_3() bfin_read16(ATAPI_ULTRA_TIM_3) -#define bfin_write_ATAPI_ULTRA_TIM_3(val) bfin_write16(ATAPI_ULTRA_TIM_3, val) - -/* SDH Registers */ - -#define bfin_read_SDH_PWR_CTL() bfin_read16(SDH_PWR_CTL) -#define bfin_write_SDH_PWR_CTL(val) bfin_write16(SDH_PWR_CTL, val) -#define bfin_read_SDH_CLK_CTL() bfin_read16(SDH_CLK_CTL) -#define bfin_write_SDH_CLK_CTL(val) bfin_write16(SDH_CLK_CTL, val) -#define bfin_read_SDH_ARGUMENT() bfin_read32(SDH_ARGUMENT) -#define bfin_write_SDH_ARGUMENT(val) bfin_write32(SDH_ARGUMENT, val) -#define bfin_read_SDH_COMMAND() bfin_read16(SDH_COMMAND) -#define bfin_write_SDH_COMMAND(val) bfin_write16(SDH_COMMAND, val) -#define bfin_read_SDH_RESP_CMD() bfin_read16(SDH_RESP_CMD) -#define bfin_write_SDH_RESP_CMD(val) bfin_write16(SDH_RESP_CMD, val) -#define bfin_read_SDH_RESPONSE0() bfin_read32(SDH_RESPONSE0) -#define bfin_write_SDH_RESPONSE0(val) bfin_write32(SDH_RESPONSE0, val) -#define bfin_read_SDH_RESPONSE1() bfin_read32(SDH_RESPONSE1) -#define bfin_write_SDH_RESPONSE1(val) bfin_write32(SDH_RESPONSE1, val) -#define bfin_read_SDH_RESPONSE2() bfin_read32(SDH_RESPONSE2) -#define bfin_write_SDH_RESPONSE2(val) bfin_write32(SDH_RESPONSE2, val) -#define bfin_read_SDH_RESPONSE3() bfin_read32(SDH_RESPONSE3) -#define bfin_write_SDH_RESPONSE3(val) bfin_write32(SDH_RESPONSE3, val) -#define bfin_read_SDH_DATA_TIMER() bfin_read32(SDH_DATA_TIMER) -#define bfin_write_SDH_DATA_TIMER(val) bfin_write32(SDH_DATA_TIMER, val) -#define bfin_read_SDH_DATA_LGTH() bfin_read16(SDH_DATA_LGTH) -#define bfin_write_SDH_DATA_LGTH(val) bfin_write16(SDH_DATA_LGTH, val) -#define bfin_read_SDH_DATA_CTL() bfin_read16(SDH_DATA_CTL) -#define bfin_write_SDH_DATA_CTL(val) bfin_write16(SDH_DATA_CTL, val) -#define bfin_read_SDH_DATA_CNT() bfin_read16(SDH_DATA_CNT) -#define bfin_write_SDH_DATA_CNT(val) bfin_write16(SDH_DATA_CNT, val) -#define bfin_read_SDH_STATUS() bfin_read32(SDH_STATUS) -#define bfin_write_SDH_STATUS(val) bfin_write32(SDH_STATUS, val) -#define bfin_read_SDH_STATUS_CLR() bfin_read16(SDH_STATUS_CLR) -#define bfin_write_SDH_STATUS_CLR(val) bfin_write16(SDH_STATUS_CLR, val) -#define bfin_read_SDH_MASK0() bfin_read32(SDH_MASK0) -#define bfin_write_SDH_MASK0(val) bfin_write32(SDH_MASK0, val) -#define bfin_read_SDH_MASK1() bfin_read32(SDH_MASK1) -#define bfin_write_SDH_MASK1(val) bfin_write32(SDH_MASK1, val) -#define bfin_read_SDH_FIFO_CNT() bfin_read16(SDH_FIFO_CNT) -#define bfin_write_SDH_FIFO_CNT(val) bfin_write16(SDH_FIFO_CNT, val) -#define bfin_read_SDH_FIFO() bfin_read32(SDH_FIFO) -#define bfin_write_SDH_FIFO(val) bfin_write32(SDH_FIFO, val) -#define bfin_read_SDH_E_STATUS() bfin_read16(SDH_E_STATUS) -#define bfin_write_SDH_E_STATUS(val) bfin_write16(SDH_E_STATUS, val) -#define bfin_read_SDH_E_MASK() bfin_read16(SDH_E_MASK) -#define bfin_write_SDH_E_MASK(val) bfin_write16(SDH_E_MASK, val) -#define bfin_read_SDH_CFG() bfin_read16(SDH_CFG) -#define bfin_write_SDH_CFG(val) bfin_write16(SDH_CFG, val) -#define bfin_read_SDH_RD_WAIT_EN() bfin_read16(SDH_RD_WAIT_EN) -#define bfin_write_SDH_RD_WAIT_EN(val) bfin_write16(SDH_RD_WAIT_EN, val) -#define bfin_read_SDH_PID0() bfin_read16(SDH_PID0) -#define bfin_write_SDH_PID0(val) bfin_write16(SDH_PID0, val) -#define bfin_read_SDH_PID1() bfin_read16(SDH_PID1) -#define bfin_write_SDH_PID1(val) bfin_write16(SDH_PID1, val) -#define bfin_read_SDH_PID2() bfin_read16(SDH_PID2) -#define bfin_write_SDH_PID2(val) bfin_write16(SDH_PID2, val) -#define bfin_read_SDH_PID3() bfin_read16(SDH_PID3) -#define bfin_write_SDH_PID3(val) bfin_write16(SDH_PID3, val) -#define bfin_read_SDH_PID4() bfin_read16(SDH_PID4) -#define bfin_write_SDH_PID4(val) bfin_write16(SDH_PID4, val) -#define bfin_read_SDH_PID5() bfin_read16(SDH_PID5) -#define bfin_write_SDH_PID5(val) bfin_write16(SDH_PID5, val) -#define bfin_read_SDH_PID6() bfin_read16(SDH_PID6) -#define bfin_write_SDH_PID6(val) bfin_write16(SDH_PID6, val) -#define bfin_read_SDH_PID7() bfin_read16(SDH_PID7) -#define bfin_write_SDH_PID7(val) bfin_write16(SDH_PID7, val) - -/* HOST Port Registers */ - -#define bfin_read_HOST_CONTROL() bfin_read16(HOST_CONTROL) -#define bfin_write_HOST_CONTROL(val) bfin_write16(HOST_CONTROL, val) -#define bfin_read_HOST_STATUS() bfin_read16(HOST_STATUS) -#define bfin_write_HOST_STATUS(val) bfin_write16(HOST_STATUS, val) -#define bfin_read_HOST_TIMEOUT() bfin_read16(HOST_TIMEOUT) -#define bfin_write_HOST_TIMEOUT(val) bfin_write16(HOST_TIMEOUT, val) - -/* USB Control Registers */ - -#define bfin_read_USB_FADDR() bfin_read16(USB_FADDR) -#define bfin_write_USB_FADDR(val) bfin_write16(USB_FADDR, val) -#define bfin_read_USB_POWER() bfin_read16(USB_POWER) -#define bfin_write_USB_POWER(val) bfin_write16(USB_POWER, val) -#define bfin_read_USB_INTRTX() bfin_read16(USB_INTRTX) -#define bfin_write_USB_INTRTX(val) bfin_write16(USB_INTRTX, val) -#define bfin_read_USB_INTRRX() bfin_read16(USB_INTRRX) -#define bfin_write_USB_INTRRX(val) bfin_write16(USB_INTRRX, val) -#define bfin_read_USB_INTRTXE() bfin_read16(USB_INTRTXE) -#define bfin_write_USB_INTRTXE(val) bfin_write16(USB_INTRTXE, val) -#define bfin_read_USB_INTRRXE() bfin_read16(USB_INTRRXE) -#define bfin_write_USB_INTRRXE(val) bfin_write16(USB_INTRRXE, val) -#define bfin_read_USB_INTRUSB() bfin_read16(USB_INTRUSB) -#define bfin_write_USB_INTRUSB(val) bfin_write16(USB_INTRUSB, val) -#define bfin_read_USB_INTRUSBE() bfin_read16(USB_INTRUSBE) -#define bfin_write_USB_INTRUSBE(val) bfin_write16(USB_INTRUSBE, val) -#define bfin_read_USB_FRAME() bfin_read16(USB_FRAME) -#define bfin_write_USB_FRAME(val) bfin_write16(USB_FRAME, val) -#define bfin_read_USB_INDEX() bfin_read16(USB_INDEX) -#define bfin_write_USB_INDEX(val) bfin_write16(USB_INDEX, val) -#define bfin_read_USB_TESTMODE() bfin_read16(USB_TESTMODE) -#define bfin_write_USB_TESTMODE(val) bfin_write16(USB_TESTMODE, val) -#define bfin_read_USB_GLOBINTR() bfin_read16(USB_GLOBINTR) -#define bfin_write_USB_GLOBINTR(val) bfin_write16(USB_GLOBINTR, val) -#define bfin_read_USB_GLOBAL_CTL() bfin_read16(USB_GLOBAL_CTL) -#define bfin_write_USB_GLOBAL_CTL(val) bfin_write16(USB_GLOBAL_CTL, val) - -/* USB Packet Control Registers */ - -#define bfin_read_USB_TX_MAX_PACKET() bfin_read16(USB_TX_MAX_PACKET) -#define bfin_write_USB_TX_MAX_PACKET(val) bfin_write16(USB_TX_MAX_PACKET, val) -#define bfin_read_USB_CSR0() bfin_read16(USB_CSR0) -#define bfin_write_USB_CSR0(val) bfin_write16(USB_CSR0, val) -#define bfin_read_USB_TXCSR() bfin_read16(USB_TXCSR) -#define bfin_write_USB_TXCSR(val) bfin_write16(USB_TXCSR, val) -#define bfin_read_USB_RX_MAX_PACKET() bfin_read16(USB_RX_MAX_PACKET) -#define bfin_write_USB_RX_MAX_PACKET(val) bfin_write16(USB_RX_MAX_PACKET, val) -#define bfin_read_USB_RXCSR() bfin_read16(USB_RXCSR) -#define bfin_write_USB_RXCSR(val) bfin_write16(USB_RXCSR, val) -#define bfin_read_USB_COUNT0() bfin_read16(USB_COUNT0) -#define bfin_write_USB_COUNT0(val) bfin_write16(USB_COUNT0, val) -#define bfin_read_USB_RXCOUNT() bfin_read16(USB_RXCOUNT) -#define bfin_write_USB_RXCOUNT(val) bfin_write16(USB_RXCOUNT, val) -#define bfin_read_USB_TXTYPE() bfin_read16(USB_TXTYPE) -#define bfin_write_USB_TXTYPE(val) bfin_write16(USB_TXTYPE, val) -#define bfin_read_USB_NAKLIMIT0() bfin_read16(USB_NAKLIMIT0) -#define bfin_write_USB_NAKLIMIT0(val) bfin_write16(USB_NAKLIMIT0, val) -#define bfin_read_USB_TXINTERVAL() bfin_read16(USB_TXINTERVAL) -#define bfin_write_USB_TXINTERVAL(val) bfin_write16(USB_TXINTERVAL, val) -#define bfin_read_USB_RXTYPE() bfin_read16(USB_RXTYPE) -#define bfin_write_USB_RXTYPE(val) bfin_write16(USB_RXTYPE, val) -#define bfin_read_USB_RXINTERVAL() bfin_read16(USB_RXINTERVAL) -#define bfin_write_USB_RXINTERVAL(val) bfin_write16(USB_RXINTERVAL, val) -#define bfin_read_USB_TXCOUNT() bfin_read16(USB_TXCOUNT) -#define bfin_write_USB_TXCOUNT(val) bfin_write16(USB_TXCOUNT, val) - -/* USB Endbfin_read_()oint FIFO Registers */ - -#define bfin_read_USB_EP0_FIFO() bfin_read16(USB_EP0_FIFO) -#define bfin_write_USB_EP0_FIFO(val) bfin_write16(USB_EP0_FIFO, val) -#define bfin_read_USB_EP1_FIFO() bfin_read16(USB_EP1_FIFO) -#define bfin_write_USB_EP1_FIFO(val) bfin_write16(USB_EP1_FIFO, val) -#define bfin_read_USB_EP2_FIFO() bfin_read16(USB_EP2_FIFO) -#define bfin_write_USB_EP2_FIFO(val) bfin_write16(USB_EP2_FIFO, val) -#define bfin_read_USB_EP3_FIFO() bfin_read16(USB_EP3_FIFO) -#define bfin_write_USB_EP3_FIFO(val) bfin_write16(USB_EP3_FIFO, val) -#define bfin_read_USB_EP4_FIFO() bfin_read16(USB_EP4_FIFO) -#define bfin_write_USB_EP4_FIFO(val) bfin_write16(USB_EP4_FIFO, val) -#define bfin_read_USB_EP5_FIFO() bfin_read16(USB_EP5_FIFO) -#define bfin_write_USB_EP5_FIFO(val) bfin_write16(USB_EP5_FIFO, val) -#define bfin_read_USB_EP6_FIFO() bfin_read16(USB_EP6_FIFO) -#define bfin_write_USB_EP6_FIFO(val) bfin_write16(USB_EP6_FIFO, val) -#define bfin_read_USB_EP7_FIFO() bfin_read16(USB_EP7_FIFO) -#define bfin_write_USB_EP7_FIFO(val) bfin_write16(USB_EP7_FIFO, val) - -/* USB OTG Control Registers */ - -#define bfin_read_USB_OTG_DEV_CTL() bfin_read16(USB_OTG_DEV_CTL) -#define bfin_write_USB_OTG_DEV_CTL(val) bfin_write16(USB_OTG_DEV_CTL, val) -#define bfin_read_USB_OTG_VBUS_IRQ() bfin_read16(USB_OTG_VBUS_IRQ) -#define bfin_write_USB_OTG_VBUS_IRQ(val) bfin_write16(USB_OTG_VBUS_IRQ, val) -#define bfin_read_USB_OTG_VBUS_MASK() bfin_read16(USB_OTG_VBUS_MASK) -#define bfin_write_USB_OTG_VBUS_MASK(val) bfin_write16(USB_OTG_VBUS_MASK, val) - -/* USB Phy Control Registers */ - -#define bfin_read_USB_LINKINFO() bfin_read16(USB_LINKINFO) -#define bfin_write_USB_LINKINFO(val) bfin_write16(USB_LINKINFO, val) -#define bfin_read_USB_VPLEN() bfin_read16(USB_VPLEN) -#define bfin_write_USB_VPLEN(val) bfin_write16(USB_VPLEN, val) -#define bfin_read_USB_HS_EOF1() bfin_read16(USB_HS_EOF1) -#define bfin_write_USB_HS_EOF1(val) bfin_write16(USB_HS_EOF1, val) -#define bfin_read_USB_FS_EOF1() bfin_read16(USB_FS_EOF1) -#define bfin_write_USB_FS_EOF1(val) bfin_write16(USB_FS_EOF1, val) -#define bfin_read_USB_LS_EOF1() bfin_read16(USB_LS_EOF1) -#define bfin_write_USB_LS_EOF1(val) bfin_write16(USB_LS_EOF1, val) - -/* (APHY_CNTRL is for ADI usage only) */ - -#define bfin_read_USB_APHY_CNTRL() bfin_read16(USB_APHY_CNTRL) -#define bfin_write_USB_APHY_CNTRL(val) bfin_write16(USB_APHY_CNTRL, val) - -/* (APHY_CALIB is for ADI usage only) */ - -#define bfin_read_USB_APHY_CALIB() bfin_read16(USB_APHY_CALIB) -#define bfin_write_USB_APHY_CALIB(val) bfin_write16(USB_APHY_CALIB, val) -#define bfin_read_USB_APHY_CNTRL2() bfin_read16(USB_APHY_CNTRL2) -#define bfin_write_USB_APHY_CNTRL2(val) bfin_write16(USB_APHY_CNTRL2, val) - -/* (PHY_TEST is for ADI usage only) */ - -#define bfin_read_USB_PHY_TEST() bfin_read16(USB_PHY_TEST) -#define bfin_write_USB_PHY_TEST(val) bfin_write16(USB_PHY_TEST, val) -#define bfin_read_USB_PLLOSC_CTRL() bfin_read16(USB_PLLOSC_CTRL) -#define bfin_write_USB_PLLOSC_CTRL(val) bfin_write16(USB_PLLOSC_CTRL, val) -#define bfin_read_USB_SRP_CLKDIV() bfin_read16(USB_SRP_CLKDIV) -#define bfin_write_USB_SRP_CLKDIV(val) bfin_write16(USB_SRP_CLKDIV, val) - -/* USB Endbfin_read_()oint 0 Control Registers */ - -#define bfin_read_USB_EP_NI0_TXMAXP() bfin_read16(USB_EP_NI0_TXMAXP) -#define bfin_write_USB_EP_NI0_TXMAXP(val) bfin_write16(USB_EP_NI0_TXMAXP, val) -#define bfin_read_USB_EP_NI0_TXCSR() bfin_read16(USB_EP_NI0_TXCSR) -#define bfin_write_USB_EP_NI0_TXCSR(val) bfin_write16(USB_EP_NI0_TXCSR, val) -#define bfin_read_USB_EP_NI0_RXMAXP() bfin_read16(USB_EP_NI0_RXMAXP) -#define bfin_write_USB_EP_NI0_RXMAXP(val) bfin_write16(USB_EP_NI0_RXMAXP, val) -#define bfin_read_USB_EP_NI0_RXCSR() bfin_read16(USB_EP_NI0_RXCSR) -#define bfin_write_USB_EP_NI0_RXCSR(val) bfin_write16(USB_EP_NI0_RXCSR, val) -#define bfin_read_USB_EP_NI0_RXCOUNT() bfin_read16(USB_EP_NI0_RXCOUNT) -#define bfin_write_USB_EP_NI0_RXCOUNT(val) bfin_write16(USB_EP_NI0_RXCOUNT, val) -#define bfin_read_USB_EP_NI0_TXTYPE() bfin_read16(USB_EP_NI0_TXTYPE) -#define bfin_write_USB_EP_NI0_TXTYPE(val) bfin_write16(USB_EP_NI0_TXTYPE, val) -#define bfin_read_USB_EP_NI0_TXINTERVAL() bfin_read16(USB_EP_NI0_TXINTERVAL) -#define bfin_write_USB_EP_NI0_TXINTERVAL(val) bfin_write16(USB_EP_NI0_TXINTERVAL, val) -#define bfin_read_USB_EP_NI0_RXTYPE() bfin_read16(USB_EP_NI0_RXTYPE) -#define bfin_write_USB_EP_NI0_RXTYPE(val) bfin_write16(USB_EP_NI0_RXTYPE, val) -#define bfin_read_USB_EP_NI0_RXINTERVAL() bfin_read16(USB_EP_NI0_RXINTERVAL) -#define bfin_write_USB_EP_NI0_RXINTERVAL(val) bfin_write16(USB_EP_NI0_RXINTERVAL, val) - -/* USB Endbfin_read_()oint 1 Control Registers */ - -#define bfin_read_USB_EP_NI0_TXCOUNT() bfin_read16(USB_EP_NI0_TXCOUNT) -#define bfin_write_USB_EP_NI0_TXCOUNT(val) bfin_write16(USB_EP_NI0_TXCOUNT, val) -#define bfin_read_USB_EP_NI1_TXMAXP() bfin_read16(USB_EP_NI1_TXMAXP) -#define bfin_write_USB_EP_NI1_TXMAXP(val) bfin_write16(USB_EP_NI1_TXMAXP, val) -#define bfin_read_USB_EP_NI1_TXCSR() bfin_read16(USB_EP_NI1_TXCSR) -#define bfin_write_USB_EP_NI1_TXCSR(val) bfin_write16(USB_EP_NI1_TXCSR, val) -#define bfin_read_USB_EP_NI1_RXMAXP() bfin_read16(USB_EP_NI1_RXMAXP) -#define bfin_write_USB_EP_NI1_RXMAXP(val) bfin_write16(USB_EP_NI1_RXMAXP, val) -#define bfin_read_USB_EP_NI1_RXCSR() bfin_read16(USB_EP_NI1_RXCSR) -#define bfin_write_USB_EP_NI1_RXCSR(val) bfin_write16(USB_EP_NI1_RXCSR, val) -#define bfin_read_USB_EP_NI1_RXCOUNT() bfin_read16(USB_EP_NI1_RXCOUNT) -#define bfin_write_USB_EP_NI1_RXCOUNT(val) bfin_write16(USB_EP_NI1_RXCOUNT, val) -#define bfin_read_USB_EP_NI1_TXTYPE() bfin_read16(USB_EP_NI1_TXTYPE) -#define bfin_write_USB_EP_NI1_TXTYPE(val) bfin_write16(USB_EP_NI1_TXTYPE, val) -#define bfin_read_USB_EP_NI1_TXINTERVAL() bfin_read16(USB_EP_NI1_TXINTERVAL) -#define bfin_write_USB_EP_NI1_TXINTERVAL(val) bfin_write16(USB_EP_NI1_TXINTERVAL, val) -#define bfin_read_USB_EP_NI1_RXTYPE() bfin_read16(USB_EP_NI1_RXTYPE) -#define bfin_write_USB_EP_NI1_RXTYPE(val) bfin_write16(USB_EP_NI1_RXTYPE, val) -#define bfin_read_USB_EP_NI1_RXINTERVAL() bfin_read16(USB_EP_NI1_RXINTERVAL) -#define bfin_write_USB_EP_NI1_RXINTERVAL(val) bfin_write16(USB_EP_NI1_RXINTERVAL, val) - -/* USB Endbfin_read_()oint 2 Control Registers */ - -#define bfin_read_USB_EP_NI1_TXCOUNT() bfin_read16(USB_EP_NI1_TXCOUNT) -#define bfin_write_USB_EP_NI1_TXCOUNT(val) bfin_write16(USB_EP_NI1_TXCOUNT, val) -#define bfin_read_USB_EP_NI2_TXMAXP() bfin_read16(USB_EP_NI2_TXMAXP) -#define bfin_write_USB_EP_NI2_TXMAXP(val) bfin_write16(USB_EP_NI2_TXMAXP, val) -#define bfin_read_USB_EP_NI2_TXCSR() bfin_read16(USB_EP_NI2_TXCSR) -#define bfin_write_USB_EP_NI2_TXCSR(val) bfin_write16(USB_EP_NI2_TXCSR, val) -#define bfin_read_USB_EP_NI2_RXMAXP() bfin_read16(USB_EP_NI2_RXMAXP) -#define bfin_write_USB_EP_NI2_RXMAXP(val) bfin_write16(USB_EP_NI2_RXMAXP, val) -#define bfin_read_USB_EP_NI2_RXCSR() bfin_read16(USB_EP_NI2_RXCSR) -#define bfin_write_USB_EP_NI2_RXCSR(val) bfin_write16(USB_EP_NI2_RXCSR, val) -#define bfin_read_USB_EP_NI2_RXCOUNT() bfin_read16(USB_EP_NI2_RXCOUNT) -#define bfin_write_USB_EP_NI2_RXCOUNT(val) bfin_write16(USB_EP_NI2_RXCOUNT, val) -#define bfin_read_USB_EP_NI2_TXTYPE() bfin_read16(USB_EP_NI2_TXTYPE) -#define bfin_write_USB_EP_NI2_TXTYPE(val) bfin_write16(USB_EP_NI2_TXTYPE, val) -#define bfin_read_USB_EP_NI2_TXINTERVAL() bfin_read16(USB_EP_NI2_TXINTERVAL) -#define bfin_write_USB_EP_NI2_TXINTERVAL(val) bfin_write16(USB_EP_NI2_TXINTERVAL, val) -#define bfin_read_USB_EP_NI2_RXTYPE() bfin_read16(USB_EP_NI2_RXTYPE) -#define bfin_write_USB_EP_NI2_RXTYPE(val) bfin_write16(USB_EP_NI2_RXTYPE, val) -#define bfin_read_USB_EP_NI2_RXINTERVAL() bfin_read16(USB_EP_NI2_RXINTERVAL) -#define bfin_write_USB_EP_NI2_RXINTERVAL(val) bfin_write16(USB_EP_NI2_RXINTERVAL, val) - -/* USB Endbfin_read_()oint 3 Control Registers */ - -#define bfin_read_USB_EP_NI2_TXCOUNT() bfin_read16(USB_EP_NI2_TXCOUNT) -#define bfin_write_USB_EP_NI2_TXCOUNT(val) bfin_write16(USB_EP_NI2_TXCOUNT, val) -#define bfin_read_USB_EP_NI3_TXMAXP() bfin_read16(USB_EP_NI3_TXMAXP) -#define bfin_write_USB_EP_NI3_TXMAXP(val) bfin_write16(USB_EP_NI3_TXMAXP, val) -#define bfin_read_USB_EP_NI3_TXCSR() bfin_read16(USB_EP_NI3_TXCSR) -#define bfin_write_USB_EP_NI3_TXCSR(val) bfin_write16(USB_EP_NI3_TXCSR, val) -#define bfin_read_USB_EP_NI3_RXMAXP() bfin_read16(USB_EP_NI3_RXMAXP) -#define bfin_write_USB_EP_NI3_RXMAXP(val) bfin_write16(USB_EP_NI3_RXMAXP, val) -#define bfin_read_USB_EP_NI3_RXCSR() bfin_read16(USB_EP_NI3_RXCSR) -#define bfin_write_USB_EP_NI3_RXCSR(val) bfin_write16(USB_EP_NI3_RXCSR, val) -#define bfin_read_USB_EP_NI3_RXCOUNT() bfin_read16(USB_EP_NI3_RXCOUNT) -#define bfin_write_USB_EP_NI3_RXCOUNT(val) bfin_write16(USB_EP_NI3_RXCOUNT, val) -#define bfin_read_USB_EP_NI3_TXTYPE() bfin_read16(USB_EP_NI3_TXTYPE) -#define bfin_write_USB_EP_NI3_TXTYPE(val) bfin_write16(USB_EP_NI3_TXTYPE, val) -#define bfin_read_USB_EP_NI3_TXINTERVAL() bfin_read16(USB_EP_NI3_TXINTERVAL) -#define bfin_write_USB_EP_NI3_TXINTERVAL(val) bfin_write16(USB_EP_NI3_TXINTERVAL, val) -#define bfin_read_USB_EP_NI3_RXTYPE() bfin_read16(USB_EP_NI3_RXTYPE) -#define bfin_write_USB_EP_NI3_RXTYPE(val) bfin_write16(USB_EP_NI3_RXTYPE, val) -#define bfin_read_USB_EP_NI3_RXINTERVAL() bfin_read16(USB_EP_NI3_RXINTERVAL) -#define bfin_write_USB_EP_NI3_RXINTERVAL(val) bfin_write16(USB_EP_NI3_RXINTERVAL, val) - -/* USB Endbfin_read_()oint 4 Control Registers */ - -#define bfin_read_USB_EP_NI3_TXCOUNT() bfin_read16(USB_EP_NI3_TXCOUNT) -#define bfin_write_USB_EP_NI3_TXCOUNT(val) bfin_write16(USB_EP_NI3_TXCOUNT, val) -#define bfin_read_USB_EP_NI4_TXMAXP() bfin_read16(USB_EP_NI4_TXMAXP) -#define bfin_write_USB_EP_NI4_TXMAXP(val) bfin_write16(USB_EP_NI4_TXMAXP, val) -#define bfin_read_USB_EP_NI4_TXCSR() bfin_read16(USB_EP_NI4_TXCSR) -#define bfin_write_USB_EP_NI4_TXCSR(val) bfin_write16(USB_EP_NI4_TXCSR, val) -#define bfin_read_USB_EP_NI4_RXMAXP() bfin_read16(USB_EP_NI4_RXMAXP) -#define bfin_write_USB_EP_NI4_RXMAXP(val) bfin_write16(USB_EP_NI4_RXMAXP, val) -#define bfin_read_USB_EP_NI4_RXCSR() bfin_read16(USB_EP_NI4_RXCSR) -#define bfin_write_USB_EP_NI4_RXCSR(val) bfin_write16(USB_EP_NI4_RXCSR, val) -#define bfin_read_USB_EP_NI4_RXCOUNT() bfin_read16(USB_EP_NI4_RXCOUNT) -#define bfin_write_USB_EP_NI4_RXCOUNT(val) bfin_write16(USB_EP_NI4_RXCOUNT, val) -#define bfin_read_USB_EP_NI4_TXTYPE() bfin_read16(USB_EP_NI4_TXTYPE) -#define bfin_write_USB_EP_NI4_TXTYPE(val) bfin_write16(USB_EP_NI4_TXTYPE, val) -#define bfin_read_USB_EP_NI4_TXINTERVAL() bfin_read16(USB_EP_NI4_TXINTERVAL) -#define bfin_write_USB_EP_NI4_TXINTERVAL(val) bfin_write16(USB_EP_NI4_TXINTERVAL, val) -#define bfin_read_USB_EP_NI4_RXTYPE() bfin_read16(USB_EP_NI4_RXTYPE) -#define bfin_write_USB_EP_NI4_RXTYPE(val) bfin_write16(USB_EP_NI4_RXTYPE, val) -#define bfin_read_USB_EP_NI4_RXINTERVAL() bfin_read16(USB_EP_NI4_RXINTERVAL) -#define bfin_write_USB_EP_NI4_RXINTERVAL(val) bfin_write16(USB_EP_NI4_RXINTERVAL, val) - -/* USB Endbfin_read_()oint 5 Control Registers */ - -#define bfin_read_USB_EP_NI4_TXCOUNT() bfin_read16(USB_EP_NI4_TXCOUNT) -#define bfin_write_USB_EP_NI4_TXCOUNT(val) bfin_write16(USB_EP_NI4_TXCOUNT, val) -#define bfin_read_USB_EP_NI5_TXMAXP() bfin_read16(USB_EP_NI5_TXMAXP) -#define bfin_write_USB_EP_NI5_TXMAXP(val) bfin_write16(USB_EP_NI5_TXMAXP, val) -#define bfin_read_USB_EP_NI5_TXCSR() bfin_read16(USB_EP_NI5_TXCSR) -#define bfin_write_USB_EP_NI5_TXCSR(val) bfin_write16(USB_EP_NI5_TXCSR, val) -#define bfin_read_USB_EP_NI5_RXMAXP() bfin_read16(USB_EP_NI5_RXMAXP) -#define bfin_write_USB_EP_NI5_RXMAXP(val) bfin_write16(USB_EP_NI5_RXMAXP, val) -#define bfin_read_USB_EP_NI5_RXCSR() bfin_read16(USB_EP_NI5_RXCSR) -#define bfin_write_USB_EP_NI5_RXCSR(val) bfin_write16(USB_EP_NI5_RXCSR, val) -#define bfin_read_USB_EP_NI5_RXCOUNT() bfin_read16(USB_EP_NI5_RXCOUNT) -#define bfin_write_USB_EP_NI5_RXCOUNT(val) bfin_write16(USB_EP_NI5_RXCOUNT, val) -#define bfin_read_USB_EP_NI5_TXTYPE() bfin_read16(USB_EP_NI5_TXTYPE) -#define bfin_write_USB_EP_NI5_TXTYPE(val) bfin_write16(USB_EP_NI5_TXTYPE, val) -#define bfin_read_USB_EP_NI5_TXINTERVAL() bfin_read16(USB_EP_NI5_TXINTERVAL) -#define bfin_write_USB_EP_NI5_TXINTERVAL(val) bfin_write16(USB_EP_NI5_TXINTERVAL, val) -#define bfin_read_USB_EP_NI5_RXTYPE() bfin_read16(USB_EP_NI5_RXTYPE) -#define bfin_write_USB_EP_NI5_RXTYPE(val) bfin_write16(USB_EP_NI5_RXTYPE, val) -#define bfin_read_USB_EP_NI5_RXINTERVAL() bfin_read16(USB_EP_NI5_RXINTERVAL) -#define bfin_write_USB_EP_NI5_RXINTERVAL(val) bfin_write16(USB_EP_NI5_RXINTERVAL, val) - -/* USB Endbfin_read_()oint 6 Control Registers */ - -#define bfin_read_USB_EP_NI5_TXCOUNT() bfin_read16(USB_EP_NI5_TXCOUNT) -#define bfin_write_USB_EP_NI5_TXCOUNT(val) bfin_write16(USB_EP_NI5_TXCOUNT, val) -#define bfin_read_USB_EP_NI6_TXMAXP() bfin_read16(USB_EP_NI6_TXMAXP) -#define bfin_write_USB_EP_NI6_TXMAXP(val) bfin_write16(USB_EP_NI6_TXMAXP, val) -#define bfin_read_USB_EP_NI6_TXCSR() bfin_read16(USB_EP_NI6_TXCSR) -#define bfin_write_USB_EP_NI6_TXCSR(val) bfin_write16(USB_EP_NI6_TXCSR, val) -#define bfin_read_USB_EP_NI6_RXMAXP() bfin_read16(USB_EP_NI6_RXMAXP) -#define bfin_write_USB_EP_NI6_RXMAXP(val) bfin_write16(USB_EP_NI6_RXMAXP, val) -#define bfin_read_USB_EP_NI6_RXCSR() bfin_read16(USB_EP_NI6_RXCSR) -#define bfin_write_USB_EP_NI6_RXCSR(val) bfin_write16(USB_EP_NI6_RXCSR, val) -#define bfin_read_USB_EP_NI6_RXCOUNT() bfin_read16(USB_EP_NI6_RXCOUNT) -#define bfin_write_USB_EP_NI6_RXCOUNT(val) bfin_write16(USB_EP_NI6_RXCOUNT, val) -#define bfin_read_USB_EP_NI6_TXTYPE() bfin_read16(USB_EP_NI6_TXTYPE) -#define bfin_write_USB_EP_NI6_TXTYPE(val) bfin_write16(USB_EP_NI6_TXTYPE, val) -#define bfin_read_USB_EP_NI6_TXINTERVAL() bfin_read16(USB_EP_NI6_TXINTERVAL) -#define bfin_write_USB_EP_NI6_TXINTERVAL(val) bfin_write16(USB_EP_NI6_TXINTERVAL, val) -#define bfin_read_USB_EP_NI6_RXTYPE() bfin_read16(USB_EP_NI6_RXTYPE) -#define bfin_write_USB_EP_NI6_RXTYPE(val) bfin_write16(USB_EP_NI6_RXTYPE, val) -#define bfin_read_USB_EP_NI6_RXINTERVAL() bfin_read16(USB_EP_NI6_RXINTERVAL) -#define bfin_write_USB_EP_NI6_RXINTERVAL(val) bfin_write16(USB_EP_NI6_RXINTERVAL, val) - -/* USB Endbfin_read_()oint 7 Control Registers */ - -#define bfin_read_USB_EP_NI6_TXCOUNT() bfin_read16(USB_EP_NI6_TXCOUNT) -#define bfin_write_USB_EP_NI6_TXCOUNT(val) bfin_write16(USB_EP_NI6_TXCOUNT, val) -#define bfin_read_USB_EP_NI7_TXMAXP() bfin_read16(USB_EP_NI7_TXMAXP) -#define bfin_write_USB_EP_NI7_TXMAXP(val) bfin_write16(USB_EP_NI7_TXMAXP, val) -#define bfin_read_USB_EP_NI7_TXCSR() bfin_read16(USB_EP_NI7_TXCSR) -#define bfin_write_USB_EP_NI7_TXCSR(val) bfin_write16(USB_EP_NI7_TXCSR, val) -#define bfin_read_USB_EP_NI7_RXMAXP() bfin_read16(USB_EP_NI7_RXMAXP) -#define bfin_write_USB_EP_NI7_RXMAXP(val) bfin_write16(USB_EP_NI7_RXMAXP, val) -#define bfin_read_USB_EP_NI7_RXCSR() bfin_read16(USB_EP_NI7_RXCSR) -#define bfin_write_USB_EP_NI7_RXCSR(val) bfin_write16(USB_EP_NI7_RXCSR, val) -#define bfin_read_USB_EP_NI7_RXCOUNT() bfin_read16(USB_EP_NI7_RXCOUNT) -#define bfin_write_USB_EP_NI7_RXCOUNT(val) bfin_write16(USB_EP_NI7_RXCOUNT, val) -#define bfin_read_USB_EP_NI7_TXTYPE() bfin_read16(USB_EP_NI7_TXTYPE) -#define bfin_write_USB_EP_NI7_TXTYPE(val) bfin_write16(USB_EP_NI7_TXTYPE, val) -#define bfin_read_USB_EP_NI7_TXINTERVAL() bfin_read16(USB_EP_NI7_TXINTERVAL) -#define bfin_write_USB_EP_NI7_TXINTERVAL(val) bfin_write16(USB_EP_NI7_TXINTERVAL, val) -#define bfin_read_USB_EP_NI7_RXTYPE() bfin_read16(USB_EP_NI7_RXTYPE) -#define bfin_write_USB_EP_NI7_RXTYPE(val) bfin_write16(USB_EP_NI7_RXTYPE, val) -#define bfin_read_USB_EP_NI7_RXINTERVAL() bfin_read16(USB_EP_NI7_RXINTERVAL) -#define bfin_write_USB_EP_NI7_RXINTERVAL(val) bfin_write16(USB_EP_NI7_RXINTERVAL, val) -#define bfin_read_USB_EP_NI7_TXCOUNT() bfin_read16(USB_EP_NI7_TXCOUNT) -#define bfin_write_USB_EP_NI7_TXCOUNT(val) bfin_write16(USB_EP_NI7_TXCOUNT, val) -#define bfin_read_USB_DMA_INTERRUPT() bfin_read16(USB_DMA_INTERRUPT) -#define bfin_write_USB_DMA_INTERRUPT(val) bfin_write16(USB_DMA_INTERRUPT, val) - -/* USB Channel 0 Config Registers */ - -#define bfin_read_USB_DMA0CONTROL() bfin_read16(USB_DMA0CONTROL) -#define bfin_write_USB_DMA0CONTROL(val) bfin_write16(USB_DMA0CONTROL, val) -#define bfin_read_USB_DMA0ADDRLOW() bfin_read16(USB_DMA0ADDRLOW) -#define bfin_write_USB_DMA0ADDRLOW(val) bfin_write16(USB_DMA0ADDRLOW, val) -#define bfin_read_USB_DMA0ADDRHIGH() bfin_read16(USB_DMA0ADDRHIGH) -#define bfin_write_USB_DMA0ADDRHIGH(val) bfin_write16(USB_DMA0ADDRHIGH, val) -#define bfin_read_USB_DMA0COUNTLOW() bfin_read16(USB_DMA0COUNTLOW) -#define bfin_write_USB_DMA0COUNTLOW(val) bfin_write16(USB_DMA0COUNTLOW, val) -#define bfin_read_USB_DMA0COUNTHIGH() bfin_read16(USB_DMA0COUNTHIGH) -#define bfin_write_USB_DMA0COUNTHIGH(val) bfin_write16(USB_DMA0COUNTHIGH, val) - -/* USB Channel 1 Config Registers */ - -#define bfin_read_USB_DMA1CONTROL() bfin_read16(USB_DMA1CONTROL) -#define bfin_write_USB_DMA1CONTROL(val) bfin_write16(USB_DMA1CONTROL, val) -#define bfin_read_USB_DMA1ADDRLOW() bfin_read16(USB_DMA1ADDRLOW) -#define bfin_write_USB_DMA1ADDRLOW(val) bfin_write16(USB_DMA1ADDRLOW, val) -#define bfin_read_USB_DMA1ADDRHIGH() bfin_read16(USB_DMA1ADDRHIGH) -#define bfin_write_USB_DMA1ADDRHIGH(val) bfin_write16(USB_DMA1ADDRHIGH, val) -#define bfin_read_USB_DMA1COUNTLOW() bfin_read16(USB_DMA1COUNTLOW) -#define bfin_write_USB_DMA1COUNTLOW(val) bfin_write16(USB_DMA1COUNTLOW, val) -#define bfin_read_USB_DMA1COUNTHIGH() bfin_read16(USB_DMA1COUNTHIGH) -#define bfin_write_USB_DMA1COUNTHIGH(val) bfin_write16(USB_DMA1COUNTHIGH, val) - -/* USB Channel 2 Config Registers */ - -#define bfin_read_USB_DMA2CONTROL() bfin_read16(USB_DMA2CONTROL) -#define bfin_write_USB_DMA2CONTROL(val) bfin_write16(USB_DMA2CONTROL, val) -#define bfin_read_USB_DMA2ADDRLOW() bfin_read16(USB_DMA2ADDRLOW) -#define bfin_write_USB_DMA2ADDRLOW(val) bfin_write16(USB_DMA2ADDRLOW, val) -#define bfin_read_USB_DMA2ADDRHIGH() bfin_read16(USB_DMA2ADDRHIGH) -#define bfin_write_USB_DMA2ADDRHIGH(val) bfin_write16(USB_DMA2ADDRHIGH, val) -#define bfin_read_USB_DMA2COUNTLOW() bfin_read16(USB_DMA2COUNTLOW) -#define bfin_write_USB_DMA2COUNTLOW(val) bfin_write16(USB_DMA2COUNTLOW, val) -#define bfin_read_USB_DMA2COUNTHIGH() bfin_read16(USB_DMA2COUNTHIGH) -#define bfin_write_USB_DMA2COUNTHIGH(val) bfin_write16(USB_DMA2COUNTHIGH, val) - -/* USB Channel 3 Config Registers */ - -#define bfin_read_USB_DMA3CONTROL() bfin_read16(USB_DMA3CONTROL) -#define bfin_write_USB_DMA3CONTROL(val) bfin_write16(USB_DMA3CONTROL, val) -#define bfin_read_USB_DMA3ADDRLOW() bfin_read16(USB_DMA3ADDRLOW) -#define bfin_write_USB_DMA3ADDRLOW(val) bfin_write16(USB_DMA3ADDRLOW, val) -#define bfin_read_USB_DMA3ADDRHIGH() bfin_read16(USB_DMA3ADDRHIGH) -#define bfin_write_USB_DMA3ADDRHIGH(val) bfin_write16(USB_DMA3ADDRHIGH, val) -#define bfin_read_USB_DMA3COUNTLOW() bfin_read16(USB_DMA3COUNTLOW) -#define bfin_write_USB_DMA3COUNTLOW(val) bfin_write16(USB_DMA3COUNTLOW, val) -#define bfin_read_USB_DMA3COUNTHIGH() bfin_read16(USB_DMA3COUNTHIGH) -#define bfin_write_USB_DMA3COUNTHIGH(val) bfin_write16(USB_DMA3COUNTHIGH, val) - -/* USB Channel 4 Config Registers */ - -#define bfin_read_USB_DMA4CONTROL() bfin_read16(USB_DMA4CONTROL) -#define bfin_write_USB_DMA4CONTROL(val) bfin_write16(USB_DMA4CONTROL, val) -#define bfin_read_USB_DMA4ADDRLOW() bfin_read16(USB_DMA4ADDRLOW) -#define bfin_write_USB_DMA4ADDRLOW(val) bfin_write16(USB_DMA4ADDRLOW, val) -#define bfin_read_USB_DMA4ADDRHIGH() bfin_read16(USB_DMA4ADDRHIGH) -#define bfin_write_USB_DMA4ADDRHIGH(val) bfin_write16(USB_DMA4ADDRHIGH, val) -#define bfin_read_USB_DMA4COUNTLOW() bfin_read16(USB_DMA4COUNTLOW) -#define bfin_write_USB_DMA4COUNTLOW(val) bfin_write16(USB_DMA4COUNTLOW, val) -#define bfin_read_USB_DMA4COUNTHIGH() bfin_read16(USB_DMA4COUNTHIGH) -#define bfin_write_USB_DMA4COUNTHIGH(val) bfin_write16(USB_DMA4COUNTHIGH, val) - -/* USB Channel 5 Config Registers */ - -#define bfin_read_USB_DMA5CONTROL() bfin_read16(USB_DMA5CONTROL) -#define bfin_write_USB_DMA5CONTROL(val) bfin_write16(USB_DMA5CONTROL, val) -#define bfin_read_USB_DMA5ADDRLOW() bfin_read16(USB_DMA5ADDRLOW) -#define bfin_write_USB_DMA5ADDRLOW(val) bfin_write16(USB_DMA5ADDRLOW, val) -#define bfin_read_USB_DMA5ADDRHIGH() bfin_read16(USB_DMA5ADDRHIGH) -#define bfin_write_USB_DMA5ADDRHIGH(val) bfin_write16(USB_DMA5ADDRHIGH, val) -#define bfin_read_USB_DMA5COUNTLOW() bfin_read16(USB_DMA5COUNTLOW) -#define bfin_write_USB_DMA5COUNTLOW(val) bfin_write16(USB_DMA5COUNTLOW, val) -#define bfin_read_USB_DMA5COUNTHIGH() bfin_read16(USB_DMA5COUNTHIGH) -#define bfin_write_USB_DMA5COUNTHIGH(val) bfin_write16(USB_DMA5COUNTHIGH, val) - -/* USB Channel 6 Config Registers */ - -#define bfin_read_USB_DMA6CONTROL() bfin_read16(USB_DMA6CONTROL) -#define bfin_write_USB_DMA6CONTROL(val) bfin_write16(USB_DMA6CONTROL, val) -#define bfin_read_USB_DMA6ADDRLOW() bfin_read16(USB_DMA6ADDRLOW) -#define bfin_write_USB_DMA6ADDRLOW(val) bfin_write16(USB_DMA6ADDRLOW, val) -#define bfin_read_USB_DMA6ADDRHIGH() bfin_read16(USB_DMA6ADDRHIGH) -#define bfin_write_USB_DMA6ADDRHIGH(val) bfin_write16(USB_DMA6ADDRHIGH, val) -#define bfin_read_USB_DMA6COUNTLOW() bfin_read16(USB_DMA6COUNTLOW) -#define bfin_write_USB_DMA6COUNTLOW(val) bfin_write16(USB_DMA6COUNTLOW, val) -#define bfin_read_USB_DMA6COUNTHIGH() bfin_read16(USB_DMA6COUNTHIGH) -#define bfin_write_USB_DMA6COUNTHIGH(val) bfin_write16(USB_DMA6COUNTHIGH, val) - -/* USB Channel 7 Config Registers */ - -#define bfin_read_USB_DMA7CONTROL() bfin_read16(USB_DMA7CONTROL) -#define bfin_write_USB_DMA7CONTROL(val) bfin_write16(USB_DMA7CONTROL, val) -#define bfin_read_USB_DMA7ADDRLOW() bfin_read16(USB_DMA7ADDRLOW) -#define bfin_write_USB_DMA7ADDRLOW(val) bfin_write16(USB_DMA7ADDRLOW, val) -#define bfin_read_USB_DMA7ADDRHIGH() bfin_read16(USB_DMA7ADDRHIGH) -#define bfin_write_USB_DMA7ADDRHIGH(val) bfin_write16(USB_DMA7ADDRHIGH, val) -#define bfin_read_USB_DMA7COUNTLOW() bfin_read16(USB_DMA7COUNTLOW) -#define bfin_write_USB_DMA7COUNTLOW(val) bfin_write16(USB_DMA7COUNTLOW, val) -#define bfin_read_USB_DMA7COUNTHIGH() bfin_read16(USB_DMA7COUNTHIGH) -#define bfin_write_USB_DMA7COUNTHIGH(val) bfin_write16(USB_DMA7COUNTHIGH, val) - -/* Keybfin_read_()ad Registers */ - -#define bfin_read_KPAD_CTL() bfin_read16(KPAD_CTL) -#define bfin_write_KPAD_CTL(val) bfin_write16(KPAD_CTL, val) -#define bfin_read_KPAD_PRESCALE() bfin_read16(KPAD_PRESCALE) -#define bfin_write_KPAD_PRESCALE(val) bfin_write16(KPAD_PRESCALE, val) -#define bfin_read_KPAD_MSEL() bfin_read16(KPAD_MSEL) -#define bfin_write_KPAD_MSEL(val) bfin_write16(KPAD_MSEL, val) -#define bfin_read_KPAD_ROWCOL() bfin_read16(KPAD_ROWCOL) -#define bfin_write_KPAD_ROWCOL(val) bfin_write16(KPAD_ROWCOL, val) -#define bfin_read_KPAD_STAT() bfin_read16(KPAD_STAT) -#define bfin_write_KPAD_STAT(val) bfin_write16(KPAD_STAT, val) -#define bfin_read_KPAD_SOFTEVAL() bfin_read16(KPAD_SOFTEVAL) -#define bfin_write_KPAD_SOFTEVAL(val) bfin_write16(KPAD_SOFTEVAL, val) - -/* Pixel Combfin_read_()ositor (PIXC) Registers */ - -#define bfin_read_PIXC_CTL() bfin_read16(PIXC_CTL) -#define bfin_write_PIXC_CTL(val) bfin_write16(PIXC_CTL, val) -#define bfin_read_PIXC_PPL() bfin_read16(PIXC_PPL) -#define bfin_write_PIXC_PPL(val) bfin_write16(PIXC_PPL, val) -#define bfin_read_PIXC_LPF() bfin_read16(PIXC_LPF) -#define bfin_write_PIXC_LPF(val) bfin_write16(PIXC_LPF, val) -#define bfin_read_PIXC_AHSTART() bfin_read16(PIXC_AHSTART) -#define bfin_write_PIXC_AHSTART(val) bfin_write16(PIXC_AHSTART, val) -#define bfin_read_PIXC_AHEND() bfin_read16(PIXC_AHEND) -#define bfin_write_PIXC_AHEND(val) bfin_write16(PIXC_AHEND, val) -#define bfin_read_PIXC_AVSTART() bfin_read16(PIXC_AVSTART) -#define bfin_write_PIXC_AVSTART(val) bfin_write16(PIXC_AVSTART, val) -#define bfin_read_PIXC_AVEND() bfin_read16(PIXC_AVEND) -#define bfin_write_PIXC_AVEND(val) bfin_write16(PIXC_AVEND, val) -#define bfin_read_PIXC_ATRANSP() bfin_read16(PIXC_ATRANSP) -#define bfin_write_PIXC_ATRANSP(val) bfin_write16(PIXC_ATRANSP, val) -#define bfin_read_PIXC_BHSTART() bfin_read16(PIXC_BHSTART) -#define bfin_write_PIXC_BHSTART(val) bfin_write16(PIXC_BHSTART, val) -#define bfin_read_PIXC_BHEND() bfin_read16(PIXC_BHEND) -#define bfin_write_PIXC_BHEND(val) bfin_write16(PIXC_BHEND, val) -#define bfin_read_PIXC_BVSTART() bfin_read16(PIXC_BVSTART) -#define bfin_write_PIXC_BVSTART(val) bfin_write16(PIXC_BVSTART, val) -#define bfin_read_PIXC_BVEND() bfin_read16(PIXC_BVEND) -#define bfin_write_PIXC_BVEND(val) bfin_write16(PIXC_BVEND, val) -#define bfin_read_PIXC_BTRANSP() bfin_read16(PIXC_BTRANSP) -#define bfin_write_PIXC_BTRANSP(val) bfin_write16(PIXC_BTRANSP, val) -#define bfin_read_PIXC_INTRSTAT() bfin_read16(PIXC_INTRSTAT) -#define bfin_write_PIXC_INTRSTAT(val) bfin_write16(PIXC_INTRSTAT, val) -#define bfin_read_PIXC_RYCON() bfin_read32(PIXC_RYCON) -#define bfin_write_PIXC_RYCON(val) bfin_write32(PIXC_RYCON, val) -#define bfin_read_PIXC_GUCON() bfin_read32(PIXC_GUCON) -#define bfin_write_PIXC_GUCON(val) bfin_write32(PIXC_GUCON, val) -#define bfin_read_PIXC_BVCON() bfin_read32(PIXC_BVCON) -#define bfin_write_PIXC_BVCON(val) bfin_write32(PIXC_BVCON, val) -#define bfin_read_PIXC_CCBIAS() bfin_read32(PIXC_CCBIAS) -#define bfin_write_PIXC_CCBIAS(val) bfin_write32(PIXC_CCBIAS, val) -#define bfin_read_PIXC_TC() bfin_read32(PIXC_TC) -#define bfin_write_PIXC_TC(val) bfin_write32(PIXC_TC, val) - -/* Handshake MDMA 0 Registers */ - -#define bfin_read_HMDMA0_CONTROL() bfin_read16(HMDMA0_CONTROL) -#define bfin_write_HMDMA0_CONTROL(val) bfin_write16(HMDMA0_CONTROL, val) -#define bfin_read_HMDMA0_ECINIT() bfin_read16(HMDMA0_ECINIT) -#define bfin_write_HMDMA0_ECINIT(val) bfin_write16(HMDMA0_ECINIT, val) -#define bfin_read_HMDMA0_BCINIT() bfin_read16(HMDMA0_BCINIT) -#define bfin_write_HMDMA0_BCINIT(val) bfin_write16(HMDMA0_BCINIT, val) -#define bfin_read_HMDMA0_ECURGENT() bfin_read16(HMDMA0_ECURGENT) -#define bfin_write_HMDMA0_ECURGENT(val) bfin_write16(HMDMA0_ECURGENT, val) -#define bfin_read_HMDMA0_ECOVERFLOW() bfin_read16(HMDMA0_ECOVERFLOW) -#define bfin_write_HMDMA0_ECOVERFLOW(val) bfin_write16(HMDMA0_ECOVERFLOW, val) -#define bfin_read_HMDMA0_ECOUNT() bfin_read16(HMDMA0_ECOUNT) -#define bfin_write_HMDMA0_ECOUNT(val) bfin_write16(HMDMA0_ECOUNT, val) -#define bfin_read_HMDMA0_BCOUNT() bfin_read16(HMDMA0_BCOUNT) -#define bfin_write_HMDMA0_BCOUNT(val) bfin_write16(HMDMA0_BCOUNT, val) - -/* Handshake MDMA 1 Registers */ - -#define bfin_read_HMDMA1_CONTROL() bfin_read16(HMDMA1_CONTROL) -#define bfin_write_HMDMA1_CONTROL(val) bfin_write16(HMDMA1_CONTROL, val) -#define bfin_read_HMDMA1_ECINIT() bfin_read16(HMDMA1_ECINIT) -#define bfin_write_HMDMA1_ECINIT(val) bfin_write16(HMDMA1_ECINIT, val) -#define bfin_read_HMDMA1_BCINIT() bfin_read16(HMDMA1_BCINIT) -#define bfin_write_HMDMA1_BCINIT(val) bfin_write16(HMDMA1_BCINIT, val) -#define bfin_read_HMDMA1_ECURGENT() bfin_read16(HMDMA1_ECURGENT) -#define bfin_write_HMDMA1_ECURGENT(val) bfin_write16(HMDMA1_ECURGENT, val) -#define bfin_read_HMDMA1_ECOVERFLOW() bfin_read16(HMDMA1_ECOVERFLOW) -#define bfin_write_HMDMA1_ECOVERFLOW(val) bfin_write16(HMDMA1_ECOVERFLOW, val) -#define bfin_read_HMDMA1_ECOUNT() bfin_read16(HMDMA1_ECOUNT) -#define bfin_write_HMDMA1_ECOUNT(val) bfin_write16(HMDMA1_ECOUNT, val) -#define bfin_read_HMDMA1_BCOUNT() bfin_read16(HMDMA1_BCOUNT) -#define bfin_write_HMDMA1_BCOUNT(val) bfin_write16(HMDMA1_BCOUNT, val) - #endif /* _CDEF_BF549_H */ diff --git a/arch/blackfin/mach-bf548/include/mach/defBF548.h b/arch/blackfin/mach-bf548/include/mach/defBF548.h index a507998..3fb33b0 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF548.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF548.h @@ -15,115 +15,8 @@ /* Include defBF54x_base.h for the set of #defines that are common to all ADSP-BF54x processors */ #include "defBF54x_base.h" -/* The following are the #defines needed by ADSP-BF548 that are not in the common header */ - -/* Timer Registers */ - -#define TIMER8_CONFIG 0xffc00600 /* Timer 8 Configuration Register */ -#define TIMER8_COUNTER 0xffc00604 /* Timer 8 Counter Register */ -#define TIMER8_PERIOD 0xffc00608 /* Timer 8 Period Register */ -#define TIMER8_WIDTH 0xffc0060c /* Timer 8 Width Register */ -#define TIMER9_CONFIG 0xffc00610 /* Timer 9 Configuration Register */ -#define TIMER9_COUNTER 0xffc00614 /* Timer 9 Counter Register */ -#define TIMER9_PERIOD 0xffc00618 /* Timer 9 Period Register */ -#define TIMER9_WIDTH 0xffc0061c /* Timer 9 Width Register */ -#define TIMER10_CONFIG 0xffc00620 /* Timer 10 Configuration Register */ -#define TIMER10_COUNTER 0xffc00624 /* Timer 10 Counter Register */ -#define TIMER10_PERIOD 0xffc00628 /* Timer 10 Period Register */ -#define TIMER10_WIDTH 0xffc0062c /* Timer 10 Width Register */ - -/* Timer Group of 3 Registers */ - -#define TIMER_ENABLE1 0xffc00640 /* Timer Group of 3 Enable Register */ -#define TIMER_DISABLE1 0xffc00644 /* Timer Group of 3 Disable Register */ -#define TIMER_STATUS1 0xffc00648 /* Timer Group of 3 Status Register */ - -/* SPORT0 Registers */ - -#define SPORT0_TCR1 0xffc00800 /* SPORT0 Transmit Configuration 1 Register */ -#define SPORT0_TCR2 0xffc00804 /* SPORT0 Transmit Configuration 2 Register */ -#define SPORT0_TCLKDIV 0xffc00808 /* SPORT0 Transmit Serial Clock Divider Register */ -#define SPORT0_TFSDIV 0xffc0080c /* SPORT0 Transmit Frame Sync Divider Register */ -#define SPORT0_TX 0xffc00810 /* SPORT0 Transmit Data Register */ -#define SPORT0_RX 0xffc00818 /* SPORT0 Receive Data Register */ -#define SPORT0_RCR1 0xffc00820 /* SPORT0 Receive Configuration 1 Register */ -#define SPORT0_RCR2 0xffc00824 /* SPORT0 Receive Configuration 2 Register */ -#define SPORT0_RCLKDIV 0xffc00828 /* SPORT0 Receive Serial Clock Divider Register */ -#define SPORT0_RFSDIV 0xffc0082c /* SPORT0 Receive Frame Sync Divider Register */ -#define SPORT0_STAT 0xffc00830 /* SPORT0 Status Register */ -#define SPORT0_CHNL 0xffc00834 /* SPORT0 Current Channel Register */ -#define SPORT0_MCMC1 0xffc00838 /* SPORT0 Multi channel Configuration Register 1 */ -#define SPORT0_MCMC2 0xffc0083c /* SPORT0 Multi channel Configuration Register 2 */ -#define SPORT0_MTCS0 0xffc00840 /* SPORT0 Multi channel Transmit Select Register 0 */ -#define SPORT0_MTCS1 0xffc00844 /* SPORT0 Multi channel Transmit Select Register 1 */ -#define SPORT0_MTCS2 0xffc00848 /* SPORT0 Multi channel Transmit Select Register 2 */ -#define SPORT0_MTCS3 0xffc0084c /* SPORT0 Multi channel Transmit Select Register 3 */ -#define SPORT0_MRCS0 0xffc00850 /* SPORT0 Multi channel Receive Select Register 0 */ -#define SPORT0_MRCS1 0xffc00854 /* SPORT0 Multi channel Receive Select Register 1 */ -#define SPORT0_MRCS2 0xffc00858 /* SPORT0 Multi channel Receive Select Register 2 */ -#define SPORT0_MRCS3 0xffc0085c /* SPORT0 Multi channel Receive Select Register 3 */ - -/* EPPI0 Registers */ - -#define EPPI0_STATUS 0xffc01000 /* EPPI0 Status Register */ -#define EPPI0_HCOUNT 0xffc01004 /* EPPI0 Horizontal Transfer Count Register */ -#define EPPI0_HDELAY 0xffc01008 /* EPPI0 Horizontal Delay Count Register */ -#define EPPI0_VCOUNT 0xffc0100c /* EPPI0 Vertical Transfer Count Register */ -#define EPPI0_VDELAY 0xffc01010 /* EPPI0 Vertical Delay Count Register */ -#define EPPI0_FRAME 0xffc01014 /* EPPI0 Lines per Frame Register */ -#define EPPI0_LINE 0xffc01018 /* EPPI0 Samples per Line Register */ -#define EPPI0_CLKDIV 0xffc0101c /* EPPI0 Clock Divide Register */ -#define EPPI0_CONTROL 0xffc01020 /* EPPI0 Control Register */ -#define EPPI0_FS1W_HBL 0xffc01024 /* EPPI0 FS1 Width Register / EPPI0 Horizontal Blanking Samples Per Line Register */ -#define EPPI0_FS1P_AVPL 0xffc01028 /* EPPI0 FS1 Period Register / EPPI0 Active Video Samples Per Line Register */ -#define EPPI0_FS2W_LVB 0xffc0102c /* EPPI0 FS2 Width Register / EPPI0 Lines of Vertical Blanking Register */ -#define EPPI0_FS2P_LAVF 0xffc01030 /* EPPI0 FS2 Period Register/ EPPI0 Lines of Active Video Per Field Register */ -#define EPPI0_CLIP 0xffc01034 /* EPPI0 Clipping Register */ - -/* UART2 Registers */ - -#define UART2_DLL 0xffc02100 /* Divisor Latch Low Byte */ -#define UART2_DLH 0xffc02104 /* Divisor Latch High Byte */ -#define UART2_GCTL 0xffc02108 /* Global Control Register */ -#define UART2_LCR 0xffc0210c /* Line Control Register */ -#define UART2_MCR 0xffc02110 /* Modem Control Register */ -#define UART2_LSR 0xffc02114 /* Line Status Register */ -#define UART2_MSR 0xffc02118 /* Modem Status Register */ -#define UART2_SCR 0xffc0211c /* Scratch Register */ -#define UART2_IER_SET 0xffc02120 /* Interrupt Enable Register Set */ -#define UART2_IER_CLEAR 0xffc02124 /* Interrupt Enable Register Clear */ -#define UART2_RBR 0xffc0212c /* Receive Buffer Register */ - -/* Two Wire Interface Registers (TWI1) */ - -#define TWI1_REGBASE 0xffc02200 -#define TWI1_CLKDIV 0xffc02200 /* Clock Divider Register */ -#define TWI1_CONTROL 0xffc02204 /* TWI Control Register */ -#define TWI1_SLAVE_CTRL 0xffc02208 /* TWI Slave Mode Control Register */ -#define TWI1_SLAVE_STAT 0xffc0220c /* TWI Slave Mode Status Register */ -#define TWI1_SLAVE_ADDR 0xffc02210 /* TWI Slave Mode Address Register */ -#define TWI1_MASTER_CTRL 0xffc02214 /* TWI Master Mode Control Register */ -#define TWI1_MASTER_STAT 0xffc02218 /* TWI Master Mode Status Register */ -#define TWI1_MASTER_ADDR 0xffc0221c /* TWI Master Mode Address Register */ -#define TWI1_INT_STAT 0xffc02220 /* TWI Interrupt Status Register */ -#define TWI1_INT_MASK 0xffc02224 /* TWI Interrupt Mask Register */ -#define TWI1_FIFO_CTRL 0xffc02228 /* TWI FIFO Control Register */ -#define TWI1_FIFO_STAT 0xffc0222c /* TWI FIFO Status Register */ -#define TWI1_XMT_DATA8 0xffc02280 /* TWI FIFO Transmit Data Single Byte Register */ -#define TWI1_XMT_DATA16 0xffc02284 /* TWI FIFO Transmit Data Double Byte Register */ -#define TWI1_RCV_DATA8 0xffc02288 /* TWI FIFO Receive Data Single Byte Register */ -#define TWI1_RCV_DATA16 0xffc0228c /* TWI FIFO Receive Data Double Byte Register */ - -/* SPI2 Registers */ - -#define SPI2_REGBASE 0xffc02400 -#define SPI2_CTL 0xffc02400 /* SPI2 Control Register */ -#define SPI2_FLG 0xffc02404 /* SPI2 Flag Register */ -#define SPI2_STAT 0xffc02408 /* SPI2 Status Register */ -#define SPI2_TDBR 0xffc0240c /* SPI2 Transmit Data Buffer Register */ -#define SPI2_RDBR 0xffc02410 /* SPI2 Receive Data Buffer Register */ -#define SPI2_BAUD 0xffc02414 /* SPI2 Baud Rate Register */ -#define SPI2_SHADOW 0xffc02418 /* SPI2 Receive Data Buffer Shadow Register */ +/* The BF548 is like the BF547, but has additional CANs */ +#include "defBF547.h" /* CAN Controller 1 Config 1 Registers */ @@ -508,1096 +401,4 @@ #define CAN1_MB31_ID0 0xffc037f8 /* CAN Controller 1 Mailbox 31 ID0 Register */ #define CAN1_MB31_ID1 0xffc037fc /* CAN Controller 1 Mailbox 31 ID1 Register */ -/* ATAPI Registers */ - -#define ATAPI_CONTROL 0xffc03800 /* ATAPI Control Register */ -#define ATAPI_STATUS 0xffc03804 /* ATAPI Status Register */ -#define ATAPI_DEV_ADDR 0xffc03808 /* ATAPI Device Register Address */ -#define ATAPI_DEV_TXBUF 0xffc0380c /* ATAPI Device Register Write Data */ -#define ATAPI_DEV_RXBUF 0xffc03810 /* ATAPI Device Register Read Data */ -#define ATAPI_INT_MASK 0xffc03814 /* ATAPI Interrupt Mask Register */ -#define ATAPI_INT_STATUS 0xffc03818 /* ATAPI Interrupt Status Register */ -#define ATAPI_XFER_LEN 0xffc0381c /* ATAPI Length of Transfer */ -#define ATAPI_LINE_STATUS 0xffc03820 /* ATAPI Line Status */ -#define ATAPI_SM_STATE 0xffc03824 /* ATAPI State Machine Status */ -#define ATAPI_TERMINATE 0xffc03828 /* ATAPI Host Terminate */ -#define ATAPI_PIO_TFRCNT 0xffc0382c /* ATAPI PIO mode transfer count */ -#define ATAPI_DMA_TFRCNT 0xffc03830 /* ATAPI DMA mode transfer count */ -#define ATAPI_UMAIN_TFRCNT 0xffc03834 /* ATAPI UDMAIN transfer count */ -#define ATAPI_UDMAOUT_TFRCNT 0xffc03838 /* ATAPI UDMAOUT transfer count */ -#define ATAPI_REG_TIM_0 0xffc03840 /* ATAPI Register Transfer Timing 0 */ -#define ATAPI_PIO_TIM_0 0xffc03844 /* ATAPI PIO Timing 0 Register */ -#define ATAPI_PIO_TIM_1 0xffc03848 /* ATAPI PIO Timing 1 Register */ -#define ATAPI_MULTI_TIM_0 0xffc03850 /* ATAPI Multi-DMA Timing 0 Register */ -#define ATAPI_MULTI_TIM_1 0xffc03854 /* ATAPI Multi-DMA Timing 1 Register */ -#define ATAPI_MULTI_TIM_2 0xffc03858 /* ATAPI Multi-DMA Timing 2 Register */ -#define ATAPI_ULTRA_TIM_0 0xffc03860 /* ATAPI Ultra-DMA Timing 0 Register */ -#define ATAPI_ULTRA_TIM_1 0xffc03864 /* ATAPI Ultra-DMA Timing 1 Register */ -#define ATAPI_ULTRA_TIM_2 0xffc03868 /* ATAPI Ultra-DMA Timing 2 Register */ -#define ATAPI_ULTRA_TIM_3 0xffc0386c /* ATAPI Ultra-DMA Timing 3 Register */ - -/* SDH Registers */ - -#define SDH_PWR_CTL 0xffc03900 /* SDH Power Control */ -#define SDH_CLK_CTL 0xffc03904 /* SDH Clock Control */ -#define SDH_ARGUMENT 0xffc03908 /* SDH Argument */ -#define SDH_COMMAND 0xffc0390c /* SDH Command */ -#define SDH_RESP_CMD 0xffc03910 /* SDH Response Command */ -#define SDH_RESPONSE0 0xffc03914 /* SDH Response0 */ -#define SDH_RESPONSE1 0xffc03918 /* SDH Response1 */ -#define SDH_RESPONSE2 0xffc0391c /* SDH Response2 */ -#define SDH_RESPONSE3 0xffc03920 /* SDH Response3 */ -#define SDH_DATA_TIMER 0xffc03924 /* SDH Data Timer */ -#define SDH_DATA_LGTH 0xffc03928 /* SDH Data Length */ -#define SDH_DATA_CTL 0xffc0392c /* SDH Data Control */ -#define SDH_DATA_CNT 0xffc03930 /* SDH Data Counter */ -#define SDH_STATUS 0xffc03934 /* SDH Status */ -#define SDH_STATUS_CLR 0xffc03938 /* SDH Status Clear */ -#define SDH_MASK0 0xffc0393c /* SDH Interrupt0 Mask */ -#define SDH_MASK1 0xffc03940 /* SDH Interrupt1 Mask */ -#define SDH_FIFO_CNT 0xffc03948 /* SDH FIFO Counter */ -#define SDH_FIFO 0xffc03980 /* SDH Data FIFO */ -#define SDH_E_STATUS 0xffc039c0 /* SDH Exception Status */ -#define SDH_E_MASK 0xffc039c4 /* SDH Exception Mask */ -#define SDH_CFG 0xffc039c8 /* SDH Configuration */ -#define SDH_RD_WAIT_EN 0xffc039cc /* SDH Read Wait Enable */ -#define SDH_PID0 0xffc039d0 /* SDH Peripheral Identification0 */ -#define SDH_PID1 0xffc039d4 /* SDH Peripheral Identification1 */ -#define SDH_PID2 0xffc039d8 /* SDH Peripheral Identification2 */ -#define SDH_PID3 0xffc039dc /* SDH Peripheral Identification3 */ -#define SDH_PID4 0xffc039e0 /* SDH Peripheral Identification4 */ -#define SDH_PID5 0xffc039e4 /* SDH Peripheral Identification5 */ -#define SDH_PID6 0xffc039e8 /* SDH Peripheral Identification6 */ -#define SDH_PID7 0xffc039ec /* SDH Peripheral Identification7 */ - -/* HOST Port Registers */ - -#define HOST_CONTROL 0xffc03a00 /* HOST Control Register */ -#define HOST_STATUS 0xffc03a04 /* HOST Status Register */ -#define HOST_TIMEOUT 0xffc03a08 /* HOST Acknowledge Mode Timeout Register */ - -/* USB Control Registers */ - -#define USB_FADDR 0xffc03c00 /* Function address register */ -#define USB_POWER 0xffc03c04 /* Power management register */ -#define USB_INTRTX 0xffc03c08 /* Interrupt register for endpoint 0 and Tx endpoint 1 to 7 */ -#define USB_INTRRX 0xffc03c0c /* Interrupt register for Rx endpoints 1 to 7 */ -#define USB_INTRTXE 0xffc03c10 /* Interrupt enable register for IntrTx */ -#define USB_INTRRXE 0xffc03c14 /* Interrupt enable register for IntrRx */ -#define USB_INTRUSB 0xffc03c18 /* Interrupt register for common USB interrupts */ -#define USB_INTRUSBE 0xffc03c1c /* Interrupt enable register for IntrUSB */ -#define USB_FRAME 0xffc03c20 /* USB frame number */ -#define USB_INDEX 0xffc03c24 /* Index register for selecting the indexed endpoint registers */ -#define USB_TESTMODE 0xffc03c28 /* Enabled USB 20 test modes */ -#define USB_GLOBINTR 0xffc03c2c /* Global Interrupt Mask register and Wakeup Exception Interrupt */ -#define USB_GLOBAL_CTL 0xffc03c30 /* Global Clock Control for the core */ - -/* USB Packet Control Registers */ - -#define USB_TX_MAX_PACKET 0xffc03c40 /* Maximum packet size for Host Tx endpoint */ -#define USB_CSR0 0xffc03c44 /* Control Status register for endpoint 0 and Control Status register for Host Tx endpoint */ -#define USB_TXCSR 0xffc03c44 /* Control Status register for endpoint 0 and Control Status register for Host Tx endpoint */ -#define USB_RX_MAX_PACKET 0xffc03c48 /* Maximum packet size for Host Rx endpoint */ -#define USB_RXCSR 0xffc03c4c /* Control Status register for Host Rx endpoint */ -#define USB_COUNT0 0xffc03c50 /* Number of bytes received in endpoint 0 FIFO and Number of bytes received in Host Tx endpoint */ -#define USB_RXCOUNT 0xffc03c50 /* Number of bytes received in endpoint 0 FIFO and Number of bytes received in Host Tx endpoint */ -#define USB_TXTYPE 0xffc03c54 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint */ -#define USB_NAKLIMIT0 0xffc03c58 /* Sets the NAK response timeout on Endpoint 0 and on Bulk transfers for Host Tx endpoint */ -#define USB_TXINTERVAL 0xffc03c58 /* Sets the NAK response timeout on Endpoint 0 and on Bulk transfers for Host Tx endpoint */ -#define USB_RXTYPE 0xffc03c5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint */ -#define USB_RXINTERVAL 0xffc03c60 /* Sets the polling interval for Interrupt and Isochronous transfers or the NAK response timeout on Bulk transfers */ -#define USB_TXCOUNT 0xffc03c68 /* Number of bytes to be written to the selected endpoint Tx FIFO */ - -/* USB Endpoint FIFO Registers */ - -#define USB_EP0_FIFO 0xffc03c80 /* Endpoint 0 FIFO */ -#define USB_EP1_FIFO 0xffc03c88 /* Endpoint 1 FIFO */ -#define USB_EP2_FIFO 0xffc03c90 /* Endpoint 2 FIFO */ -#define USB_EP3_FIFO 0xffc03c98 /* Endpoint 3 FIFO */ -#define USB_EP4_FIFO 0xffc03ca0 /* Endpoint 4 FIFO */ -#define USB_EP5_FIFO 0xffc03ca8 /* Endpoint 5 FIFO */ -#define USB_EP6_FIFO 0xffc03cb0 /* Endpoint 6 FIFO */ -#define USB_EP7_FIFO 0xffc03cb8 /* Endpoint 7 FIFO */ - -/* USB OTG Control Registers */ - -#define USB_OTG_DEV_CTL 0xffc03d00 /* OTG Device Control Register */ -#define USB_OTG_VBUS_IRQ 0xffc03d04 /* OTG VBUS Control Interrupts */ -#define USB_OTG_VBUS_MASK 0xffc03d08 /* VBUS Control Interrupt Enable */ - -/* USB Phy Control Registers */ - -#define USB_LINKINFO 0xffc03d48 /* Enables programming of some PHY-side delays */ -#define USB_VPLEN 0xffc03d4c /* Determines duration of VBUS pulse for VBUS charging */ -#define USB_HS_EOF1 0xffc03d50 /* Time buffer for High-Speed transactions */ -#define USB_FS_EOF1 0xffc03d54 /* Time buffer for Full-Speed transactions */ -#define USB_LS_EOF1 0xffc03d58 /* Time buffer for Low-Speed transactions */ - -/* (APHY_CNTRL is for ADI usage only) */ - -#define USB_APHY_CNTRL 0xffc03de0 /* Register that increases visibility of Analog PHY */ - -/* (APHY_CALIB is for ADI usage only) */ - -#define USB_APHY_CALIB 0xffc03de4 /* Register used to set some calibration values */ -#define USB_APHY_CNTRL2 0xffc03de8 /* Register used to prevent re-enumeration once Moab goes into hibernate mode */ - -/* (PHY_TEST is for ADI usage only) */ - -#define USB_PHY_TEST 0xffc03dec /* Used for reducing simulation time and simplifies FIFO testability */ -#define USB_PLLOSC_CTRL 0xffc03df0 /* Used to program different parameters for USB PLL and Oscillator */ -#define USB_SRP_CLKDIV 0xffc03df4 /* Used to program clock divide value for the clock fed to the SRP detection logic */ - -/* USB Endpoint 0 Control Registers */ - -#define USB_EP_NI0_TXMAXP 0xffc03e00 /* Maximum packet size for Host Tx endpoint0 */ -#define USB_EP_NI0_TXCSR 0xffc03e04 /* Control Status register for endpoint 0 */ -#define USB_EP_NI0_RXMAXP 0xffc03e08 /* Maximum packet size for Host Rx endpoint0 */ -#define USB_EP_NI0_RXCSR 0xffc03e0c /* Control Status register for Host Rx endpoint0 */ -#define USB_EP_NI0_RXCOUNT 0xffc03e10 /* Number of bytes received in endpoint 0 FIFO */ -#define USB_EP_NI0_TXTYPE 0xffc03e14 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint0 */ -#define USB_EP_NI0_TXINTERVAL 0xffc03e18 /* Sets the NAK response timeout on Endpoint 0 */ -#define USB_EP_NI0_RXTYPE 0xffc03e1c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint0 */ -#define USB_EP_NI0_RXINTERVAL 0xffc03e20 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint0 */ - -/* USB Endpoint 1 Control Registers */ - -#define USB_EP_NI0_TXCOUNT 0xffc03e28 /* Number of bytes to be written to the endpoint0 Tx FIFO */ -#define USB_EP_NI1_TXMAXP 0xffc03e40 /* Maximum packet size for Host Tx endpoint1 */ -#define USB_EP_NI1_TXCSR 0xffc03e44 /* Control Status register for endpoint1 */ -#define USB_EP_NI1_RXMAXP 0xffc03e48 /* Maximum packet size for Host Rx endpoint1 */ -#define USB_EP_NI1_RXCSR 0xffc03e4c /* Control Status register for Host Rx endpoint1 */ -#define USB_EP_NI1_RXCOUNT 0xffc03e50 /* Number of bytes received in endpoint1 FIFO */ -#define USB_EP_NI1_TXTYPE 0xffc03e54 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint1 */ -#define USB_EP_NI1_TXINTERVAL 0xffc03e58 /* Sets the NAK response timeout on Endpoint1 */ -#define USB_EP_NI1_RXTYPE 0xffc03e5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint1 */ -#define USB_EP_NI1_RXINTERVAL 0xffc03e60 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint1 */ - -/* USB Endpoint 2 Control Registers */ - -#define USB_EP_NI1_TXCOUNT 0xffc03e68 /* Number of bytes to be written to the+H102 endpoint1 Tx FIFO */ -#define USB_EP_NI2_TXMAXP 0xffc03e80 /* Maximum packet size for Host Tx endpoint2 */ -#define USB_EP_NI2_TXCSR 0xffc03e84 /* Control Status register for endpoint2 */ -#define USB_EP_NI2_RXMAXP 0xffc03e88 /* Maximum packet size for Host Rx endpoint2 */ -#define USB_EP_NI2_RXCSR 0xffc03e8c /* Control Status register for Host Rx endpoint2 */ -#define USB_EP_NI2_RXCOUNT 0xffc03e90 /* Number of bytes received in endpoint2 FIFO */ -#define USB_EP_NI2_TXTYPE 0xffc03e94 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint2 */ -#define USB_EP_NI2_TXINTERVAL 0xffc03e98 /* Sets the NAK response timeout on Endpoint2 */ -#define USB_EP_NI2_RXTYPE 0xffc03e9c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint2 */ -#define USB_EP_NI2_RXINTERVAL 0xffc03ea0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint2 */ - -/* USB Endpoint 3 Control Registers */ - -#define USB_EP_NI2_TXCOUNT 0xffc03ea8 /* Number of bytes to be written to the endpoint2 Tx FIFO */ -#define USB_EP_NI3_TXMAXP 0xffc03ec0 /* Maximum packet size for Host Tx endpoint3 */ -#define USB_EP_NI3_TXCSR 0xffc03ec4 /* Control Status register for endpoint3 */ -#define USB_EP_NI3_RXMAXP 0xffc03ec8 /* Maximum packet size for Host Rx endpoint3 */ -#define USB_EP_NI3_RXCSR 0xffc03ecc /* Control Status register for Host Rx endpoint3 */ -#define USB_EP_NI3_RXCOUNT 0xffc03ed0 /* Number of bytes received in endpoint3 FIFO */ -#define USB_EP_NI3_TXTYPE 0xffc03ed4 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint3 */ -#define USB_EP_NI3_TXINTERVAL 0xffc03ed8 /* Sets the NAK response timeout on Endpoint3 */ -#define USB_EP_NI3_RXTYPE 0xffc03edc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint3 */ -#define USB_EP_NI3_RXINTERVAL 0xffc03ee0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint3 */ - -/* USB Endpoint 4 Control Registers */ - -#define USB_EP_NI3_TXCOUNT 0xffc03ee8 /* Number of bytes to be written to the H124endpoint3 Tx FIFO */ -#define USB_EP_NI4_TXMAXP 0xffc03f00 /* Maximum packet size for Host Tx endpoint4 */ -#define USB_EP_NI4_TXCSR 0xffc03f04 /* Control Status register for endpoint4 */ -#define USB_EP_NI4_RXMAXP 0xffc03f08 /* Maximum packet size for Host Rx endpoint4 */ -#define USB_EP_NI4_RXCSR 0xffc03f0c /* Control Status register for Host Rx endpoint4 */ -#define USB_EP_NI4_RXCOUNT 0xffc03f10 /* Number of bytes received in endpoint4 FIFO */ -#define USB_EP_NI4_TXTYPE 0xffc03f14 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint4 */ -#define USB_EP_NI4_TXINTERVAL 0xffc03f18 /* Sets the NAK response timeout on Endpoint4 */ -#define USB_EP_NI4_RXTYPE 0xffc03f1c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint4 */ -#define USB_EP_NI4_RXINTERVAL 0xffc03f20 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint4 */ - -/* USB Endpoint 5 Control Registers */ - -#define USB_EP_NI4_TXCOUNT 0xffc03f28 /* Number of bytes to be written to the endpoint4 Tx FIFO */ -#define USB_EP_NI5_TXMAXP 0xffc03f40 /* Maximum packet size for Host Tx endpoint5 */ -#define USB_EP_NI5_TXCSR 0xffc03f44 /* Control Status register for endpoint5 */ -#define USB_EP_NI5_RXMAXP 0xffc03f48 /* Maximum packet size for Host Rx endpoint5 */ -#define USB_EP_NI5_RXCSR 0xffc03f4c /* Control Status register for Host Rx endpoint5 */ -#define USB_EP_NI5_RXCOUNT 0xffc03f50 /* Number of bytes received in endpoint5 FIFO */ -#define USB_EP_NI5_TXTYPE 0xffc03f54 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint5 */ -#define USB_EP_NI5_TXINTERVAL 0xffc03f58 /* Sets the NAK response timeout on Endpoint5 */ -#define USB_EP_NI5_RXTYPE 0xffc03f5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint5 */ -#define USB_EP_NI5_RXINTERVAL 0xffc03f60 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint5 */ - -/* USB Endpoint 6 Control Registers */ - -#define USB_EP_NI5_TXCOUNT 0xffc03f68 /* Number of bytes to be written to the H145endpoint5 Tx FIFO */ -#define USB_EP_NI6_TXMAXP 0xffc03f80 /* Maximum packet size for Host Tx endpoint6 */ -#define USB_EP_NI6_TXCSR 0xffc03f84 /* Control Status register for endpoint6 */ -#define USB_EP_NI6_RXMAXP 0xffc03f88 /* Maximum packet size for Host Rx endpoint6 */ -#define USB_EP_NI6_RXCSR 0xffc03f8c /* Control Status register for Host Rx endpoint6 */ -#define USB_EP_NI6_RXCOUNT 0xffc03f90 /* Number of bytes received in endpoint6 FIFO */ -#define USB_EP_NI6_TXTYPE 0xffc03f94 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint6 */ -#define USB_EP_NI6_TXINTERVAL 0xffc03f98 /* Sets the NAK response timeout on Endpoint6 */ -#define USB_EP_NI6_RXTYPE 0xffc03f9c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint6 */ -#define USB_EP_NI6_RXINTERVAL 0xffc03fa0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint6 */ - -/* USB Endpoint 7 Control Registers */ - -#define USB_EP_NI6_TXCOUNT 0xffc03fa8 /* Number of bytes to be written to the endpoint6 Tx FIFO */ -#define USB_EP_NI7_TXMAXP 0xffc03fc0 /* Maximum packet size for Host Tx endpoint7 */ -#define USB_EP_NI7_TXCSR 0xffc03fc4 /* Control Status register for endpoint7 */ -#define USB_EP_NI7_RXMAXP 0xffc03fc8 /* Maximum packet size for Host Rx endpoint7 */ -#define USB_EP_NI7_RXCSR 0xffc03fcc /* Control Status register for Host Rx endpoint7 */ -#define USB_EP_NI7_RXCOUNT 0xffc03fd0 /* Number of bytes received in endpoint7 FIFO */ -#define USB_EP_NI7_TXTYPE 0xffc03fd4 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */ -#define USB_EP_NI7_TXINTERVAL 0xffc03fd8 /* Sets the NAK response timeout on Endpoint7 */ -#define USB_EP_NI7_RXTYPE 0xffc03fdc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */ -#define USB_EP_NI7_RXINTERVAL 0xffc03ff0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */ -#define USB_EP_NI7_TXCOUNT 0xffc03ff8 /* Number of bytes to be written to the endpoint7 Tx FIFO */ -#define USB_DMA_INTERRUPT 0xffc04000 /* Indicates pending interrupts for the DMA channels */ - -/* USB Channel 0 Config Registers */ - -#define USB_DMA0CONTROL 0xffc04004 /* DMA master channel 0 configuration */ -#define USB_DMA0ADDRLOW 0xffc04008 /* Lower 16-bits of memory source/destination address for DMA master channel 0 */ -#define USB_DMA0ADDRHIGH 0xffc0400c /* Upper 16-bits of memory source/destination address for DMA master channel 0 */ -#define USB_DMA0COUNTLOW 0xffc04010 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 0 */ -#define USB_DMA0COUNTHIGH 0xffc04014 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 0 */ - -/* USB Channel 1 Config Registers */ - -#define USB_DMA1CONTROL 0xffc04024 /* DMA master channel 1 configuration */ -#define USB_DMA1ADDRLOW 0xffc04028 /* Lower 16-bits of memory source/destination address for DMA master channel 1 */ -#define USB_DMA1ADDRHIGH 0xffc0402c /* Upper 16-bits of memory source/destination address for DMA master channel 1 */ -#define USB_DMA1COUNTLOW 0xffc04030 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 1 */ -#define USB_DMA1COUNTHIGH 0xffc04034 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 1 */ - -/* USB Channel 2 Config Registers */ - -#define USB_DMA2CONTROL 0xffc04044 /* DMA master channel 2 configuration */ -#define USB_DMA2ADDRLOW 0xffc04048 /* Lower 16-bits of memory source/destination address for DMA master channel 2 */ -#define USB_DMA2ADDRHIGH 0xffc0404c /* Upper 16-bits of memory source/destination address for DMA master channel 2 */ -#define USB_DMA2COUNTLOW 0xffc04050 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 2 */ -#define USB_DMA2COUNTHIGH 0xffc04054 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 2 */ - -/* USB Channel 3 Config Registers */ - -#define USB_DMA3CONTROL 0xffc04064 /* DMA master channel 3 configuration */ -#define USB_DMA3ADDRLOW 0xffc04068 /* Lower 16-bits of memory source/destination address for DMA master channel 3 */ -#define USB_DMA3ADDRHIGH 0xffc0406c /* Upper 16-bits of memory source/destination address for DMA master channel 3 */ -#define USB_DMA3COUNTLOW 0xffc04070 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 3 */ -#define USB_DMA3COUNTHIGH 0xffc04074 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 3 */ - -/* USB Channel 4 Config Registers */ - -#define USB_DMA4CONTROL 0xffc04084 /* DMA master channel 4 configuration */ -#define USB_DMA4ADDRLOW 0xffc04088 /* Lower 16-bits of memory source/destination address for DMA master channel 4 */ -#define USB_DMA4ADDRHIGH 0xffc0408c /* Upper 16-bits of memory source/destination address for DMA master channel 4 */ -#define USB_DMA4COUNTLOW 0xffc04090 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 4 */ -#define USB_DMA4COUNTHIGH 0xffc04094 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 4 */ - -/* USB Channel 5 Config Registers */ - -#define USB_DMA5CONTROL 0xffc040a4 /* DMA master channel 5 configuration */ -#define USB_DMA5ADDRLOW 0xffc040a8 /* Lower 16-bits of memory source/destination address for DMA master channel 5 */ -#define USB_DMA5ADDRHIGH 0xffc040ac /* Upper 16-bits of memory source/destination address for DMA master channel 5 */ -#define USB_DMA5COUNTLOW 0xffc040b0 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 5 */ -#define USB_DMA5COUNTHIGH 0xffc040b4 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 5 */ - -/* USB Channel 6 Config Registers */ - -#define USB_DMA6CONTROL 0xffc040c4 /* DMA master channel 6 configuration */ -#define USB_DMA6ADDRLOW 0xffc040c8 /* Lower 16-bits of memory source/destination address for DMA master channel 6 */ -#define USB_DMA6ADDRHIGH 0xffc040cc /* Upper 16-bits of memory source/destination address for DMA master channel 6 */ -#define USB_DMA6COUNTLOW 0xffc040d0 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 6 */ -#define USB_DMA6COUNTHIGH 0xffc040d4 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 6 */ - -/* USB Channel 7 Config Registers */ - -#define USB_DMA7CONTROL 0xffc040e4 /* DMA master channel 7 configuration */ -#define USB_DMA7ADDRLOW 0xffc040e8 /* Lower 16-bits of memory source/destination address for DMA master channel 7 */ -#define USB_DMA7ADDRHIGH 0xffc040ec /* Upper 16-bits of memory source/destination address for DMA master channel 7 */ -#define USB_DMA7COUNTLOW 0xffc040f0 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 7 */ -#define USB_DMA7COUNTHIGH 0xffc040f4 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 7 */ - -/* Keypad Registers */ - -#define KPAD_CTL 0xffc04100 /* Controls keypad module enable and disable */ -#define KPAD_PRESCALE 0xffc04104 /* Establish a time base for programing the KPAD_MSEL register */ -#define KPAD_MSEL 0xffc04108 /* Selects delay parameters for keypad interface sensitivity */ -#define KPAD_ROWCOL 0xffc0410c /* Captures the row and column output values of the keys pressed */ -#define KPAD_STAT 0xffc04110 /* Holds and clears the status of the keypad interface interrupt */ -#define KPAD_SOFTEVAL 0xffc04114 /* Lets software force keypad interface to check for keys being pressed */ - -/* Pixel Compositor (PIXC) Registers */ - -#define PIXC_CTL 0xffc04400 /* Overlay enable, resampling mode, I/O data format, transparency enable, watermark level, FIFO status */ -#define PIXC_PPL 0xffc04404 /* Holds the number of pixels per line of the display */ -#define PIXC_LPF 0xffc04408 /* Holds the number of lines per frame of the display */ -#define PIXC_AHSTART 0xffc0440c /* Contains horizontal start pixel information of the overlay data (set A) */ -#define PIXC_AHEND 0xffc04410 /* Contains horizontal end pixel information of the overlay data (set A) */ -#define PIXC_AVSTART 0xffc04414 /* Contains vertical start pixel information of the overlay data (set A) */ -#define PIXC_AVEND 0xffc04418 /* Contains vertical end pixel information of the overlay data (set A) */ -#define PIXC_ATRANSP 0xffc0441c /* Contains the transparency ratio (set A) */ -#define PIXC_BHSTART 0xffc04420 /* Contains horizontal start pixel information of the overlay data (set B) */ -#define PIXC_BHEND 0xffc04424 /* Contains horizontal end pixel information of the overlay data (set B) */ -#define PIXC_BVSTART 0xffc04428 /* Contains vertical start pixel information of the overlay data (set B) */ -#define PIXC_BVEND 0xffc0442c /* Contains vertical end pixel information of the overlay data (set B) */ -#define PIXC_BTRANSP 0xffc04430 /* Contains the transparency ratio (set B) */ -#define PIXC_INTRSTAT 0xffc0443c /* Overlay interrupt configuration/status */ -#define PIXC_RYCON 0xffc04440 /* Color space conversion matrix register. Contains the R/Y conversion coefficients */ -#define PIXC_GUCON 0xffc04444 /* Color space conversion matrix register. Contains the G/U conversion coefficients */ -#define PIXC_BVCON 0xffc04448 /* Color space conversion matrix register. Contains the B/V conversion coefficients */ -#define PIXC_CCBIAS 0xffc0444c /* Bias values for the color space conversion matrix */ -#define PIXC_TC 0xffc04450 /* Holds the transparent color value */ - -/* Handshake MDMA 0 Registers */ - -#define HMDMA0_CONTROL 0xffc04500 /* Handshake MDMA0 Control Register */ -#define HMDMA0_ECINIT 0xffc04504 /* Handshake MDMA0 Initial Edge Count Register */ -#define HMDMA0_BCINIT 0xffc04508 /* Handshake MDMA0 Initial Block Count Register */ -#define HMDMA0_ECURGENT 0xffc0450c /* Handshake MDMA0 Urgent Edge Count Threshold Register */ -#define HMDMA0_ECOVERFLOW 0xffc04510 /* Handshake MDMA0 Edge Count Overflow Interrupt Register */ -#define HMDMA0_ECOUNT 0xffc04514 /* Handshake MDMA0 Current Edge Count Register */ -#define HMDMA0_BCOUNT 0xffc04518 /* Handshake MDMA0 Current Block Count Register */ - -/* Handshake MDMA 1 Registers */ - -#define HMDMA1_CONTROL 0xffc04540 /* Handshake MDMA1 Control Register */ -#define HMDMA1_ECINIT 0xffc04544 /* Handshake MDMA1 Initial Edge Count Register */ -#define HMDMA1_BCINIT 0xffc04548 /* Handshake MDMA1 Initial Block Count Register */ -#define HMDMA1_ECURGENT 0xffc0454c /* Handshake MDMA1 Urgent Edge Count Threshold Register */ -#define HMDMA1_ECOVERFLOW 0xffc04550 /* Handshake MDMA1 Edge Count Overflow Interrupt Register */ -#define HMDMA1_ECOUNT 0xffc04554 /* Handshake MDMA1 Current Edge Count Register */ -#define HMDMA1_BCOUNT 0xffc04558 /* Handshake MDMA1 Current Block Count Register */ - - -/* ********************************************************** */ -/* SINGLE BIT MACRO PAIRS (bit mask and negated one) */ -/* and MULTI BIT READ MACROS */ -/* ********************************************************** */ - -/* Bit masks for PIXC_CTL */ - -#define PIXC_EN 0x1 /* Pixel Compositor Enable */ -#define OVR_A_EN 0x2 /* Overlay A Enable */ -#define OVR_B_EN 0x4 /* Overlay B Enable */ -#define IMG_FORM 0x8 /* Image Data Format */ -#define OVR_FORM 0x10 /* Overlay Data Format */ -#define OUT_FORM 0x20 /* Output Data Format */ -#define UDS_MOD 0x40 /* Resampling Mode */ -#define TC_EN 0x80 /* Transparent Color Enable */ -#define IMG_STAT 0x300 /* Image FIFO Status */ -#define OVR_STAT 0xc00 /* Overlay FIFO Status */ -#define WM_LVL 0x3000 /* FIFO Watermark Level */ - -/* Bit masks for PIXC_AHSTART */ - -#define A_HSTART 0xfff /* Horizontal Start Coordinates */ - -/* Bit masks for PIXC_AHEND */ - -#define A_HEND 0xfff /* Horizontal End Coordinates */ - -/* Bit masks for PIXC_AVSTART */ - -#define A_VSTART 0x3ff /* Vertical Start Coordinates */ - -/* Bit masks for PIXC_AVEND */ - -#define A_VEND 0x3ff /* Vertical End Coordinates */ - -/* Bit masks for PIXC_ATRANSP */ - -#define A_TRANSP 0xf /* Transparency Value */ - -/* Bit masks for PIXC_BHSTART */ - -#define B_HSTART 0xfff /* Horizontal Start Coordinates */ - -/* Bit masks for PIXC_BHEND */ - -#define B_HEND 0xfff /* Horizontal End Coordinates */ - -/* Bit masks for PIXC_BVSTART */ - -#define B_VSTART 0x3ff /* Vertical Start Coordinates */ - -/* Bit masks for PIXC_BVEND */ - -#define B_VEND 0x3ff /* Vertical End Coordinates */ - -/* Bit masks for PIXC_BTRANSP */ - -#define B_TRANSP 0xf /* Transparency Value */ - -/* Bit masks for PIXC_INTRSTAT */ - -#define OVR_INT_EN 0x1 /* Interrupt at End of Last Valid Overlay */ -#define FRM_INT_EN 0x2 /* Interrupt at End of Frame */ -#define OVR_INT_STAT 0x4 /* Overlay Interrupt Status */ -#define FRM_INT_STAT 0x8 /* Frame Interrupt Status */ - -/* Bit masks for PIXC_RYCON */ - -#define A11 0x3ff /* A11 in the Coefficient Matrix */ -#define A12 0xffc00 /* A12 in the Coefficient Matrix */ -#define A13 0x3ff00000 /* A13 in the Coefficient Matrix */ -#define RY_MULT4 0x40000000 /* Multiply Row by 4 */ - -/* Bit masks for PIXC_GUCON */ - -#define A21 0x3ff /* A21 in the Coefficient Matrix */ -#define A22 0xffc00 /* A22 in the Coefficient Matrix */ -#define A23 0x3ff00000 /* A23 in the Coefficient Matrix */ -#define GU_MULT4 0x40000000 /* Multiply Row by 4 */ - -/* Bit masks for PIXC_BVCON */ - -#define A31 0x3ff /* A31 in the Coefficient Matrix */ -#define A32 0xffc00 /* A32 in the Coefficient Matrix */ -#define A33 0x3ff00000 /* A33 in the Coefficient Matrix */ -#define BV_MULT4 0x40000000 /* Multiply Row by 4 */ - -/* Bit masks for PIXC_CCBIAS */ - -#define A14 0x3ff /* A14 in the Bias Vector */ -#define A24 0xffc00 /* A24 in the Bias Vector */ -#define A34 0x3ff00000 /* A34 in the Bias Vector */ - -/* Bit masks for PIXC_TC */ - -#define RY_TRANS 0xff /* Transparent Color - R/Y Component */ -#define GU_TRANS 0xff00 /* Transparent Color - G/U Component */ -#define BV_TRANS 0xff0000 /* Transparent Color - B/V Component */ - -/* Bit masks for HOST_CONTROL */ - -#define HOST_EN 0x1 /* Host Enable */ -#define HOST_END 0x2 /* Host Endianess */ -#define DATA_SIZE 0x4 /* Data Size */ -#define HOST_RST 0x8 /* Host Reset */ -#define HRDY_OVR 0x20 /* Host Ready Override */ -#define INT_MODE 0x40 /* Interrupt Mode */ -#define BT_EN 0x80 /* Bus Timeout Enable */ -#define EHW 0x100 /* Enable Host Write */ -#define EHR 0x200 /* Enable Host Read */ -#define BDR 0x400 /* Burst DMA Requests */ - -/* Bit masks for HOST_STATUS */ - -#define DMA_READY 0x1 /* DMA Ready */ -#define FIFOFULL 0x2 /* FIFO Full */ -#define FIFOEMPTY 0x4 /* FIFO Empty */ -#define DMA_COMPLETE 0x8 /* DMA Complete */ -#define HSHK 0x10 /* Host Handshake */ -#define HSTIMEOUT 0x20 /* Host Timeout */ -#define HIRQ 0x40 /* Host Interrupt Request */ -#define ALLOW_CNFG 0x80 /* Allow New Configuration */ -#define DMA_DIR 0x100 /* DMA Direction */ -#define BTE 0x200 /* Bus Timeout Enabled */ - -/* Bit masks for HOST_TIMEOUT */ - -#define COUNT_TIMEOUT 0x7ff /* Host Timeout count */ - -/* Bit masks for KPAD_CTL */ - -#define KPAD_EN 0x1 /* Keypad Enable */ -#define KPAD_IRQMODE 0x6 /* Key Press Interrupt Enable */ -#define KPAD_ROWEN 0x1c00 /* Row Enable Width */ -#define KPAD_COLEN 0xe000 /* Column Enable Width */ - -/* Bit masks for KPAD_PRESCALE */ - -#define KPAD_PRESCALE_VAL 0x3f /* Key Prescale Value */ - -/* Bit masks for KPAD_MSEL */ - -#define DBON_SCALE 0xff /* Debounce Scale Value */ -#define COLDRV_SCALE 0xff00 /* Column Driver Scale Value */ - -/* Bit masks for KPAD_ROWCOL */ - -#define KPAD_ROW 0xff /* Rows Pressed */ -#define KPAD_COL 0xff00 /* Columns Pressed */ - -/* Bit masks for KPAD_STAT */ - -#define KPAD_IRQ 0x1 /* Keypad Interrupt Status */ -#define KPAD_MROWCOL 0x6 /* Multiple Row/Column Keypress Status */ -#define KPAD_PRESSED 0x8 /* Key press current status */ - -/* Bit masks for KPAD_SOFTEVAL */ - -#define KPAD_SOFTEVAL_E 0x2 /* Software Programmable Force Evaluate */ - -/* Bit masks for SDH_COMMAND */ - -#define CMD_IDX 0x3f /* Command Index */ -#define CMD_RSP 0x40 /* Response */ -#define CMD_L_RSP 0x80 /* Long Response */ -#define CMD_INT_E 0x100 /* Command Interrupt */ -#define CMD_PEND_E 0x200 /* Command Pending */ -#define CMD_E 0x400 /* Command Enable */ - -/* Bit masks for SDH_PWR_CTL */ - -#define PWR_ON 0x3 /* Power On */ -#if 0 -#define TBD 0x3c /* TBD */ -#endif -#define SD_CMD_OD 0x40 /* Open Drain Output */ -#define ROD_CTL 0x80 /* Rod Control */ - -/* Bit masks for SDH_CLK_CTL */ - -#define CLKDIV 0xff /* MC_CLK Divisor */ -#define CLK_E 0x100 /* MC_CLK Bus Clock Enable */ -#define PWR_SV_E 0x200 /* Power Save Enable */ -#define CLKDIV_BYPASS 0x400 /* Bypass Divisor */ -#define WIDE_BUS 0x800 /* Wide Bus Mode Enable */ - -/* Bit masks for SDH_RESP_CMD */ - -#define RESP_CMD 0x3f /* Response Command */ - -/* Bit masks for SDH_DATA_CTL */ - -#define DTX_E 0x1 /* Data Transfer Enable */ -#define DTX_DIR 0x2 /* Data Transfer Direction */ -#define DTX_MODE 0x4 /* Data Transfer Mode */ -#define DTX_DMA_E 0x8 /* Data Transfer DMA Enable */ -#define DTX_BLK_LGTH 0xf0 /* Data Transfer Block Length */ - -/* Bit masks for SDH_STATUS */ - -#define CMD_CRC_FAIL 0x1 /* CMD CRC Fail */ -#define DAT_CRC_FAIL 0x2 /* Data CRC Fail */ -#define CMD_TIME_OUT 0x4 /* CMD Time Out */ -#define DAT_TIME_OUT 0x8 /* Data Time Out */ -#define TX_UNDERRUN 0x10 /* Transmit Underrun */ -#define RX_OVERRUN 0x20 /* Receive Overrun */ -#define CMD_RESP_END 0x40 /* CMD Response End */ -#define CMD_SENT 0x80 /* CMD Sent */ -#define DAT_END 0x100 /* Data End */ -#define START_BIT_ERR 0x200 /* Start Bit Error */ -#define DAT_BLK_END 0x400 /* Data Block End */ -#define CMD_ACT 0x800 /* CMD Active */ -#define TX_ACT 0x1000 /* Transmit Active */ -#define RX_ACT 0x2000 /* Receive Active */ -#define TX_FIFO_STAT 0x4000 /* Transmit FIFO Status */ -#define RX_FIFO_STAT 0x8000 /* Receive FIFO Status */ -#define TX_FIFO_FULL 0x10000 /* Transmit FIFO Full */ -#define RX_FIFO_FULL 0x20000 /* Receive FIFO Full */ -#define TX_FIFO_ZERO 0x40000 /* Transmit FIFO Empty */ -#define RX_DAT_ZERO 0x80000 /* Receive FIFO Empty */ -#define TX_DAT_RDY 0x100000 /* Transmit Data Available */ -#define RX_FIFO_RDY 0x200000 /* Receive Data Available */ - -/* Bit masks for SDH_STATUS_CLR */ - -#define CMD_CRC_FAIL_STAT 0x1 /* CMD CRC Fail Status */ -#define DAT_CRC_FAIL_STAT 0x2 /* Data CRC Fail Status */ -#define CMD_TIMEOUT_STAT 0x4 /* CMD Time Out Status */ -#define DAT_TIMEOUT_STAT 0x8 /* Data Time Out status */ -#define TX_UNDERRUN_STAT 0x10 /* Transmit Underrun Status */ -#define RX_OVERRUN_STAT 0x20 /* Receive Overrun Status */ -#define CMD_RESP_END_STAT 0x40 /* CMD Response End Status */ -#define CMD_SENT_STAT 0x80 /* CMD Sent Status */ -#define DAT_END_STAT 0x100 /* Data End Status */ -#define START_BIT_ERR_STAT 0x200 /* Start Bit Error Status */ -#define DAT_BLK_END_STAT 0x400 /* Data Block End Status */ - -/* Bit masks for SDH_MASK0 */ - -#define CMD_CRC_FAIL_MASK 0x1 /* CMD CRC Fail Mask */ -#define DAT_CRC_FAIL_MASK 0x2 /* Data CRC Fail Mask */ -#define CMD_TIMEOUT_MASK 0x4 /* CMD Time Out Mask */ -#define DAT_TIMEOUT_MASK 0x8 /* Data Time Out Mask */ -#define TX_UNDERRUN_MASK 0x10 /* Transmit Underrun Mask */ -#define RX_OVERRUN_MASK 0x20 /* Receive Overrun Mask */ -#define CMD_RESP_END_MASK 0x40 /* CMD Response End Mask */ -#define CMD_SENT_MASK 0x80 /* CMD Sent Mask */ -#define DAT_END_MASK 0x100 /* Data End Mask */ -#define START_BIT_ERR_MASK 0x200 /* Start Bit Error Mask */ -#define DAT_BLK_END_MASK 0x400 /* Data Block End Mask */ -#define CMD_ACT_MASK 0x800 /* CMD Active Mask */ -#define TX_ACT_MASK 0x1000 /* Transmit Active Mask */ -#define RX_ACT_MASK 0x2000 /* Receive Active Mask */ -#define TX_FIFO_STAT_MASK 0x4000 /* Transmit FIFO Status Mask */ -#define RX_FIFO_STAT_MASK 0x8000 /* Receive FIFO Status Mask */ -#define TX_FIFO_FULL_MASK 0x10000 /* Transmit FIFO Full Mask */ -#define RX_FIFO_FULL_MASK 0x20000 /* Receive FIFO Full Mask */ -#define TX_FIFO_ZERO_MASK 0x40000 /* Transmit FIFO Empty Mask */ -#define RX_DAT_ZERO_MASK 0x80000 /* Receive FIFO Empty Mask */ -#define TX_DAT_RDY_MASK 0x100000 /* Transmit Data Available Mask */ -#define RX_FIFO_RDY_MASK 0x200000 /* Receive Data Available Mask */ - -/* Bit masks for SDH_FIFO_CNT */ - -#define FIFO_COUNT 0x7fff /* FIFO Count */ - -/* Bit masks for SDH_E_STATUS */ - -#define SDIO_INT_DET 0x2 /* SDIO Int Detected */ -#define SD_CARD_DET 0x10 /* SD Card Detect */ - -/* Bit masks for SDH_E_MASK */ - -#define SDIO_MSK 0x2 /* Mask SDIO Int Detected */ -#define SCD_MSK 0x40 /* Mask Card Detect */ - -/* Bit masks for SDH_CFG */ - -#define CLKS_EN 0x1 /* Clocks Enable */ -#define SD4E 0x4 /* SDIO 4-Bit Enable */ -#define MWE 0x8 /* Moving Window Enable */ -#define SD_RST 0x10 /* SDMMC Reset */ -#define PUP_SDDAT 0x20 /* Pull-up SD_DAT */ -#define PUP_SDDAT3 0x40 /* Pull-up SD_DAT3 */ -#define PD_SDDAT3 0x80 /* Pull-down SD_DAT3 */ - -/* Bit masks for SDH_RD_WAIT_EN */ - -#define RWR 0x1 /* Read Wait Request */ - -/* Bit masks for ATAPI_CONTROL */ - -#define PIO_START 0x1 /* Start PIO/Reg Op */ -#define MULTI_START 0x2 /* Start Multi-DMA Op */ -#define ULTRA_START 0x4 /* Start Ultra-DMA Op */ -#define XFER_DIR 0x8 /* Transfer Direction */ -#define IORDY_EN 0x10 /* IORDY Enable */ -#define FIFO_FLUSH 0x20 /* Flush FIFOs */ -#define SOFT_RST 0x40 /* Soft Reset */ -#define DEV_RST 0x80 /* Device Reset */ -#define TFRCNT_RST 0x100 /* Trans Count Reset */ -#define END_ON_TERM 0x200 /* End/Terminate Select */ -#define PIO_USE_DMA 0x400 /* PIO-DMA Enable */ -#define UDMAIN_FIFO_THRS 0xf000 /* Ultra DMA-IN FIFO Threshold */ - -/* Bit masks for ATAPI_STATUS */ - -#define PIO_XFER_ON 0x1 /* PIO transfer in progress */ -#define MULTI_XFER_ON 0x2 /* Multi-word DMA transfer in progress */ -#define ULTRA_XFER_ON 0x4 /* Ultra DMA transfer in progress */ -#define ULTRA_IN_FL 0xf0 /* Ultra DMA Input FIFO Level */ - -/* Bit masks for ATAPI_DEV_ADDR */ - -#define DEV_ADDR 0x1f /* Device Address */ - -/* Bit masks for ATAPI_INT_MASK */ - -#define ATAPI_DEV_INT_MASK 0x1 /* Device interrupt mask */ -#define PIO_DONE_MASK 0x2 /* PIO transfer done interrupt mask */ -#define MULTI_DONE_MASK 0x4 /* Multi-DMA transfer done interrupt mask */ -#define UDMAIN_DONE_MASK 0x8 /* Ultra-DMA in transfer done interrupt mask */ -#define UDMAOUT_DONE_MASK 0x10 /* Ultra-DMA out transfer done interrupt mask */ -#define HOST_TERM_XFER_MASK 0x20 /* Host terminate current transfer interrupt mask */ -#define MULTI_TERM_MASK 0x40 /* Device terminate Multi-DMA transfer interrupt mask */ -#define UDMAIN_TERM_MASK 0x80 /* Device terminate Ultra-DMA-in transfer interrupt mask */ -#define UDMAOUT_TERM_MASK 0x100 /* Device terminate Ultra-DMA-out transfer interrupt mask */ - -/* Bit masks for ATAPI_INT_STATUS */ - -#define ATAPI_DEV_INT 0x1 /* Device interrupt status */ -#define PIO_DONE_INT 0x2 /* PIO transfer done interrupt status */ -#define MULTI_DONE_INT 0x4 /* Multi-DMA transfer done interrupt status */ -#define UDMAIN_DONE_INT 0x8 /* Ultra-DMA in transfer done interrupt status */ -#define UDMAOUT_DONE_INT 0x10 /* Ultra-DMA out transfer done interrupt status */ -#define HOST_TERM_XFER_INT 0x20 /* Host terminate current transfer interrupt status */ -#define MULTI_TERM_INT 0x40 /* Device terminate Multi-DMA transfer interrupt status */ -#define UDMAIN_TERM_INT 0x80 /* Device terminate Ultra-DMA-in transfer interrupt status */ -#define UDMAOUT_TERM_INT 0x100 /* Device terminate Ultra-DMA-out transfer interrupt status */ - -/* Bit masks for ATAPI_LINE_STATUS */ - -#define ATAPI_INTR 0x1 /* Device interrupt to host line status */ -#define ATAPI_DASP 0x2 /* Device dasp to host line status */ -#define ATAPI_CS0N 0x4 /* ATAPI chip select 0 line status */ -#define ATAPI_CS1N 0x8 /* ATAPI chip select 1 line status */ -#define ATAPI_ADDR 0x70 /* ATAPI address line status */ -#define ATAPI_DMAREQ 0x80 /* ATAPI DMA request line status */ -#define ATAPI_DMAACKN 0x100 /* ATAPI DMA acknowledge line status */ -#define ATAPI_DIOWN 0x200 /* ATAPI write line status */ -#define ATAPI_DIORN 0x400 /* ATAPI read line status */ -#define ATAPI_IORDY 0x800 /* ATAPI IORDY line status */ - -/* Bit masks for ATAPI_SM_STATE */ - -#define PIO_CSTATE 0xf /* PIO mode state machine current state */ -#define DMA_CSTATE 0xf0 /* DMA mode state machine current state */ -#define UDMAIN_CSTATE 0xf00 /* Ultra DMA-In mode state machine current state */ -#define UDMAOUT_CSTATE 0xf000 /* ATAPI IORDY line status */ - -/* Bit masks for ATAPI_TERMINATE */ - -#define ATAPI_HOST_TERM 0x1 /* Host terminationation */ - -/* Bit masks for ATAPI_REG_TIM_0 */ - -#define T2_REG 0xff /* End of cycle time for register access transfers */ -#define TEOC_REG 0xff00 /* Selects DIOR/DIOW pulsewidth */ - -/* Bit masks for ATAPI_PIO_TIM_0 */ - -#define T1_REG 0xf /* Time from address valid to DIOR/DIOW */ -#define T2_REG_PIO 0xff0 /* DIOR/DIOW pulsewidth */ -#define T4_REG 0xf000 /* DIOW data hold */ - -/* Bit masks for ATAPI_PIO_TIM_1 */ - -#define TEOC_REG_PIO 0xff /* End of cycle time for PIO access transfers. */ - -/* Bit masks for ATAPI_MULTI_TIM_0 */ - -#define TD 0xff /* DIOR/DIOW asserted pulsewidth */ -#define TM 0xff00 /* Time from address valid to DIOR/DIOW */ - -/* Bit masks for ATAPI_MULTI_TIM_1 */ - -#define TKW 0xff /* Selects DIOW negated pulsewidth */ -#define TKR 0xff00 /* Selects DIOR negated pulsewidth */ - -/* Bit masks for ATAPI_MULTI_TIM_2 */ - -#define TH 0xff /* Selects DIOW data hold */ -#define TEOC 0xff00 /* Selects end of cycle for DMA */ - -/* Bit masks for ATAPI_ULTRA_TIM_0 */ - -#define TACK 0xff /* Selects setup and hold times for TACK */ -#define TENV 0xff00 /* Selects envelope time */ - -/* Bit masks for ATAPI_ULTRA_TIM_1 */ - -#define TDVS 0xff /* Selects data valid setup time */ -#define TCYC_TDVS 0xff00 /* Selects cycle time - TDVS time */ - -/* Bit masks for ATAPI_ULTRA_TIM_2 */ - -#define TSS 0xff /* Selects time from STROBE edge to negation of DMARQ or assertion of STOP */ -#define TMLI 0xff00 /* Selects interlock time */ - -/* Bit masks for ATAPI_ULTRA_TIM_3 */ - -#define TZAH 0xff /* Selects minimum delay required for output */ -#define READY_PAUSE 0xff00 /* Selects ready to pause */ - -/* Bit masks for TIMER_ENABLE1 */ - -#define TIMEN8 0x1 /* Timer 8 Enable */ -#define TIMEN9 0x2 /* Timer 9 Enable */ -#define TIMEN10 0x4 /* Timer 10 Enable */ - -/* Bit masks for TIMER_DISABLE1 */ - -#define TIMDIS8 0x1 /* Timer 8 Disable */ -#define TIMDIS9 0x2 /* Timer 9 Disable */ -#define TIMDIS10 0x4 /* Timer 10 Disable */ - -/* Bit masks for TIMER_STATUS1 */ - -#define TIMIL8 0x1 /* Timer 8 Interrupt */ -#define TIMIL9 0x2 /* Timer 9 Interrupt */ -#define TIMIL10 0x4 /* Timer 10 Interrupt */ -#define TOVF_ERR8 0x10 /* Timer 8 Counter Overflow */ -#define TOVF_ERR9 0x20 /* Timer 9 Counter Overflow */ -#define TOVF_ERR10 0x40 /* Timer 10 Counter Overflow */ -#define TRUN8 0x1000 /* Timer 8 Slave Enable Status */ -#define TRUN9 0x2000 /* Timer 9 Slave Enable Status */ -#define TRUN10 0x4000 /* Timer 10 Slave Enable Status */ - -/* Bit masks for EPPI0 are obtained from common base header for EPPIx (EPPI1 and EPPI2) */ - -/* Bit masks for USB_FADDR */ - -#define FUNCTION_ADDRESS 0x7f /* Function address */ - -/* Bit masks for USB_POWER */ - -#define ENABLE_SUSPENDM 0x1 /* enable SuspendM output */ -#define SUSPEND_MODE 0x2 /* Suspend Mode indicator */ -#define RESUME_MODE 0x4 /* DMA Mode */ -#define RESET 0x8 /* Reset indicator */ -#define HS_MODE 0x10 /* High Speed mode indicator */ -#define HS_ENABLE 0x20 /* high Speed Enable */ -#define SOFT_CONN 0x40 /* Soft connect */ -#define ISO_UPDATE 0x80 /* Isochronous update */ - -/* Bit masks for USB_INTRTX */ - -#define EP0_TX 0x1 /* Tx Endpoint 0 interrupt */ -#define EP1_TX 0x2 /* Tx Endpoint 1 interrupt */ -#define EP2_TX 0x4 /* Tx Endpoint 2 interrupt */ -#define EP3_TX 0x8 /* Tx Endpoint 3 interrupt */ -#define EP4_TX 0x10 /* Tx Endpoint 4 interrupt */ -#define EP5_TX 0x20 /* Tx Endpoint 5 interrupt */ -#define EP6_TX 0x40 /* Tx Endpoint 6 interrupt */ -#define EP7_TX 0x80 /* Tx Endpoint 7 interrupt */ - -/* Bit masks for USB_INTRRX */ - -#define EP1_RX 0x2 /* Rx Endpoint 1 interrupt */ -#define EP2_RX 0x4 /* Rx Endpoint 2 interrupt */ -#define EP3_RX 0x8 /* Rx Endpoint 3 interrupt */ -#define EP4_RX 0x10 /* Rx Endpoint 4 interrupt */ -#define EP5_RX 0x20 /* Rx Endpoint 5 interrupt */ -#define EP6_RX 0x40 /* Rx Endpoint 6 interrupt */ -#define EP7_RX 0x80 /* Rx Endpoint 7 interrupt */ - -/* Bit masks for USB_INTRTXE */ - -#define EP0_TX_E 0x1 /* Endpoint 0 interrupt Enable */ -#define EP1_TX_E 0x2 /* Tx Endpoint 1 interrupt Enable */ -#define EP2_TX_E 0x4 /* Tx Endpoint 2 interrupt Enable */ -#define EP3_TX_E 0x8 /* Tx Endpoint 3 interrupt Enable */ -#define EP4_TX_E 0x10 /* Tx Endpoint 4 interrupt Enable */ -#define EP5_TX_E 0x20 /* Tx Endpoint 5 interrupt Enable */ -#define EP6_TX_E 0x40 /* Tx Endpoint 6 interrupt Enable */ -#define EP7_TX_E 0x80 /* Tx Endpoint 7 interrupt Enable */ - -/* Bit masks for USB_INTRRXE */ - -#define EP1_RX_E 0x2 /* Rx Endpoint 1 interrupt Enable */ -#define EP2_RX_E 0x4 /* Rx Endpoint 2 interrupt Enable */ -#define EP3_RX_E 0x8 /* Rx Endpoint 3 interrupt Enable */ -#define EP4_RX_E 0x10 /* Rx Endpoint 4 interrupt Enable */ -#define EP5_RX_E 0x20 /* Rx Endpoint 5 interrupt Enable */ -#define EP6_RX_E 0x40 /* Rx Endpoint 6 interrupt Enable */ -#define EP7_RX_E 0x80 /* Rx Endpoint 7 interrupt Enable */ - -/* Bit masks for USB_INTRUSB */ - -#define SUSPEND_B 0x1 /* Suspend indicator */ -#define RESUME_B 0x2 /* Resume indicator */ -#define RESET_OR_BABLE_B 0x4 /* Reset/babble indicator */ -#define SOF_B 0x8 /* Start of frame */ -#define CONN_B 0x10 /* Connection indicator */ -#define DISCON_B 0x20 /* Disconnect indicator */ -#define SESSION_REQ_B 0x40 /* Session Request */ -#define VBUS_ERROR_B 0x80 /* Vbus threshold indicator */ - -/* Bit masks for USB_INTRUSBE */ - -#define SUSPEND_BE 0x1 /* Suspend indicator int enable */ -#define RESUME_BE 0x2 /* Resume indicator int enable */ -#define RESET_OR_BABLE_BE 0x4 /* Reset/babble indicator int enable */ -#define SOF_BE 0x8 /* Start of frame int enable */ -#define CONN_BE 0x10 /* Connection indicator int enable */ -#define DISCON_BE 0x20 /* Disconnect indicator int enable */ -#define SESSION_REQ_BE 0x40 /* Session Request int enable */ -#define VBUS_ERROR_BE 0x80 /* Vbus threshold indicator int enable */ - -/* Bit masks for USB_FRAME */ - -#define FRAME_NUMBER 0x7ff /* Frame number */ - -/* Bit masks for USB_INDEX */ - -#define SELECTED_ENDPOINT 0xf /* selected endpoint */ - -/* Bit masks for USB_GLOBAL_CTL */ - -#define GLOBAL_ENA 0x1 /* enables USB module */ -#define EP1_TX_ENA 0x2 /* Transmit endpoint 1 enable */ -#define EP2_TX_ENA 0x4 /* Transmit endpoint 2 enable */ -#define EP3_TX_ENA 0x8 /* Transmit endpoint 3 enable */ -#define EP4_TX_ENA 0x10 /* Transmit endpoint 4 enable */ -#define EP5_TX_ENA 0x20 /* Transmit endpoint 5 enable */ -#define EP6_TX_ENA 0x40 /* Transmit endpoint 6 enable */ -#define EP7_TX_ENA 0x80 /* Transmit endpoint 7 enable */ -#define EP1_RX_ENA 0x100 /* Receive endpoint 1 enable */ -#define EP2_RX_ENA 0x200 /* Receive endpoint 2 enable */ -#define EP3_RX_ENA 0x400 /* Receive endpoint 3 enable */ -#define EP4_RX_ENA 0x800 /* Receive endpoint 4 enable */ -#define EP5_RX_ENA 0x1000 /* Receive endpoint 5 enable */ -#define EP6_RX_ENA 0x2000 /* Receive endpoint 6 enable */ -#define EP7_RX_ENA 0x4000 /* Receive endpoint 7 enable */ - -/* Bit masks for USB_OTG_DEV_CTL */ - -#define SESSION 0x1 /* session indicator */ -#define HOST_REQ 0x2 /* Host negotiation request */ -#define HOST_MODE 0x4 /* indicates USBDRC is a host */ -#define VBUS0 0x8 /* Vbus level indicator[0] */ -#define VBUS1 0x10 /* Vbus level indicator[1] */ -#define LSDEV 0x20 /* Low-speed indicator */ -#define FSDEV 0x40 /* Full or High-speed indicator */ -#define B_DEVICE 0x80 /* A' or 'B' device indicator */ - -/* Bit masks for USB_OTG_VBUS_IRQ */ - -#define DRIVE_VBUS_ON 0x1 /* indicator to drive VBUS control circuit */ -#define DRIVE_VBUS_OFF 0x2 /* indicator to shut off charge pump */ -#define CHRG_VBUS_START 0x4 /* indicator for external circuit to start charging VBUS */ -#define CHRG_VBUS_END 0x8 /* indicator for external circuit to end charging VBUS */ -#define DISCHRG_VBUS_START 0x10 /* indicator to start discharging VBUS */ -#define DISCHRG_VBUS_END 0x20 /* indicator to stop discharging VBUS */ - -/* Bit masks for USB_OTG_VBUS_MASK */ - -#define DRIVE_VBUS_ON_ENA 0x1 /* enable DRIVE_VBUS_ON interrupt */ -#define DRIVE_VBUS_OFF_ENA 0x2 /* enable DRIVE_VBUS_OFF interrupt */ -#define CHRG_VBUS_START_ENA 0x4 /* enable CHRG_VBUS_START interrupt */ -#define CHRG_VBUS_END_ENA 0x8 /* enable CHRG_VBUS_END interrupt */ -#define DISCHRG_VBUS_START_ENA 0x10 /* enable DISCHRG_VBUS_START interrupt */ -#define DISCHRG_VBUS_END_ENA 0x20 /* enable DISCHRG_VBUS_END interrupt */ - -/* Bit masks for USB_CSR0 */ - -#define RXPKTRDY 0x1 /* data packet receive indicator */ -#define TXPKTRDY 0x2 /* data packet in FIFO indicator */ -#define STALL_SENT 0x4 /* STALL handshake sent */ -#define DATAEND 0x8 /* Data end indicator */ -#define SETUPEND 0x10 /* Setup end */ -#define SENDSTALL 0x20 /* Send STALL handshake */ -#define SERVICED_RXPKTRDY 0x40 /* used to clear the RxPktRdy bit */ -#define SERVICED_SETUPEND 0x80 /* used to clear the SetupEnd bit */ -#define FLUSHFIFO 0x100 /* flush endpoint FIFO */ -#define STALL_RECEIVED_H 0x4 /* STALL handshake received host mode */ -#define SETUPPKT_H 0x8 /* send Setup token host mode */ -#define ERROR_H 0x10 /* timeout error indicator host mode */ -#define REQPKT_H 0x20 /* Request an IN transaction host mode */ -#define STATUSPKT_H 0x40 /* Status stage transaction host mode */ -#define NAK_TIMEOUT_H 0x80 /* EP0 halted after a NAK host mode */ - -/* Bit masks for USB_COUNT0 */ - -#define EP0_RX_COUNT 0x7f /* number of received bytes in EP0 FIFO */ - -/* Bit masks for USB_NAKLIMIT0 */ - -#define EP0_NAK_LIMIT 0x1f /* number of frames/micro frames after which EP0 timeouts */ - -/* Bit masks for USB_TX_MAX_PACKET */ - -#define MAX_PACKET_SIZE_T 0x7ff /* maximum data pay load in a frame */ - -/* Bit masks for USB_RX_MAX_PACKET */ - -#define MAX_PACKET_SIZE_R 0x7ff /* maximum data pay load in a frame */ - -/* Bit masks for USB_TXCSR */ - -#define TXPKTRDY_T 0x1 /* data packet in FIFO indicator */ -#define FIFO_NOT_EMPTY_T 0x2 /* FIFO not empty */ -#define UNDERRUN_T 0x4 /* TxPktRdy not set for an IN token */ -#define FLUSHFIFO_T 0x8 /* flush endpoint FIFO */ -#define STALL_SEND_T 0x10 /* issue a Stall handshake */ -#define STALL_SENT_T 0x20 /* Stall handshake transmitted */ -#define CLEAR_DATATOGGLE_T 0x40 /* clear endpoint data toggle */ -#define INCOMPTX_T 0x80 /* indicates that a large packet is split */ -#define DMAREQMODE_T 0x400 /* DMA mode (0 or 1) selection */ -#define FORCE_DATATOGGLE_T 0x800 /* Force data toggle */ -#define DMAREQ_ENA_T 0x1000 /* Enable DMA request for Tx EP */ -#define ISO_T 0x4000 /* enable Isochronous transfers */ -#define AUTOSET_T 0x8000 /* allows TxPktRdy to be set automatically */ -#define ERROR_TH 0x4 /* error condition host mode */ -#define STALL_RECEIVED_TH 0x20 /* Stall handshake received host mode */ -#define NAK_TIMEOUT_TH 0x80 /* NAK timeout host mode */ - -/* Bit masks for USB_TXCOUNT */ - -#define TX_COUNT 0x1fff /* Number of bytes to be written to the selected endpoint Tx FIFO */ - -/* Bit masks for USB_RXCSR */ - -#define RXPKTRDY_R 0x1 /* data packet in FIFO indicator */ -#define FIFO_FULL_R 0x2 /* FIFO not empty */ -#define OVERRUN_R 0x4 /* TxPktRdy not set for an IN token */ -#define DATAERROR_R 0x8 /* Out packet cannot be loaded into Rx FIFO */ -#define FLUSHFIFO_R 0x10 /* flush endpoint FIFO */ -#define STALL_SEND_R 0x20 /* issue a Stall handshake */ -#define STALL_SENT_R 0x40 /* Stall handshake transmitted */ -#define CLEAR_DATATOGGLE_R 0x80 /* clear endpoint data toggle */ -#define INCOMPRX_R 0x100 /* indicates that a large packet is split */ -#define DMAREQMODE_R 0x800 /* DMA mode (0 or 1) selection */ -#define DISNYET_R 0x1000 /* disable Nyet handshakes */ -#define DMAREQ_ENA_R 0x2000 /* Enable DMA request for Tx EP */ -#define ISO_R 0x4000 /* enable Isochronous transfers */ -#define AUTOCLEAR_R 0x8000 /* allows TxPktRdy to be set automatically */ -#define ERROR_RH 0x4 /* TxPktRdy not set for an IN token host mode */ -#define REQPKT_RH 0x20 /* request an IN transaction host mode */ -#define STALL_RECEIVED_RH 0x40 /* Stall handshake received host mode */ -#define INCOMPRX_RH 0x100 /* indicates that a large packet is split host mode */ -#define DMAREQMODE_RH 0x800 /* DMA mode (0 or 1) selection host mode */ -#define AUTOREQ_RH 0x4000 /* sets ReqPkt automatically host mode */ - -/* Bit masks for USB_RXCOUNT */ - -#define RX_COUNT 0x1fff /* Number of received bytes in the packet in the Rx FIFO */ - -/* Bit masks for USB_TXTYPE */ - -#define TARGET_EP_NO_T 0xf /* EP number */ -#define PROTOCOL_T 0xc /* transfer type */ - -/* Bit masks for USB_TXINTERVAL */ - -#define TX_POLL_INTERVAL 0xff /* polling interval for selected Tx EP */ - -/* Bit masks for USB_RXTYPE */ - -#define TARGET_EP_NO_R 0xf /* EP number */ -#define PROTOCOL_R 0xc /* transfer type */ - -/* Bit masks for USB_RXINTERVAL */ - -#define RX_POLL_INTERVAL 0xff /* polling interval for selected Rx EP */ - -/* Bit masks for USB_DMA_INTERRUPT */ - -#define DMA0_INT 0x1 /* DMA0 pending interrupt */ -#define DMA1_INT 0x2 /* DMA1 pending interrupt */ -#define DMA2_INT 0x4 /* DMA2 pending interrupt */ -#define DMA3_INT 0x8 /* DMA3 pending interrupt */ -#define DMA4_INT 0x10 /* DMA4 pending interrupt */ -#define DMA5_INT 0x20 /* DMA5 pending interrupt */ -#define DMA6_INT 0x40 /* DMA6 pending interrupt */ -#define DMA7_INT 0x80 /* DMA7 pending interrupt */ - -/* Bit masks for USB_DMAxCONTROL */ - -#define DMA_ENA 0x1 /* DMA enable */ -#define DIRECTION 0x2 /* direction of DMA transfer */ -#define MODE 0x4 /* DMA Bus error */ -#define INT_ENA 0x8 /* Interrupt enable */ -#define EPNUM 0xf0 /* EP number */ -#define BUSERROR 0x100 /* DMA Bus error */ - -/* Bit masks for USB_DMAxADDRHIGH */ - -#define DMA_ADDR_HIGH 0xffff /* Upper 16-bits of memory source/destination address for the DMA master channel */ - -/* Bit masks for USB_DMAxADDRLOW */ - -#define DMA_ADDR_LOW 0xffff /* Lower 16-bits of memory source/destination address for the DMA master channel */ - -/* Bit masks for USB_DMAxCOUNTHIGH */ - -#define DMA_COUNT_HIGH 0xffff /* Upper 16-bits of byte count of DMA transfer for DMA master channel */ - -/* Bit masks for USB_DMAxCOUNTLOW */ - -#define DMA_COUNT_LOW 0xffff /* Lower 16-bits of byte count of DMA transfer for DMA master channel */ - -/* Bit masks for HMDMAx_CONTROL */ - -#define HMDMAEN 0x1 /* Handshake MDMA Enable */ -#define REP 0x2 /* Handshake MDMA Request Polarity */ -#define UTE 0x8 /* Urgency Threshold Enable */ -#define OIE 0x10 /* Overflow Interrupt Enable */ -#define BDIE 0x20 /* Block Done Interrupt Enable */ -#define MBDI 0x40 /* Mask Block Done Interrupt */ -#define DRQ 0x300 /* Handshake MDMA Request Type */ -#define RBC 0x1000 /* Force Reload of BCOUNT */ -#define PS 0x2000 /* Pin Status */ -#define OI 0x4000 /* Overflow Interrupt Generated */ -#define BDI 0x8000 /* Block Done Interrupt Generated */ - -/* ******************************************* */ -/* MULTI BIT MACRO ENUMERATIONS */ -/* ******************************************* */ - - #endif /* _DEF_BF548_H */ diff --git a/arch/blackfin/mach-bf548/include/mach/defBF549.h b/arch/blackfin/mach-bf548/include/mach/defBF549.h index f7f0435..d84dbe9 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF549.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF549.h @@ -10,121 +10,13 @@ /* Include all Core registers and bit definitions */ #include - /* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF549 */ /* Include defBF54x_base.h for the set of #defines that are common to all ADSP-BF54x processors */ #include "defBF54x_base.h" -/* The following are the #defines needed by ADSP-BF549 that are not in the common header */ - -/* Timer Registers */ - -#define TIMER8_CONFIG 0xffc00600 /* Timer 8 Configuration Register */ -#define TIMER8_COUNTER 0xffc00604 /* Timer 8 Counter Register */ -#define TIMER8_PERIOD 0xffc00608 /* Timer 8 Period Register */ -#define TIMER8_WIDTH 0xffc0060c /* Timer 8 Width Register */ -#define TIMER9_CONFIG 0xffc00610 /* Timer 9 Configuration Register */ -#define TIMER9_COUNTER 0xffc00614 /* Timer 9 Counter Register */ -#define TIMER9_PERIOD 0xffc00618 /* Timer 9 Period Register */ -#define TIMER9_WIDTH 0xffc0061c /* Timer 9 Width Register */ -#define TIMER10_CONFIG 0xffc00620 /* Timer 10 Configuration Register */ -#define TIMER10_COUNTER 0xffc00624 /* Timer 10 Counter Register */ -#define TIMER10_PERIOD 0xffc00628 /* Timer 10 Period Register */ -#define TIMER10_WIDTH 0xffc0062c /* Timer 10 Width Register */ - -/* Timer Group of 3 Registers */ - -#define TIMER_ENABLE1 0xffc00640 /* Timer Group of 3 Enable Register */ -#define TIMER_DISABLE1 0xffc00644 /* Timer Group of 3 Disable Register */ -#define TIMER_STATUS1 0xffc00648 /* Timer Group of 3 Status Register */ - -/* SPORT0 Registers */ - -#define SPORT0_TCR1 0xffc00800 /* SPORT0 Transmit Configuration 1 Register */ -#define SPORT0_TCR2 0xffc00804 /* SPORT0 Transmit Configuration 2 Register */ -#define SPORT0_TCLKDIV 0xffc00808 /* SPORT0 Transmit Serial Clock Divider Register */ -#define SPORT0_TFSDIV 0xffc0080c /* SPORT0 Transmit Frame Sync Divider Register */ -#define SPORT0_TX 0xffc00810 /* SPORT0 Transmit Data Register */ -#define SPORT0_RX 0xffc00818 /* SPORT0 Receive Data Register */ -#define SPORT0_RCR1 0xffc00820 /* SPORT0 Receive Configuration 1 Register */ -#define SPORT0_RCR2 0xffc00824 /* SPORT0 Receive Configuration 2 Register */ -#define SPORT0_RCLKDIV 0xffc00828 /* SPORT0 Receive Serial Clock Divider Register */ -#define SPORT0_RFSDIV 0xffc0082c /* SPORT0 Receive Frame Sync Divider Register */ -#define SPORT0_STAT 0xffc00830 /* SPORT0 Status Register */ -#define SPORT0_CHNL 0xffc00834 /* SPORT0 Current Channel Register */ -#define SPORT0_MCMC1 0xffc00838 /* SPORT0 Multi channel Configuration Register 1 */ -#define SPORT0_MCMC2 0xffc0083c /* SPORT0 Multi channel Configuration Register 2 */ -#define SPORT0_MTCS0 0xffc00840 /* SPORT0 Multi channel Transmit Select Register 0 */ -#define SPORT0_MTCS1 0xffc00844 /* SPORT0 Multi channel Transmit Select Register 1 */ -#define SPORT0_MTCS2 0xffc00848 /* SPORT0 Multi channel Transmit Select Register 2 */ -#define SPORT0_MTCS3 0xffc0084c /* SPORT0 Multi channel Transmit Select Register 3 */ -#define SPORT0_MRCS0 0xffc00850 /* SPORT0 Multi channel Receive Select Register 0 */ -#define SPORT0_MRCS1 0xffc00854 /* SPORT0 Multi channel Receive Select Register 1 */ -#define SPORT0_MRCS2 0xffc00858 /* SPORT0 Multi channel Receive Select Register 2 */ -#define SPORT0_MRCS3 0xffc0085c /* SPORT0 Multi channel Receive Select Register 3 */ - -/* EPPI0 Registers */ - -#define EPPI0_STATUS 0xffc01000 /* EPPI0 Status Register */ -#define EPPI0_HCOUNT 0xffc01004 /* EPPI0 Horizontal Transfer Count Register */ -#define EPPI0_HDELAY 0xffc01008 /* EPPI0 Horizontal Delay Count Register */ -#define EPPI0_VCOUNT 0xffc0100c /* EPPI0 Vertical Transfer Count Register */ -#define EPPI0_VDELAY 0xffc01010 /* EPPI0 Vertical Delay Count Register */ -#define EPPI0_FRAME 0xffc01014 /* EPPI0 Lines per Frame Register */ -#define EPPI0_LINE 0xffc01018 /* EPPI0 Samples per Line Register */ -#define EPPI0_CLKDIV 0xffc0101c /* EPPI0 Clock Divide Register */ -#define EPPI0_CONTROL 0xffc01020 /* EPPI0 Control Register */ -#define EPPI0_FS1W_HBL 0xffc01024 /* EPPI0 FS1 Width Register / EPPI0 Horizontal Blanking Samples Per Line Register */ -#define EPPI0_FS1P_AVPL 0xffc01028 /* EPPI0 FS1 Period Register / EPPI0 Active Video Samples Per Line Register */ -#define EPPI0_FS2W_LVB 0xffc0102c /* EPPI0 FS2 Width Register / EPPI0 Lines of Vertical Blanking Register */ -#define EPPI0_FS2P_LAVF 0xffc01030 /* EPPI0 FS2 Period Register/ EPPI0 Lines of Active Video Per Field Register */ -#define EPPI0_CLIP 0xffc01034 /* EPPI0 Clipping Register */ - -/* UART2 Registers */ - -#define UART2_DLL 0xffc02100 /* Divisor Latch Low Byte */ -#define UART2_DLH 0xffc02104 /* Divisor Latch High Byte */ -#define UART2_GCTL 0xffc02108 /* Global Control Register */ -#define UART2_LCR 0xffc0210c /* Line Control Register */ -#define UART2_MCR 0xffc02110 /* Modem Control Register */ -#define UART2_LSR 0xffc02114 /* Line Status Register */ -#define UART2_MSR 0xffc02118 /* Modem Status Register */ -#define UART2_SCR 0xffc0211c /* Scratch Register */ -#define UART2_IER_SET 0xffc02120 /* Interrupt Enable Register Set */ -#define UART2_IER_CLEAR 0xffc02124 /* Interrupt Enable Register Clear */ -#define UART2_RBR 0xffc0212c /* Receive Buffer Register */ - -/* Two Wire Interface Registers (TWI1) */ - -#define TWI1_REGBASE 0xffc02200 -#define TWI1_CLKDIV 0xffc02200 /* Clock Divider Register */ -#define TWI1_CONTROL 0xffc02204 /* TWI Control Register */ -#define TWI1_SLAVE_CTRL 0xffc02208 /* TWI Slave Mode Control Register */ -#define TWI1_SLAVE_STAT 0xffc0220c /* TWI Slave Mode Status Register */ -#define TWI1_SLAVE_ADDR 0xffc02210 /* TWI Slave Mode Address Register */ -#define TWI1_MASTER_CTRL 0xffc02214 /* TWI Master Mode Control Register */ -#define TWI1_MASTER_STAT 0xffc02218 /* TWI Master Mode Status Register */ -#define TWI1_MASTER_ADDR 0xffc0221c /* TWI Master Mode Address Register */ -#define TWI1_INT_STAT 0xffc02220 /* TWI Interrupt Status Register */ -#define TWI1_INT_MASK 0xffc02224 /* TWI Interrupt Mask Register */ -#define TWI1_FIFO_CTRL 0xffc02228 /* TWI FIFO Control Register */ -#define TWI1_FIFO_STAT 0xffc0222c /* TWI FIFO Status Register */ -#define TWI1_XMT_DATA8 0xffc02280 /* TWI FIFO Transmit Data Single Byte Register */ -#define TWI1_XMT_DATA16 0xffc02284 /* TWI FIFO Transmit Data Double Byte Register */ -#define TWI1_RCV_DATA8 0xffc02288 /* TWI FIFO Receive Data Single Byte Register */ -#define TWI1_RCV_DATA16 0xffc0228c /* TWI FIFO Receive Data Double Byte Register */ - -/* SPI2 Registers */ - -#define SPI2_REGBASE 0xffc02400 -#define SPI2_CTL 0xffc02400 /* SPI2 Control Register */ -#define SPI2_FLG 0xffc02404 /* SPI2 Flag Register */ -#define SPI2_STAT 0xffc02408 /* SPI2 Status Register */ -#define SPI2_TDBR 0xffc0240c /* SPI2 Transmit Data Buffer Register */ -#define SPI2_RDBR 0xffc02410 /* SPI2 Receive Data Buffer Register */ -#define SPI2_BAUD 0xffc02414 /* SPI2 Baud Rate Register */ -#define SPI2_SHADOW 0xffc02418 /* SPI2 Receive Data Buffer Shadow Register */ +/* The BF549 is like the BF544, but has MXVR */ +#include "defBF547.h" /* MXVR Registers */ @@ -296,879 +188,6 @@ #define MXVR_PIN_CTL 0xffc028dc /* MXVR Pin Control Register */ #define MXVR_SCLK_CNT 0xffc028e0 /* MXVR System Clock Counter Register */ -/* CAN Controller 1 Config 1 Registers */ - -#define CAN1_MC1 0xffc03200 /* CAN Controller 1 Mailbox Configuration Register 1 */ -#define CAN1_MD1 0xffc03204 /* CAN Controller 1 Mailbox Direction Register 1 */ -#define CAN1_TRS1 0xffc03208 /* CAN Controller 1 Transmit Request Set Register 1 */ -#define CAN1_TRR1 0xffc0320c /* CAN Controller 1 Transmit Request Reset Register 1 */ -#define CAN1_TA1 0xffc03210 /* CAN Controller 1 Transmit Acknowledge Register 1 */ -#define CAN1_AA1 0xffc03214 /* CAN Controller 1 Abort Acknowledge Register 1 */ -#define CAN1_RMP1 0xffc03218 /* CAN Controller 1 Receive Message Pending Register 1 */ -#define CAN1_RML1 0xffc0321c /* CAN Controller 1 Receive Message Lost Register 1 */ -#define CAN1_MBTIF1 0xffc03220 /* CAN Controller 1 Mailbox Transmit Interrupt Flag Register 1 */ -#define CAN1_MBRIF1 0xffc03224 /* CAN Controller 1 Mailbox Receive Interrupt Flag Register 1 */ -#define CAN1_MBIM1 0xffc03228 /* CAN Controller 1 Mailbox Interrupt Mask Register 1 */ -#define CAN1_RFH1 0xffc0322c /* CAN Controller 1 Remote Frame Handling Enable Register 1 */ -#define CAN1_OPSS1 0xffc03230 /* CAN Controller 1 Overwrite Protection Single Shot Transmit Register 1 */ - -/* CAN Controller 1 Config 2 Registers */ - -#define CAN1_MC2 0xffc03240 /* CAN Controller 1 Mailbox Configuration Register 2 */ -#define CAN1_MD2 0xffc03244 /* CAN Controller 1 Mailbox Direction Register 2 */ -#define CAN1_TRS2 0xffc03248 /* CAN Controller 1 Transmit Request Set Register 2 */ -#define CAN1_TRR2 0xffc0324c /* CAN Controller 1 Transmit Request Reset Register 2 */ -#define CAN1_TA2 0xffc03250 /* CAN Controller 1 Transmit Acknowledge Register 2 */ -#define CAN1_AA2 0xffc03254 /* CAN Controller 1 Abort Acknowledge Register 2 */ -#define CAN1_RMP2 0xffc03258 /* CAN Controller 1 Receive Message Pending Register 2 */ -#define CAN1_RML2 0xffc0325c /* CAN Controller 1 Receive Message Lost Register 2 */ -#define CAN1_MBTIF2 0xffc03260 /* CAN Controller 1 Mailbox Transmit Interrupt Flag Register 2 */ -#define CAN1_MBRIF2 0xffc03264 /* CAN Controller 1 Mailbox Receive Interrupt Flag Register 2 */ -#define CAN1_MBIM2 0xffc03268 /* CAN Controller 1 Mailbox Interrupt Mask Register 2 */ -#define CAN1_RFH2 0xffc0326c /* CAN Controller 1 Remote Frame Handling Enable Register 2 */ -#define CAN1_OPSS2 0xffc03270 /* CAN Controller 1 Overwrite Protection Single Shot Transmit Register 2 */ - -/* CAN Controller 1 Clock/Interrupt/Counter Registers */ - -#define CAN1_CLOCK 0xffc03280 /* CAN Controller 1 Clock Register */ -#define CAN1_TIMING 0xffc03284 /* CAN Controller 1 Timing Register */ -#define CAN1_DEBUG 0xffc03288 /* CAN Controller 1 Debug Register */ -#define CAN1_STATUS 0xffc0328c /* CAN Controller 1 Global Status Register */ -#define CAN1_CEC 0xffc03290 /* CAN Controller 1 Error Counter Register */ -#define CAN1_GIS 0xffc03294 /* CAN Controller 1 Global Interrupt Status Register */ -#define CAN1_GIM 0xffc03298 /* CAN Controller 1 Global Interrupt Mask Register */ -#define CAN1_GIF 0xffc0329c /* CAN Controller 1 Global Interrupt Flag Register */ -#define CAN1_CONTROL 0xffc032a0 /* CAN Controller 1 Master Control Register */ -#define CAN1_INTR 0xffc032a4 /* CAN Controller 1 Interrupt Pending Register */ -#define CAN1_MBTD 0xffc032ac /* CAN Controller 1 Mailbox Temporary Disable Register */ -#define CAN1_EWR 0xffc032b0 /* CAN Controller 1 Programmable Warning Level Register */ -#define CAN1_ESR 0xffc032b4 /* CAN Controller 1 Error Status Register */ -#define CAN1_UCCNT 0xffc032c4 /* CAN Controller 1 Universal Counter Register */ -#define CAN1_UCRC 0xffc032c8 /* CAN Controller 1 Universal Counter Force Reload Register */ -#define CAN1_UCCNF 0xffc032cc /* CAN Controller 1 Universal Counter Configuration Register */ - -/* CAN Controller 1 Mailbox Acceptance Registers */ - -#define CAN1_AM00L 0xffc03300 /* CAN Controller 1 Mailbox 0 Acceptance Mask High Register */ -#define CAN1_AM00H 0xffc03304 /* CAN Controller 1 Mailbox 0 Acceptance Mask Low Register */ -#define CAN1_AM01L 0xffc03308 /* CAN Controller 1 Mailbox 1 Acceptance Mask High Register */ -#define CAN1_AM01H 0xffc0330c /* CAN Controller 1 Mailbox 1 Acceptance Mask Low Register */ -#define CAN1_AM02L 0xffc03310 /* CAN Controller 1 Mailbox 2 Acceptance Mask High Register */ -#define CAN1_AM02H 0xffc03314 /* CAN Controller 1 Mailbox 2 Acceptance Mask Low Register */ -#define CAN1_AM03L 0xffc03318 /* CAN Controller 1 Mailbox 3 Acceptance Mask High Register */ -#define CAN1_AM03H 0xffc0331c /* CAN Controller 1 Mailbox 3 Acceptance Mask Low Register */ -#define CAN1_AM04L 0xffc03320 /* CAN Controller 1 Mailbox 4 Acceptance Mask High Register */ -#define CAN1_AM04H 0xffc03324 /* CAN Controller 1 Mailbox 4 Acceptance Mask Low Register */ -#define CAN1_AM05L 0xffc03328 /* CAN Controller 1 Mailbox 5 Acceptance Mask High Register */ -#define CAN1_AM05H 0xffc0332c /* CAN Controller 1 Mailbox 5 Acceptance Mask Low Register */ -#define CAN1_AM06L 0xffc03330 /* CAN Controller 1 Mailbox 6 Acceptance Mask High Register */ -#define CAN1_AM06H 0xffc03334 /* CAN Controller 1 Mailbox 6 Acceptance Mask Low Register */ -#define CAN1_AM07L 0xffc03338 /* CAN Controller 1 Mailbox 7 Acceptance Mask High Register */ -#define CAN1_AM07H 0xffc0333c /* CAN Controller 1 Mailbox 7 Acceptance Mask Low Register */ -#define CAN1_AM08L 0xffc03340 /* CAN Controller 1 Mailbox 8 Acceptance Mask High Register */ -#define CAN1_AM08H 0xffc03344 /* CAN Controller 1 Mailbox 8 Acceptance Mask Low Register */ -#define CAN1_AM09L 0xffc03348 /* CAN Controller 1 Mailbox 9 Acceptance Mask High Register */ -#define CAN1_AM09H 0xffc0334c /* CAN Controller 1 Mailbox 9 Acceptance Mask Low Register */ -#define CAN1_AM10L 0xffc03350 /* CAN Controller 1 Mailbox 10 Acceptance Mask High Register */ -#define CAN1_AM10H 0xffc03354 /* CAN Controller 1 Mailbox 10 Acceptance Mask Low Register */ -#define CAN1_AM11L 0xffc03358 /* CAN Controller 1 Mailbox 11 Acceptance Mask High Register */ -#define CAN1_AM11H 0xffc0335c /* CAN Controller 1 Mailbox 11 Acceptance Mask Low Register */ -#define CAN1_AM12L 0xffc03360 /* CAN Controller 1 Mailbox 12 Acceptance Mask High Register */ -#define CAN1_AM12H 0xffc03364 /* CAN Controller 1 Mailbox 12 Acceptance Mask Low Register */ -#define CAN1_AM13L 0xffc03368 /* CAN Controller 1 Mailbox 13 Acceptance Mask High Register */ -#define CAN1_AM13H 0xffc0336c /* CAN Controller 1 Mailbox 13 Acceptance Mask Low Register */ -#define CAN1_AM14L 0xffc03370 /* CAN Controller 1 Mailbox 14 Acceptance Mask High Register */ -#define CAN1_AM14H 0xffc03374 /* CAN Controller 1 Mailbox 14 Acceptance Mask Low Register */ -#define CAN1_AM15L 0xffc03378 /* CAN Controller 1 Mailbox 15 Acceptance Mask High Register */ -#define CAN1_AM15H 0xffc0337c /* CAN Controller 1 Mailbox 15 Acceptance Mask Low Register */ - -/* CAN Controller 1 Mailbox Acceptance Registers */ - -#define CAN1_AM16L 0xffc03380 /* CAN Controller 1 Mailbox 16 Acceptance Mask High Register */ -#define CAN1_AM16H 0xffc03384 /* CAN Controller 1 Mailbox 16 Acceptance Mask Low Register */ -#define CAN1_AM17L 0xffc03388 /* CAN Controller 1 Mailbox 17 Acceptance Mask High Register */ -#define CAN1_AM17H 0xffc0338c /* CAN Controller 1 Mailbox 17 Acceptance Mask Low Register */ -#define CAN1_AM18L 0xffc03390 /* CAN Controller 1 Mailbox 18 Acceptance Mask High Register */ -#define CAN1_AM18H 0xffc03394 /* CAN Controller 1 Mailbox 18 Acceptance Mask Low Register */ -#define CAN1_AM19L 0xffc03398 /* CAN Controller 1 Mailbox 19 Acceptance Mask High Register */ -#define CAN1_AM19H 0xffc0339c /* CAN Controller 1 Mailbox 19 Acceptance Mask Low Register */ -#define CAN1_AM20L 0xffc033a0 /* CAN Controller 1 Mailbox 20 Acceptance Mask High Register */ -#define CAN1_AM20H 0xffc033a4 /* CAN Controller 1 Mailbox 20 Acceptance Mask Low Register */ -#define CAN1_AM21L 0xffc033a8 /* CAN Controller 1 Mailbox 21 Acceptance Mask High Register */ -#define CAN1_AM21H 0xffc033ac /* CAN Controller 1 Mailbox 21 Acceptance Mask Low Register */ -#define CAN1_AM22L 0xffc033b0 /* CAN Controller 1 Mailbox 22 Acceptance Mask High Register */ -#define CAN1_AM22H 0xffc033b4 /* CAN Controller 1 Mailbox 22 Acceptance Mask Low Register */ -#define CAN1_AM23L 0xffc033b8 /* CAN Controller 1 Mailbox 23 Acceptance Mask High Register */ -#define CAN1_AM23H 0xffc033bc /* CAN Controller 1 Mailbox 23 Acceptance Mask Low Register */ -#define CAN1_AM24L 0xffc033c0 /* CAN Controller 1 Mailbox 24 Acceptance Mask High Register */ -#define CAN1_AM24H 0xffc033c4 /* CAN Controller 1 Mailbox 24 Acceptance Mask Low Register */ -#define CAN1_AM25L 0xffc033c8 /* CAN Controller 1 Mailbox 25 Acceptance Mask High Register */ -#define CAN1_AM25H 0xffc033cc /* CAN Controller 1 Mailbox 25 Acceptance Mask Low Register */ -#define CAN1_AM26L 0xffc033d0 /* CAN Controller 1 Mailbox 26 Acceptance Mask High Register */ -#define CAN1_AM26H 0xffc033d4 /* CAN Controller 1 Mailbox 26 Acceptance Mask Low Register */ -#define CAN1_AM27L 0xffc033d8 /* CAN Controller 1 Mailbox 27 Acceptance Mask High Register */ -#define CAN1_AM27H 0xffc033dc /* CAN Controller 1 Mailbox 27 Acceptance Mask Low Register */ -#define CAN1_AM28L 0xffc033e0 /* CAN Controller 1 Mailbox 28 Acceptance Mask High Register */ -#define CAN1_AM28H 0xffc033e4 /* CAN Controller 1 Mailbox 28 Acceptance Mask Low Register */ -#define CAN1_AM29L 0xffc033e8 /* CAN Controller 1 Mailbox 29 Acceptance Mask High Register */ -#define CAN1_AM29H 0xffc033ec /* CAN Controller 1 Mailbox 29 Acceptance Mask Low Register */ -#define CAN1_AM30L 0xffc033f0 /* CAN Controller 1 Mailbox 30 Acceptance Mask High Register */ -#define CAN1_AM30H 0xffc033f4 /* CAN Controller 1 Mailbox 30 Acceptance Mask Low Register */ -#define CAN1_AM31L 0xffc033f8 /* CAN Controller 1 Mailbox 31 Acceptance Mask High Register */ -#define CAN1_AM31H 0xffc033fc /* CAN Controller 1 Mailbox 31 Acceptance Mask Low Register */ - -/* CAN Controller 1 Mailbox Data Registers */ - -#define CAN1_MB00_DATA0 0xffc03400 /* CAN Controller 1 Mailbox 0 Data 0 Register */ -#define CAN1_MB00_DATA1 0xffc03404 /* CAN Controller 1 Mailbox 0 Data 1 Register */ -#define CAN1_MB00_DATA2 0xffc03408 /* CAN Controller 1 Mailbox 0 Data 2 Register */ -#define CAN1_MB00_DATA3 0xffc0340c /* CAN Controller 1 Mailbox 0 Data 3 Register */ -#define CAN1_MB00_LENGTH 0xffc03410 /* CAN Controller 1 Mailbox 0 Length Register */ -#define CAN1_MB00_TIMESTAMP 0xffc03414 /* CAN Controller 1 Mailbox 0 Timestamp Register */ -#define CAN1_MB00_ID0 0xffc03418 /* CAN Controller 1 Mailbox 0 ID0 Register */ -#define CAN1_MB00_ID1 0xffc0341c /* CAN Controller 1 Mailbox 0 ID1 Register */ -#define CAN1_MB01_DATA0 0xffc03420 /* CAN Controller 1 Mailbox 1 Data 0 Register */ -#define CAN1_MB01_DATA1 0xffc03424 /* CAN Controller 1 Mailbox 1 Data 1 Register */ -#define CAN1_MB01_DATA2 0xffc03428 /* CAN Controller 1 Mailbox 1 Data 2 Register */ -#define CAN1_MB01_DATA3 0xffc0342c /* CAN Controller 1 Mailbox 1 Data 3 Register */ -#define CAN1_MB01_LENGTH 0xffc03430 /* CAN Controller 1 Mailbox 1 Length Register */ -#define CAN1_MB01_TIMESTAMP 0xffc03434 /* CAN Controller 1 Mailbox 1 Timestamp Register */ -#define CAN1_MB01_ID0 0xffc03438 /* CAN Controller 1 Mailbox 1 ID0 Register */ -#define CAN1_MB01_ID1 0xffc0343c /* CAN Controller 1 Mailbox 1 ID1 Register */ -#define CAN1_MB02_DATA0 0xffc03440 /* CAN Controller 1 Mailbox 2 Data 0 Register */ -#define CAN1_MB02_DATA1 0xffc03444 /* CAN Controller 1 Mailbox 2 Data 1 Register */ -#define CAN1_MB02_DATA2 0xffc03448 /* CAN Controller 1 Mailbox 2 Data 2 Register */ -#define CAN1_MB02_DATA3 0xffc0344c /* CAN Controller 1 Mailbox 2 Data 3 Register */ -#define CAN1_MB02_LENGTH 0xffc03450 /* CAN Controller 1 Mailbox 2 Length Register */ -#define CAN1_MB02_TIMESTAMP 0xffc03454 /* CAN Controller 1 Mailbox 2 Timestamp Register */ -#define CAN1_MB02_ID0 0xffc03458 /* CAN Controller 1 Mailbox 2 ID0 Register */ -#define CAN1_MB02_ID1 0xffc0345c /* CAN Controller 1 Mailbox 2 ID1 Register */ -#define CAN1_MB03_DATA0 0xffc03460 /* CAN Controller 1 Mailbox 3 Data 0 Register */ -#define CAN1_MB03_DATA1 0xffc03464 /* CAN Controller 1 Mailbox 3 Data 1 Register */ -#define CAN1_MB03_DATA2 0xffc03468 /* CAN Controller 1 Mailbox 3 Data 2 Register */ -#define CAN1_MB03_DATA3 0xffc0346c /* CAN Controller 1 Mailbox 3 Data 3 Register */ -#define CAN1_MB03_LENGTH 0xffc03470 /* CAN Controller 1 Mailbox 3 Length Register */ -#define CAN1_MB03_TIMESTAMP 0xffc03474 /* CAN Controller 1 Mailbox 3 Timestamp Register */ -#define CAN1_MB03_ID0 0xffc03478 /* CAN Controller 1 Mailbox 3 ID0 Register */ -#define CAN1_MB03_ID1 0xffc0347c /* CAN Controller 1 Mailbox 3 ID1 Register */ -#define CAN1_MB04_DATA0 0xffc03480 /* CAN Controller 1 Mailbox 4 Data 0 Register */ -#define CAN1_MB04_DATA1 0xffc03484 /* CAN Controller 1 Mailbox 4 Data 1 Register */ -#define CAN1_MB04_DATA2 0xffc03488 /* CAN Controller 1 Mailbox 4 Data 2 Register */ -#define CAN1_MB04_DATA3 0xffc0348c /* CAN Controller 1 Mailbox 4 Data 3 Register */ -#define CAN1_MB04_LENGTH 0xffc03490 /* CAN Controller 1 Mailbox 4 Length Register */ -#define CAN1_MB04_TIMESTAMP 0xffc03494 /* CAN Controller 1 Mailbox 4 Timestamp Register */ -#define CAN1_MB04_ID0 0xffc03498 /* CAN Controller 1 Mailbox 4 ID0 Register */ -#define CAN1_MB04_ID1 0xffc0349c /* CAN Controller 1 Mailbox 4 ID1 Register */ -#define CAN1_MB05_DATA0 0xffc034a0 /* CAN Controller 1 Mailbox 5 Data 0 Register */ -#define CAN1_MB05_DATA1 0xffc034a4 /* CAN Controller 1 Mailbox 5 Data 1 Register */ -#define CAN1_MB05_DATA2 0xffc034a8 /* CAN Controller 1 Mailbox 5 Data 2 Register */ -#define CAN1_MB05_DATA3 0xffc034ac /* CAN Controller 1 Mailbox 5 Data 3 Register */ -#define CAN1_MB05_LENGTH 0xffc034b0 /* CAN Controller 1 Mailbox 5 Length Register */ -#define CAN1_MB05_TIMESTAMP 0xffc034b4 /* CAN Controller 1 Mailbox 5 Timestamp Register */ -#define CAN1_MB05_ID0 0xffc034b8 /* CAN Controller 1 Mailbox 5 ID0 Register */ -#define CAN1_MB05_ID1 0xffc034bc /* CAN Controller 1 Mailbox 5 ID1 Register */ -#define CAN1_MB06_DATA0 0xffc034c0 /* CAN Controller 1 Mailbox 6 Data 0 Register */ -#define CAN1_MB06_DATA1 0xffc034c4 /* CAN Controller 1 Mailbox 6 Data 1 Register */ -#define CAN1_MB06_DATA2 0xffc034c8 /* CAN Controller 1 Mailbox 6 Data 2 Register */ -#define CAN1_MB06_DATA3 0xffc034cc /* CAN Controller 1 Mailbox 6 Data 3 Register */ -#define CAN1_MB06_LENGTH 0xffc034d0 /* CAN Controller 1 Mailbox 6 Length Register */ -#define CAN1_MB06_TIMESTAMP 0xffc034d4 /* CAN Controller 1 Mailbox 6 Timestamp Register */ -#define CAN1_MB06_ID0 0xffc034d8 /* CAN Controller 1 Mailbox 6 ID0 Register */ -#define CAN1_MB06_ID1 0xffc034dc /* CAN Controller 1 Mailbox 6 ID1 Register */ -#define CAN1_MB07_DATA0 0xffc034e0 /* CAN Controller 1 Mailbox 7 Data 0 Register */ -#define CAN1_MB07_DATA1 0xffc034e4 /* CAN Controller 1 Mailbox 7 Data 1 Register */ -#define CAN1_MB07_DATA2 0xffc034e8 /* CAN Controller 1 Mailbox 7 Data 2 Register */ -#define CAN1_MB07_DATA3 0xffc034ec /* CAN Controller 1 Mailbox 7 Data 3 Register */ -#define CAN1_MB07_LENGTH 0xffc034f0 /* CAN Controller 1 Mailbox 7 Length Register */ -#define CAN1_MB07_TIMESTAMP 0xffc034f4 /* CAN Controller 1 Mailbox 7 Timestamp Register */ -#define CAN1_MB07_ID0 0xffc034f8 /* CAN Controller 1 Mailbox 7 ID0 Register */ -#define CAN1_MB07_ID1 0xffc034fc /* CAN Controller 1 Mailbox 7 ID1 Register */ -#define CAN1_MB08_DATA0 0xffc03500 /* CAN Controller 1 Mailbox 8 Data 0 Register */ -#define CAN1_MB08_DATA1 0xffc03504 /* CAN Controller 1 Mailbox 8 Data 1 Register */ -#define CAN1_MB08_DATA2 0xffc03508 /* CAN Controller 1 Mailbox 8 Data 2 Register */ -#define CAN1_MB08_DATA3 0xffc0350c /* CAN Controller 1 Mailbox 8 Data 3 Register */ -#define CAN1_MB08_LENGTH 0xffc03510 /* CAN Controller 1 Mailbox 8 Length Register */ -#define CAN1_MB08_TIMESTAMP 0xffc03514 /* CAN Controller 1 Mailbox 8 Timestamp Register */ -#define CAN1_MB08_ID0 0xffc03518 /* CAN Controller 1 Mailbox 8 ID0 Register */ -#define CAN1_MB08_ID1 0xffc0351c /* CAN Controller 1 Mailbox 8 ID1 Register */ -#define CAN1_MB09_DATA0 0xffc03520 /* CAN Controller 1 Mailbox 9 Data 0 Register */ -#define CAN1_MB09_DATA1 0xffc03524 /* CAN Controller 1 Mailbox 9 Data 1 Register */ -#define CAN1_MB09_DATA2 0xffc03528 /* CAN Controller 1 Mailbox 9 Data 2 Register */ -#define CAN1_MB09_DATA3 0xffc0352c /* CAN Controller 1 Mailbox 9 Data 3 Register */ -#define CAN1_MB09_LENGTH 0xffc03530 /* CAN Controller 1 Mailbox 9 Length Register */ -#define CAN1_MB09_TIMESTAMP 0xffc03534 /* CAN Controller 1 Mailbox 9 Timestamp Register */ -#define CAN1_MB09_ID0 0xffc03538 /* CAN Controller 1 Mailbox 9 ID0 Register */ -#define CAN1_MB09_ID1 0xffc0353c /* CAN Controller 1 Mailbox 9 ID1 Register */ -#define CAN1_MB10_DATA0 0xffc03540 /* CAN Controller 1 Mailbox 10 Data 0 Register */ -#define CAN1_MB10_DATA1 0xffc03544 /* CAN Controller 1 Mailbox 10 Data 1 Register */ -#define CAN1_MB10_DATA2 0xffc03548 /* CAN Controller 1 Mailbox 10 Data 2 Register */ -#define CAN1_MB10_DATA3 0xffc0354c /* CAN Controller 1 Mailbox 10 Data 3 Register */ -#define CAN1_MB10_LENGTH 0xffc03550 /* CAN Controller 1 Mailbox 10 Length Register */ -#define CAN1_MB10_TIMESTAMP 0xffc03554 /* CAN Controller 1 Mailbox 10 Timestamp Register */ -#define CAN1_MB10_ID0 0xffc03558 /* CAN Controller 1 Mailbox 10 ID0 Register */ -#define CAN1_MB10_ID1 0xffc0355c /* CAN Controller 1 Mailbox 10 ID1 Register */ -#define CAN1_MB11_DATA0 0xffc03560 /* CAN Controller 1 Mailbox 11 Data 0 Register */ -#define CAN1_MB11_DATA1 0xffc03564 /* CAN Controller 1 Mailbox 11 Data 1 Register */ -#define CAN1_MB11_DATA2 0xffc03568 /* CAN Controller 1 Mailbox 11 Data 2 Register */ -#define CAN1_MB11_DATA3 0xffc0356c /* CAN Controller 1 Mailbox 11 Data 3 Register */ -#define CAN1_MB11_LENGTH 0xffc03570 /* CAN Controller 1 Mailbox 11 Length Register */ -#define CAN1_MB11_TIMESTAMP 0xffc03574 /* CAN Controller 1 Mailbox 11 Timestamp Register */ -#define CAN1_MB11_ID0 0xffc03578 /* CAN Controller 1 Mailbox 11 ID0 Register */ -#define CAN1_MB11_ID1 0xffc0357c /* CAN Controller 1 Mailbox 11 ID1 Register */ -#define CAN1_MB12_DATA0 0xffc03580 /* CAN Controller 1 Mailbox 12 Data 0 Register */ -#define CAN1_MB12_DATA1 0xffc03584 /* CAN Controller 1 Mailbox 12 Data 1 Register */ -#define CAN1_MB12_DATA2 0xffc03588 /* CAN Controller 1 Mailbox 12 Data 2 Register */ -#define CAN1_MB12_DATA3 0xffc0358c /* CAN Controller 1 Mailbox 12 Data 3 Register */ -#define CAN1_MB12_LENGTH 0xffc03590 /* CAN Controller 1 Mailbox 12 Length Register */ -#define CAN1_MB12_TIMESTAMP 0xffc03594 /* CAN Controller 1 Mailbox 12 Timestamp Register */ -#define CAN1_MB12_ID0 0xffc03598 /* CAN Controller 1 Mailbox 12 ID0 Register */ -#define CAN1_MB12_ID1 0xffc0359c /* CAN Controller 1 Mailbox 12 ID1 Register */ -#define CAN1_MB13_DATA0 0xffc035a0 /* CAN Controller 1 Mailbox 13 Data 0 Register */ -#define CAN1_MB13_DATA1 0xffc035a4 /* CAN Controller 1 Mailbox 13 Data 1 Register */ -#define CAN1_MB13_DATA2 0xffc035a8 /* CAN Controller 1 Mailbox 13 Data 2 Register */ -#define CAN1_MB13_DATA3 0xffc035ac /* CAN Controller 1 Mailbox 13 Data 3 Register */ -#define CAN1_MB13_LENGTH 0xffc035b0 /* CAN Controller 1 Mailbox 13 Length Register */ -#define CAN1_MB13_TIMESTAMP 0xffc035b4 /* CAN Controller 1 Mailbox 13 Timestamp Register */ -#define CAN1_MB13_ID0 0xffc035b8 /* CAN Controller 1 Mailbox 13 ID0 Register */ -#define CAN1_MB13_ID1 0xffc035bc /* CAN Controller 1 Mailbox 13 ID1 Register */ -#define CAN1_MB14_DATA0 0xffc035c0 /* CAN Controller 1 Mailbox 14 Data 0 Register */ -#define CAN1_MB14_DATA1 0xffc035c4 /* CAN Controller 1 Mailbox 14 Data 1 Register */ -#define CAN1_MB14_DATA2 0xffc035c8 /* CAN Controller 1 Mailbox 14 Data 2 Register */ -#define CAN1_MB14_DATA3 0xffc035cc /* CAN Controller 1 Mailbox 14 Data 3 Register */ -#define CAN1_MB14_LENGTH 0xffc035d0 /* CAN Controller 1 Mailbox 14 Length Register */ -#define CAN1_MB14_TIMESTAMP 0xffc035d4 /* CAN Controller 1 Mailbox 14 Timestamp Register */ -#define CAN1_MB14_ID0 0xffc035d8 /* CAN Controller 1 Mailbox 14 ID0 Register */ -#define CAN1_MB14_ID1 0xffc035dc /* CAN Controller 1 Mailbox 14 ID1 Register */ -#define CAN1_MB15_DATA0 0xffc035e0 /* CAN Controller 1 Mailbox 15 Data 0 Register */ -#define CAN1_MB15_DATA1 0xffc035e4 /* CAN Controller 1 Mailbox 15 Data 1 Register */ -#define CAN1_MB15_DATA2 0xffc035e8 /* CAN Controller 1 Mailbox 15 Data 2 Register */ -#define CAN1_MB15_DATA3 0xffc035ec /* CAN Controller 1 Mailbox 15 Data 3 Register */ -#define CAN1_MB15_LENGTH 0xffc035f0 /* CAN Controller 1 Mailbox 15 Length Register */ -#define CAN1_MB15_TIMESTAMP 0xffc035f4 /* CAN Controller 1 Mailbox 15 Timestamp Register */ -#define CAN1_MB15_ID0 0xffc035f8 /* CAN Controller 1 Mailbox 15 ID0 Register */ -#define CAN1_MB15_ID1 0xffc035fc /* CAN Controller 1 Mailbox 15 ID1 Register */ - -/* CAN Controller 1 Mailbox Data Registers */ - -#define CAN1_MB16_DATA0 0xffc03600 /* CAN Controller 1 Mailbox 16 Data 0 Register */ -#define CAN1_MB16_DATA1 0xffc03604 /* CAN Controller 1 Mailbox 16 Data 1 Register */ -#define CAN1_MB16_DATA2 0xffc03608 /* CAN Controller 1 Mailbox 16 Data 2 Register */ -#define CAN1_MB16_DATA3 0xffc0360c /* CAN Controller 1 Mailbox 16 Data 3 Register */ -#define CAN1_MB16_LENGTH 0xffc03610 /* CAN Controller 1 Mailbox 16 Length Register */ -#define CAN1_MB16_TIMESTAMP 0xffc03614 /* CAN Controller 1 Mailbox 16 Timestamp Register */ -#define CAN1_MB16_ID0 0xffc03618 /* CAN Controller 1 Mailbox 16 ID0 Register */ -#define CAN1_MB16_ID1 0xffc0361c /* CAN Controller 1 Mailbox 16 ID1 Register */ -#define CAN1_MB17_DATA0 0xffc03620 /* CAN Controller 1 Mailbox 17 Data 0 Register */ -#define CAN1_MB17_DATA1 0xffc03624 /* CAN Controller 1 Mailbox 17 Data 1 Register */ -#define CAN1_MB17_DATA2 0xffc03628 /* CAN Controller 1 Mailbox 17 Data 2 Register */ -#define CAN1_MB17_DATA3 0xffc0362c /* CAN Controller 1 Mailbox 17 Data 3 Register */ -#define CAN1_MB17_LENGTH 0xffc03630 /* CAN Controller 1 Mailbox 17 Length Register */ -#define CAN1_MB17_TIMESTAMP 0xffc03634 /* CAN Controller 1 Mailbox 17 Timestamp Register */ -#define CAN1_MB17_ID0 0xffc03638 /* CAN Controller 1 Mailbox 17 ID0 Register */ -#define CAN1_MB17_ID1 0xffc0363c /* CAN Controller 1 Mailbox 17 ID1 Register */ -#define CAN1_MB18_DATA0 0xffc03640 /* CAN Controller 1 Mailbox 18 Data 0 Register */ -#define CAN1_MB18_DATA1 0xffc03644 /* CAN Controller 1 Mailbox 18 Data 1 Register */ -#define CAN1_MB18_DATA2 0xffc03648 /* CAN Controller 1 Mailbox 18 Data 2 Register */ -#define CAN1_MB18_DATA3 0xffc0364c /* CAN Controller 1 Mailbox 18 Data 3 Register */ -#define CAN1_MB18_LENGTH 0xffc03650 /* CAN Controller 1 Mailbox 18 Length Register */ -#define CAN1_MB18_TIMESTAMP 0xffc03654 /* CAN Controller 1 Mailbox 18 Timestamp Register */ -#define CAN1_MB18_ID0 0xffc03658 /* CAN Controller 1 Mailbox 18 ID0 Register */ -#define CAN1_MB18_ID1 0xffc0365c /* CAN Controller 1 Mailbox 18 ID1 Register */ -#define CAN1_MB19_DATA0 0xffc03660 /* CAN Controller 1 Mailbox 19 Data 0 Register */ -#define CAN1_MB19_DATA1 0xffc03664 /* CAN Controller 1 Mailbox 19 Data 1 Register */ -#define CAN1_MB19_DATA2 0xffc03668 /* CAN Controller 1 Mailbox 19 Data 2 Register */ -#define CAN1_MB19_DATA3 0xffc0366c /* CAN Controller 1 Mailbox 19 Data 3 Register */ -#define CAN1_MB19_LENGTH 0xffc03670 /* CAN Controller 1 Mailbox 19 Length Register */ -#define CAN1_MB19_TIMESTAMP 0xffc03674 /* CAN Controller 1 Mailbox 19 Timestamp Register */ -#define CAN1_MB19_ID0 0xffc03678 /* CAN Controller 1 Mailbox 19 ID0 Register */ -#define CAN1_MB19_ID1 0xffc0367c /* CAN Controller 1 Mailbox 19 ID1 Register */ -#define CAN1_MB20_DATA0 0xffc03680 /* CAN Controller 1 Mailbox 20 Data 0 Register */ -#define CAN1_MB20_DATA1 0xffc03684 /* CAN Controller 1 Mailbox 20 Data 1 Register */ -#define CAN1_MB20_DATA2 0xffc03688 /* CAN Controller 1 Mailbox 20 Data 2 Register */ -#define CAN1_MB20_DATA3 0xffc0368c /* CAN Controller 1 Mailbox 20 Data 3 Register */ -#define CAN1_MB20_LENGTH 0xffc03690 /* CAN Controller 1 Mailbox 20 Length Register */ -#define CAN1_MB20_TIMESTAMP 0xffc03694 /* CAN Controller 1 Mailbox 20 Timestamp Register */ -#define CAN1_MB20_ID0 0xffc03698 /* CAN Controller 1 Mailbox 20 ID0 Register */ -#define CAN1_MB20_ID1 0xffc0369c /* CAN Controller 1 Mailbox 20 ID1 Register */ -#define CAN1_MB21_DATA0 0xffc036a0 /* CAN Controller 1 Mailbox 21 Data 0 Register */ -#define CAN1_MB21_DATA1 0xffc036a4 /* CAN Controller 1 Mailbox 21 Data 1 Register */ -#define CAN1_MB21_DATA2 0xffc036a8 /* CAN Controller 1 Mailbox 21 Data 2 Register */ -#define CAN1_MB21_DATA3 0xffc036ac /* CAN Controller 1 Mailbox 21 Data 3 Register */ -#define CAN1_MB21_LENGTH 0xffc036b0 /* CAN Controller 1 Mailbox 21 Length Register */ -#define CAN1_MB21_TIMESTAMP 0xffc036b4 /* CAN Controller 1 Mailbox 21 Timestamp Register */ -#define CAN1_MB21_ID0 0xffc036b8 /* CAN Controller 1 Mailbox 21 ID0 Register */ -#define CAN1_MB21_ID1 0xffc036bc /* CAN Controller 1 Mailbox 21 ID1 Register */ -#define CAN1_MB22_DATA0 0xffc036c0 /* CAN Controller 1 Mailbox 22 Data 0 Register */ -#define CAN1_MB22_DATA1 0xffc036c4 /* CAN Controller 1 Mailbox 22 Data 1 Register */ -#define CAN1_MB22_DATA2 0xffc036c8 /* CAN Controller 1 Mailbox 22 Data 2 Register */ -#define CAN1_MB22_DATA3 0xffc036cc /* CAN Controller 1 Mailbox 22 Data 3 Register */ -#define CAN1_MB22_LENGTH 0xffc036d0 /* CAN Controller 1 Mailbox 22 Length Register */ -#define CAN1_MB22_TIMESTAMP 0xffc036d4 /* CAN Controller 1 Mailbox 22 Timestamp Register */ -#define CAN1_MB22_ID0 0xffc036d8 /* CAN Controller 1 Mailbox 22 ID0 Register */ -#define CAN1_MB22_ID1 0xffc036dc /* CAN Controller 1 Mailbox 22 ID1 Register */ -#define CAN1_MB23_DATA0 0xffc036e0 /* CAN Controller 1 Mailbox 23 Data 0 Register */ -#define CAN1_MB23_DATA1 0xffc036e4 /* CAN Controller 1 Mailbox 23 Data 1 Register */ -#define CAN1_MB23_DATA2 0xffc036e8 /* CAN Controller 1 Mailbox 23 Data 2 Register */ -#define CAN1_MB23_DATA3 0xffc036ec /* CAN Controller 1 Mailbox 23 Data 3 Register */ -#define CAN1_MB23_LENGTH 0xffc036f0 /* CAN Controller 1 Mailbox 23 Length Register */ -#define CAN1_MB23_TIMESTAMP 0xffc036f4 /* CAN Controller 1 Mailbox 23 Timestamp Register */ -#define CAN1_MB23_ID0 0xffc036f8 /* CAN Controller 1 Mailbox 23 ID0 Register */ -#define CAN1_MB23_ID1 0xffc036fc /* CAN Controller 1 Mailbox 23 ID1 Register */ -#define CAN1_MB24_DATA0 0xffc03700 /* CAN Controller 1 Mailbox 24 Data 0 Register */ -#define CAN1_MB24_DATA1 0xffc03704 /* CAN Controller 1 Mailbox 24 Data 1 Register */ -#define CAN1_MB24_DATA2 0xffc03708 /* CAN Controller 1 Mailbox 24 Data 2 Register */ -#define CAN1_MB24_DATA3 0xffc0370c /* CAN Controller 1 Mailbox 24 Data 3 Register */ -#define CAN1_MB24_LENGTH 0xffc03710 /* CAN Controller 1 Mailbox 24 Length Register */ -#define CAN1_MB24_TIMESTAMP 0xffc03714 /* CAN Controller 1 Mailbox 24 Timestamp Register */ -#define CAN1_MB24_ID0 0xffc03718 /* CAN Controller 1 Mailbox 24 ID0 Register */ -#define CAN1_MB24_ID1 0xffc0371c /* CAN Controller 1 Mailbox 24 ID1 Register */ -#define CAN1_MB25_DATA0 0xffc03720 /* CAN Controller 1 Mailbox 25 Data 0 Register */ -#define CAN1_MB25_DATA1 0xffc03724 /* CAN Controller 1 Mailbox 25 Data 1 Register */ -#define CAN1_MB25_DATA2 0xffc03728 /* CAN Controller 1 Mailbox 25 Data 2 Register */ -#define CAN1_MB25_DATA3 0xffc0372c /* CAN Controller 1 Mailbox 25 Data 3 Register */ -#define CAN1_MB25_LENGTH 0xffc03730 /* CAN Controller 1 Mailbox 25 Length Register */ -#define CAN1_MB25_TIMESTAMP 0xffc03734 /* CAN Controller 1 Mailbox 25 Timestamp Register */ -#define CAN1_MB25_ID0 0xffc03738 /* CAN Controller 1 Mailbox 25 ID0 Register */ -#define CAN1_MB25_ID1 0xffc0373c /* CAN Controller 1 Mailbox 25 ID1 Register */ -#define CAN1_MB26_DATA0 0xffc03740 /* CAN Controller 1 Mailbox 26 Data 0 Register */ -#define CAN1_MB26_DATA1 0xffc03744 /* CAN Controller 1 Mailbox 26 Data 1 Register */ -#define CAN1_MB26_DATA2 0xffc03748 /* CAN Controller 1 Mailbox 26 Data 2 Register */ -#define CAN1_MB26_DATA3 0xffc0374c /* CAN Controller 1 Mailbox 26 Data 3 Register */ -#define CAN1_MB26_LENGTH 0xffc03750 /* CAN Controller 1 Mailbox 26 Length Register */ -#define CAN1_MB26_TIMESTAMP 0xffc03754 /* CAN Controller 1 Mailbox 26 Timestamp Register */ -#define CAN1_MB26_ID0 0xffc03758 /* CAN Controller 1 Mailbox 26 ID0 Register */ -#define CAN1_MB26_ID1 0xffc0375c /* CAN Controller 1 Mailbox 26 ID1 Register */ -#define CAN1_MB27_DATA0 0xffc03760 /* CAN Controller 1 Mailbox 27 Data 0 Register */ -#define CAN1_MB27_DATA1 0xffc03764 /* CAN Controller 1 Mailbox 27 Data 1 Register */ -#define CAN1_MB27_DATA2 0xffc03768 /* CAN Controller 1 Mailbox 27 Data 2 Register */ -#define CAN1_MB27_DATA3 0xffc0376c /* CAN Controller 1 Mailbox 27 Data 3 Register */ -#define CAN1_MB27_LENGTH 0xffc03770 /* CAN Controller 1 Mailbox 27 Length Register */ -#define CAN1_MB27_TIMESTAMP 0xffc03774 /* CAN Controller 1 Mailbox 27 Timestamp Register */ -#define CAN1_MB27_ID0 0xffc03778 /* CAN Controller 1 Mailbox 27 ID0 Register */ -#define CAN1_MB27_ID1 0xffc0377c /* CAN Controller 1 Mailbox 27 ID1 Register */ -#define CAN1_MB28_DATA0 0xffc03780 /* CAN Controller 1 Mailbox 28 Data 0 Register */ -#define CAN1_MB28_DATA1 0xffc03784 /* CAN Controller 1 Mailbox 28 Data 1 Register */ -#define CAN1_MB28_DATA2 0xffc03788 /* CAN Controller 1 Mailbox 28 Data 2 Register */ -#define CAN1_MB28_DATA3 0xffc0378c /* CAN Controller 1 Mailbox 28 Data 3 Register */ -#define CAN1_MB28_LENGTH 0xffc03790 /* CAN Controller 1 Mailbox 28 Length Register */ -#define CAN1_MB28_TIMESTAMP 0xffc03794 /* CAN Controller 1 Mailbox 28 Timestamp Register */ -#define CAN1_MB28_ID0 0xffc03798 /* CAN Controller 1 Mailbox 28 ID0 Register */ -#define CAN1_MB28_ID1 0xffc0379c /* CAN Controller 1 Mailbox 28 ID1 Register */ -#define CAN1_MB29_DATA0 0xffc037a0 /* CAN Controller 1 Mailbox 29 Data 0 Register */ -#define CAN1_MB29_DATA1 0xffc037a4 /* CAN Controller 1 Mailbox 29 Data 1 Register */ -#define CAN1_MB29_DATA2 0xffc037a8 /* CAN Controller 1 Mailbox 29 Data 2 Register */ -#define CAN1_MB29_DATA3 0xffc037ac /* CAN Controller 1 Mailbox 29 Data 3 Register */ -#define CAN1_MB29_LENGTH 0xffc037b0 /* CAN Controller 1 Mailbox 29 Length Register */ -#define CAN1_MB29_TIMESTAMP 0xffc037b4 /* CAN Controller 1 Mailbox 29 Timestamp Register */ -#define CAN1_MB29_ID0 0xffc037b8 /* CAN Controller 1 Mailbox 29 ID0 Register */ -#define CAN1_MB29_ID1 0xffc037bc /* CAN Controller 1 Mailbox 29 ID1 Register */ -#define CAN1_MB30_DATA0 0xffc037c0 /* CAN Controller 1 Mailbox 30 Data 0 Register */ -#define CAN1_MB30_DATA1 0xffc037c4 /* CAN Controller 1 Mailbox 30 Data 1 Register */ -#define CAN1_MB30_DATA2 0xffc037c8 /* CAN Controller 1 Mailbox 30 Data 2 Register */ -#define CAN1_MB30_DATA3 0xffc037cc /* CAN Controller 1 Mailbox 30 Data 3 Register */ -#define CAN1_MB30_LENGTH 0xffc037d0 /* CAN Controller 1 Mailbox 30 Length Register */ -#define CAN1_MB30_TIMESTAMP 0xffc037d4 /* CAN Controller 1 Mailbox 30 Timestamp Register */ -#define CAN1_MB30_ID0 0xffc037d8 /* CAN Controller 1 Mailbox 30 ID0 Register */ -#define CAN1_MB30_ID1 0xffc037dc /* CAN Controller 1 Mailbox 30 ID1 Register */ -#define CAN1_MB31_DATA0 0xffc037e0 /* CAN Controller 1 Mailbox 31 Data 0 Register */ -#define CAN1_MB31_DATA1 0xffc037e4 /* CAN Controller 1 Mailbox 31 Data 1 Register */ -#define CAN1_MB31_DATA2 0xffc037e8 /* CAN Controller 1 Mailbox 31 Data 2 Register */ -#define CAN1_MB31_DATA3 0xffc037ec /* CAN Controller 1 Mailbox 31 Data 3 Register */ -#define CAN1_MB31_LENGTH 0xffc037f0 /* CAN Controller 1 Mailbox 31 Length Register */ -#define CAN1_MB31_TIMESTAMP 0xffc037f4 /* CAN Controller 1 Mailbox 31 Timestamp Register */ -#define CAN1_MB31_ID0 0xffc037f8 /* CAN Controller 1 Mailbox 31 ID0 Register */ -#define CAN1_MB31_ID1 0xffc037fc /* CAN Controller 1 Mailbox 31 ID1 Register */ - -/* ATAPI Registers */ - -#define ATAPI_CONTROL 0xffc03800 /* ATAPI Control Register */ -#define ATAPI_STATUS 0xffc03804 /* ATAPI Status Register */ -#define ATAPI_DEV_ADDR 0xffc03808 /* ATAPI Device Register Address */ -#define ATAPI_DEV_TXBUF 0xffc0380c /* ATAPI Device Register Write Data */ -#define ATAPI_DEV_RXBUF 0xffc03810 /* ATAPI Device Register Read Data */ -#define ATAPI_INT_MASK 0xffc03814 /* ATAPI Interrupt Mask Register */ -#define ATAPI_INT_STATUS 0xffc03818 /* ATAPI Interrupt Status Register */ -#define ATAPI_XFER_LEN 0xffc0381c /* ATAPI Length of Transfer */ -#define ATAPI_LINE_STATUS 0xffc03820 /* ATAPI Line Status */ -#define ATAPI_SM_STATE 0xffc03824 /* ATAPI State Machine Status */ -#define ATAPI_TERMINATE 0xffc03828 /* ATAPI Host Terminate */ -#define ATAPI_PIO_TFRCNT 0xffc0382c /* ATAPI PIO mode transfer count */ -#define ATAPI_DMA_TFRCNT 0xffc03830 /* ATAPI DMA mode transfer count */ -#define ATAPI_UMAIN_TFRCNT 0xffc03834 /* ATAPI UDMAIN transfer count */ -#define ATAPI_UDMAOUT_TFRCNT 0xffc03838 /* ATAPI UDMAOUT transfer count */ -#define ATAPI_REG_TIM_0 0xffc03840 /* ATAPI Register Transfer Timing 0 */ -#define ATAPI_PIO_TIM_0 0xffc03844 /* ATAPI PIO Timing 0 Register */ -#define ATAPI_PIO_TIM_1 0xffc03848 /* ATAPI PIO Timing 1 Register */ -#define ATAPI_MULTI_TIM_0 0xffc03850 /* ATAPI Multi-DMA Timing 0 Register */ -#define ATAPI_MULTI_TIM_1 0xffc03854 /* ATAPI Multi-DMA Timing 1 Register */ -#define ATAPI_MULTI_TIM_2 0xffc03858 /* ATAPI Multi-DMA Timing 2 Register */ -#define ATAPI_ULTRA_TIM_0 0xffc03860 /* ATAPI Ultra-DMA Timing 0 Register */ -#define ATAPI_ULTRA_TIM_1 0xffc03864 /* ATAPI Ultra-DMA Timing 1 Register */ -#define ATAPI_ULTRA_TIM_2 0xffc03868 /* ATAPI Ultra-DMA Timing 2 Register */ -#define ATAPI_ULTRA_TIM_3 0xffc0386c /* ATAPI Ultra-DMA Timing 3 Register */ - -/* SDH Registers */ - -#define SDH_PWR_CTL 0xffc03900 /* SDH Power Control */ -#define SDH_CLK_CTL 0xffc03904 /* SDH Clock Control */ -#define SDH_ARGUMENT 0xffc03908 /* SDH Argument */ -#define SDH_COMMAND 0xffc0390c /* SDH Command */ -#define SDH_RESP_CMD 0xffc03910 /* SDH Response Command */ -#define SDH_RESPONSE0 0xffc03914 /* SDH Response0 */ -#define SDH_RESPONSE1 0xffc03918 /* SDH Response1 */ -#define SDH_RESPONSE2 0xffc0391c /* SDH Response2 */ -#define SDH_RESPONSE3 0xffc03920 /* SDH Response3 */ -#define SDH_DATA_TIMER 0xffc03924 /* SDH Data Timer */ -#define SDH_DATA_LGTH 0xffc03928 /* SDH Data Length */ -#define SDH_DATA_CTL 0xffc0392c /* SDH Data Control */ -#define SDH_DATA_CNT 0xffc03930 /* SDH Data Counter */ -#define SDH_STATUS 0xffc03934 /* SDH Status */ -#define SDH_STATUS_CLR 0xffc03938 /* SDH Status Clear */ -#define SDH_MASK0 0xffc0393c /* SDH Interrupt0 Mask */ -#define SDH_MASK1 0xffc03940 /* SDH Interrupt1 Mask */ -#define SDH_FIFO_CNT 0xffc03948 /* SDH FIFO Counter */ -#define SDH_FIFO 0xffc03980 /* SDH Data FIFO */ -#define SDH_E_STATUS 0xffc039c0 /* SDH Exception Status */ -#define SDH_E_MASK 0xffc039c4 /* SDH Exception Mask */ -#define SDH_CFG 0xffc039c8 /* SDH Configuration */ -#define SDH_RD_WAIT_EN 0xffc039cc /* SDH Read Wait Enable */ -#define SDH_PID0 0xffc039d0 /* SDH Peripheral Identification0 */ -#define SDH_PID1 0xffc039d4 /* SDH Peripheral Identification1 */ -#define SDH_PID2 0xffc039d8 /* SDH Peripheral Identification2 */ -#define SDH_PID3 0xffc039dc /* SDH Peripheral Identification3 */ -#define SDH_PID4 0xffc039e0 /* SDH Peripheral Identification4 */ -#define SDH_PID5 0xffc039e4 /* SDH Peripheral Identification5 */ -#define SDH_PID6 0xffc039e8 /* SDH Peripheral Identification6 */ -#define SDH_PID7 0xffc039ec /* SDH Peripheral Identification7 */ - -/* HOST Port Registers */ - -#define HOST_CONTROL 0xffc03a00 /* HOST Control Register */ -#define HOST_STATUS 0xffc03a04 /* HOST Status Register */ -#define HOST_TIMEOUT 0xffc03a08 /* HOST Acknowledge Mode Timeout Register */ - -/* USB Control Registers */ - -#define USB_FADDR 0xffc03c00 /* Function address register */ -#define USB_POWER 0xffc03c04 /* Power management register */ -#define USB_INTRTX 0xffc03c08 /* Interrupt register for endpoint 0 and Tx endpoint 1 to 7 */ -#define USB_INTRRX 0xffc03c0c /* Interrupt register for Rx endpoints 1 to 7 */ -#define USB_INTRTXE 0xffc03c10 /* Interrupt enable register for IntrTx */ -#define USB_INTRRXE 0xffc03c14 /* Interrupt enable register for IntrRx */ -#define USB_INTRUSB 0xffc03c18 /* Interrupt register for common USB interrupts */ -#define USB_INTRUSBE 0xffc03c1c /* Interrupt enable register for IntrUSB */ -#define USB_FRAME 0xffc03c20 /* USB frame number */ -#define USB_INDEX 0xffc03c24 /* Index register for selecting the indexed endpoint registers */ -#define USB_TESTMODE 0xffc03c28 /* Enabled USB 20 test modes */ -#define USB_GLOBINTR 0xffc03c2c /* Global Interrupt Mask register and Wakeup Exception Interrupt */ -#define USB_GLOBAL_CTL 0xffc03c30 /* Global Clock Control for the core */ - -/* USB Packet Control Registers */ - -#define USB_TX_MAX_PACKET 0xffc03c40 /* Maximum packet size for Host Tx endpoint */ -#define USB_CSR0 0xffc03c44 /* Control Status register for endpoint 0 and Control Status register for Host Tx endpoint */ -#define USB_TXCSR 0xffc03c44 /* Control Status register for endpoint 0 and Control Status register for Host Tx endpoint */ -#define USB_RX_MAX_PACKET 0xffc03c48 /* Maximum packet size for Host Rx endpoint */ -#define USB_RXCSR 0xffc03c4c /* Control Status register for Host Rx endpoint */ -#define USB_COUNT0 0xffc03c50 /* Number of bytes received in endpoint 0 FIFO and Number of bytes received in Host Tx endpoint */ -#define USB_RXCOUNT 0xffc03c50 /* Number of bytes received in endpoint 0 FIFO and Number of bytes received in Host Tx endpoint */ -#define USB_TXTYPE 0xffc03c54 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint */ -#define USB_NAKLIMIT0 0xffc03c58 /* Sets the NAK response timeout on Endpoint 0 and on Bulk transfers for Host Tx endpoint */ -#define USB_TXINTERVAL 0xffc03c58 /* Sets the NAK response timeout on Endpoint 0 and on Bulk transfers for Host Tx endpoint */ -#define USB_RXTYPE 0xffc03c5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint */ -#define USB_RXINTERVAL 0xffc03c60 /* Sets the polling interval for Interrupt and Isochronous transfers or the NAK response timeout on Bulk transfers */ -#define USB_TXCOUNT 0xffc03c68 /* Number of bytes to be written to the selected endpoint Tx FIFO */ - -/* USB Endpoint FIFO Registers */ - -#define USB_EP0_FIFO 0xffc03c80 /* Endpoint 0 FIFO */ -#define USB_EP1_FIFO 0xffc03c88 /* Endpoint 1 FIFO */ -#define USB_EP2_FIFO 0xffc03c90 /* Endpoint 2 FIFO */ -#define USB_EP3_FIFO 0xffc03c98 /* Endpoint 3 FIFO */ -#define USB_EP4_FIFO 0xffc03ca0 /* Endpoint 4 FIFO */ -#define USB_EP5_FIFO 0xffc03ca8 /* Endpoint 5 FIFO */ -#define USB_EP6_FIFO 0xffc03cb0 /* Endpoint 6 FIFO */ -#define USB_EP7_FIFO 0xffc03cb8 /* Endpoint 7 FIFO */ - -/* USB OTG Control Registers */ - -#define USB_OTG_DEV_CTL 0xffc03d00 /* OTG Device Control Register */ -#define USB_OTG_VBUS_IRQ 0xffc03d04 /* OTG VBUS Control Interrupts */ -#define USB_OTG_VBUS_MASK 0xffc03d08 /* VBUS Control Interrupt Enable */ - -/* USB Phy Control Registers */ - -#define USB_LINKINFO 0xffc03d48 /* Enables programming of some PHY-side delays */ -#define USB_VPLEN 0xffc03d4c /* Determines duration of VBUS pulse for VBUS charging */ -#define USB_HS_EOF1 0xffc03d50 /* Time buffer for High-Speed transactions */ -#define USB_FS_EOF1 0xffc03d54 /* Time buffer for Full-Speed transactions */ -#define USB_LS_EOF1 0xffc03d58 /* Time buffer for Low-Speed transactions */ - -/* (APHY_CNTRL is for ADI usage only) */ - -#define USB_APHY_CNTRL 0xffc03de0 /* Register that increases visibility of Analog PHY */ - -/* (APHY_CALIB is for ADI usage only) */ - -#define USB_APHY_CALIB 0xffc03de4 /* Register used to set some calibration values */ -#define USB_APHY_CNTRL2 0xffc03de8 /* Register used to prevent re-enumeration once Moab goes into hibernate mode */ - -/* (PHY_TEST is for ADI usage only) */ - -#define USB_PHY_TEST 0xffc03dec /* Used for reducing simulation time and simplifies FIFO testability */ -#define USB_PLLOSC_CTRL 0xffc03df0 /* Used to program different parameters for USB PLL and Oscillator */ -#define USB_SRP_CLKDIV 0xffc03df4 /* Used to program clock divide value for the clock fed to the SRP detection logic */ - -/* USB Endpoint 0 Control Registers */ - -#define USB_EP_NI0_TXMAXP 0xffc03e00 /* Maximum packet size for Host Tx endpoint0 */ -#define USB_EP_NI0_TXCSR 0xffc03e04 /* Control Status register for endpoint 0 */ -#define USB_EP_NI0_RXMAXP 0xffc03e08 /* Maximum packet size for Host Rx endpoint0 */ -#define USB_EP_NI0_RXCSR 0xffc03e0c /* Control Status register for Host Rx endpoint0 */ -#define USB_EP_NI0_RXCOUNT 0xffc03e10 /* Number of bytes received in endpoint 0 FIFO */ -#define USB_EP_NI0_TXTYPE 0xffc03e14 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint0 */ -#define USB_EP_NI0_TXINTERVAL 0xffc03e18 /* Sets the NAK response timeout on Endpoint 0 */ -#define USB_EP_NI0_RXTYPE 0xffc03e1c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint0 */ -#define USB_EP_NI0_RXINTERVAL 0xffc03e20 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint0 */ - -/* USB Endpoint 1 Control Registers */ - -#define USB_EP_NI0_TXCOUNT 0xffc03e28 /* Number of bytes to be written to the endpoint0 Tx FIFO */ -#define USB_EP_NI1_TXMAXP 0xffc03e40 /* Maximum packet size for Host Tx endpoint1 */ -#define USB_EP_NI1_TXCSR 0xffc03e44 /* Control Status register for endpoint1 */ -#define USB_EP_NI1_RXMAXP 0xffc03e48 /* Maximum packet size for Host Rx endpoint1 */ -#define USB_EP_NI1_RXCSR 0xffc03e4c /* Control Status register for Host Rx endpoint1 */ -#define USB_EP_NI1_RXCOUNT 0xffc03e50 /* Number of bytes received in endpoint1 FIFO */ -#define USB_EP_NI1_TXTYPE 0xffc03e54 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint1 */ -#define USB_EP_NI1_TXINTERVAL 0xffc03e58 /* Sets the NAK response timeout on Endpoint1 */ -#define USB_EP_NI1_RXTYPE 0xffc03e5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint1 */ -#define USB_EP_NI1_RXINTERVAL 0xffc03e60 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint1 */ - -/* USB Endpoint 2 Control Registers */ - -#define USB_EP_NI1_TXCOUNT 0xffc03e68 /* Number of bytes to be written to the+H102 endpoint1 Tx FIFO */ -#define USB_EP_NI2_TXMAXP 0xffc03e80 /* Maximum packet size for Host Tx endpoint2 */ -#define USB_EP_NI2_TXCSR 0xffc03e84 /* Control Status register for endpoint2 */ -#define USB_EP_NI2_RXMAXP 0xffc03e88 /* Maximum packet size for Host Rx endpoint2 */ -#define USB_EP_NI2_RXCSR 0xffc03e8c /* Control Status register for Host Rx endpoint2 */ -#define USB_EP_NI2_RXCOUNT 0xffc03e90 /* Number of bytes received in endpoint2 FIFO */ -#define USB_EP_NI2_TXTYPE 0xffc03e94 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint2 */ -#define USB_EP_NI2_TXINTERVAL 0xffc03e98 /* Sets the NAK response timeout on Endpoint2 */ -#define USB_EP_NI2_RXTYPE 0xffc03e9c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint2 */ -#define USB_EP_NI2_RXINTERVAL 0xffc03ea0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint2 */ - -/* USB Endpoint 3 Control Registers */ - -#define USB_EP_NI2_TXCOUNT 0xffc03ea8 /* Number of bytes to be written to the endpoint2 Tx FIFO */ -#define USB_EP_NI3_TXMAXP 0xffc03ec0 /* Maximum packet size for Host Tx endpoint3 */ -#define USB_EP_NI3_TXCSR 0xffc03ec4 /* Control Status register for endpoint3 */ -#define USB_EP_NI3_RXMAXP 0xffc03ec8 /* Maximum packet size for Host Rx endpoint3 */ -#define USB_EP_NI3_RXCSR 0xffc03ecc /* Control Status register for Host Rx endpoint3 */ -#define USB_EP_NI3_RXCOUNT 0xffc03ed0 /* Number of bytes received in endpoint3 FIFO */ -#define USB_EP_NI3_TXTYPE 0xffc03ed4 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint3 */ -#define USB_EP_NI3_TXINTERVAL 0xffc03ed8 /* Sets the NAK response timeout on Endpoint3 */ -#define USB_EP_NI3_RXTYPE 0xffc03edc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint3 */ -#define USB_EP_NI3_RXINTERVAL 0xffc03ee0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint3 */ - -/* USB Endpoint 4 Control Registers */ - -#define USB_EP_NI3_TXCOUNT 0xffc03ee8 /* Number of bytes to be written to the H124endpoint3 Tx FIFO */ -#define USB_EP_NI4_TXMAXP 0xffc03f00 /* Maximum packet size for Host Tx endpoint4 */ -#define USB_EP_NI4_TXCSR 0xffc03f04 /* Control Status register for endpoint4 */ -#define USB_EP_NI4_RXMAXP 0xffc03f08 /* Maximum packet size for Host Rx endpoint4 */ -#define USB_EP_NI4_RXCSR 0xffc03f0c /* Control Status register for Host Rx endpoint4 */ -#define USB_EP_NI4_RXCOUNT 0xffc03f10 /* Number of bytes received in endpoint4 FIFO */ -#define USB_EP_NI4_TXTYPE 0xffc03f14 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint4 */ -#define USB_EP_NI4_TXINTERVAL 0xffc03f18 /* Sets the NAK response timeout on Endpoint4 */ -#define USB_EP_NI4_RXTYPE 0xffc03f1c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint4 */ -#define USB_EP_NI4_RXINTERVAL 0xffc03f20 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint4 */ - -/* USB Endpoint 5 Control Registers */ - -#define USB_EP_NI4_TXCOUNT 0xffc03f28 /* Number of bytes to be written to the endpoint4 Tx FIFO */ -#define USB_EP_NI5_TXMAXP 0xffc03f40 /* Maximum packet size for Host Tx endpoint5 */ -#define USB_EP_NI5_TXCSR 0xffc03f44 /* Control Status register for endpoint5 */ -#define USB_EP_NI5_RXMAXP 0xffc03f48 /* Maximum packet size for Host Rx endpoint5 */ -#define USB_EP_NI5_RXCSR 0xffc03f4c /* Control Status register for Host Rx endpoint5 */ -#define USB_EP_NI5_RXCOUNT 0xffc03f50 /* Number of bytes received in endpoint5 FIFO */ -#define USB_EP_NI5_TXTYPE 0xffc03f54 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint5 */ -#define USB_EP_NI5_TXINTERVAL 0xffc03f58 /* Sets the NAK response timeout on Endpoint5 */ -#define USB_EP_NI5_RXTYPE 0xffc03f5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint5 */ -#define USB_EP_NI5_RXINTERVAL 0xffc03f60 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint5 */ - -/* USB Endpoint 6 Control Registers */ - -#define USB_EP_NI5_TXCOUNT 0xffc03f68 /* Number of bytes to be written to the H145endpoint5 Tx FIFO */ -#define USB_EP_NI6_TXMAXP 0xffc03f80 /* Maximum packet size for Host Tx endpoint6 */ -#define USB_EP_NI6_TXCSR 0xffc03f84 /* Control Status register for endpoint6 */ -#define USB_EP_NI6_RXMAXP 0xffc03f88 /* Maximum packet size for Host Rx endpoint6 */ -#define USB_EP_NI6_RXCSR 0xffc03f8c /* Control Status register for Host Rx endpoint6 */ -#define USB_EP_NI6_RXCOUNT 0xffc03f90 /* Number of bytes received in endpoint6 FIFO */ -#define USB_EP_NI6_TXTYPE 0xffc03f94 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint6 */ -#define USB_EP_NI6_TXINTERVAL 0xffc03f98 /* Sets the NAK response timeout on Endpoint6 */ -#define USB_EP_NI6_RXTYPE 0xffc03f9c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint6 */ -#define USB_EP_NI6_RXINTERVAL 0xffc03fa0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint6 */ - -/* USB Endpoint 7 Control Registers */ - -#define USB_EP_NI6_TXCOUNT 0xffc03fa8 /* Number of bytes to be written to the endpoint6 Tx FIFO */ -#define USB_EP_NI7_TXMAXP 0xffc03fc0 /* Maximum packet size for Host Tx endpoint7 */ -#define USB_EP_NI7_TXCSR 0xffc03fc4 /* Control Status register for endpoint7 */ -#define USB_EP_NI7_RXMAXP 0xffc03fc8 /* Maximum packet size for Host Rx endpoint7 */ -#define USB_EP_NI7_RXCSR 0xffc03fcc /* Control Status register for Host Rx endpoint7 */ -#define USB_EP_NI7_RXCOUNT 0xffc03fd0 /* Number of bytes received in endpoint7 FIFO */ -#define USB_EP_NI7_TXTYPE 0xffc03fd4 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */ -#define USB_EP_NI7_TXINTERVAL 0xffc03fd8 /* Sets the NAK response timeout on Endpoint7 */ -#define USB_EP_NI7_RXTYPE 0xffc03fdc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */ -#define USB_EP_NI7_RXINTERVAL 0xffc03ff0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */ -#define USB_EP_NI7_TXCOUNT 0xffc03ff8 /* Number of bytes to be written to the endpoint7 Tx FIFO */ -#define USB_DMA_INTERRUPT 0xffc04000 /* Indicates pending interrupts for the DMA channels */ - -/* USB Channel 0 Config Registers */ - -#define USB_DMA0CONTROL 0xffc04004 /* DMA master channel 0 configuration */ -#define USB_DMA0ADDRLOW 0xffc04008 /* Lower 16-bits of memory source/destination address for DMA master channel 0 */ -#define USB_DMA0ADDRHIGH 0xffc0400c /* Upper 16-bits of memory source/destination address for DMA master channel 0 */ -#define USB_DMA0COUNTLOW 0xffc04010 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 0 */ -#define USB_DMA0COUNTHIGH 0xffc04014 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 0 */ - -/* USB Channel 1 Config Registers */ - -#define USB_DMA1CONTROL 0xffc04024 /* DMA master channel 1 configuration */ -#define USB_DMA1ADDRLOW 0xffc04028 /* Lower 16-bits of memory source/destination address for DMA master channel 1 */ -#define USB_DMA1ADDRHIGH 0xffc0402c /* Upper 16-bits of memory source/destination address for DMA master channel 1 */ -#define USB_DMA1COUNTLOW 0xffc04030 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 1 */ -#define USB_DMA1COUNTHIGH 0xffc04034 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 1 */ - -/* USB Channel 2 Config Registers */ - -#define USB_DMA2CONTROL 0xffc04044 /* DMA master channel 2 configuration */ -#define USB_DMA2ADDRLOW 0xffc04048 /* Lower 16-bits of memory source/destination address for DMA master channel 2 */ -#define USB_DMA2ADDRHIGH 0xffc0404c /* Upper 16-bits of memory source/destination address for DMA master channel 2 */ -#define USB_DMA2COUNTLOW 0xffc04050 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 2 */ -#define USB_DMA2COUNTHIGH 0xffc04054 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 2 */ - -/* USB Channel 3 Config Registers */ - -#define USB_DMA3CONTROL 0xffc04064 /* DMA master channel 3 configuration */ -#define USB_DMA3ADDRLOW 0xffc04068 /* Lower 16-bits of memory source/destination address for DMA master channel 3 */ -#define USB_DMA3ADDRHIGH 0xffc0406c /* Upper 16-bits of memory source/destination address for DMA master channel 3 */ -#define USB_DMA3COUNTLOW 0xffc04070 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 3 */ -#define USB_DMA3COUNTHIGH 0xffc04074 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 3 */ - -/* USB Channel 4 Config Registers */ - -#define USB_DMA4CONTROL 0xffc04084 /* DMA master channel 4 configuration */ -#define USB_DMA4ADDRLOW 0xffc04088 /* Lower 16-bits of memory source/destination address for DMA master channel 4 */ -#define USB_DMA4ADDRHIGH 0xffc0408c /* Upper 16-bits of memory source/destination address for DMA master channel 4 */ -#define USB_DMA4COUNTLOW 0xffc04090 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 4 */ -#define USB_DMA4COUNTHIGH 0xffc04094 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 4 */ - -/* USB Channel 5 Config Registers */ - -#define USB_DMA5CONTROL 0xffc040a4 /* DMA master channel 5 configuration */ -#define USB_DMA5ADDRLOW 0xffc040a8 /* Lower 16-bits of memory source/destination address for DMA master channel 5 */ -#define USB_DMA5ADDRHIGH 0xffc040ac /* Upper 16-bits of memory source/destination address for DMA master channel 5 */ -#define USB_DMA5COUNTLOW 0xffc040b0 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 5 */ -#define USB_DMA5COUNTHIGH 0xffc040b4 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 5 */ - -/* USB Channel 6 Config Registers */ - -#define USB_DMA6CONTROL 0xffc040c4 /* DMA master channel 6 configuration */ -#define USB_DMA6ADDRLOW 0xffc040c8 /* Lower 16-bits of memory source/destination address for DMA master channel 6 */ -#define USB_DMA6ADDRHIGH 0xffc040cc /* Upper 16-bits of memory source/destination address for DMA master channel 6 */ -#define USB_DMA6COUNTLOW 0xffc040d0 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 6 */ -#define USB_DMA6COUNTHIGH 0xffc040d4 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 6 */ - -/* USB Channel 7 Config Registers */ - -#define USB_DMA7CONTROL 0xffc040e4 /* DMA master channel 7 configuration */ -#define USB_DMA7ADDRLOW 0xffc040e8 /* Lower 16-bits of memory source/destination address for DMA master channel 7 */ -#define USB_DMA7ADDRHIGH 0xffc040ec /* Upper 16-bits of memory source/destination address for DMA master channel 7 */ -#define USB_DMA7COUNTLOW 0xffc040f0 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 7 */ -#define USB_DMA7COUNTHIGH 0xffc040f4 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 7 */ - -/* Keypad Registers */ - -#define KPAD_CTL 0xffc04100 /* Controls keypad module enable and disable */ -#define KPAD_PRESCALE 0xffc04104 /* Establish a time base for programing the KPAD_MSEL register */ -#define KPAD_MSEL 0xffc04108 /* Selects delay parameters for keypad interface sensitivity */ -#define KPAD_ROWCOL 0xffc0410c /* Captures the row and column output values of the keys pressed */ -#define KPAD_STAT 0xffc04110 /* Holds and clears the status of the keypad interface interrupt */ -#define KPAD_SOFTEVAL 0xffc04114 /* Lets software force keypad interface to check for keys being pressed */ - -/* Pixel Compositor (PIXC) Registers */ - -#define PIXC_CTL 0xffc04400 /* Overlay enable, resampling mode, I/O data format, transparency enable, watermark level, FIFO status */ -#define PIXC_PPL 0xffc04404 /* Holds the number of pixels per line of the display */ -#define PIXC_LPF 0xffc04408 /* Holds the number of lines per frame of the display */ -#define PIXC_AHSTART 0xffc0440c /* Contains horizontal start pixel information of the overlay data (set A) */ -#define PIXC_AHEND 0xffc04410 /* Contains horizontal end pixel information of the overlay data (set A) */ -#define PIXC_AVSTART 0xffc04414 /* Contains vertical start pixel information of the overlay data (set A) */ -#define PIXC_AVEND 0xffc04418 /* Contains vertical end pixel information of the overlay data (set A) */ -#define PIXC_ATRANSP 0xffc0441c /* Contains the transparency ratio (set A) */ -#define PIXC_BHSTART 0xffc04420 /* Contains horizontal start pixel information of the overlay data (set B) */ -#define PIXC_BHEND 0xffc04424 /* Contains horizontal end pixel information of the overlay data (set B) */ -#define PIXC_BVSTART 0xffc04428 /* Contains vertical start pixel information of the overlay data (set B) */ -#define PIXC_BVEND 0xffc0442c /* Contains vertical end pixel information of the overlay data (set B) */ -#define PIXC_BTRANSP 0xffc04430 /* Contains the transparency ratio (set B) */ -#define PIXC_INTRSTAT 0xffc0443c /* Overlay interrupt configuration/status */ -#define PIXC_RYCON 0xffc04440 /* Color space conversion matrix register. Contains the R/Y conversion coefficients */ -#define PIXC_GUCON 0xffc04444 /* Color space conversion matrix register. Contains the G/U conversion coefficients */ -#define PIXC_BVCON 0xffc04448 /* Color space conversion matrix register. Contains the B/V conversion coefficients */ -#define PIXC_CCBIAS 0xffc0444c /* Bias values for the color space conversion matrix */ -#define PIXC_TC 0xffc04450 /* Holds the transparent color value */ - -/* Handshake MDMA 0 Registers */ - -#define HMDMA0_CONTROL 0xffc04500 /* Handshake MDMA0 Control Register */ -#define HMDMA0_ECINIT 0xffc04504 /* Handshake MDMA0 Initial Edge Count Register */ -#define HMDMA0_BCINIT 0xffc04508 /* Handshake MDMA0 Initial Block Count Register */ -#define HMDMA0_ECURGENT 0xffc0450c /* Handshake MDMA0 Urgent Edge Count Threshold Register */ -#define HMDMA0_ECOVERFLOW 0xffc04510 /* Handshake MDMA0 Edge Count Overflow Interrupt Register */ -#define HMDMA0_ECOUNT 0xffc04514 /* Handshake MDMA0 Current Edge Count Register */ -#define HMDMA0_BCOUNT 0xffc04518 /* Handshake MDMA0 Current Block Count Register */ - -/* Handshake MDMA 1 Registers */ - -#define HMDMA1_CONTROL 0xffc04540 /* Handshake MDMA1 Control Register */ -#define HMDMA1_ECINIT 0xffc04544 /* Handshake MDMA1 Initial Edge Count Register */ -#define HMDMA1_BCINIT 0xffc04548 /* Handshake MDMA1 Initial Block Count Register */ -#define HMDMA1_ECURGENT 0xffc0454c /* Handshake MDMA1 Urgent Edge Count Threshold Register */ -#define HMDMA1_ECOVERFLOW 0xffc04550 /* Handshake MDMA1 Edge Count Overflow Interrupt Register */ -#define HMDMA1_ECOUNT 0xffc04554 /* Handshake MDMA1 Current Edge Count Register */ -#define HMDMA1_BCOUNT 0xffc04558 /* Handshake MDMA1 Current Block Count Register */ - - -/* ********************************************************** */ -/* SINGLE BIT MACRO PAIRS (bit mask and negated one) */ -/* and MULTI BIT READ MACROS */ -/* ********************************************************** */ - -/* Bit masks for PIXC_CTL */ - -#define PIXC_EN 0x1 /* Pixel Compositor Enable */ -#define OVR_A_EN 0x2 /* Overlay A Enable */ -#define OVR_B_EN 0x4 /* Overlay B Enable */ -#define IMG_FORM 0x8 /* Image Data Format */ -#define OVR_FORM 0x10 /* Overlay Data Format */ -#define OUT_FORM 0x20 /* Output Data Format */ -#define UDS_MOD 0x40 /* Resampling Mode */ -#define TC_EN 0x80 /* Transparent Color Enable */ -#define IMG_STAT 0x300 /* Image FIFO Status */ -#define OVR_STAT 0xc00 /* Overlay FIFO Status */ -#define WM_LVL 0x3000 /* FIFO Watermark Level */ - -/* Bit masks for PIXC_AHSTART */ - -#define A_HSTART 0xfff /* Horizontal Start Coordinates */ - -/* Bit masks for PIXC_AHEND */ - -#define A_HEND 0xfff /* Horizontal End Coordinates */ - -/* Bit masks for PIXC_AVSTART */ - -#define A_VSTART 0x3ff /* Vertical Start Coordinates */ - -/* Bit masks for PIXC_AVEND */ - -#define A_VEND 0x3ff /* Vertical End Coordinates */ - -/* Bit masks for PIXC_ATRANSP */ - -#define A_TRANSP 0xf /* Transparency Value */ - -/* Bit masks for PIXC_BHSTART */ - -#define B_HSTART 0xfff /* Horizontal Start Coordinates */ - -/* Bit masks for PIXC_BHEND */ - -#define B_HEND 0xfff /* Horizontal End Coordinates */ - -/* Bit masks for PIXC_BVSTART */ - -#define B_VSTART 0x3ff /* Vertical Start Coordinates */ - -/* Bit masks for PIXC_BVEND */ - -#define B_VEND 0x3ff /* Vertical End Coordinates */ - -/* Bit masks for PIXC_BTRANSP */ - -#define B_TRANSP 0xf /* Transparency Value */ - -/* Bit masks for PIXC_INTRSTAT */ - -#define OVR_INT_EN 0x1 /* Interrupt at End of Last Valid Overlay */ -#define FRM_INT_EN 0x2 /* Interrupt at End of Frame */ -#define OVR_INT_STAT 0x4 /* Overlay Interrupt Status */ -#define FRM_INT_STAT 0x8 /* Frame Interrupt Status */ - -/* Bit masks for PIXC_RYCON */ - -#define A11 0x3ff /* A11 in the Coefficient Matrix */ -#define A12 0xffc00 /* A12 in the Coefficient Matrix */ -#define A13 0x3ff00000 /* A13 in the Coefficient Matrix */ -#define RY_MULT4 0x40000000 /* Multiply Row by 4 */ - -/* Bit masks for PIXC_GUCON */ - -#define A21 0x3ff /* A21 in the Coefficient Matrix */ -#define A22 0xffc00 /* A22 in the Coefficient Matrix */ -#define A23 0x3ff00000 /* A23 in the Coefficient Matrix */ -#define GU_MULT4 0x40000000 /* Multiply Row by 4 */ - -/* Bit masks for PIXC_BVCON */ - -#define A31 0x3ff /* A31 in the Coefficient Matrix */ -#define A32 0xffc00 /* A32 in the Coefficient Matrix */ -#define A33 0x3ff00000 /* A33 in the Coefficient Matrix */ -#define BV_MULT4 0x40000000 /* Multiply Row by 4 */ - -/* Bit masks for PIXC_CCBIAS */ - -#define A14 0x3ff /* A14 in the Bias Vector */ -#define A24 0xffc00 /* A24 in the Bias Vector */ -#define A34 0x3ff00000 /* A34 in the Bias Vector */ - -/* Bit masks for PIXC_TC */ - -#define RY_TRANS 0xff /* Transparent Color - R/Y Component */ -#define GU_TRANS 0xff00 /* Transparent Color - G/U Component */ -#define BV_TRANS 0xff0000 /* Transparent Color - B/V Component */ - -/* Bit masks for HOST_CONTROL */ - -#define HOST_EN 0x1 /* Host Enable */ -#define HOST_END 0x2 /* Host Endianess */ -#define DATA_SIZE 0x4 /* Data Size */ -#define HOST_RST 0x8 /* Host Reset */ -#define HRDY_OVR 0x20 /* Host Ready Override */ -#define INT_MODE 0x40 /* Interrupt Mode */ -#define BT_EN 0x80 /* Bus Timeout Enable */ -#define EHW 0x100 /* Enable Host Write */ -#define EHR 0x200 /* Enable Host Read */ -#define BDR 0x400 /* Burst DMA Requests */ - -/* Bit masks for HOST_STATUS */ - -#define DMA_READY 0x1 /* DMA Ready */ -#define FIFOFULL 0x2 /* FIFO Full */ -#define FIFOEMPTY 0x4 /* FIFO Empty */ -#define DMA_COMPLETE 0x8 /* DMA Complete */ -#define HSHK 0x10 /* Host Handshake */ -#define TIMEOUT 0x20 /* Host Timeout */ -#define HIRQ 0x40 /* Host Interrupt Request */ -#define ALLOW_CNFG 0x80 /* Allow New Configuration */ -#define DMA_DIR 0x100 /* DMA Direction */ -#define BTE 0x200 /* Bus Timeout Enabled */ - -/* Bit masks for HOST_TIMEOUT */ - -#define COUNT_TIMEOUT 0x7ff /* Host Timeout count */ - /* Bit masks for MXVR_CONFIG */ #define MXVREN 0x1 /* MXVR Enable */ @@ -2031,603 +1050,6 @@ #define SCNT 0xffff /* System Clock Count */ -/* Bit masks for KPAD_CTL */ - -#define KPAD_EN 0x1 /* Keypad Enable */ -#define KPAD_IRQMODE 0x6 /* Key Press Interrupt Enable */ -#define KPAD_ROWEN 0x1c00 /* Row Enable Width */ -#define KPAD_COLEN 0xe000 /* Column Enable Width */ - -/* Bit masks for KPAD_PRESCALE */ - -#define KPAD_PRESCALE_VAL 0x3f /* Key Prescale Value */ - -/* Bit masks for KPAD_MSEL */ - -#define DBON_SCALE 0xff /* Debounce Scale Value */ -#define COLDRV_SCALE 0xff00 /* Column Driver Scale Value */ - -/* Bit masks for KPAD_ROWCOL */ - -#define KPAD_ROW 0xff /* Rows Pressed */ -#define KPAD_COL 0xff00 /* Columns Pressed */ - -/* Bit masks for KPAD_STAT */ - -#define KPAD_IRQ 0x1 /* Keypad Interrupt Status */ -#define KPAD_MROWCOL 0x6 /* Multiple Row/Column Keypress Status */ -#define KPAD_PRESSED 0x8 /* Key press current status */ - -/* Bit masks for KPAD_SOFTEVAL */ - -#define KPAD_SOFTEVAL_E 0x2 /* Software Programmable Force Evaluate */ - -/* Bit masks for SDH_COMMAND */ - -#define CMD_IDX 0x3f /* Command Index */ -#define CMD_RSP 0x40 /* Response */ -#define CMD_L_RSP 0x80 /* Long Response */ -#define CMD_INT_E 0x100 /* Command Interrupt */ -#define CMD_PEND_E 0x200 /* Command Pending */ -#define CMD_E 0x400 /* Command Enable */ - -/* Bit masks for SDH_PWR_CTL */ - -#define PWR_ON 0x3 /* Power On */ -#if 0 -#define TBD 0x3c /* TBD */ -#endif -#define SD_CMD_OD 0x40 /* Open Drain Output */ -#define ROD_CTL 0x80 /* Rod Control */ - -/* Bit masks for SDH_CLK_CTL */ - -#define CLKDIV 0xff /* MC_CLK Divisor */ -#define CLK_E 0x100 /* MC_CLK Bus Clock Enable */ -#define PWR_SV_E 0x200 /* Power Save Enable */ -#define CLKDIV_BYPASS 0x400 /* Bypass Divisor */ -#define WIDE_BUS 0x800 /* Wide Bus Mode Enable */ - -/* Bit masks for SDH_RESP_CMD */ - -#define RESP_CMD 0x3f /* Response Command */ - -/* Bit masks for SDH_DATA_CTL */ - -#define DTX_E 0x1 /* Data Transfer Enable */ -#define DTX_DIR 0x2 /* Data Transfer Direction */ -#define DTX_MODE 0x4 /* Data Transfer Mode */ -#define DTX_DMA_E 0x8 /* Data Transfer DMA Enable */ -#define DTX_BLK_LGTH 0xf0 /* Data Transfer Block Length */ - -/* Bit masks for SDH_STATUS */ - -#define CMD_CRC_FAIL 0x1 /* CMD CRC Fail */ -#define DAT_CRC_FAIL 0x2 /* Data CRC Fail */ -#define CMD_TIME_OUT 0x4 /* CMD Time Out */ -#define DAT_TIME_OUT 0x8 /* Data Time Out */ -#define TX_UNDERRUN 0x10 /* Transmit Underrun */ -#define RX_OVERRUN 0x20 /* Receive Overrun */ -#define CMD_RESP_END 0x40 /* CMD Response End */ -#define CMD_SENT 0x80 /* CMD Sent */ -#define DAT_END 0x100 /* Data End */ -#define START_BIT_ERR 0x200 /* Start Bit Error */ -#define DAT_BLK_END 0x400 /* Data Block End */ -#define CMD_ACT 0x800 /* CMD Active */ -#define TX_ACT 0x1000 /* Transmit Active */ -#define RX_ACT 0x2000 /* Receive Active */ -#define TX_FIFO_STAT 0x4000 /* Transmit FIFO Status */ -#define RX_FIFO_STAT 0x8000 /* Receive FIFO Status */ -#define TX_FIFO_FULL 0x10000 /* Transmit FIFO Full */ -#define RX_FIFO_FULL 0x20000 /* Receive FIFO Full */ -#define TX_FIFO_ZERO 0x40000 /* Transmit FIFO Empty */ -#define RX_DAT_ZERO 0x80000 /* Receive FIFO Empty */ -#define TX_DAT_RDY 0x100000 /* Transmit Data Available */ -#define RX_FIFO_RDY 0x200000 /* Receive Data Available */ - -/* Bit masks for SDH_STATUS_CLR */ - -#define CMD_CRC_FAIL_STAT 0x1 /* CMD CRC Fail Status */ -#define DAT_CRC_FAIL_STAT 0x2 /* Data CRC Fail Status */ -#define CMD_TIMEOUT_STAT 0x4 /* CMD Time Out Status */ -#define DAT_TIMEOUT_STAT 0x8 /* Data Time Out status */ -#define TX_UNDERRUN_STAT 0x10 /* Transmit Underrun Status */ -#define RX_OVERRUN_STAT 0x20 /* Receive Overrun Status */ -#define CMD_RESP_END_STAT 0x40 /* CMD Response End Status */ -#define CMD_SENT_STAT 0x80 /* CMD Sent Status */ -#define DAT_END_STAT 0x100 /* Data End Status */ -#define START_BIT_ERR_STAT 0x200 /* Start Bit Error Status */ -#define DAT_BLK_END_STAT 0x400 /* Data Block End Status */ - -/* Bit masks for SDH_MASK0 */ - -#define CMD_CRC_FAIL_MASK 0x1 /* CMD CRC Fail Mask */ -#define DAT_CRC_FAIL_MASK 0x2 /* Data CRC Fail Mask */ -#define CMD_TIMEOUT_MASK 0x4 /* CMD Time Out Mask */ -#define DAT_TIMEOUT_MASK 0x8 /* Data Time Out Mask */ -#define TX_UNDERRUN_MASK 0x10 /* Transmit Underrun Mask */ -#define RX_OVERRUN_MASK 0x20 /* Receive Overrun Mask */ -#define CMD_RESP_END_MASK 0x40 /* CMD Response End Mask */ -#define CMD_SENT_MASK 0x80 /* CMD Sent Mask */ -#define DAT_END_MASK 0x100 /* Data End Mask */ -#define START_BIT_ERR_MASK 0x200 /* Start Bit Error Mask */ -#define DAT_BLK_END_MASK 0x400 /* Data Block End Mask */ -#define CMD_ACT_MASK 0x800 /* CMD Active Mask */ -#define TX_ACT_MASK 0x1000 /* Transmit Active Mask */ -#define RX_ACT_MASK 0x2000 /* Receive Active Mask */ -#define TX_FIFO_STAT_MASK 0x4000 /* Transmit FIFO Status Mask */ -#define RX_FIFO_STAT_MASK 0x8000 /* Receive FIFO Status Mask */ -#define TX_FIFO_FULL_MASK 0x10000 /* Transmit FIFO Full Mask */ -#define RX_FIFO_FULL_MASK 0x20000 /* Receive FIFO Full Mask */ -#define TX_FIFO_ZERO_MASK 0x40000 /* Transmit FIFO Empty Mask */ -#define RX_DAT_ZERO_MASK 0x80000 /* Receive FIFO Empty Mask */ -#define TX_DAT_RDY_MASK 0x100000 /* Transmit Data Available Mask */ -#define RX_FIFO_RDY_MASK 0x200000 /* Receive Data Available Mask */ - -/* Bit masks for SDH_FIFO_CNT */ - -#define FIFO_COUNT 0x7fff /* FIFO Count */ - -/* Bit masks for SDH_E_STATUS */ - -#define SDIO_INT_DET 0x2 /* SDIO Int Detected */ -#define SD_CARD_DET 0x10 /* SD Card Detect */ - -/* Bit masks for SDH_E_MASK */ - -#define SDIO_MSK 0x2 /* Mask SDIO Int Detected */ -#define SCD_MSK 0x40 /* Mask Card Detect */ - -/* Bit masks for SDH_CFG */ - -#define CLKS_EN 0x1 /* Clocks Enable */ -#define SD4E 0x4 /* SDIO 4-Bit Enable */ -#define MWE 0x8 /* Moving Window Enable */ -#define SD_RST 0x10 /* SDMMC Reset */ -#define PUP_SDDAT 0x20 /* Pull-up SD_DAT */ -#define PUP_SDDAT3 0x40 /* Pull-up SD_DAT3 */ -#define PD_SDDAT3 0x80 /* Pull-down SD_DAT3 */ - -/* Bit masks for SDH_RD_WAIT_EN */ - -#define RWR 0x1 /* Read Wait Request */ - -/* Bit masks for ATAPI_CONTROL */ - -#define PIO_START 0x1 /* Start PIO/Reg Op */ -#define MULTI_START 0x2 /* Start Multi-DMA Op */ -#define ULTRA_START 0x4 /* Start Ultra-DMA Op */ -#define XFER_DIR 0x8 /* Transfer Direction */ -#define IORDY_EN 0x10 /* IORDY Enable */ -#define FIFO_FLUSH 0x20 /* Flush FIFOs */ -#define SOFT_RST 0x40 /* Soft Reset */ -#define DEV_RST 0x80 /* Device Reset */ -#define TFRCNT_RST 0x100 /* Trans Count Reset */ -#define END_ON_TERM 0x200 /* End/Terminate Select */ -#define PIO_USE_DMA 0x400 /* PIO-DMA Enable */ -#define UDMAIN_FIFO_THRS 0xf000 /* Ultra DMA-IN FIFO Threshold */ - -/* Bit masks for ATAPI_STATUS */ - -#define PIO_XFER_ON 0x1 /* PIO transfer in progress */ -#define MULTI_XFER_ON 0x2 /* Multi-word DMA transfer in progress */ -#define ULTRA_XFER_ON 0x4 /* Ultra DMA transfer in progress */ -#define ULTRA_IN_FL 0xf0 /* Ultra DMA Input FIFO Level */ - -/* Bit masks for ATAPI_DEV_ADDR */ - -#define DEV_ADDR 0x1f /* Device Address */ - -/* Bit masks for ATAPI_INT_MASK */ - -#define ATAPI_DEV_INT_MASK 0x1 /* Device interrupt mask */ -#define PIO_DONE_MASK 0x2 /* PIO transfer done interrupt mask */ -#define MULTI_DONE_MASK 0x4 /* Multi-DMA transfer done interrupt mask */ -#define UDMAIN_DONE_MASK 0x8 /* Ultra-DMA in transfer done interrupt mask */ -#define UDMAOUT_DONE_MASK 0x10 /* Ultra-DMA out transfer done interrupt mask */ -#define HOST_TERM_XFER_MASK 0x20 /* Host terminate current transfer interrupt mask */ -#define MULTI_TERM_MASK 0x40 /* Device terminate Multi-DMA transfer interrupt mask */ -#define UDMAIN_TERM_MASK 0x80 /* Device terminate Ultra-DMA-in transfer interrupt mask */ -#define UDMAOUT_TERM_MASK 0x100 /* Device terminate Ultra-DMA-out transfer interrupt mask */ - -/* Bit masks for ATAPI_INT_STATUS */ - -#define ATAPI_DEV_INT 0x1 /* Device interrupt status */ -#define PIO_DONE_INT 0x2 /* PIO transfer done interrupt status */ -#define MULTI_DONE_INT 0x4 /* Multi-DMA transfer done interrupt status */ -#define UDMAIN_DONE_INT 0x8 /* Ultra-DMA in transfer done interrupt status */ -#define UDMAOUT_DONE_INT 0x10 /* Ultra-DMA out transfer done interrupt status */ -#define HOST_TERM_XFER_INT 0x20 /* Host terminate current transfer interrupt status */ -#define MULTI_TERM_INT 0x40 /* Device terminate Multi-DMA transfer interrupt status */ -#define UDMAIN_TERM_INT 0x80 /* Device terminate Ultra-DMA-in transfer interrupt status */ -#define UDMAOUT_TERM_INT 0x100 /* Device terminate Ultra-DMA-out transfer interrupt status */ - -/* Bit masks for ATAPI_LINE_STATUS */ - -#define ATAPI_INTR 0x1 /* Device interrupt to host line status */ -#define ATAPI_DASP 0x2 /* Device dasp to host line status */ -#define ATAPI_CS0N 0x4 /* ATAPI chip select 0 line status */ -#define ATAPI_CS1N 0x8 /* ATAPI chip select 1 line status */ -#define ATAPI_ADDR 0x70 /* ATAPI address line status */ -#define ATAPI_DMAREQ 0x80 /* ATAPI DMA request line status */ -#define ATAPI_DMAACKN 0x100 /* ATAPI DMA acknowledge line status */ -#define ATAPI_DIOWN 0x200 /* ATAPI write line status */ -#define ATAPI_DIORN 0x400 /* ATAPI read line status */ -#define ATAPI_IORDY 0x800 /* ATAPI IORDY line status */ - -/* Bit masks for ATAPI_SM_STATE */ - -#define PIO_CSTATE 0xf /* PIO mode state machine current state */ -#define DMA_CSTATE 0xf0 /* DMA mode state machine current state */ -#define UDMAIN_CSTATE 0xf00 /* Ultra DMA-In mode state machine current state */ -#define UDMAOUT_CSTATE 0xf000 /* ATAPI IORDY line status */ - -/* Bit masks for ATAPI_TERMINATE */ - -#define ATAPI_HOST_TERM 0x1 /* Host terminationation */ - -/* Bit masks for ATAPI_REG_TIM_0 */ - -#define T2_REG 0xff /* End of cycle time for register access transfers */ -#define TEOC_REG 0xff00 /* Selects DIOR/DIOW pulsewidth */ - -/* Bit masks for ATAPI_PIO_TIM_0 */ - -#define T1_REG 0xf /* Time from address valid to DIOR/DIOW */ -#define T2_REG_PIO 0xff0 /* DIOR/DIOW pulsewidth */ -#define T4_REG 0xf000 /* DIOW data hold */ - -/* Bit masks for ATAPI_PIO_TIM_1 */ - -#define TEOC_REG_PIO 0xff /* End of cycle time for PIO access transfers. */ - -/* Bit masks for ATAPI_MULTI_TIM_0 */ - -#define TD 0xff /* DIOR/DIOW asserted pulsewidth */ -#define TM 0xff00 /* Time from address valid to DIOR/DIOW */ - -/* Bit masks for ATAPI_MULTI_TIM_1 */ - -#define TKW 0xff /* Selects DIOW negated pulsewidth */ -#define TKR 0xff00 /* Selects DIOR negated pulsewidth */ - -/* Bit masks for ATAPI_MULTI_TIM_2 */ - -#define TH 0xff /* Selects DIOW data hold */ -#define TEOC 0xff00 /* Selects end of cycle for DMA */ - -/* Bit masks for ATAPI_ULTRA_TIM_0 */ - -#define TACK 0xff /* Selects setup and hold times for TACK */ -#define TENV 0xff00 /* Selects envelope time */ - -/* Bit masks for ATAPI_ULTRA_TIM_1 */ - -#define TDVS 0xff /* Selects data valid setup time */ -#define TCYC_TDVS 0xff00 /* Selects cycle time - TDVS time */ - -/* Bit masks for ATAPI_ULTRA_TIM_2 */ - -#define TSS 0xff /* Selects time from STROBE edge to negation of DMARQ or assertion of STOP */ -#define TMLI 0xff00 /* Selects interlock time */ - -/* Bit masks for ATAPI_ULTRA_TIM_3 */ - -#define TZAH 0xff /* Selects minimum delay required for output */ -#define READY_PAUSE 0xff00 /* Selects ready to pause */ - -/* Bit masks for TIMER_ENABLE1 */ - -#define TIMEN8 0x1 /* Timer 8 Enable */ -#define TIMEN9 0x2 /* Timer 9 Enable */ -#define TIMEN10 0x4 /* Timer 10 Enable */ - -/* Bit masks for TIMER_DISABLE1 */ - -#define TIMDIS8 0x1 /* Timer 8 Disable */ -#define TIMDIS9 0x2 /* Timer 9 Disable */ -#define TIMDIS10 0x4 /* Timer 10 Disable */ - -/* Bit masks for TIMER_STATUS1 */ - -#define TIMIL8 0x1 /* Timer 8 Interrupt */ -#define TIMIL9 0x2 /* Timer 9 Interrupt */ -#define TIMIL10 0x4 /* Timer 10 Interrupt */ -#define TOVF_ERR8 0x10 /* Timer 8 Counter Overflow */ -#define TOVF_ERR9 0x20 /* Timer 9 Counter Overflow */ -#define TOVF_ERR10 0x40 /* Timer 10 Counter Overflow */ -#define TRUN8 0x1000 /* Timer 8 Slave Enable Status */ -#define TRUN9 0x2000 /* Timer 9 Slave Enable Status */ -#define TRUN10 0x4000 /* Timer 10 Slave Enable Status */ - -/* Bit masks for EPPI0 are obtained from common base header for EPPIx (EPPI1 and EPPI2) */ - -/* Bit masks for USB_FADDR */ - -#define FUNCTION_ADDRESS 0x7f /* Function address */ - -/* Bit masks for USB_POWER */ - -#define ENABLE_SUSPENDM 0x1 /* enable SuspendM output */ -#define SUSPEND_MODE 0x2 /* Suspend Mode indicator */ -#define RESUME_MODE 0x4 /* DMA Mode */ -#define RESET 0x8 /* Reset indicator */ -#define HS_MODE 0x10 /* High Speed mode indicator */ -#define HS_ENABLE 0x20 /* high Speed Enable */ -#define SOFT_CONN 0x40 /* Soft connect */ -#define ISO_UPDATE 0x80 /* Isochronous update */ - -/* Bit masks for USB_INTRTX */ - -#define EP0_TX 0x1 /* Tx Endpoint 0 interrupt */ -#define EP1_TX 0x2 /* Tx Endpoint 1 interrupt */ -#define EP2_TX 0x4 /* Tx Endpoint 2 interrupt */ -#define EP3_TX 0x8 /* Tx Endpoint 3 interrupt */ -#define EP4_TX 0x10 /* Tx Endpoint 4 interrupt */ -#define EP5_TX 0x20 /* Tx Endpoint 5 interrupt */ -#define EP6_TX 0x40 /* Tx Endpoint 6 interrupt */ -#define EP7_TX 0x80 /* Tx Endpoint 7 interrupt */ - -/* Bit masks for USB_INTRRX */ - -#define EP1_RX 0x2 /* Rx Endpoint 1 interrupt */ -#define EP2_RX 0x4 /* Rx Endpoint 2 interrupt */ -#define EP3_RX 0x8 /* Rx Endpoint 3 interrupt */ -#define EP4_RX 0x10 /* Rx Endpoint 4 interrupt */ -#define EP5_RX 0x20 /* Rx Endpoint 5 interrupt */ -#define EP6_RX 0x40 /* Rx Endpoint 6 interrupt */ -#define EP7_RX 0x80 /* Rx Endpoint 7 interrupt */ - -/* Bit masks for USB_INTRTXE */ - -#define EP0_TX_E 0x1 /* Endpoint 0 interrupt Enable */ -#define EP1_TX_E 0x2 /* Tx Endpoint 1 interrupt Enable */ -#define EP2_TX_E 0x4 /* Tx Endpoint 2 interrupt Enable */ -#define EP3_TX_E 0x8 /* Tx Endpoint 3 interrupt Enable */ -#define EP4_TX_E 0x10 /* Tx Endpoint 4 interrupt Enable */ -#define EP5_TX_E 0x20 /* Tx Endpoint 5 interrupt Enable */ -#define EP6_TX_E 0x40 /* Tx Endpoint 6 interrupt Enable */ -#define EP7_TX_E 0x80 /* Tx Endpoint 7 interrupt Enable */ - -/* Bit masks for USB_INTRRXE */ - -#define EP1_RX_E 0x2 /* Rx Endpoint 1 interrupt Enable */ -#define EP2_RX_E 0x4 /* Rx Endpoint 2 interrupt Enable */ -#define EP3_RX_E 0x8 /* Rx Endpoint 3 interrupt Enable */ -#define EP4_RX_E 0x10 /* Rx Endpoint 4 interrupt Enable */ -#define EP5_RX_E 0x20 /* Rx Endpoint 5 interrupt Enable */ -#define EP6_RX_E 0x40 /* Rx Endpoint 6 interrupt Enable */ -#define EP7_RX_E 0x80 /* Rx Endpoint 7 interrupt Enable */ - -/* Bit masks for USB_INTRUSB */ - -#define SUSPEND_B 0x1 /* Suspend indicator */ -#define RESUME_B 0x2 /* Resume indicator */ -#define RESET_OR_BABLE_B 0x4 /* Reset/babble indicator */ -#define SOF_B 0x8 /* Start of frame */ -#define CONN_B 0x10 /* Connection indicator */ -#define DISCON_B 0x20 /* Disconnect indicator */ -#define SESSION_REQ_B 0x40 /* Session Request */ -#define VBUS_ERROR_B 0x80 /* Vbus threshold indicator */ - -/* Bit masks for USB_INTRUSBE */ - -#define SUSPEND_BE 0x1 /* Suspend indicator int enable */ -#define RESUME_BE 0x2 /* Resume indicator int enable */ -#define RESET_OR_BABLE_BE 0x4 /* Reset/babble indicator int enable */ -#define SOF_BE 0x8 /* Start of frame int enable */ -#define CONN_BE 0x10 /* Connection indicator int enable */ -#define DISCON_BE 0x20 /* Disconnect indicator int enable */ -#define SESSION_REQ_BE 0x40 /* Session Request int enable */ -#define VBUS_ERROR_BE 0x80 /* Vbus threshold indicator int enable */ - -/* Bit masks for USB_FRAME */ - -#define FRAME_NUMBER 0x7ff /* Frame number */ - -/* Bit masks for USB_INDEX */ - -#define SELECTED_ENDPOINT 0xf /* selected endpoint */ - -/* Bit masks for USB_GLOBAL_CTL */ - -#define GLOBAL_ENA 0x1 /* enables USB module */ -#define EP1_TX_ENA 0x2 /* Transmit endpoint 1 enable */ -#define EP2_TX_ENA 0x4 /* Transmit endpoint 2 enable */ -#define EP3_TX_ENA 0x8 /* Transmit endpoint 3 enable */ -#define EP4_TX_ENA 0x10 /* Transmit endpoint 4 enable */ -#define EP5_TX_ENA 0x20 /* Transmit endpoint 5 enable */ -#define EP6_TX_ENA 0x40 /* Transmit endpoint 6 enable */ -#define EP7_TX_ENA 0x80 /* Transmit endpoint 7 enable */ -#define EP1_RX_ENA 0x100 /* Receive endpoint 1 enable */ -#define EP2_RX_ENA 0x200 /* Receive endpoint 2 enable */ -#define EP3_RX_ENA 0x400 /* Receive endpoint 3 enable */ -#define EP4_RX_ENA 0x800 /* Receive endpoint 4 enable */ -#define EP5_RX_ENA 0x1000 /* Receive endpoint 5 enable */ -#define EP6_RX_ENA 0x2000 /* Receive endpoint 6 enable */ -#define EP7_RX_ENA 0x4000 /* Receive endpoint 7 enable */ - -/* Bit masks for USB_OTG_DEV_CTL */ - -#define SESSION 0x1 /* session indicator */ -#define HOST_REQ 0x2 /* Host negotiation request */ -#define HOST_MODE 0x4 /* indicates USBDRC is a host */ -#define VBUS0 0x8 /* Vbus level indicator[0] */ -#define VBUS1 0x10 /* Vbus level indicator[1] */ -#define LSDEV 0x20 /* Low-speed indicator */ -#define FSDEV 0x40 /* Full or High-speed indicator */ -#define B_DEVICE 0x80 /* A' or 'B' device indicator */ - -/* Bit masks for USB_OTG_VBUS_IRQ */ - -#define DRIVE_VBUS_ON 0x1 /* indicator to drive VBUS control circuit */ -#define DRIVE_VBUS_OFF 0x2 /* indicator to shut off charge pump */ -#define CHRG_VBUS_START 0x4 /* indicator for external circuit to start charging VBUS */ -#define CHRG_VBUS_END 0x8 /* indicator for external circuit to end charging VBUS */ -#define DISCHRG_VBUS_START 0x10 /* indicator to start discharging VBUS */ -#define DISCHRG_VBUS_END 0x20 /* indicator to stop discharging VBUS */ - -/* Bit masks for USB_OTG_VBUS_MASK */ - -#define DRIVE_VBUS_ON_ENA 0x1 /* enable DRIVE_VBUS_ON interrupt */ -#define DRIVE_VBUS_OFF_ENA 0x2 /* enable DRIVE_VBUS_OFF interrupt */ -#define CHRG_VBUS_START_ENA 0x4 /* enable CHRG_VBUS_START interrupt */ -#define CHRG_VBUS_END_ENA 0x8 /* enable CHRG_VBUS_END interrupt */ -#define DISCHRG_VBUS_START_ENA 0x10 /* enable DISCHRG_VBUS_START interrupt */ -#define DISCHRG_VBUS_END_ENA 0x20 /* enable DISCHRG_VBUS_END interrupt */ - -/* Bit masks for USB_CSR0 */ - -#define RXPKTRDY 0x1 /* data packet receive indicator */ -#define TXPKTRDY 0x2 /* data packet in FIFO indicator */ -#define STALL_SENT 0x4 /* STALL handshake sent */ -#define DATAEND 0x8 /* Data end indicator */ -#define SETUPEND 0x10 /* Setup end */ -#define SENDSTALL 0x20 /* Send STALL handshake */ -#define SERVICED_RXPKTRDY 0x40 /* used to clear the RxPktRdy bit */ -#define SERVICED_SETUPEND 0x80 /* used to clear the SetupEnd bit */ -#define FLUSHFIFO 0x100 /* flush endpoint FIFO */ -#define STALL_RECEIVED_H 0x4 /* STALL handshake received host mode */ -#define SETUPPKT_H 0x8 /* send Setup token host mode */ -#define ERROR_H 0x10 /* timeout error indicator host mode */ -#define REQPKT_H 0x20 /* Request an IN transaction host mode */ -#define STATUSPKT_H 0x40 /* Status stage transaction host mode */ -#define NAK_TIMEOUT_H 0x80 /* EP0 halted after a NAK host mode */ - -/* Bit masks for USB_COUNT0 */ - -#define EP0_RX_COUNT 0x7f /* number of received bytes in EP0 FIFO */ - -/* Bit masks for USB_NAKLIMIT0 */ - -#define EP0_NAK_LIMIT 0x1f /* number of frames/micro frames after which EP0 timeouts */ - -/* Bit masks for USB_TX_MAX_PACKET */ - -#define MAX_PACKET_SIZE_T 0x7ff /* maximum data pay load in a frame */ - -/* Bit masks for USB_RX_MAX_PACKET */ - -#define MAX_PACKET_SIZE_R 0x7ff /* maximum data pay load in a frame */ - -/* Bit masks for USB_TXCSR */ - -#define TXPKTRDY_T 0x1 /* data packet in FIFO indicator */ -#define FIFO_NOT_EMPTY_T 0x2 /* FIFO not empty */ -#define UNDERRUN_T 0x4 /* TxPktRdy not set for an IN token */ -#define FLUSHFIFO_T 0x8 /* flush endpoint FIFO */ -#define STALL_SEND_T 0x10 /* issue a Stall handshake */ -#define STALL_SENT_T 0x20 /* Stall handshake transmitted */ -#define CLEAR_DATATOGGLE_T 0x40 /* clear endpoint data toggle */ -#define INCOMPTX_T 0x80 /* indicates that a large packet is split */ -#define DMAREQMODE_T 0x400 /* DMA mode (0 or 1) selection */ -#define FORCE_DATATOGGLE_T 0x800 /* Force data toggle */ -#define DMAREQ_ENA_T 0x1000 /* Enable DMA request for Tx EP */ -#define ISO_T 0x4000 /* enable Isochronous transfers */ -#define AUTOSET_T 0x8000 /* allows TxPktRdy to be set automatically */ -#define ERROR_TH 0x4 /* error condition host mode */ -#define STALL_RECEIVED_TH 0x20 /* Stall handshake received host mode */ -#define NAK_TIMEOUT_TH 0x80 /* NAK timeout host mode */ - -/* Bit masks for USB_TXCOUNT */ - -#define TX_COUNT 0x1fff /* Number of bytes to be written to the selected endpoint Tx FIFO */ - -/* Bit masks for USB_RXCSR */ - -#define RXPKTRDY_R 0x1 /* data packet in FIFO indicator */ -#define FIFO_FULL_R 0x2 /* FIFO not empty */ -#define OVERRUN_R 0x4 /* TxPktRdy not set for an IN token */ -#define DATAERROR_R 0x8 /* Out packet cannot be loaded into Rx FIFO */ -#define FLUSHFIFO_R 0x10 /* flush endpoint FIFO */ -#define STALL_SEND_R 0x20 /* issue a Stall handshake */ -#define STALL_SENT_R 0x40 /* Stall handshake transmitted */ -#define CLEAR_DATATOGGLE_R 0x80 /* clear endpoint data toggle */ -#define INCOMPRX_R 0x100 /* indicates that a large packet is split */ -#define DMAREQMODE_R 0x800 /* DMA mode (0 or 1) selection */ -#define DISNYET_R 0x1000 /* disable Nyet handshakes */ -#define DMAREQ_ENA_R 0x2000 /* Enable DMA request for Tx EP */ -#define ISO_R 0x4000 /* enable Isochronous transfers */ -#define AUTOCLEAR_R 0x8000 /* allows TxPktRdy to be set automatically */ -#define ERROR_RH 0x4 /* TxPktRdy not set for an IN token host mode */ -#define REQPKT_RH 0x20 /* request an IN transaction host mode */ -#define STALL_RECEIVED_RH 0x40 /* Stall handshake received host mode */ -#define INCOMPRX_RH 0x100 /* indicates that a large packet is split host mode */ -#define DMAREQMODE_RH 0x800 /* DMA mode (0 or 1) selection host mode */ -#define AUTOREQ_RH 0x4000 /* sets ReqPkt automatically host mode */ - -/* Bit masks for USB_RXCOUNT */ - -#define RX_COUNT 0x1fff /* Number of received bytes in the packet in the Rx FIFO */ - -/* Bit masks for USB_TXTYPE */ - -#define TARGET_EP_NO_T 0xf /* EP number */ -#define PROTOCOL_T 0xc /* transfer type */ - -/* Bit masks for USB_TXINTERVAL */ - -#define TX_POLL_INTERVAL 0xff /* polling interval for selected Tx EP */ - -/* Bit masks for USB_RXTYPE */ - -#define TARGET_EP_NO_R 0xf /* EP number */ -#define PROTOCOL_R 0xc /* transfer type */ - -/* Bit masks for USB_RXINTERVAL */ - -#define RX_POLL_INTERVAL 0xff /* polling interval for selected Rx EP */ - -/* Bit masks for USB_DMA_INTERRUPT */ - -#define DMA0_INT 0x1 /* DMA0 pending interrupt */ -#define DMA1_INT 0x2 /* DMA1 pending interrupt */ -#define DMA2_INT 0x4 /* DMA2 pending interrupt */ -#define DMA3_INT 0x8 /* DMA3 pending interrupt */ -#define DMA4_INT 0x10 /* DMA4 pending interrupt */ -#define DMA5_INT 0x20 /* DMA5 pending interrupt */ -#define DMA6_INT 0x40 /* DMA6 pending interrupt */ -#define DMA7_INT 0x80 /* DMA7 pending interrupt */ - -/* Bit masks for USB_DMAxCONTROL */ - -#define DMA_ENA 0x1 /* DMA enable */ -#define DIRECTION 0x2 /* direction of DMA transfer */ -#define MODE 0x4 /* DMA Bus error */ -#define INT_ENA 0x8 /* Interrupt enable */ -#define EPNUM 0xf0 /* EP number */ -#define BUSERROR 0x100 /* DMA Bus error */ - -/* Bit masks for USB_DMAxADDRHIGH */ - -#define DMA_ADDR_HIGH 0xffff /* Upper 16-bits of memory source/destination address for the DMA master channel */ - -/* Bit masks for USB_DMAxADDRLOW */ - -#define DMA_ADDR_LOW 0xffff /* Lower 16-bits of memory source/destination address for the DMA master channel */ - -/* Bit masks for USB_DMAxCOUNTHIGH */ - -#define DMA_COUNT_HIGH 0xffff /* Upper 16-bits of byte count of DMA transfer for DMA master channel */ - -/* Bit masks for USB_DMAxCOUNTLOW */ - -#define DMA_COUNT_LOW 0xffff /* Lower 16-bits of byte count of DMA transfer for DMA master channel */ - -/* Bit masks for HMDMAx_CONTROL */ - -#define HMDMAEN 0x1 /* Handshake MDMA Enable */ -#define REP 0x2 /* Handshake MDMA Request Polarity */ -#define UTE 0x8 /* Urgency Threshold Enable */ -#define OIE 0x10 /* Overflow Interrupt Enable */ -#define BDIE 0x20 /* Block Done Interrupt Enable */ -#define MBDI 0x40 /* Mask Block Done Interrupt */ -#define DRQ 0x300 /* Handshake MDMA Request Type */ -#define RBC 0x1000 /* Force Reload of BCOUNT */ -#define PS 0x2000 /* Pin Status */ -#define OI 0x4000 /* Overflow Interrupt Generated */ -#define BDI 0x8000 /* Block Done Interrupt Generated */ - /* ******************************************* */ /* MULTI BIT MACRO ENUMERATIONS */ /* ******************************************* */ -- cgit v0.10.2 From 1915b6c0aedbba3bc5042e2b9bdbf7734579352d Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 15 Oct 2009 03:10:38 +0000 Subject: Blackfin: scrub unused RTC masks The RTC driver code doesn't need these, and the other parts had these punted, so keep the global namespace clean. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h index f9fd2b2..48c702d 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h @@ -790,32 +790,6 @@ #define TRO_P 0x0F - -/* *************** REAL TIME CLOCK MASKS **************************/ -/* RTC_STAT and RTC_ALARM Masks */ -#define RTC_SEC 0x0000003F /* Real-Time Clock Seconds */ -#define RTC_MIN 0x00000FC0 /* Real-Time Clock Minutes */ -#define RTC_HR 0x0001F000 /* Real-Time Clock Hours */ -#define RTC_DAY 0xFFFE0000 /* Real-Time Clock Days */ - -/* RTC_ALARM Macro z=day y=hr x=min w=sec */ -#define SET_ALARM(z,y,x,w) ((((z)&0x7FFF)<<0x11)|(((y)&0x1F)<<0xC)|(((x)&0x3F)<<0x6)|((w)&0x3F)) - -/* RTC_ICTL and RTC_ISTAT Masks */ -#define STOPWATCH 0x0001 /* Stopwatch Interrupt Enable */ -#define ALARM 0x0002 /* Alarm Interrupt Enable */ -#define SECOND 0x0004 /* Seconds (1 Hz) Interrupt Enable */ -#define MINUTE 0x0008 /* Minutes Interrupt Enable */ -#define HOUR 0x0010 /* Hours Interrupt Enable */ -#define DAY 0x0020 /* 24 Hours (Days) Interrupt Enable */ -#define DAY_ALARM 0x0040 /* Day Alarm (Day, Hour, Minute, Second) Interrupt Enable */ -#define WRITE_PENDING 0x4000 /* Write Pending Status */ -#define WRITE_COMPLETE 0x8000 /* Write Complete Interrupt Enable */ - -/* RTC_FAST / RTC_PREN Mask */ -#define PREN 0x0001 /* Enable Prescaler, RTC Runs @1 Hz */ - - /* ************** UART CONTROLLER MASKS *************************/ /* UARTx_LCR Masks */ #define WLS(x) (((x)-5) & 0x03) /* Word Length Select */ diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h index b9dbb73..51bdea2 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h @@ -791,32 +791,6 @@ #define TRO_P 0x0F - -/* *************** REAL TIME CLOCK MASKS **************************/ -/* RTC_STAT and RTC_ALARM Masks */ -#define RTC_SEC 0x0000003F /* Real-Time Clock Seconds */ -#define RTC_MIN 0x00000FC0 /* Real-Time Clock Minutes */ -#define RTC_HR 0x0001F000 /* Real-Time Clock Hours */ -#define RTC_DAY 0xFFFE0000 /* Real-Time Clock Days */ - -/* RTC_ALARM Macro z=day y=hr x=min w=sec */ -#define SET_ALARM(z,y,x,w) ((((z)&0x7FFF)<<0x11)|(((y)&0x1F)<<0xC)|(((x)&0x3F)<<0x6)|((w)&0x3F)) - -/* RTC_ICTL and RTC_ISTAT Masks */ -#define STOPWATCH 0x0001 /* Stopwatch Interrupt Enable */ -#define ALARM 0x0002 /* Alarm Interrupt Enable */ -#define SECOND 0x0004 /* Seconds (1 Hz) Interrupt Enable */ -#define MINUTE 0x0008 /* Minutes Interrupt Enable */ -#define HOUR 0x0010 /* Hours Interrupt Enable */ -#define DAY 0x0020 /* 24 Hours (Days) Interrupt Enable */ -#define DAY_ALARM 0x0040 /* Day Alarm (Day, Hour, Minute, Second) Interrupt Enable */ -#define WRITE_PENDING 0x4000 /* Write Pending Status */ -#define WRITE_COMPLETE 0x8000 /* Write Complete Interrupt Enable */ - -/* RTC_FAST / RTC_PREN Mask */ -#define PREN 0x0001 /* Enable Prescaler, RTC Runs @1 Hz */ - - /* ************** UART CONTROLLER MASKS *************************/ /* UARTx_LCR Masks */ #define WLS(x) (((x)-5) & 0x03) /* Word Length Select */ diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h index 1f1aeab..bfe94dd 100644 --- a/arch/blackfin/mach-bf538/include/mach/defBF539.h +++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h @@ -1644,56 +1644,6 @@ #define TRO_P 0x0F -/* *************** REAL TIME CLOCK MASKS **************************/ -/* RTC_STAT and RTC_ALARM register */ -#define RTSEC 0x0000003F /* Real-Time Clock Seconds */ -#define RTMIN 0x00000FC0 /* Real-Time Clock Minutes */ -#define RTHR 0x0001F000 /* Real-Time Clock Hours */ -#define RTDAY 0xFFFE0000 /* Real-Time Clock Days */ - -/* RTC_ICTL register */ -#define SWIE 0x0001 /* Stopwatch Interrupt Enable */ -#define AIE 0x0002 /* Alarm Interrupt Enable */ -#define SIE 0x0004 /* Seconds (1 Hz) Interrupt Enable */ -#define MIE 0x0008 /* Minutes Interrupt Enable */ -#define HIE 0x0010 /* Hours Interrupt Enable */ -#define DIE 0x0020 /* 24 Hours (Days) Interrupt Enable */ -#define DAIE 0x0040 /* Day Alarm (Day, Hour, Minute, Second) Interrupt Enable */ -#define WCIE 0x8000 /* Write Complete Interrupt Enable */ - -/* RTC_ISTAT register */ -#define SWEF 0x0001 /* Stopwatch Event Flag */ -#define AEF 0x0002 /* Alarm Event Flag */ -#define SEF 0x0004 /* Seconds (1 Hz) Event Flag */ -#define MEF 0x0008 /* Minutes Event Flag */ -#define HEF 0x0010 /* Hours Event Flag */ -#define DEF 0x0020 /* 24 Hours (Days) Event Flag */ -#define DAEF 0x0040 /* Day Alarm (Day, Hour, Minute, Second) Event Flag */ -#define WPS 0x4000 /* Write Pending Status (RO) */ -#define WCOM 0x8000 /* Write Complete */ - -/* RTC_FAST Mask (RTC_PREN Mask) */ -#define ENABLE_PRESCALE 0x00000001 /* Enable prescaler so RTC runs at 1 Hz */ -#define PREN 0x00000001 - /* ** Must be set after power-up for proper operation of RTC */ - -/* Deprecated RTC_STAT and RTC_ALARM Masks */ -#define RTC_SEC RTSEC /* Real-Time Clock Seconds */ -#define RTC_MIN RTMIN /* Real-Time Clock Minutes */ -#define RTC_HR RTHR /* Real-Time Clock Hours */ -#define RTC_DAY RTDAY /* Real-Time Clock Days */ - -/* Deprecated RTC_ICTL/RTC_ISTAT Masks */ -#define STOPWATCH SWIE /* Stopwatch Interrupt Enable */ -#define ALARM AIE /* Alarm Interrupt Enable */ -#define SECOND SIE /* Seconds (1 Hz) Interrupt Enable */ -#define MINUTE MIE /* Minutes Interrupt Enable */ -#define HOUR HIE /* Hours Interrupt Enable */ -#define DAY DIE /* 24 Hours (Days) Interrupt Enable */ -#define DAY_ALARM DAIE /* Day Alarm (Day, Hour, Minute, Second) Interrupt Enable */ -#define WRITE_COMPLETE WCIE /* Write Complete Interrupt Enable */ - - /* ***************************** UART CONTROLLER MASKS ********************** */ /* UARTx_LCR Register */ #ifdef _MISRA_RULES diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h index 8590c8c..0d89f22 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h @@ -2149,51 +2149,6 @@ #define DPRESCALE 0xf /* Load Counter Register */ -/* Bit masks for RTC_STAT */ - -#define SECONDS 0x3f /* Seconds */ -#define MINUTES 0xfc0 /* Minutes */ -#define HOURS 0x1f000 /* Hours */ -#define DAY_COUNTER 0xfffe0000 /* Day Counter */ - -/* Bit masks for RTC_ICTL */ - -#define STOPWATCH_INTERRUPT_ENABLE 0x1 /* Stopwatch Interrupt Enable */ -#define ALARM_INTERRUPT_ENABLE 0x2 /* Alarm Interrupt Enable */ -#define SECONDS_INTERRUPT_ENABLE 0x4 /* Seconds Interrupt Enable */ -#define MINUTES_INTERRUPT_ENABLE 0x8 /* Minutes Interrupt Enable */ -#define HOURS_INTERRUPT_ENABLE 0x10 /* Hours Interrupt Enable */ -#define TWENTY_FOUR_HOURS_INTERRUPT_ENABLE 0x20 /* 24 Hours Interrupt Enable */ -#define DAY_ALARM_INTERRUPT_ENABLE 0x40 /* Day Alarm Interrupt Enable */ -#define WRITE_COMPLETE_INTERRUPT_ENABLE 0x8000 /* Write Complete Interrupt Enable */ - -/* Bit masks for RTC_ISTAT */ - -#define STOPWATCH_EVENT_FLAG 0x1 /* Stopwatch Event Flag */ -#define ALARM_EVENT_FLAG 0x2 /* Alarm Event Flag */ -#define SECONDS_EVENT_FLAG 0x4 /* Seconds Event Flag */ -#define MINUTES_EVENT_FLAG 0x8 /* Minutes Event Flag */ -#define HOURS_EVENT_FLAG 0x10 /* Hours Event Flag */ -#define TWENTY_FOUR_HOURS_EVENT_FLAG 0x20 /* 24 Hours Event Flag */ -#define DAY_ALARM_EVENT_FLAG 0x40 /* Day Alarm Event Flag */ -#define WRITE_PENDING__STATUS 0x4000 /* Write Pending Status */ -#define WRITE_COMPLETE 0x8000 /* Write Complete */ - -/* Bit masks for RTC_SWCNT */ - -#define STOPWATCH_COUNT 0xffff /* Stopwatch Count */ - -/* Bit masks for RTC_ALARM */ - -#define SECONDS 0x3f /* Seconds */ -#define MINUTES 0xfc0 /* Minutes */ -#define HOURS 0x1f000 /* Hours */ -#define DAY 0xfffe0000 /* Day */ - -/* Bit masks for RTC_PREN */ - -#define PREN 0x1 /* Prescaler Enable */ - /* Bit masks for OTP_CONTROL */ #define FUSE_FADDR 0x1ff /* OTP/Fuse Address */ -- cgit v0.10.2 From 341a1fc0d1efbb202a77aa69f4c7d97a507b1056 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 15 Oct 2009 03:14:09 +0000 Subject: Blackfin: scrub unused watchdog mmr masks The watchdog code doesn't need these, and the other parts had these punted, so keep the global namespace clean. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h index 48c702d..83e8c34 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h @@ -756,40 +756,6 @@ #define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Wakeup Disable Peripheral #x */ -/* ********* WATCHDOG TIMER MASKS ******************** */ - -/* Watchdog Timer WDOG_CTL Register Masks */ - -#define WDEV(x) (((x)<<1) & 0x0006) /* event generated on roll over */ -#define WDEV_RESET 0x0000 /* generate reset event on roll over */ -#define WDEV_NMI 0x0002 /* generate NMI event on roll over */ -#define WDEV_GPI 0x0004 /* generate GP IRQ on roll over */ -#define WDEV_NONE 0x0006 /* no event on roll over */ -#define WDEN 0x0FF0 /* enable watchdog */ -#define WDDIS 0x0AD0 /* disable watchdog */ -#define WDRO 0x8000 /* watchdog rolled over latch */ - -/* depreciated WDOG_CTL Register Masks for legacy code */ - - -#define ICTL WDEV -#define ENABLE_RESET WDEV_RESET -#define WDOG_RESET WDEV_RESET -#define ENABLE_NMI WDEV_NMI -#define WDOG_NMI WDEV_NMI -#define ENABLE_GPI WDEV_GPI -#define WDOG_GPI WDEV_GPI -#define DISABLE_EVT WDEV_NONE -#define WDOG_NONE WDEV_NONE - -#define TMR_EN WDEN -#define TMR_DIS WDDIS -#define TRO WDRO -#define ICTL_P0 0x01 - #define ICTL_P1 0x02 -#define TRO_P 0x0F - - /* ************** UART CONTROLLER MASKS *************************/ /* UARTx_LCR Masks */ #define WLS(x) (((x)-5) & 0x03) /* Word Length Select */ diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h index 51bdea2..3dda2b8 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h @@ -757,40 +757,6 @@ #define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Wakeup Disable Peripheral #x */ -/* ********* WATCHDOG TIMER MASKS ******************** */ - -/* Watchdog Timer WDOG_CTL Register Masks */ - -#define WDEV(x) (((x)<<1) & 0x0006) /* event generated on roll over */ -#define WDEV_RESET 0x0000 /* generate reset event on roll over */ -#define WDEV_NMI 0x0002 /* generate NMI event on roll over */ -#define WDEV_GPI 0x0004 /* generate GP IRQ on roll over */ -#define WDEV_NONE 0x0006 /* no event on roll over */ -#define WDEN 0x0FF0 /* enable watchdog */ -#define WDDIS 0x0AD0 /* disable watchdog */ -#define WDRO 0x8000 /* watchdog rolled over latch */ - -/* depreciated WDOG_CTL Register Masks for legacy code */ - - -#define ICTL WDEV -#define ENABLE_RESET WDEV_RESET -#define WDOG_RESET WDEV_RESET -#define ENABLE_NMI WDEV_NMI -#define WDOG_NMI WDEV_NMI -#define ENABLE_GPI WDEV_GPI -#define WDOG_GPI WDEV_GPI -#define DISABLE_EVT WDEV_NONE -#define WDOG_NONE WDEV_NONE - -#define TMR_EN WDEN -#define TMR_DIS WDDIS -#define TRO WDRO -#define ICTL_P0 0x01 - #define ICTL_P1 0x02 -#define TRO_P 0x0F - - /* ************** UART CONTROLLER MASKS *************************/ /* UARTx_LCR Masks */ #define WLS(x) (((x)-5) & 0x03) /* Word Length Select */ diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h index bfe94dd..5a9d0d5 100644 --- a/arch/blackfin/mach-bf538/include/mach/defBF539.h +++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h @@ -1609,41 +1609,6 @@ #endif /* _MISRA_RULES */ -/* ********* WATCHDOG TIMER MASKS ******************** */ -/* Watchdog Timer WDOG_CTL Register Masks */ -#ifdef _MISRA_RULES -#define WDEV(x) (((x)<<1) & 0x0006u) /* event generated on roll over */ -#else -#define WDEV(x) (((x)<<1) & 0x0006) /* event generated on roll over */ -#endif /* _MISRA_RULES */ -#define WDEV_RESET 0x0000 /* generate reset event on roll over */ -#define WDEV_NMI 0x0002 /* generate NMI event on roll over */ -#define WDEV_GPI 0x0004 /* generate GP IRQ on roll over */ -#define WDEV_NONE 0x0006 /* no event on roll over */ -#define WDEN 0x0FF0 /* enable watchdog */ -#define WDDIS 0x0AD0 /* disable watchdog */ -#define WDRO 0x8000 /* watchdog rolled over latch */ - -/* deprecated WDOG_CTL Register Masks for legacy code */ -#define ICTL WDEV -#define ENABLE_RESET WDEV_RESET -#define WDOG_RESET WDEV_RESET -#define ENABLE_NMI WDEV_NMI -#define WDOG_NMI WDEV_NMI -#define ENABLE_GPI WDEV_GPI -#define WDOG_GPI WDEV_GPI -#define DISABLE_EVT WDEV_NONE -#define WDOG_NONE WDEV_NONE - -#define TMR_EN WDEN -#define WDOG_DISABLE WDDIS -#define TRO WDRO - -#define ICTL_P0 0x01 -#define ICTL_P1 0x02 -#define TRO_P 0x0F - - /* ***************************** UART CONTROLLER MASKS ********************** */ /* UARTx_LCR Register */ #ifdef _MISRA_RULES diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h index 0d89f22..3ce5ce6 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h @@ -2092,12 +2092,6 @@ #define TRUN6 0x40000000 /* Timer 6 Slave Enable Status */ #define TRUN7 0x80000000 /* Timer 7 Slave Enable Status */ -/* Bit masks for WDOG_CTL */ - -#define WDEV 0x6 /* Watchdog Event */ -#define WDEN 0xff0 /* Watchdog Enable */ -#define WDRO 0x8000 /* Watchdog Rolled Over */ - /* Bit masks for CNT_CONFIG */ #define CNTE 0x1 /* Counter Enable */ -- cgit v0.10.2 From b1fa2e8f626e997c2c4f991f10ed00b6ee080b99 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 15 Oct 2009 03:41:42 +0000 Subject: Blackfin: BF51x: dump non-existent SPI/NFC MMRs Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h index d2d0533..c1b71bb 100644 --- a/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h +++ b/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h @@ -131,23 +131,6 @@ #define bfin_write_UART0_GCTL(val) bfin_write16(UART0_GCTL, val) -/* SPI Controller (0xFFC00500 - 0xFFC005FF) */ -#define bfin_read_SPI_CTL() bfin_read16(SPI_CTL) -#define bfin_write_SPI_CTL(val) bfin_write16(SPI_CTL, val) -#define bfin_read_SPI_FLG() bfin_read16(SPI_FLG) -#define bfin_write_SPI_FLG(val) bfin_write16(SPI_FLG, val) -#define bfin_read_SPI_STAT() bfin_read16(SPI_STAT) -#define bfin_write_SPI_STAT(val) bfin_write16(SPI_STAT, val) -#define bfin_read_SPI_TDBR() bfin_read16(SPI_TDBR) -#define bfin_write_SPI_TDBR(val) bfin_write16(SPI_TDBR, val) -#define bfin_read_SPI_RDBR() bfin_read16(SPI_RDBR) -#define bfin_write_SPI_RDBR(val) bfin_write16(SPI_RDBR, val) -#define bfin_read_SPI_BAUD() bfin_read16(SPI_BAUD) -#define bfin_write_SPI_BAUD(val) bfin_write16(SPI_BAUD, val) -#define bfin_read_SPI_SHADOW() bfin_read16(SPI_SHADOW) -#define bfin_write_SPI_SHADOW(val) bfin_write16(SPI_SHADOW, val) - - /* TIMER0-7 Registers (0xFFC00600 - 0xFFC006FF) */ #define bfin_read_TIMER0_CONFIG() bfin_read16(TIMER0_CONFIG) #define bfin_write_TIMER0_CONFIG(val) bfin_write16(TIMER0_CONFIG, val) @@ -1094,41 +1077,6 @@ #define bfin_read_OTP_DATA3() bfin_read32(OTP_DATA3) #define bfin_write_OTP_DATA3(val) bfin_write32(OTP_DATA3, val) -/* NFC Registers */ - -#define bfin_read_NFC_CTL() bfin_read16(NFC_CTL) -#define bfin_write_NFC_CTL(val) bfin_write16(NFC_CTL, val) -#define bfin_read_NFC_STAT() bfin_read16(NFC_STAT) -#define bfin_write_NFC_STAT(val) bfin_write16(NFC_STAT, val) -#define bfin_read_NFC_IRQSTAT() bfin_read16(NFC_IRQSTAT) -#define bfin_write_NFC_IRQSTAT(val) bfin_write16(NFC_IRQSTAT, val) -#define bfin_read_NFC_IRQMASK() bfin_read16(NFC_IRQMASK) -#define bfin_write_NFC_IRQMASK(val) bfin_write16(NFC_IRQMASK, val) -#define bfin_read_NFC_ECC0() bfin_read16(NFC_ECC0) -#define bfin_write_NFC_ECC0(val) bfin_write16(NFC_ECC0, val) -#define bfin_read_NFC_ECC1() bfin_read16(NFC_ECC1) -#define bfin_write_NFC_ECC1(val) bfin_write16(NFC_ECC1, val) -#define bfin_read_NFC_ECC2() bfin_read16(NFC_ECC2) -#define bfin_write_NFC_ECC2(val) bfin_write16(NFC_ECC2, val) -#define bfin_read_NFC_ECC3() bfin_read16(NFC_ECC3) -#define bfin_write_NFC_ECC3(val) bfin_write16(NFC_ECC3, val) -#define bfin_read_NFC_COUNT() bfin_read16(NFC_COUNT) -#define bfin_write_NFC_COUNT(val) bfin_write16(NFC_COUNT, val) -#define bfin_read_NFC_RST() bfin_read16(NFC_RST) -#define bfin_write_NFC_RST(val) bfin_write16(NFC_RST, val) -#define bfin_read_NFC_PGCTL() bfin_read16(NFC_PGCTL) -#define bfin_write_NFC_PGCTL(val) bfin_write16(NFC_PGCTL, val) -#define bfin_read_NFC_READ() bfin_read16(NFC_READ) -#define bfin_write_NFC_READ(val) bfin_write16(NFC_READ, val) -#define bfin_read_NFC_ADDR() bfin_read16(NFC_ADDR) -#define bfin_write_NFC_ADDR(val) bfin_write16(NFC_ADDR, val) -#define bfin_read_NFC_CMD() bfin_read16(NFC_CMD) -#define bfin_write_NFC_CMD(val) bfin_write16(NFC_CMD, val) -#define bfin_read_NFC_DATA_WR() bfin_read16(NFC_DATA_WR) -#define bfin_write_NFC_DATA_WR(val) bfin_write16(NFC_DATA_WR, val) -#define bfin_read_NFC_DATA_RD() bfin_read16(NFC_DATA_RD) -#define bfin_write_NFC_DATA_RD(val) bfin_write16(NFC_DATA_RD, val) - /* These need to be last due to the cdef/linux inter-dependencies */ #include -- cgit v0.10.2 From cd32cc73625641c068393978e7bb337d29c0cd29 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 15 Oct 2009 03:45:47 +0000 Subject: Blackfin: punt OTP MMRs People should not be accessing OTP MMRs directly. They should instead go through the Blackfin ROM helper functions. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h index c1b71bb..e548e9d 100644 --- a/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h +++ b/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h @@ -1046,17 +1046,6 @@ #define bfin_read_CNT_MIN() bfin_read32(CNT_MIN) #define bfin_write_CNT_MIN(val) bfin_write32(CNT_MIN, val) -/* OTP/FUSE Registers */ - -#define bfin_read_OTP_CONTROL() bfin_read16(OTP_CONTROL) -#define bfin_write_OTP_CONTROL(val) bfin_write16(OTP_CONTROL, val) -#define bfin_read_OTP_BEN() bfin_read16(OTP_BEN) -#define bfin_write_OTP_BEN(val) bfin_write16(OTP_BEN, val) -#define bfin_read_OTP_STATUS() bfin_read16(OTP_STATUS) -#define bfin_write_OTP_STATUS(val) bfin_write16(OTP_STATUS, val) -#define bfin_read_OTP_TIMING() bfin_read32(OTP_TIMING) -#define bfin_write_OTP_TIMING(val) bfin_write32(OTP_TIMING, val) - /* Security Registers */ #define bfin_read_SECURE_SYSSWT() bfin_read32(SECURE_SYSSWT) @@ -1066,17 +1055,6 @@ #define bfin_read_SECURE_STATUS() bfin_read16(SECURE_STATUS) #define bfin_write_SECURE_STATUS(val) bfin_write16(SECURE_STATUS, val) -/* OTP Read/Write Data Buffer Registers */ - -#define bfin_read_OTP_DATA0() bfin_read32(OTP_DATA0) -#define bfin_write_OTP_DATA0(val) bfin_write32(OTP_DATA0, val) -#define bfin_read_OTP_DATA1() bfin_read32(OTP_DATA1) -#define bfin_write_OTP_DATA1(val) bfin_write32(OTP_DATA1, val) -#define bfin_read_OTP_DATA2() bfin_read32(OTP_DATA2) -#define bfin_write_OTP_DATA2(val) bfin_write32(OTP_DATA2, val) -#define bfin_read_OTP_DATA3() bfin_read32(OTP_DATA3) -#define bfin_write_OTP_DATA3(val) bfin_write32(OTP_DATA3, val) - /* These need to be last due to the cdef/linux inter-dependencies */ #include diff --git a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h index 83e8c34..78253e8 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h @@ -1770,46 +1770,6 @@ #define BNDMODE_CAPT 0x2000 /* boundary capture mode */ #define BNDMODE_AEXT 0x3000 /* boundary auto-extend mode */ -/* Bit masks for OTP_CONTROL */ - -#define FUSE_FADDR 0x1ff /* OTP/Fuse Address */ -#define FIEN 0x800 /* OTP/Fuse Interrupt Enable */ -#define nFIEN 0x0 -#define FTESTDEC 0x1000 /* OTP/Fuse Test Decoder */ -#define nFTESTDEC 0x0 -#define FWRTEST 0x2000 /* OTP/Fuse Write Test */ -#define nFWRTEST 0x0 -#define FRDEN 0x4000 /* OTP/Fuse Read Enable */ -#define nFRDEN 0x0 -#define FWREN 0x8000 /* OTP/Fuse Write Enable */ -#define nFWREN 0x0 - -/* Bit masks for OTP_BEN */ - -#define FBEN 0xffff /* OTP/Fuse Byte Enable */ - -/* Bit masks for OTP_STATUS */ - -#define FCOMP 0x1 /* OTP/Fuse Access Complete */ -#define nFCOMP 0x0 -#define FERROR 0x2 /* OTP/Fuse Access Error */ -#define nFERROR 0x0 -#define MMRGLOAD 0x10 /* Memory Mapped Register Gasket Load */ -#define nMMRGLOAD 0x0 -#define MMRGLOCK 0x20 /* Memory Mapped Register Gasket Lock */ -#define nMMRGLOCK 0x0 -#define FPGMEN 0x40 /* OTP/Fuse Program Enable */ -#define nFPGMEN 0x0 - -/* Bit masks for OTP_TIMING */ - -#define USECDIV 0xff /* Micro Second Divider */ -#define READACC 0x7f00 /* Read Access Time */ -#define CPUMPRL 0x38000 /* Charge Pump Release Time */ -#define CPUMPSU 0xc0000 /* Charge Pump Setup Time */ -#define CPUMPHD 0xf00000 /* Charge Pump Hold Time */ -#define PGMTIME 0xff000000 /* Program Time */ - /* Bit masks for SECURE_SYSSWT */ #define EMUDABL 0x1 /* Emulation Disable. */ diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h index b6b99bb..12f2ad4 100644 --- a/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h +++ b/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h @@ -1063,17 +1063,6 @@ #define bfin_read_CNT_MIN() bfin_read32(CNT_MIN) #define bfin_write_CNT_MIN(val) bfin_write32(CNT_MIN, val) -/* OTP/FUSE Registers */ - -#define bfin_read_OTP_CONTROL() bfin_read16(OTP_CONTROL) -#define bfin_write_OTP_CONTROL(val) bfin_write16(OTP_CONTROL, val) -#define bfin_read_OTP_BEN() bfin_read16(OTP_BEN) -#define bfin_write_OTP_BEN(val) bfin_write16(OTP_BEN, val) -#define bfin_read_OTP_STATUS() bfin_read16(OTP_STATUS) -#define bfin_write_OTP_STATUS(val) bfin_write16(OTP_STATUS, val) -#define bfin_read_OTP_TIMING() bfin_read32(OTP_TIMING) -#define bfin_write_OTP_TIMING(val) bfin_write32(OTP_TIMING, val) - /* Security Registers */ #define bfin_read_SECURE_SYSSWT() bfin_read32(SECURE_SYSSWT) @@ -1083,17 +1072,6 @@ #define bfin_read_SECURE_STATUS() bfin_read16(SECURE_STATUS) #define bfin_write_SECURE_STATUS(val) bfin_write16(SECURE_STATUS, val) -/* OTP Read/Write Data Buffer Registers */ - -#define bfin_read_OTP_DATA0() bfin_read32(OTP_DATA0) -#define bfin_write_OTP_DATA0(val) bfin_write32(OTP_DATA0, val) -#define bfin_read_OTP_DATA1() bfin_read32(OTP_DATA1) -#define bfin_write_OTP_DATA1(val) bfin_write32(OTP_DATA1, val) -#define bfin_read_OTP_DATA2() bfin_read32(OTP_DATA2) -#define bfin_write_OTP_DATA2(val) bfin_write32(OTP_DATA2, val) -#define bfin_read_OTP_DATA3() bfin_read32(OTP_DATA3) -#define bfin_write_OTP_DATA3(val) bfin_write32(OTP_DATA3, val) - /* NFC Registers */ #define bfin_read_NFC_CTL() bfin_read16(NFC_CTL) diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h index 3dda2b8..6e6a8df 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h @@ -1783,46 +1783,6 @@ #define BNDMODE_CAPT 0x2000 /* boundary capture mode */ #define BNDMODE_AEXT 0x3000 /* boundary auto-extend mode */ -/* Bit masks for OTP_CONTROL */ - -#define FUSE_FADDR 0x1ff /* OTP/Fuse Address */ -#define FIEN 0x800 /* OTP/Fuse Interrupt Enable */ -#define nFIEN 0x0 -#define FTESTDEC 0x1000 /* OTP/Fuse Test Decoder */ -#define nFTESTDEC 0x0 -#define FWRTEST 0x2000 /* OTP/Fuse Write Test */ -#define nFWRTEST 0x0 -#define FRDEN 0x4000 /* OTP/Fuse Read Enable */ -#define nFRDEN 0x0 -#define FWREN 0x8000 /* OTP/Fuse Write Enable */ -#define nFWREN 0x0 - -/* Bit masks for OTP_BEN */ - -#define FBEN 0xffff /* OTP/Fuse Byte Enable */ - -/* Bit masks for OTP_STATUS */ - -#define FCOMP 0x1 /* OTP/Fuse Access Complete */ -#define nFCOMP 0x0 -#define FERROR 0x2 /* OTP/Fuse Access Error */ -#define nFERROR 0x0 -#define MMRGLOAD 0x10 /* Memory Mapped Register Gasket Load */ -#define nMMRGLOAD 0x0 -#define MMRGLOCK 0x20 /* Memory Mapped Register Gasket Lock */ -#define nMMRGLOCK 0x0 -#define FPGMEN 0x40 /* OTP/Fuse Program Enable */ -#define nFPGMEN 0x0 - -/* Bit masks for OTP_TIMING */ - -#define USECDIV 0xff /* Micro Second Divider */ -#define READACC 0x7f00 /* Read Access Time */ -#define CPUMPRL 0x38000 /* Charge Pump Release Time */ -#define CPUMPSU 0xc0000 /* Charge Pump Setup Time */ -#define CPUMPHD 0xf00000 /* Charge Pump Hold Time */ -#define PGMTIME 0xff000000 /* Program Time */ - /* Bit masks for SECURE_SYSSWT */ #define EMUDABL 0x1 /* Emulation Disable. */ diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h index a2e9d98..32f71e6 100644 --- a/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h +++ b/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h @@ -2615,17 +2615,6 @@ #define bfin_read_CNT_MIN() bfin_read32(CNT_MIN) #define bfin_write_CNT_MIN(val) bfin_write32(CNT_MIN, val) -/* OTP/FUSE Registers */ - -#define bfin_read_OTP_CONTROL() bfin_read16(OTP_CONTROL) -#define bfin_write_OTP_CONTROL(val) bfin_write16(OTP_CONTROL, val) -#define bfin_read_OTP_BEN() bfin_read16(OTP_BEN) -#define bfin_write_OTP_BEN(val) bfin_write16(OTP_BEN, val) -#define bfin_read_OTP_STATUS() bfin_read16(OTP_STATUS) -#define bfin_write_OTP_STATUS(val) bfin_write16(OTP_STATUS, val) -#define bfin_read_OTP_TIMING() bfin_read32(OTP_TIMING) -#define bfin_write_OTP_TIMING(val) bfin_write32(OTP_TIMING, val) - /* Security Registers */ #define bfin_read_SECURE_SYSSWT() bfin_read32(SECURE_SYSSWT) @@ -2640,17 +2629,6 @@ #define bfin_read_DMAC1_PERIMUX() bfin_read16(DMAC1_PERIMUX) #define bfin_write_DMAC1_PERIMUX(val) bfin_write16(DMAC1_PERIMUX, val) -/* OTP Read/Write Data Buffer Registers */ - -#define bfin_read_OTP_DATA0() bfin_read32(OTP_DATA0) -#define bfin_write_OTP_DATA0(val) bfin_write32(OTP_DATA0, val) -#define bfin_read_OTP_DATA1() bfin_read32(OTP_DATA1) -#define bfin_write_OTP_DATA1(val) bfin_write32(OTP_DATA1, val) -#define bfin_read_OTP_DATA2() bfin_read32(OTP_DATA2) -#define bfin_write_OTP_DATA2(val) bfin_write32(OTP_DATA2, val) -#define bfin_read_OTP_DATA3() bfin_read32(OTP_DATA3) -#define bfin_write_OTP_DATA3(val) bfin_write32(OTP_DATA3, val) - /* Handshake MDMA is not defined in the shared file because it is not available on the ADSP-BF542 bfin_read_()rocessor */ /* legacy definitions */ diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h index 3ce5ce6..f07c0f7 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h @@ -2143,36 +2143,6 @@ #define DPRESCALE 0xf /* Load Counter Register */ -/* Bit masks for OTP_CONTROL */ - -#define FUSE_FADDR 0x1ff /* OTP/Fuse Address */ -#define FIEN 0x800 /* OTP/Fuse Interrupt Enable */ -#define FTESTDEC 0x1000 /* OTP/Fuse Test Decoder */ -#define FWRTEST 0x2000 /* OTP/Fuse Write Test */ -#define FRDEN 0x4000 /* OTP/Fuse Read Enable */ -#define FWREN 0x8000 /* OTP/Fuse Write Enable */ - -/* Bit masks for OTP_BEN */ - -#define FBEN 0xffff /* OTP/Fuse Byte Enable */ - -/* Bit masks for OTP_STATUS */ - -#define FCOMP 0x1 /* OTP/Fuse Access Complete */ -#define FERROR 0x2 /* OTP/Fuse Access Error */ -#define MMRGLOAD 0x10 /* Memory Mapped Register Gasket Load */ -#define MMRGLOCK 0x20 /* Memory Mapped Register Gasket Lock */ -#define FPGMEN 0x40 /* OTP/Fuse Program Enable */ - -/* Bit masks for OTP_TIMING */ - -#define USECDIV 0xff /* Micro Second Divider */ -#define READACC 0x7f00 /* Read Access Time */ -#define CPUMPRL 0x38000 /* Charge Pump Release Time */ -#define CPUMPSU 0xc0000 /* Charge Pump Setup Time */ -#define CPUMPHD 0xf00000 /* Charge Pump Hold Time */ -#define PGMTIME 0xff000000 /* Program Time */ - /* Bit masks for SECURE_SYSSWT */ #define EMUDABL 0x1 /* Emulation Disable. */ -- cgit v0.10.2 From e153a97c2103706e3d2308e70c78b95b4f040321 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 15 Oct 2009 03:51:30 +0000 Subject: Blackfin: punt unused MXVR masks There are no MXVR device drivers, and if someday there is, we can put these in a dedicated header rather than polluting the global namespace. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h index 5a9d0d5..312686a 100644 --- a/arch/blackfin/mach-bf538/include/mach/defBF539.h +++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h @@ -2540,1019 +2540,6 @@ #define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ -/********************************* MXVR MASKS ****************************************/ - -/* MXVR_CONFIG Masks */ - -#define MXVREN 0x00000001lu -#define MMSM 0x00000002lu -#define ACTIVE 0x00000004lu -#define SDELAY 0x00000008lu -#define NCMRXEN 0x00000010lu -#define RWRRXEN 0x00000020lu -#define MTXEN 0x00000040lu -#define MTXON 0x00000080lu /*legacy*/ -#define MTXONB 0x00000080lu -#define EPARITY 0x00000100lu -#define MSB 0x00001E00lu -#define APRXEN 0x00002000lu -#define WAKEUP 0x00004000lu -#define LMECH 0x00008000lu - -#ifdef _MISRA_RULES -#define SET_MSB(x) (((x)&0xFu) << 0x9) -#else -#define SET_MSB(x) (((x)&0xF) << 0x9) -#endif /* _MISRA_RULES */ - - -/* MXVR_PLL_CTL_0 Masks */ - -#define MXTALCEN 0x00000001lu -#define MXTALFEN 0x00000002lu -#define MPLLMS 0x00000008lu -#define MXTALMUL 0x00000030lu -#define MPLLEN 0x00000040lu -#define MPLLEN0 0x00000040lu /* legacy */ -#define MPLLEN1 0x00000080lu /* legacy */ -#define MMCLKEN 0x00000100lu -#define MMCLKMUL 0x00001E00lu -#define MPLLRSTB 0x00002000lu -#define MPLLRSTB0 0x00002000lu /* legacy */ -#define MPLLRSTB1 0x00004000lu /* legacy */ -#define MBCLKEN 0x00010000lu -#define MBCLKDIV 0x001E0000lu -#define MPLLCDR 0x00200000lu -#define MPLLCDR0 0x00200000lu /* legacy */ -#define MPLLCDR1 0x00400000lu /* legacy */ -#define INVRX 0x00800000lu -#define MFSEN 0x01000000lu -#define MFSDIV 0x1E000000lu -#define MFSSEL 0x60000000lu -#define MFSSYNC 0x80000000lu - -#define MXTALMUL_256FS 0x00000000lu /* legacy */ -#define MXTALMUL_384FS 0x00000010lu /* legacy */ -#define MXTALMUL_512FS 0x00000020lu /* legacy */ -#define MXTALMUL_1024FS 0x00000030lu - -#define MMCLKMUL_1024FS 0x00000000lu -#define MMCLKMUL_512FS 0x00000200lu -#define MMCLKMUL_256FS 0x00000400lu -#define MMCLKMUL_128FS 0x00000600lu -#define MMCLKMUL_64FS 0x00000800lu -#define MMCLKMUL_32FS 0x00000A00lu -#define MMCLKMUL_16FS 0x00000C00lu -#define MMCLKMUL_8FS 0x00000E00lu -#define MMCLKMUL_4FS 0x00001000lu -#define MMCLKMUL_2FS 0x00001200lu -#define MMCLKMUL_1FS 0x00001400lu -#define MMCLKMUL_1536FS 0x00001A00lu -#define MMCLKMUL_768FS 0x00001C00lu -#define MMCLKMUL_384FS 0x00001E00lu - -#define MBCLKDIV_DIV2 0x00020000lu -#define MBCLKDIV_DIV4 0x00040000lu -#define MBCLKDIV_DIV8 0x00060000lu -#define MBCLKDIV_DIV16 0x00080000lu -#define MBCLKDIV_DIV32 0x000A0000lu -#define MBCLKDIV_DIV64 0x000C0000lu -#define MBCLKDIV_DIV128 0x000E0000lu -#define MBCLKDIV_DIV256 0x00100000lu -#define MBCLKDIV_DIV512 0x00120000lu -#define MBCLKDIV_DIV1024 0x00140000lu - -#define MFSDIV_DIV2 0x02000000lu -#define MFSDIV_DIV4 0x04000000lu -#define MFSDIV_DIV8 0x06000000lu -#define MFSDIV_DIV16 0x08000000lu -#define MFSDIV_DIV32 0x0A000000lu -#define MFSDIV_DIV64 0x0C000000lu -#define MFSDIV_DIV128 0x0E000000lu -#define MFSDIV_DIV256 0x10000000lu -#define MFSDIV_DIV512 0x12000000lu -#define MFSDIV_DIV1024 0x14000000lu - -#define MFSSEL_CLOCK 0x00000000lu -#define MFSSEL_PULSE_HI 0x20000000lu -#define MFSSEL_PULSE_LO 0x40000000lu - - -/* MXVR_PLL_CTL_1 Masks */ - -#define MSTO 0x00000001lu -#define MSTO0 0x00000001lu /* legacy */ -#define MHOGGD 0x00000004lu -#define MHOGGD0 0x00000004lu /* legacy */ -#define MHOGGD1 0x00000008lu /* legacy */ -#define MSHAPEREN 0x00000010lu -#define MSHAPEREN0 0x00000010lu /* legacy */ -#define MSHAPEREN1 0x00000020lu /* legacy */ -#define MPLLCNTEN 0x00008000lu -#define MPLLCNT 0xFFFF0000lu - -#ifdef _MISRA_RULES -#define SET_MPLLCNT(x) (((x)&0xFFFFu) << 0x10) -#else -#define SET_MPLLCNT(x) (((x)&0xFFFF) << 0x10) -#endif /* _MISRA_RULES */ - - -/* MXVR_PLL_CTL_2 Masks */ - -#define MSHAPERSEL 0x00000007lu -#define MCPSEL 0x000000E0lu - -/* MXVR_INT_STAT_0 Masks */ - -#define NI2A 0x00000001lu -#define NA2I 0x00000002lu -#define SBU2L 0x00000004lu -#define SBL2U 0x00000008lu -#define PRU 0x00000010lu -#define MPRU 0x00000020lu -#define DRU 0x00000040lu -#define MDRU 0x00000080lu -#define SBU 0x00000100lu -#define ATU 0x00000200lu -#define FCZ0 0x00000400lu -#define FCZ1 0x00000800lu -#define PERR 0x00001000lu -#define MH2L 0x00002000lu -#define ML2H 0x00004000lu -#define WUP 0x00008000lu -#define FU2L 0x00010000lu -#define FL2U 0x00020000lu -#define BU2L 0x00040000lu -#define BL2U 0x00080000lu -#define PCZ 0x00400000lu -#define FERR 0x00800000lu -#define CMR 0x01000000lu -#define CMROF 0x02000000lu -#define CMTS 0x04000000lu -#define CMTC 0x08000000lu -#define RWRC 0x10000000lu -#define BCZ 0x20000000lu -#define BMERR 0x40000000lu -#define DERR 0x80000000lu - - -/* MXVR_INT_EN_0 Masks */ - -#define NI2AEN NI2A -#define NA2IEN NA2I -#define SBU2LEN SBU2L -#define SBL2UEN SBL2U -#define PRUEN PRU -#define MPRUEN MPRU -#define DRUEN DRU -#define MDRUEN MDRU -#define SBUEN SBU -#define ATUEN ATU -#define FCZ0EN FCZ0 -#define FCZ1EN FCZ1 -#define PERREN PERR -#define MH2LEN MH2L -#define ML2HEN ML2H -#define WUPEN WUP -#define FU2LEN FU2L -#define FL2UEN FL2U -#define BU2LEN BU2L -#define BL2UEN BL2U -#define PCZEN PCZ -#define FERREN FERR -#define CMREN CMR -#define CMROFEN CMROF -#define CMTSEN CMTS -#define CMTCEN CMTC -#define RWRCEN RWRC -#define BCZEN BCZ -#define BMERREN BMERR -#define DERREN DERR - - -/* MXVR_INT_STAT_1 Masks */ - -#define APR 0x00000004lu -#define APROF 0x00000008lu -#define APTS 0x00000040lu -#define APTC 0x00000080lu -#define APRCE 0x00000400lu -#define APRPE 0x00000800lu - -#define HDONE0 0x00000001lu -#define DONE0 0x00000002lu -#define HDONE1 0x00000010lu -#define DONE1 0x00000020lu -#define HDONE2 0x00000100lu -#define DONE2 0x00000200lu -#define HDONE3 0x00001000lu -#define DONE3 0x00002000lu -#define HDONE4 0x00010000lu -#define DONE4 0x00020000lu -#define HDONE5 0x00100000lu -#define DONE5 0x00200000lu -#define HDONE6 0x01000000lu -#define DONE6 0x02000000lu -#define HDONE7 0x10000000lu -#define DONE7 0x20000000lu - -#define DONEX(x) (0x00000002 << (4 * (x))) -#define HDONEX(x) (0x00000001 << (4 * (x))) - - -/* MXVR_INT_EN_1 Masks */ - -#define APREN APR -#define APROFEN APROF -#define APTSEN APTS -#define APTCEN APTC -#define APRCEEN APRCE -#define APRPEEN APRPE - -#define HDONEEN0 HDONE0 -#define DONEEN0 DONE0 -#define HDONEEN1 HDONE1 -#define DONEEN1 DONE1 -#define HDONEEN2 HDONE2 -#define DONEEN2 DONE2 -#define HDONEEN3 HDONE3 -#define DONEEN3 DONE3 -#define HDONEEN4 HDONE4 -#define DONEEN4 DONE4 -#define HDONEEN5 HDONE5 -#define DONEEN5 DONE5 -#define HDONEEN6 HDONE6 -#define DONEEN6 DONE6 -#define HDONEEN7 HDONE7 -#define DONEEN7 DONE7 - -#define DONEENX(x) (0x00000002 << (4 * (x))) -#define HDONEENX(x) (0x00000001 << (4 * (x))) - - -/* MXVR_STATE_0 Masks */ - -#define NACT 0x00000001lu -#define SBLOCK 0x00000002lu -#define PFDLOCK 0x00000004lu -#define PFDLOCK0 0x00000004lu /* legacy */ -#define PDD 0x00000008lu -#define PDD0 0x00000008lu /* legacy */ -#define PVCO 0x00000010lu -#define PVCO0 0x00000010lu /* legacy */ -#define PFDLOCK1 0x00000020lu /* legacy */ -#define PDD1 0x00000040lu /* legacy */ -#define PVCO1 0x00000080lu /* legacy */ -#define APBSY 0x00000100lu -#define APARB 0x00000200lu -#define APTX 0x00000400lu -#define APRX 0x00000800lu -#define CMBSY 0x00001000lu -#define CMARB 0x00002000lu -#define CMTX 0x00004000lu -#define CMRX 0x00008000lu -#define MRXONB 0x00010000lu -#define RGSIP 0x00020000lu -#define DALIP 0x00040000lu -#define ALIP 0x00080000lu -#define RRDIP 0x00100000lu -#define RWRIP 0x00200000lu -#define FLOCK 0x00400000lu -#define BLOCK 0x00800000lu -#define RSB 0x0F000000lu -#define DERRNUM 0xF0000000lu - - -/* MXVR_STATE_1 Masks */ - -#define STXNUMB 0x0000000Flu -#define SRXNUMB 0x000000F0lu -#define APCONT 0x00000100lu -#define DMAACTIVEX 0x00FF0000lu -#define DMAACTIVE0 0x00010000lu -#define DMAACTIVE1 0x00020000lu -#define DMAACTIVE2 0x00040000lu -#define DMAACTIVE3 0x00080000lu -#define DMAACTIVE4 0x00100000lu -#define DMAACTIVE5 0x00200000lu -#define DMAACTIVE6 0x00400000lu -#define DMAACTIVE7 0x00800000lu -#define DMAPMENX 0xFF000000lu -#define DMAPMEN0 0x01000000lu -#define DMAPMEN1 0x02000000lu -#define DMAPMEN2 0x04000000lu -#define DMAPMEN3 0x08000000lu -#define DMAPMEN4 0x10000000lu -#define DMAPMEN5 0x20000000lu -#define DMAPMEN6 0x40000000lu -#define DMAPMEN7 0x80000000lu - - -/* MXVR_POSITION Masks */ - -#define PVALID 0x8000 -#define POSITION 0x003F - - -/* MXVR_MAX_POSITION Masks */ - -#define MPVALID 0x8000 -#define MPOSITION 0x003F - - -/* MXVR_DELAY Masks */ - -#define DVALID 0x8000 -#define DELAY 0x003F - - -/* MXVR_MAX_DELAY Masks */ - -#define MDVALID 0x8000 -#define MDELAY 0x003F - - -/* MXVR_LADDR Masks */ - -#define LVALID 0x80000000lu -#define LADDR 0x0000FFFFlu - - -/* MXVR_GADDR Masks */ - -#define GVALID 0x8000 -#define GADDRL 0x00FF - - -/* MXVR_AADDR Masks */ - -#define AVALID 0x80000000lu -#define AADDR 0x0000FFFFlu - - -/* MXVR_ALLOC_0 Masks */ - -#define CIU0 0x00000080lu -#define CIU1 0x00008000lu -#define CIU2 0x00800000lu -#define CIU3 0x80000000lu - -#define CL0 0x0000007Flu -#define CL1 0x00007F00lu -#define CL2 0x007F0000lu -#define CL3 0x7F000000lu - - -/* MXVR_ALLOC_1 Masks */ - -#define CIU4 0x00000080lu -#define CIU5 0x00008000lu -#define CIU6 0x00800000lu -#define CIU7 0x80000000lu - -#define CL4 0x0000007Flu -#define CL5 0x00007F00lu -#define CL6 0x007F0000lu -#define CL7 0x7F000000lu - - -/* MXVR_ALLOC_2 Masks */ - -#define CIU8 0x00000080lu -#define CIU9 0x00008000lu -#define CIU10 0x00800000lu -#define CIU11 0x80000000lu - -#define CL8 0x0000007Flu -#define CL9 0x00007F00lu -#define CL10 0x007F0000lu -#define CL11 0x7F000000lu - - -/* MXVR_ALLOC_3 Masks */ - -#define CIU12 0x00000080lu -#define CIU13 0x00008000lu -#define CIU14 0x00800000lu -#define CIU15 0x80000000lu - -#define CL12 0x0000007Flu -#define CL13 0x00007F00lu -#define CL14 0x007F0000lu -#define CL15 0x7F000000lu - - -/* MXVR_ALLOC_4 Masks */ - -#define CIU16 0x00000080lu -#define CIU17 0x00008000lu -#define CIU18 0x00800000lu -#define CIU19 0x80000000lu - -#define CL16 0x0000007Flu -#define CL17 0x00007F00lu -#define CL18 0x007F0000lu -#define CL19 0x7F000000lu - - -/* MXVR_ALLOC_5 Masks */ - -#define CIU20 0x00000080lu -#define CIU21 0x00008000lu -#define CIU22 0x00800000lu -#define CIU23 0x80000000lu - -#define CL20 0x0000007Flu -#define CL21 0x00007F00lu -#define CL22 0x007F0000lu -#define CL23 0x7F000000lu - - -/* MXVR_ALLOC_6 Masks */ - -#define CIU24 0x00000080lu -#define CIU25 0x00008000lu -#define CIU26 0x00800000lu -#define CIU27 0x80000000lu - -#define CL24 0x0000007Flu -#define CL25 0x00007F00lu -#define CL26 0x007F0000lu -#define CL27 0x7F000000lu - - -/* MXVR_ALLOC_7 Masks */ - -#define CIU28 0x00000080lu -#define CIU29 0x00008000lu -#define CIU30 0x00800000lu -#define CIU31 0x80000000lu - -#define CL28 0x0000007Flu -#define CL29 0x00007F00lu -#define CL30 0x007F0000lu -#define CL31 0x7F000000lu - - -/* MXVR_ALLOC_8 Masks */ - -#define CIU32 0x00000080lu -#define CIU33 0x00008000lu -#define CIU34 0x00800000lu -#define CIU35 0x80000000lu - -#define CL32 0x0000007Flu -#define CL33 0x00007F00lu -#define CL34 0x007F0000lu -#define CL35 0x7F000000lu - - -/* MXVR_ALLOC_9 Masks */ - -#define CIU36 0x00000080lu -#define CIU37 0x00008000lu -#define CIU38 0x00800000lu -#define CIU39 0x80000000lu - -#define CL36 0x0000007Flu -#define CL37 0x00007F00lu -#define CL38 0x007F0000lu -#define CL39 0x7F000000lu - - -/* MXVR_ALLOC_10 Masks */ - -#define CIU40 0x00000080lu -#define CIU41 0x00008000lu -#define CIU42 0x00800000lu -#define CIU43 0x80000000lu - -#define CL40 0x0000007Flu -#define CL41 0x00007F00lu -#define CL42 0x007F0000lu -#define CL43 0x7F000000lu - - -/* MXVR_ALLOC_11 Masks */ - -#define CIU44 0x00000080lu -#define CIU45 0x00008000lu -#define CIU46 0x00800000lu -#define CIU47 0x80000000lu - -#define CL44 0x0000007Flu -#define CL45 0x00007F00lu -#define CL46 0x007F0000lu -#define CL47 0x7F000000lu - - -/* MXVR_ALLOC_12 Masks */ - -#define CIU48 0x00000080lu -#define CIU49 0x00008000lu -#define CIU50 0x00800000lu -#define CIU51 0x80000000lu - -#define CL48 0x0000007Flu -#define CL49 0x00007F00lu -#define CL50 0x007F0000lu -#define CL51 0x7F000000lu - - -/* MXVR_ALLOC_13 Masks */ - -#define CIU52 0x00000080lu -#define CIU53 0x00008000lu -#define CIU54 0x00800000lu -#define CIU55 0x80000000lu - -#define CL52 0x0000007Flu -#define CL53 0x00007F00lu -#define CL54 0x007F0000lu -#define CL55 0x7F000000lu - - -/* MXVR_ALLOC_14 Masks */ - -#define CIU56 0x00000080lu -#define CIU57 0x00008000lu -#define CIU58 0x00800000lu -#define CIU59 0x80000000lu - -#define CL56 0x0000007Flu -#define CL57 0x00007F00lu -#define CL58 0x007F0000lu -#define CL59 0x7F000000lu - - -/* MXVR_SYNC_LCHAN_0 Masks */ - -#define LCHANPC0 0x0000000Flu -#define LCHANPC1 0x000000F0lu -#define LCHANPC2 0x00000F00lu -#define LCHANPC3 0x0000F000lu -#define LCHANPC4 0x000F0000lu -#define LCHANPC5 0x00F00000lu -#define LCHANPC6 0x0F000000lu -#define LCHANPC7 0xF0000000lu - - -/* MXVR_SYNC_LCHAN_1 Masks */ - -#define LCHANPC8 0x0000000Flu -#define LCHANPC9 0x000000F0lu -#define LCHANPC10 0x00000F00lu -#define LCHANPC11 0x0000F000lu -#define LCHANPC12 0x000F0000lu -#define LCHANPC13 0x00F00000lu -#define LCHANPC14 0x0F000000lu -#define LCHANPC15 0xF0000000lu - - -/* MXVR_SYNC_LCHAN_2 Masks */ - -#define LCHANPC16 0x0000000Flu -#define LCHANPC17 0x000000F0lu -#define LCHANPC18 0x00000F00lu -#define LCHANPC19 0x0000F000lu -#define LCHANPC20 0x000F0000lu -#define LCHANPC21 0x00F00000lu -#define LCHANPC22 0x0F000000lu -#define LCHANPC23 0xF0000000lu - - -/* MXVR_SYNC_LCHAN_3 Masks */ - -#define LCHANPC24 0x0000000Flu -#define LCHANPC25 0x000000F0lu -#define LCHANPC26 0x00000F00lu -#define LCHANPC27 0x0000F000lu -#define LCHANPC28 0x000F0000lu -#define LCHANPC29 0x00F00000lu -#define LCHANPC30 0x0F000000lu -#define LCHANPC31 0xF0000000lu - - -/* MXVR_SYNC_LCHAN_4 Masks */ - -#define LCHANPC32 0x0000000Flu -#define LCHANPC33 0x000000F0lu -#define LCHANPC34 0x00000F00lu -#define LCHANPC35 0x0000F000lu -#define LCHANPC36 0x000F0000lu -#define LCHANPC37 0x00F00000lu -#define LCHANPC38 0x0F000000lu -#define LCHANPC39 0xF0000000lu - - -/* MXVR_SYNC_LCHAN_5 Masks */ - -#define LCHANPC40 0x0000000Flu -#define LCHANPC41 0x000000F0lu -#define LCHANPC42 0x00000F00lu -#define LCHANPC43 0x0000F000lu -#define LCHANPC44 0x000F0000lu -#define LCHANPC45 0x00F00000lu -#define LCHANPC46 0x0F000000lu -#define LCHANPC47 0xF0000000lu - - -/* MXVR_SYNC_LCHAN_6 Masks */ - -#define LCHANPC48 0x0000000Flu -#define LCHANPC49 0x000000F0lu -#define LCHANPC50 0x00000F00lu -#define LCHANPC51 0x0000F000lu -#define LCHANPC52 0x000F0000lu -#define LCHANPC53 0x00F00000lu -#define LCHANPC54 0x0F000000lu -#define LCHANPC55 0xF0000000lu - - -/* MXVR_SYNC_LCHAN_7 Masks */ - -#define LCHANPC56 0x0000000Flu -#define LCHANPC57 0x000000F0lu -#define LCHANPC58 0x00000F00lu -#define LCHANPC59 0x0000F000lu - - -/* MXVR_DMAx_CONFIG Masks */ - -#define MDMAEN 0x00000001lu -#define DD 0x00000002lu -#define LCHAN 0x000003C0lu -#define BITSWAPEN 0x00000400lu -#define BYSWAPEN 0x00000800lu -#define MFLOW 0x00007000lu -#define FIXEDPM 0x00080000lu -#define STARTPAT 0x00300000lu -#define STOPPAT 0x00C00000lu -#define COUNTPOS 0x1C000000lu - -#define DD_TX 0x00000000lu -#define DD_RX 0x00000002lu - -#define LCHAN_0 0x00000000lu -#define LCHAN_1 0x00000040lu -#define LCHAN_2 0x00000080lu -#define LCHAN_3 0x000000C0lu -#define LCHAN_4 0x00000100lu -#define LCHAN_5 0x00000140lu -#define LCHAN_6 0x00000180lu -#define LCHAN_7 0x000001C0lu - -#define MFLOW_STOP 0x00000000lu -#define MFLOW_AUTO 0x00001000lu -#define MFLOW_PVC 0x00002000lu -#define MFLOW_PSS 0x00003000lu -#define MFLOW_PFC 0x00004000lu - -#define STARTPAT_0 0x00000000lu -#define STARTPAT_1 0x00100000lu - -#define STOPPAT_0 0x00000000lu -#define STOPPAT_1 0x00400000lu - -#define COUNTPOS_0 0x00000000lu -#define COUNTPOS_1 0x04000000lu -#define COUNTPOS_2 0x08000000lu -#define COUNTPOS_3 0x0C000000lu -#define COUNTPOS_4 0x10000000lu -#define COUNTPOS_5 0x14000000lu -#define COUNTPOS_6 0x18000000lu -#define COUNTPOS_7 0x1C000000lu - - -/* MXVR_AP_CTL Masks */ - -#define STARTAP 0x00000001lu -#define CANCELAP 0x00000002lu -#define RESETAP 0x00000004lu -#define APRBE0 0x00004000lu -#define APRBE1 0x00008000lu -#define APRBEX 0x0000C000lu - - -/* MXVR_CM_CTL Masks */ - -#define STARTCM 0x00000001lu -#define CANCELCM 0x00000002lu -#define CMRBEX 0xFFFF0000lu -#define CMRBE0 0x00010000lu -#define CMRBE1 0x00020000lu -#define CMRBE2 0x00040000lu -#define CMRBE3 0x00080000lu -#define CMRBE4 0x00100000lu -#define CMRBE5 0x00200000lu -#define CMRBE6 0x00400000lu -#define CMRBE7 0x00800000lu -#define CMRBE8 0x01000000lu -#define CMRBE9 0x02000000lu -#define CMRBE10 0x04000000lu -#define CMRBE11 0x08000000lu -#define CMRBE12 0x10000000lu -#define CMRBE13 0x20000000lu -#define CMRBE14 0x40000000lu -#define CMRBE15 0x80000000lu - - -/* MXVR_PAT_DATA_x Masks */ - -#define MATCH_DATA_0 0x000000FFlu -#define MATCH_DATA_1 0x0000FF00lu -#define MATCH_DATA_2 0x00FF0000lu -#define MATCH_DATA_3 0xFF000000lu - - - -/* MXVR_PAT_EN_x Masks */ - -#define MATCH_EN_0_0 0x00000001lu -#define MATCH_EN_0_1 0x00000002lu -#define MATCH_EN_0_2 0x00000004lu -#define MATCH_EN_0_3 0x00000008lu -#define MATCH_EN_0_4 0x00000010lu -#define MATCH_EN_0_5 0x00000020lu -#define MATCH_EN_0_6 0x00000040lu -#define MATCH_EN_0_7 0x00000080lu - -#define MATCH_EN_1_0 0x00000100lu -#define MATCH_EN_1_1 0x00000200lu -#define MATCH_EN_1_2 0x00000400lu -#define MATCH_EN_1_3 0x00000800lu -#define MATCH_EN_1_4 0x00001000lu -#define MATCH_EN_1_5 0x00002000lu -#define MATCH_EN_1_6 0x00004000lu -#define MATCH_EN_1_7 0x00008000lu - -#define MATCH_EN_2_0 0x00010000lu -#define MATCH_EN_2_1 0x00020000lu -#define MATCH_EN_2_2 0x00040000lu -#define MATCH_EN_2_3 0x00080000lu -#define MATCH_EN_2_4 0x00100000lu -#define MATCH_EN_2_5 0x00200000lu -#define MATCH_EN_2_6 0x00400000lu -#define MATCH_EN_2_7 0x00800000lu - -#define MATCH_EN_3_0 0x01000000lu -#define MATCH_EN_3_1 0x02000000lu -#define MATCH_EN_3_2 0x04000000lu -#define MATCH_EN_3_3 0x08000000lu -#define MATCH_EN_3_4 0x10000000lu -#define MATCH_EN_3_5 0x20000000lu -#define MATCH_EN_3_6 0x40000000lu -#define MATCH_EN_3_7 0x80000000lu - - -/* MXVR_ROUTING_0 Masks */ - -#define MUTE_CH0 0x00000080lu -#define MUTE_CH1 0x00008000lu -#define MUTE_CH2 0x00800000lu -#define MUTE_CH3 0x80000000lu - -#define TX_CH0 0x0000007Flu -#define TX_CH1 0x00007F00lu -#define TX_CH2 0x007F0000lu -#define TX_CH3 0x7F000000lu - - -/* MXVR_ROUTING_1 Masks */ - -#define MUTE_CH4 0x00000080lu -#define MUTE_CH5 0x00008000lu -#define MUTE_CH6 0x00800000lu -#define MUTE_CH7 0x80000000lu - -#define TX_CH4 0x0000007Flu -#define TX_CH5 0x00007F00lu -#define TX_CH6 0x007F0000lu -#define TX_CH7 0x7F000000lu - - -/* MXVR_ROUTING_2 Masks */ - -#define MUTE_CH8 0x00000080lu -#define MUTE_CH9 0x00008000lu -#define MUTE_CH10 0x00800000lu -#define MUTE_CH11 0x80000000lu - -#define TX_CH8 0x0000007Flu -#define TX_CH9 0x00007F00lu -#define TX_CH10 0x007F0000lu -#define TX_CH11 0x7F000000lu - -/* MXVR_ROUTING_3 Masks */ - -#define MUTE_CH12 0x00000080lu -#define MUTE_CH13 0x00008000lu -#define MUTE_CH14 0x00800000lu -#define MUTE_CH15 0x80000000lu - -#define TX_CH12 0x0000007Flu -#define TX_CH13 0x00007F00lu -#define TX_CH14 0x007F0000lu -#define TX_CH15 0x7F000000lu - - -/* MXVR_ROUTING_4 Masks */ - -#define MUTE_CH16 0x00000080lu -#define MUTE_CH17 0x00008000lu -#define MUTE_CH18 0x00800000lu -#define MUTE_CH19 0x80000000lu - -#define TX_CH16 0x0000007Flu -#define TX_CH17 0x00007F00lu -#define TX_CH18 0x007F0000lu -#define TX_CH19 0x7F000000lu - - -/* MXVR_ROUTING_5 Masks */ - -#define MUTE_CH20 0x00000080lu -#define MUTE_CH21 0x00008000lu -#define MUTE_CH22 0x00800000lu -#define MUTE_CH23 0x80000000lu - -#define TX_CH20 0x0000007Flu -#define TX_CH21 0x00007F00lu -#define TX_CH22 0x007F0000lu -#define TX_CH23 0x7F000000lu - - -/* MXVR_ROUTING_6 Masks */ - -#define MUTE_CH24 0x00000080lu -#define MUTE_CH25 0x00008000lu -#define MUTE_CH26 0x00800000lu -#define MUTE_CH27 0x80000000lu - -#define TX_CH24 0x0000007Flu -#define TX_CH25 0x00007F00lu -#define TX_CH26 0x007F0000lu -#define TX_CH27 0x7F000000lu - - -/* MXVR_ROUTING_7 Masks */ - -#define MUTE_CH28 0x00000080lu -#define MUTE_CH29 0x00008000lu -#define MUTE_CH30 0x00800000lu -#define MUTE_CH31 0x80000000lu - -#define TX_CH28 0x0000007Flu -#define TX_CH29 0x00007F00lu -#define TX_CH30 0x007F0000lu -#define TX_CH31 0x7F000000lu - - -/* MXVR_ROUTING_8 Masks */ - -#define MUTE_CH32 0x00000080lu -#define MUTE_CH33 0x00008000lu -#define MUTE_CH34 0x00800000lu -#define MUTE_CH35 0x80000000lu - -#define TX_CH32 0x0000007Flu -#define TX_CH33 0x00007F00lu -#define TX_CH34 0x007F0000lu -#define TX_CH35 0x7F000000lu - - -/* MXVR_ROUTING_9 Masks */ - -#define MUTE_CH36 0x00000080lu -#define MUTE_CH37 0x00008000lu -#define MUTE_CH38 0x00800000lu -#define MUTE_CH39 0x80000000lu - -#define TX_CH36 0x0000007Flu -#define TX_CH37 0x00007F00lu -#define TX_CH38 0x007F0000lu -#define TX_CH39 0x7F000000lu - - -/* MXVR_ROUTING_10 Masks */ - -#define MUTE_CH40 0x00000080lu -#define MUTE_CH41 0x00008000lu -#define MUTE_CH42 0x00800000lu -#define MUTE_CH43 0x80000000lu - -#define TX_CH40 0x0000007Flu -#define TX_CH41 0x00007F00lu -#define TX_CH42 0x007F0000lu -#define TX_CH43 0x7F000000lu - - -/* MXVR_ROUTING_11 Masks */ - -#define MUTE_CH44 0x00000080lu -#define MUTE_CH45 0x00008000lu -#define MUTE_CH46 0x00800000lu -#define MUTE_CH47 0x80000000lu - -#define TX_CH44 0x0000007Flu -#define TX_CH45 0x00007F00lu -#define TX_CH46 0x007F0000lu -#define TX_CH47 0x7F000000lu - - -/* MXVR_ROUTING_12 Masks */ - -#define MUTE_CH48 0x00000080lu -#define MUTE_CH49 0x00008000lu -#define MUTE_CH50 0x00800000lu -#define MUTE_CH51 0x80000000lu - -#define TX_CH48 0x0000007Flu -#define TX_CH49 0x00007F00lu -#define TX_CH50 0x007F0000lu -#define TX_CH51 0x7F000000lu - - -/* MXVR_ROUTING_13 Masks */ - -#define MUTE_CH52 0x00000080lu -#define MUTE_CH53 0x00008000lu -#define MUTE_CH54 0x00800000lu -#define MUTE_CH55 0x80000000lu - -#define TX_CH52 0x0000007Flu -#define TX_CH53 0x00007F00lu -#define TX_CH54 0x007F0000lu -#define TX_CH55 0x7F000000lu - - -/* MXVR_ROUTING_14 Masks */ - -#define MUTE_CH56 0x00000080lu -#define MUTE_CH57 0x00008000lu -#define MUTE_CH58 0x00800000lu -#define MUTE_CH59 0x80000000lu - -#define TX_CH56 0x0000007Flu -#define TX_CH57 0x00007F00lu -#define TX_CH58 0x007F0000lu -#define TX_CH59 0x7F000000lu - - -/* Control Message Receive Buffer (CMRB) Address Offsets */ - -#define CMRB_STRIDE 0x00000016lu - -#define CMRB_DST_OFFSET 0x00000000lu -#define CMRB_SRC_OFFSET 0x00000002lu -#define CMRB_DATA_OFFSET 0x00000005lu - - -/* Control Message Transmit Buffer (CMTB) Address Offsets */ - -#define CMTB_PRIO_OFFSET 0x00000000lu -#define CMTB_DST_OFFSET 0x00000002lu -#define CMTB_SRC_OFFSET 0x00000004lu -#define CMTB_TYPE_OFFSET 0x00000006lu -#define CMTB_DATA_OFFSET 0x00000007lu - -#define CMTB_ANSWER_OFFSET 0x0000000Alu - -#define CMTB_STAT_N_OFFSET 0x00000018lu -#define CMTB_STAT_A_OFFSET 0x00000016lu -#define CMTB_STAT_D_OFFSET 0x0000000Elu -#define CMTB_STAT_R_OFFSET 0x00000014lu -#define CMTB_STAT_W_OFFSET 0x00000014lu -#define CMTB_STAT_G_OFFSET 0x00000014lu - - -/* Asynchronous Packet Receive Buffer (APRB) Address Offsets */ - -#define APRB_STRIDE 0x00000400lu - -#define APRB_DST_OFFSET 0x00000000lu -#define APRB_LEN_OFFSET 0x00000002lu -#define APRB_SRC_OFFSET 0x00000004lu -#define APRB_DATA_OFFSET 0x00000006lu - - -/* Asynchronous Packet Transmit Buffer (APTB) Address Offsets */ - -#define APTB_PRIO_OFFSET 0x00000000lu -#define APTB_DST_OFFSET 0x00000002lu -#define APTB_LEN_OFFSET 0x00000004lu -#define APTB_SRC_OFFSET 0x00000006lu -#define APTB_DATA_OFFSET 0x00000008lu - - -/* Remote Read Buffer (RRDB) Address Offsets */ - -#define RRDB_WADDR_OFFSET 0x00000100lu -#define RRDB_WLEN_OFFSET 0x00000101lu - - - /* ************ CONTROLLER AREA NETWORK (CAN) MASKS ***************/ /* CAN_CONTROL Masks */ #define SRS 0x0001 /* Software Reset */ diff --git a/arch/blackfin/mach-bf548/include/mach/defBF549.h b/arch/blackfin/mach-bf548/include/mach/defBF549.h index d84dbe9..5a04e6d 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF549.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF549.h @@ -188,948 +188,4 @@ #define MXVR_PIN_CTL 0xffc028dc /* MXVR Pin Control Register */ #define MXVR_SCLK_CNT 0xffc028e0 /* MXVR System Clock Counter Register */ -/* Bit masks for MXVR_CONFIG */ - -#define MXVREN 0x1 /* MXVR Enable */ -#define MMSM 0x2 /* MXVR Master/Slave Mode Select */ -#define ACTIVE 0x4 /* Active Mode */ -#define SDELAY 0x8 /* Synchronous Data Delay */ -#define NCMRXEN 0x10 /* Normal Control Message Receive Enable */ -#define RWRRXEN 0x20 /* Remote Write Receive Enable */ -#define MTXEN 0x40 /* MXVR Transmit Data Enable */ -#define MTXONB 0x80 /* MXVR Phy Transmitter On */ -#define EPARITY 0x100 /* Even Parity Select */ -#define MSB 0x1e00 /* Master Synchronous Boundary */ -#define APRXEN 0x2000 /* Asynchronous Packet Receive Enable */ -#define WAKEUP 0x4000 /* Wake-Up */ -#define LMECH 0x8000 /* Lock Mechanism Select */ - -/* Bit masks for MXVR_STATE_0 */ - -#define NACT 0x1 /* Network Activity */ -#define SBLOCK 0x2 /* Super Block Lock */ -#define FMPLLST 0xc /* Frequency Multiply PLL SM State */ -#define CDRPLLST 0xe0 /* Clock/Data Recovery PLL SM State */ -#define APBSY 0x100 /* Asynchronous Packet Transmit Buffer Busy */ -#define APARB 0x200 /* Asynchronous Packet Arbitrating */ -#define APTX 0x400 /* Asynchronous Packet Transmitting */ -#define APRX 0x800 /* Receiving Asynchronous Packet */ -#define CMBSY 0x1000 /* Control Message Transmit Buffer Busy */ -#define CMARB 0x2000 /* Control Message Arbitrating */ -#define CMTX 0x4000 /* Control Message Transmitting */ -#define CMRX 0x8000 /* Receiving Control Message */ -#define MRXONB 0x10000 /* MRXONB Pin State */ -#define RGSIP 0x20000 /* Remote Get Source In Progress */ -#define DALIP 0x40000 /* Resource Deallocate In Progress */ -#define ALIP 0x80000 /* Resource Allocate In Progress */ -#define RRDIP 0x100000 /* Remote Read In Progress */ -#define RWRIP 0x200000 /* Remote Write In Progress */ -#define FLOCK 0x400000 /* Frame Lock */ -#define BLOCK 0x800000 /* Block Lock */ -#define RSB 0xf000000 /* Received Synchronous Boundary */ -#define DERRNUM 0xf0000000 /* DMA Error Channel Number */ - -/* Bit masks for MXVR_STATE_1 */ - -#define SRXNUMB 0xf /* Synchronous Receive FIFO Number of Bytes */ -#define STXNUMB 0xf0 /* Synchronous Transmit FIFO Number of Bytes */ -#define APCONT 0x100 /* Asynchronous Packet Continuation */ -#define OBERRNUM 0xe00 /* DMA Out of Bounds Error Channel Number */ -#define DMAACTIVE0 0x10000 /* DMA0 Active */ -#define DMAACTIVE1 0x20000 /* DMA1 Active */ -#define DMAACTIVE2 0x40000 /* DMA2 Active */ -#define DMAACTIVE3 0x80000 /* DMA3 Active */ -#define DMAACTIVE4 0x100000 /* DMA4 Active */ -#define DMAACTIVE5 0x200000 /* DMA5 Active */ -#define DMAACTIVE6 0x400000 /* DMA6 Active */ -#define DMAACTIVE7 0x800000 /* DMA7 Active */ -#define DMAPMEN0 0x1000000 /* DMA0 Pattern Matching Enabled */ -#define DMAPMEN1 0x2000000 /* DMA1 Pattern Matching Enabled */ -#define DMAPMEN2 0x4000000 /* DMA2 Pattern Matching Enabled */ -#define DMAPMEN3 0x8000000 /* DMA3 Pattern Matching Enabled */ -#define DMAPMEN4 0x10000000 /* DMA4 Pattern Matching Enabled */ -#define DMAPMEN5 0x20000000 /* DMA5 Pattern Matching Enabled */ -#define DMAPMEN6 0x40000000 /* DMA6 Pattern Matching Enabled */ -#define DMAPMEN7 0x80000000 /* DMA7 Pattern Matching Enabled */ - -/* Bit masks for MXVR_INT_STAT_0 */ - -#define NI2A 0x1 /* Network Inactive to Active */ -#define NA2I 0x2 /* Network Active to Inactive */ -#define SBU2L 0x4 /* Super Block Unlock to Lock */ -#define SBL2U 0x8 /* Super Block Lock to Unlock */ -#define PRU 0x10 /* Position Register Updated */ -#define MPRU 0x20 /* Maximum Position Register Updated */ -#define DRU 0x40 /* Delay Register Updated */ -#define MDRU 0x80 /* Maximum Delay Register Updated */ -#define SBU 0x100 /* Synchronous Boundary Updated */ -#define ATU 0x200 /* Allocation Table Updated */ -#define FCZ0 0x400 /* Frame Counter 0 Zero */ -#define FCZ1 0x800 /* Frame Counter 1 Zero */ -#define PERR 0x1000 /* Parity Error */ -#define MH2L 0x2000 /* MRXONB High to Low */ -#define ML2H 0x4000 /* MRXONB Low to High */ -#define WUP 0x8000 /* Wake-Up Preamble Received */ -#define FU2L 0x10000 /* Frame Unlock to Lock */ -#define FL2U 0x20000 /* Frame Lock to Unlock */ -#define BU2L 0x40000 /* Block Unlock to Lock */ -#define BL2U 0x80000 /* Block Lock to Unlock */ -#define OBERR 0x100000 /* DMA Out of Bounds Error */ -#define PFL 0x200000 /* PLL Frequency Locked */ -#define SCZ 0x400000 /* System Clock Counter Zero */ -#define FERR 0x800000 /* FIFO Error */ -#define CMR 0x1000000 /* Control Message Received */ -#define CMROF 0x2000000 /* Control Message Receive Buffer Overflow */ -#define CMTS 0x4000000 /* Control Message Transmit Buffer Successfully Sent */ -#define CMTC 0x8000000 /* Control Message Transmit Buffer Successfully Cancelled */ -#define RWRC 0x10000000 /* Remote Write Control Message Completed */ -#define BCZ 0x20000000 /* Block Counter Zero */ -#define BMERR 0x40000000 /* Biphase Mark Coding Error */ -#define DERR 0x80000000 /* DMA Error */ - -/* Bit masks for MXVR_INT_STAT_1 */ - -#define HDONE0 0x1 /* DMA0 Half Done */ -#define DONE0 0x2 /* DMA0 Done */ -#define APR 0x4 /* Asynchronous Packet Received */ -#define APROF 0x8 /* Asynchronous Packet Receive Buffer Overflow */ -#define HDONE1 0x10 /* DMA1 Half Done */ -#define DONE1 0x20 /* DMA1 Done */ -#define APTS 0x40 /* Asynchronous Packet Transmit Buffer Successfully Sent */ -#define APTC 0x80 /* Asynchronous Packet Transmit Buffer Successfully Cancelled */ -#define HDONE2 0x100 /* DMA2 Half Done */ -#define DONE2 0x200 /* DMA2 Done */ -#define APRCE 0x400 /* Asynchronous Packet Receive CRC Error */ -#define APRPE 0x800 /* Asynchronous Packet Receive Packet Error */ -#define HDONE3 0x1000 /* DMA3 Half Done */ -#define DONE3 0x2000 /* DMA3 Done */ -#define HDONE4 0x10000 /* DMA4 Half Done */ -#define DONE4 0x20000 /* DMA4 Done */ -#define HDONE5 0x100000 /* DMA5 Half Done */ -#define DONE5 0x200000 /* DMA5 Done */ -#define HDONE6 0x1000000 /* DMA6 Half Done */ -#define DONE6 0x2000000 /* DMA6 Done */ -#define HDONE7 0x10000000 /* DMA7 Half Done */ -#define DONE7 0x20000000 /* DMA7 Done */ - -/* Bit masks for MXVR_INT_EN_0 */ - -#define NI2AEN 0x1 /* Network Inactive to Active Interrupt Enable */ -#define NA2IEN 0x2 /* Network Active to Inactive Interrupt Enable */ -#define SBU2LEN 0x4 /* Super Block Unlock to Lock Interrupt Enable */ -#define SBL2UEN 0x8 /* Super Block Lock to Unlock Interrupt Enable */ -#define PRUEN 0x10 /* Position Register Updated Interrupt Enable */ -#define MPRUEN 0x20 /* Maximum Position Register Updated Interrupt Enable */ -#define DRUEN 0x40 /* Delay Register Updated Interrupt Enable */ -#define MDRUEN 0x80 /* Maximum Delay Register Updated Interrupt Enable */ -#define SBUEN 0x100 /* Synchronous Boundary Updated Interrupt Enable */ -#define ATUEN 0x200 /* Allocation Table Updated Interrupt Enable */ -#define FCZ0EN 0x400 /* Frame Counter 0 Zero Interrupt Enable */ -#define FCZ1EN 0x800 /* Frame Counter 1 Zero Interrupt Enable */ -#define PERREN 0x1000 /* Parity Error Interrupt Enable */ -#define MH2LEN 0x2000 /* MRXONB High to Low Interrupt Enable */ -#define ML2HEN 0x4000 /* MRXONB Low to High Interrupt Enable */ -#define WUPEN 0x8000 /* Wake-Up Preamble Received Interrupt Enable */ -#define FU2LEN 0x10000 /* Frame Unlock to Lock Interrupt Enable */ -#define FL2UEN 0x20000 /* Frame Lock to Unlock Interrupt Enable */ -#define BU2LEN 0x40000 /* Block Unlock to Lock Interrupt Enable */ -#define BL2UEN 0x80000 /* Block Lock to Unlock Interrupt Enable */ -#define OBERREN 0x100000 /* DMA Out of Bounds Error Interrupt Enable */ -#define PFLEN 0x200000 /* PLL Frequency Locked Interrupt Enable */ -#define SCZEN 0x400000 /* System Clock Counter Zero Interrupt Enable */ -#define FERREN 0x800000 /* FIFO Error Interrupt Enable */ -#define CMREN 0x1000000 /* Control Message Received Interrupt Enable */ -#define CMROFEN 0x2000000 /* Control Message Receive Buffer Overflow Interrupt Enable */ -#define CMTSEN 0x4000000 /* Control Message Transmit Buffer Successfully Sent Interrupt Enable */ -#define CMTCEN 0x8000000 /* Control Message Transmit Buffer Successfully Cancelled Interrupt Enable */ -#define RWRCEN 0x10000000 /* Remote Write Control Message Completed Interrupt Enable */ -#define BCZEN 0x20000000 /* Block Counter Zero Interrupt Enable */ -#define BMERREN 0x40000000 /* Biphase Mark Coding Error Interrupt Enable */ -#define DERREN 0x80000000 /* DMA Error Interrupt Enable */ - -/* Bit masks for MXVR_INT_EN_1 */ - -#define HDONEEN0 0x1 /* DMA0 Half Done Interrupt Enable */ -#define DONEEN0 0x2 /* DMA0 Done Interrupt Enable */ -#define APREN 0x4 /* Asynchronous Packet Received Interrupt Enable */ -#define APROFEN 0x8 /* Asynchronous Packet Receive Buffer Overflow Interrupt Enable */ -#define HDONEEN1 0x10 /* DMA1 Half Done Interrupt Enable */ -#define DONEEN1 0x20 /* DMA1 Done Interrupt Enable */ -#define APTSEN 0x40 /* Asynchronous Packet Transmit Buffer Successfully Sent Interrupt Enable */ -#define APTCEN 0x80 /* Asynchronous Packet Transmit Buffer Successfully Cancelled Interrupt Enable */ -#define HDONEEN2 0x100 /* DMA2 Half Done Interrupt Enable */ -#define DONEEN2 0x200 /* DMA2 Done Interrupt Enable */ -#define APRCEEN 0x400 /* Asynchronous Packet Receive CRC Error Interrupt Enable */ -#define APRPEEN 0x800 /* Asynchronous Packet Receive Packet Error Interrupt Enable */ -#define HDONEEN3 0x1000 /* DMA3 Half Done Interrupt Enable */ -#define DONEEN3 0x2000 /* DMA3 Done Interrupt Enable */ -#define HDONEEN4 0x10000 /* DMA4 Half Done Interrupt Enable */ -#define DONEEN4 0x20000 /* DMA4 Done Interrupt Enable */ -#define HDONEEN5 0x100000 /* DMA5 Half Done Interrupt Enable */ -#define DONEEN5 0x200000 /* DMA5 Done Interrupt Enable */ -#define HDONEEN6 0x1000000 /* DMA6 Half Done Interrupt Enable */ -#define DONEEN6 0x2000000 /* DMA6 Done Interrupt Enable */ -#define HDONEEN7 0x10000000 /* DMA7 Half Done Interrupt Enable */ -#define DONEEN7 0x20000000 /* DMA7 Done Interrupt Enable */ - -/* Bit masks for MXVR_POSITION */ - -#define POSITION 0x3f /* Node Position */ -#define PVALID 0x8000 /* Node Position Valid */ - -/* Bit masks for MXVR_MAX_POSITION */ - -#define MPOSITION 0x3f /* Maximum Node Position */ -#define MPVALID 0x8000 /* Maximum Node Position Valid */ - -/* Bit masks for MXVR_DELAY */ - -#define DELAY 0x3f /* Node Frame Delay */ -#define DVALID 0x8000 /* Node Frame Delay Valid */ - -/* Bit masks for MXVR_MAX_DELAY */ - -#define MDELAY 0x3f /* Maximum Node Frame Delay */ -#define MDVALID 0x8000 /* Maximum Node Frame Delay Valid */ - -/* Bit masks for MXVR_LADDR */ - -#define LADDR 0xffff /* Logical Address */ -#define LVALID 0x80000000 /* Logical Address Valid */ - -/* Bit masks for MXVR_GADDR */ - -#define GADDRL 0xff /* Group Address Lower Byte */ -#define GVALID 0x8000 /* Group Address Valid */ - -/* Bit masks for MXVR_AADDR */ - -#define AADDR 0xffff /* Alternate Address */ -#define AVALID 0x80000000 /* Alternate Address Valid */ - -/* Bit masks for MXVR_ALLOC_0 */ - -#define CL0 0x7f /* Channel 0 Connection Label */ -#define CIU0 0x80 /* Channel 0 In Use */ -#define CL1 0x7f00 /* Channel 0 Connection Label */ -#define CIU1 0x8000 /* Channel 0 In Use */ -#define CL2 0x7f0000 /* Channel 0 Connection Label */ -#define CIU2 0x800000 /* Channel 0 In Use */ -#define CL3 0x7f000000 /* Channel 0 Connection Label */ -#define CIU3 0x80000000 /* Channel 0 In Use */ - -/* Bit masks for MXVR_ALLOC_1 */ - -#define CL4 0x7f /* Channel 4 Connection Label */ -#define CIU4 0x80 /* Channel 4 In Use */ -#define CL5 0x7f00 /* Channel 5 Connection Label */ -#define CIU5 0x8000 /* Channel 5 In Use */ -#define CL6 0x7f0000 /* Channel 6 Connection Label */ -#define CIU6 0x800000 /* Channel 6 In Use */ -#define CL7 0x7f000000 /* Channel 7 Connection Label */ -#define CIU7 0x80000000 /* Channel 7 In Use */ - -/* Bit masks for MXVR_ALLOC_2 */ - -#define CL8 0x7f /* Channel 8 Connection Label */ -#define CIU8 0x80 /* Channel 8 In Use */ -#define CL9 0x7f00 /* Channel 9 Connection Label */ -#define CIU9 0x8000 /* Channel 9 In Use */ -#define CL10 0x7f0000 /* Channel 10 Connection Label */ -#define CIU10 0x800000 /* Channel 10 In Use */ -#define CL11 0x7f000000 /* Channel 11 Connection Label */ -#define CIU11 0x80000000 /* Channel 11 In Use */ - -/* Bit masks for MXVR_ALLOC_3 */ - -#define CL12 0x7f /* Channel 12 Connection Label */ -#define CIU12 0x80 /* Channel 12 In Use */ -#define CL13 0x7f00 /* Channel 13 Connection Label */ -#define CIU13 0x8000 /* Channel 13 In Use */ -#define CL14 0x7f0000 /* Channel 14 Connection Label */ -#define CIU14 0x800000 /* Channel 14 In Use */ -#define CL15 0x7f000000 /* Channel 15 Connection Label */ -#define CIU15 0x80000000 /* Channel 15 In Use */ - -/* Bit masks for MXVR_ALLOC_4 */ - -#define CL16 0x7f /* Channel 16 Connection Label */ -#define CIU16 0x80 /* Channel 16 In Use */ -#define CL17 0x7f00 /* Channel 17 Connection Label */ -#define CIU17 0x8000 /* Channel 17 In Use */ -#define CL18 0x7f0000 /* Channel 18 Connection Label */ -#define CIU18 0x800000 /* Channel 18 In Use */ -#define CL19 0x7f000000 /* Channel 19 Connection Label */ -#define CIU19 0x80000000 /* Channel 19 In Use */ - -/* Bit masks for MXVR_ALLOC_5 */ - -#define CL20 0x7f /* Channel 20 Connection Label */ -#define CIU20 0x80 /* Channel 20 In Use */ -#define CL21 0x7f00 /* Channel 21 Connection Label */ -#define CIU21 0x8000 /* Channel 21 In Use */ -#define CL22 0x7f0000 /* Channel 22 Connection Label */ -#define CIU22 0x800000 /* Channel 22 In Use */ -#define CL23 0x7f000000 /* Channel 23 Connection Label */ -#define CIU23 0x80000000 /* Channel 23 In Use */ - -/* Bit masks for MXVR_ALLOC_6 */ - -#define CL24 0x7f /* Channel 24 Connection Label */ -#define CIU24 0x80 /* Channel 24 In Use */ -#define CL25 0x7f00 /* Channel 25 Connection Label */ -#define CIU25 0x8000 /* Channel 25 In Use */ -#define CL26 0x7f0000 /* Channel 26 Connection Label */ -#define CIU26 0x800000 /* Channel 26 In Use */ -#define CL27 0x7f000000 /* Channel 27 Connection Label */ -#define CIU27 0x80000000 /* Channel 27 In Use */ - -/* Bit masks for MXVR_ALLOC_7 */ - -#define CL28 0x7f /* Channel 28 Connection Label */ -#define CIU28 0x80 /* Channel 28 In Use */ -#define CL29 0x7f00 /* Channel 29 Connection Label */ -#define CIU29 0x8000 /* Channel 29 In Use */ -#define CL30 0x7f0000 /* Channel 30 Connection Label */ -#define CIU30 0x800000 /* Channel 30 In Use */ -#define CL31 0x7f000000 /* Channel 31 Connection Label */ -#define CIU31 0x80000000 /* Channel 31 In Use */ - -/* Bit masks for MXVR_ALLOC_8 */ - -#define CL32 0x7f /* Channel 32 Connection Label */ -#define CIU32 0x80 /* Channel 32 In Use */ -#define CL33 0x7f00 /* Channel 33 Connection Label */ -#define CIU33 0x8000 /* Channel 33 In Use */ -#define CL34 0x7f0000 /* Channel 34 Connection Label */ -#define CIU34 0x800000 /* Channel 34 In Use */ -#define CL35 0x7f000000 /* Channel 35 Connection Label */ -#define CIU35 0x80000000 /* Channel 35 In Use */ - -/* Bit masks for MXVR_ALLOC_9 */ - -#define CL36 0x7f /* Channel 36 Connection Label */ -#define CIU36 0x80 /* Channel 36 In Use */ -#define CL37 0x7f00 /* Channel 37 Connection Label */ -#define CIU37 0x8000 /* Channel 37 In Use */ -#define CL38 0x7f0000 /* Channel 38 Connection Label */ -#define CIU38 0x800000 /* Channel 38 In Use */ -#define CL39 0x7f000000 /* Channel 39 Connection Label */ -#define CIU39 0x80000000 /* Channel 39 In Use */ - -/* Bit masks for MXVR_ALLOC_10 */ - -#define CL40 0x7f /* Channel 40 Connection Label */ -#define CIU40 0x80 /* Channel 40 In Use */ -#define CL41 0x7f00 /* Channel 41 Connection Label */ -#define CIU41 0x8000 /* Channel 41 In Use */ -#define CL42 0x7f0000 /* Channel 42 Connection Label */ -#define CIU42 0x800000 /* Channel 42 In Use */ -#define CL43 0x7f000000 /* Channel 43 Connection Label */ -#define CIU43 0x80000000 /* Channel 43 In Use */ - -/* Bit masks for MXVR_ALLOC_11 */ - -#define CL44 0x7f /* Channel 44 Connection Label */ -#define CIU44 0x80 /* Channel 44 In Use */ -#define CL45 0x7f00 /* Channel 45 Connection Label */ -#define CIU45 0x8000 /* Channel 45 In Use */ -#define CL46 0x7f0000 /* Channel 46 Connection Label */ -#define CIU46 0x800000 /* Channel 46 In Use */ -#define CL47 0x7f000000 /* Channel 47 Connection Label */ -#define CIU47 0x80000000 /* Channel 47 In Use */ - -/* Bit masks for MXVR_ALLOC_12 */ - -#define CL48 0x7f /* Channel 48 Connection Label */ -#define CIU48 0x80 /* Channel 48 In Use */ -#define CL49 0x7f00 /* Channel 49 Connection Label */ -#define CIU49 0x8000 /* Channel 49 In Use */ -#define CL50 0x7f0000 /* Channel 50 Connection Label */ -#define CIU50 0x800000 /* Channel 50 In Use */ -#define CL51 0x7f000000 /* Channel 51 Connection Label */ -#define CIU51 0x80000000 /* Channel 51 In Use */ - -/* Bit masks for MXVR_ALLOC_13 */ - -#define CL52 0x7f /* Channel 52 Connection Label */ -#define CIU52 0x80 /* Channel 52 In Use */ -#define CL53 0x7f00 /* Channel 53 Connection Label */ -#define CIU53 0x8000 /* Channel 53 In Use */ -#define CL54 0x7f0000 /* Channel 54 Connection Label */ -#define CIU54 0x800000 /* Channel 54 In Use */ -#define CL55 0x7f000000 /* Channel 55 Connection Label */ -#define CIU55 0x80000000 /* Channel 55 In Use */ - -/* Bit masks for MXVR_ALLOC_14 */ - -#define CL56 0x7f /* Channel 56 Connection Label */ -#define CIU56 0x80 /* Channel 56 In Use */ -#define CL57 0x7f00 /* Channel 57 Connection Label */ -#define CIU57 0x8000 /* Channel 57 In Use */ -#define CL58 0x7f0000 /* Channel 58 Connection Label */ -#define CIU58 0x800000 /* Channel 58 In Use */ -#define CL59 0x7f000000 /* Channel 59 Connection Label */ -#define CIU59 0x80000000 /* Channel 59 In Use */ - -/* MXVR_SYNC_LCHAN_0 Masks */ - -#define LCHANPC0 0x0000000Flu -#define LCHANPC1 0x000000F0lu -#define LCHANPC2 0x00000F00lu -#define LCHANPC3 0x0000F000lu -#define LCHANPC4 0x000F0000lu -#define LCHANPC5 0x00F00000lu -#define LCHANPC6 0x0F000000lu -#define LCHANPC7 0xF0000000lu - - -/* MXVR_SYNC_LCHAN_1 Masks */ - -#define LCHANPC8 0x0000000Flu -#define LCHANPC9 0x000000F0lu -#define LCHANPC10 0x00000F00lu -#define LCHANPC11 0x0000F000lu -#define LCHANPC12 0x000F0000lu -#define LCHANPC13 0x00F00000lu -#define LCHANPC14 0x0F000000lu -#define LCHANPC15 0xF0000000lu - - -/* MXVR_SYNC_LCHAN_2 Masks */ - -#define LCHANPC16 0x0000000Flu -#define LCHANPC17 0x000000F0lu -#define LCHANPC18 0x00000F00lu -#define LCHANPC19 0x0000F000lu -#define LCHANPC20 0x000F0000lu -#define LCHANPC21 0x00F00000lu -#define LCHANPC22 0x0F000000lu -#define LCHANPC23 0xF0000000lu - - -/* MXVR_SYNC_LCHAN_3 Masks */ - -#define LCHANPC24 0x0000000Flu -#define LCHANPC25 0x000000F0lu -#define LCHANPC26 0x00000F00lu -#define LCHANPC27 0x0000F000lu -#define LCHANPC28 0x000F0000lu -#define LCHANPC29 0x00F00000lu -#define LCHANPC30 0x0F000000lu -#define LCHANPC31 0xF0000000lu - - -/* MXVR_SYNC_LCHAN_4 Masks */ - -#define LCHANPC32 0x0000000Flu -#define LCHANPC33 0x000000F0lu -#define LCHANPC34 0x00000F00lu -#define LCHANPC35 0x0000F000lu -#define LCHANPC36 0x000F0000lu -#define LCHANPC37 0x00F00000lu -#define LCHANPC38 0x0F000000lu -#define LCHANPC39 0xF0000000lu - - -/* MXVR_SYNC_LCHAN_5 Masks */ - -#define LCHANPC40 0x0000000Flu -#define LCHANPC41 0x000000F0lu -#define LCHANPC42 0x00000F00lu -#define LCHANPC43 0x0000F000lu -#define LCHANPC44 0x000F0000lu -#define LCHANPC45 0x00F00000lu -#define LCHANPC46 0x0F000000lu -#define LCHANPC47 0xF0000000lu - - -/* MXVR_SYNC_LCHAN_6 Masks */ - -#define LCHANPC48 0x0000000Flu -#define LCHANPC49 0x000000F0lu -#define LCHANPC50 0x00000F00lu -#define LCHANPC51 0x0000F000lu -#define LCHANPC52 0x000F0000lu -#define LCHANPC53 0x00F00000lu -#define LCHANPC54 0x0F000000lu -#define LCHANPC55 0xF0000000lu - - -/* MXVR_SYNC_LCHAN_7 Masks */ - -#define LCHANPC56 0x0000000Flu -#define LCHANPC57 0x000000F0lu -#define LCHANPC58 0x00000F00lu -#define LCHANPC59 0x0000F000lu - -/* Bit masks for MXVR_DMAx_CONFIG */ - -#define MDMAEN 0x1 /* DMA Channel Enable */ -#define DMADD 0x2 /* DMA Channel Direction */ -#define BY4SWAPEN 0x20 /* DMA Channel Four Byte Swap Enable */ -#define LCHAN 0x3c0 /* DMA Channel Logical Channel */ -#define BITSWAPEN 0x400 /* DMA Channel Bit Swap Enable */ -#define BY2SWAPEN 0x800 /* DMA Channel Two Byte Swap Enable */ -#define MFLOW 0x7000 /* DMA Channel Operation Flow */ -#define FIXEDPM 0x80000 /* DMA Channel Fixed Pattern Matching Select */ -#define STARTPAT 0x300000 /* DMA Channel Start Pattern Select */ -#define STOPPAT 0xc00000 /* DMA Channel Stop Pattern Select */ -#define COUNTPOS 0x1c000000 /* DMA Channel Count Position */ - -/* Bit masks for MXVR_AP_CTL */ - -#define STARTAP 0x1 /* Start Asynchronous Packet Transmission */ -#define CANCELAP 0x2 /* Cancel Asynchronous Packet Transmission */ -#define RESETAP 0x4 /* Reset Asynchronous Packet Arbitration */ -#define APRBE0 0x4000 /* Asynchronous Packet Receive Buffer Entry 0 */ -#define APRBE1 0x8000 /* Asynchronous Packet Receive Buffer Entry 1 */ - -/* Bit masks for MXVR_APRB_START_ADDR */ - -#define MXVR_APRB_START_ADDR_MASK 0x1fffffe /* Asynchronous Packet Receive Buffer Start Address */ - -/* Bit masks for MXVR_APRB_CURR_ADDR */ - -#define MXVR_APRB_CURR_ADDR_MASK 0xffffffff /* Asynchronous Packet Receive Buffer Current Address */ - -/* Bit masks for MXVR_APTB_START_ADDR */ - -#define MXVR_APTB_START_ADDR_MASK 0x1fffffe /* Asynchronous Packet Transmit Buffer Start Address */ - -/* Bit masks for MXVR_APTB_CURR_ADDR */ - -#define MXVR_APTB_CURR_ADDR_MASK 0xffffffff /* Asynchronous Packet Transmit Buffer Current Address */ - -/* Bit masks for MXVR_CM_CTL */ - -#define STARTCM 0x1 /* Start Control Message Transmission */ -#define CANCELCM 0x2 /* Cancel Control Message Transmission */ -#define CMRBE0 0x10000 /* Control Message Receive Buffer Entry 0 */ -#define CMRBE1 0x20000 /* Control Message Receive Buffer Entry 1 */ -#define CMRBE2 0x40000 /* Control Message Receive Buffer Entry 2 */ -#define CMRBE3 0x80000 /* Control Message Receive Buffer Entry 3 */ -#define CMRBE4 0x100000 /* Control Message Receive Buffer Entry 4 */ -#define CMRBE5 0x200000 /* Control Message Receive Buffer Entry 5 */ -#define CMRBE6 0x400000 /* Control Message Receive Buffer Entry 6 */ -#define CMRBE7 0x800000 /* Control Message Receive Buffer Entry 7 */ -#define CMRBE8 0x1000000 /* Control Message Receive Buffer Entry 8 */ -#define CMRBE9 0x2000000 /* Control Message Receive Buffer Entry 9 */ -#define CMRBE10 0x4000000 /* Control Message Receive Buffer Entry 10 */ -#define CMRBE11 0x8000000 /* Control Message Receive Buffer Entry 11 */ -#define CMRBE12 0x10000000 /* Control Message Receive Buffer Entry 12 */ -#define CMRBE13 0x20000000 /* Control Message Receive Buffer Entry 13 */ -#define CMRBE14 0x40000000 /* Control Message Receive Buffer Entry 14 */ -#define CMRBE15 0x80000000 /* Control Message Receive Buffer Entry 15 */ - -/* Bit masks for MXVR_CMRB_START_ADDR */ - -#define MXVR_CMRB_START_ADDR_MASK 0x1fffffe /* Control Message Receive Buffer Start Address */ - -/* Bit masks for MXVR_CMRB_CURR_ADDR */ - -#define MXVR_CMRB_CURR_ADDR_MASK 0xffffffff /* Control Message Receive Buffer Current Address */ - -/* Bit masks for MXVR_CMTB_START_ADDR */ - -#define MXVR_CMTB_START_ADDR_MASK 0x1fffffe /* Control Message Transmit Buffer Start Address */ - -/* Bit masks for MXVR_CMTB_CURR_ADDR */ - -#define MXVR_CMTB_CURR_ADDR_MASK 0xffffffff /* Control Message Transmit Buffer Current Address */ - -/* Bit masks for MXVR_RRDB_START_ADDR */ - -#define MXVR_RRDB_START_ADDR_MASK 0x1fffffe /* Remote Read Buffer Start Address */ - -/* Bit masks for MXVR_RRDB_CURR_ADDR */ - -#define MXVR_RRDB_CURR_ADDR_MASK 0xffffffff /* Remote Read Buffer Current Address */ - -/* Bit masks for MXVR_PAT_DATAx */ - -#define MATCH_DATA_0 0xff /* Pattern Match Data Byte 0 */ -#define MATCH_DATA_1 0xff00 /* Pattern Match Data Byte 1 */ -#define MATCH_DATA_2 0xff0000 /* Pattern Match Data Byte 2 */ -#define MATCH_DATA_3 0xff000000 /* Pattern Match Data Byte 3 */ - -/* Bit masks for MXVR_PAT_EN_0 */ - -#define MATCH_EN_0_0 0x1 /* Pattern Match Enable Byte 0 Bit 0 */ -#define MATCH_EN_0_1 0x2 /* Pattern Match Enable Byte 0 Bit 1 */ -#define MATCH_EN_0_2 0x4 /* Pattern Match Enable Byte 0 Bit 2 */ -#define MATCH_EN_0_3 0x8 /* Pattern Match Enable Byte 0 Bit 3 */ -#define MATCH_EN_0_4 0x10 /* Pattern Match Enable Byte 0 Bit 4 */ -#define MATCH_EN_0_5 0x20 /* Pattern Match Enable Byte 0 Bit 5 */ -#define MATCH_EN_0_6 0x40 /* Pattern Match Enable Byte 0 Bit 6 */ -#define MATCH_EN_0_7 0x80 /* Pattern Match Enable Byte 0 Bit 7 */ -#define MATCH_EN_1_0 0x100 /* Pattern Match Enable Byte 1 Bit 0 */ -#define MATCH_EN_1_1 0x200 /* Pattern Match Enable Byte 1 Bit 1 */ -#define MATCH_EN_1_2 0x400 /* Pattern Match Enable Byte 1 Bit 2 */ -#define MATCH_EN_1_3 0x800 /* Pattern Match Enable Byte 1 Bit 3 */ -#define MATCH_EN_1_4 0x1000 /* Pattern Match Enable Byte 1 Bit 4 */ -#define MATCH_EN_1_5 0x2000 /* Pattern Match Enable Byte 1 Bit 5 */ -#define MATCH_EN_1_6 0x4000 /* Pattern Match Enable Byte 1 Bit 6 */ -#define MATCH_EN_1_7 0x8000 /* Pattern Match Enable Byte 1 Bit 7 */ -#define MATCH_EN_2_0 0x10000 /* Pattern Match Enable Byte 2 Bit 0 */ -#define MATCH_EN_2_1 0x20000 /* Pattern Match Enable Byte 2 Bit 1 */ -#define MATCH_EN_2_2 0x40000 /* Pattern Match Enable Byte 2 Bit 2 */ -#define MATCH_EN_2_3 0x80000 /* Pattern Match Enable Byte 2 Bit 3 */ -#define MATCH_EN_2_4 0x100000 /* Pattern Match Enable Byte 2 Bit 4 */ -#define MATCH_EN_2_5 0x200000 /* Pattern Match Enable Byte 2 Bit 5 */ -#define MATCH_EN_2_6 0x400000 /* Pattern Match Enable Byte 2 Bit 6 */ -#define MATCH_EN_2_7 0x800000 /* Pattern Match Enable Byte 2 Bit 7 */ -#define MATCH_EN_3_0 0x1000000 /* Pattern Match Enable Byte 3 Bit 0 */ -#define MATCH_EN_3_1 0x2000000 /* Pattern Match Enable Byte 3 Bit 1 */ -#define MATCH_EN_3_2 0x4000000 /* Pattern Match Enable Byte 3 Bit 2 */ -#define MATCH_EN_3_3 0x8000000 /* Pattern Match Enable Byte 3 Bit 3 */ -#define MATCH_EN_3_4 0x10000000 /* Pattern Match Enable Byte 3 Bit 4 */ -#define MATCH_EN_3_5 0x20000000 /* Pattern Match Enable Byte 3 Bit 5 */ -#define MATCH_EN_3_6 0x40000000 /* Pattern Match Enable Byte 3 Bit 6 */ -#define MATCH_EN_3_7 0x80000000 /* Pattern Match Enable Byte 3 Bit 7 */ - -/* Bit masks for MXVR_PAT_EN_1 */ - -#define MATCH_EN_0_0 0x1 /* Pattern Match Enable Byte 0 Bit 0 */ -#define MATCH_EN_0_1 0x2 /* Pattern Match Enable Byte 0 Bit 1 */ -#define MATCH_EN_0_2 0x4 /* Pattern Match Enable Byte 0 Bit 2 */ -#define MATCH_EN_0_3 0x8 /* Pattern Match Enable Byte 0 Bit 3 */ -#define MATCH_EN_0_4 0x10 /* Pattern Match Enable Byte 0 Bit 4 */ -#define MATCH_EN_0_5 0x20 /* Pattern Match Enable Byte 0 Bit 5 */ -#define MATCH_EN_0_6 0x40 /* Pattern Match Enable Byte 0 Bit 6 */ -#define MATCH_EN_0_7 0x80 /* Pattern Match Enable Byte 0 Bit 7 */ -#define MATCH_EN_1_0 0x100 /* Pattern Match Enable Byte 1 Bit 0 */ -#define MATCH_EN_1_1 0x200 /* Pattern Match Enable Byte 1 Bit 1 */ -#define MATCH_EN_1_2 0x400 /* Pattern Match Enable Byte 1 Bit 2 */ -#define MATCH_EN_1_3 0x800 /* Pattern Match Enable Byte 1 Bit 3 */ -#define MATCH_EN_1_4 0x1000 /* Pattern Match Enable Byte 1 Bit 4 */ -#define MATCH_EN_1_5 0x2000 /* Pattern Match Enable Byte 1 Bit 5 */ -#define MATCH_EN_1_6 0x4000 /* Pattern Match Enable Byte 1 Bit 6 */ -#define MATCH_EN_1_7 0x8000 /* Pattern Match Enable Byte 1 Bit 7 */ -#define MATCH_EN_2_0 0x10000 /* Pattern Match Enable Byte 2 Bit 0 */ -#define MATCH_EN_2_1 0x20000 /* Pattern Match Enable Byte 2 Bit 1 */ -#define MATCH_EN_2_2 0x40000 /* Pattern Match Enable Byte 2 Bit 2 */ -#define MATCH_EN_2_3 0x80000 /* Pattern Match Enable Byte 2 Bit 3 */ -#define MATCH_EN_2_4 0x100000 /* Pattern Match Enable Byte 2 Bit 4 */ -#define MATCH_EN_2_5 0x200000 /* Pattern Match Enable Byte 2 Bit 5 */ -#define MATCH_EN_2_6 0x400000 /* Pattern Match Enable Byte 2 Bit 6 */ -#define MATCH_EN_2_7 0x800000 /* Pattern Match Enable Byte 2 Bit 7 */ -#define MATCH_EN_3_0 0x1000000 /* Pattern Match Enable Byte 3 Bit 0 */ -#define MATCH_EN_3_1 0x2000000 /* Pattern Match Enable Byte 3 Bit 1 */ -#define MATCH_EN_3_2 0x4000000 /* Pattern Match Enable Byte 3 Bit 2 */ -#define MATCH_EN_3_3 0x8000000 /* Pattern Match Enable Byte 3 Bit 3 */ -#define MATCH_EN_3_4 0x10000000 /* Pattern Match Enable Byte 3 Bit 4 */ -#define MATCH_EN_3_5 0x20000000 /* Pattern Match Enable Byte 3 Bit 5 */ -#define MATCH_EN_3_6 0x40000000 /* Pattern Match Enable Byte 3 Bit 6 */ -#define MATCH_EN_3_7 0x80000000 /* Pattern Match Enable Byte 3 Bit 7 */ - -/* Bit masks for MXVR_FRAME_CNT_0 */ - -#define FCNT 0xffff /* Frame Count */ - -/* Bit masks for MXVR_FRAME_CNT_1 */ - -#define FCNT 0xffff /* Frame Count */ - -/* Bit masks for MXVR_ROUTING_0 */ - -#define TX_CH0 0x3f /* Transmit Channel 0 */ -#define MUTE_CH0 0x80 /* Mute Channel 0 */ -#define TX_CH1 0x3f00 /* Transmit Channel 0 */ -#define MUTE_CH1 0x8000 /* Mute Channel 0 */ -#define TX_CH2 0x3f0000 /* Transmit Channel 0 */ -#define MUTE_CH2 0x800000 /* Mute Channel 0 */ -#define TX_CH3 0x3f000000 /* Transmit Channel 0 */ -#define MUTE_CH3 0x80000000 /* Mute Channel 0 */ - -/* Bit masks for MXVR_ROUTING_1 */ - -#define TX_CH4 0x3f /* Transmit Channel 4 */ -#define MUTE_CH4 0x80 /* Mute Channel 4 */ -#define TX_CH5 0x3f00 /* Transmit Channel 5 */ -#define MUTE_CH5 0x8000 /* Mute Channel 5 */ -#define TX_CH6 0x3f0000 /* Transmit Channel 6 */ -#define MUTE_CH6 0x800000 /* Mute Channel 6 */ -#define TX_CH7 0x3f000000 /* Transmit Channel 7 */ -#define MUTE_CH7 0x80000000 /* Mute Channel 7 */ - -/* Bit masks for MXVR_ROUTING_2 */ - -#define TX_CH8 0x3f /* Transmit Channel 8 */ -#define MUTE_CH8 0x80 /* Mute Channel 8 */ -#define TX_CH9 0x3f00 /* Transmit Channel 9 */ -#define MUTE_CH9 0x8000 /* Mute Channel 9 */ -#define TX_CH10 0x3f0000 /* Transmit Channel 10 */ -#define MUTE_CH10 0x800000 /* Mute Channel 10 */ -#define TX_CH11 0x3f000000 /* Transmit Channel 11 */ -#define MUTE_CH11 0x80000000 /* Mute Channel 11 */ - -/* Bit masks for MXVR_ROUTING_3 */ - -#define TX_CH12 0x3f /* Transmit Channel 12 */ -#define MUTE_CH12 0x80 /* Mute Channel 12 */ -#define TX_CH13 0x3f00 /* Transmit Channel 13 */ -#define MUTE_CH13 0x8000 /* Mute Channel 13 */ -#define TX_CH14 0x3f0000 /* Transmit Channel 14 */ -#define MUTE_CH14 0x800000 /* Mute Channel 14 */ -#define TX_CH15 0x3f000000 /* Transmit Channel 15 */ -#define MUTE_CH15 0x80000000 /* Mute Channel 15 */ - -/* Bit masks for MXVR_ROUTING_4 */ - -#define TX_CH16 0x3f /* Transmit Channel 16 */ -#define MUTE_CH16 0x80 /* Mute Channel 16 */ -#define TX_CH17 0x3f00 /* Transmit Channel 17 */ -#define MUTE_CH17 0x8000 /* Mute Channel 17 */ -#define TX_CH18 0x3f0000 /* Transmit Channel 18 */ -#define MUTE_CH18 0x800000 /* Mute Channel 18 */ -#define TX_CH19 0x3f000000 /* Transmit Channel 19 */ -#define MUTE_CH19 0x80000000 /* Mute Channel 19 */ - -/* Bit masks for MXVR_ROUTING_5 */ - -#define TX_CH20 0x3f /* Transmit Channel 20 */ -#define MUTE_CH20 0x80 /* Mute Channel 20 */ -#define TX_CH21 0x3f00 /* Transmit Channel 21 */ -#define MUTE_CH21 0x8000 /* Mute Channel 21 */ -#define TX_CH22 0x3f0000 /* Transmit Channel 22 */ -#define MUTE_CH22 0x800000 /* Mute Channel 22 */ -#define TX_CH23 0x3f000000 /* Transmit Channel 23 */ -#define MUTE_CH23 0x80000000 /* Mute Channel 23 */ - -/* Bit masks for MXVR_ROUTING_6 */ - -#define TX_CH24 0x3f /* Transmit Channel 24 */ -#define MUTE_CH24 0x80 /* Mute Channel 24 */ -#define TX_CH25 0x3f00 /* Transmit Channel 25 */ -#define MUTE_CH25 0x8000 /* Mute Channel 25 */ -#define TX_CH26 0x3f0000 /* Transmit Channel 26 */ -#define MUTE_CH26 0x800000 /* Mute Channel 26 */ -#define TX_CH27 0x3f000000 /* Transmit Channel 27 */ -#define MUTE_CH27 0x80000000 /* Mute Channel 27 */ - -/* Bit masks for MXVR_ROUTING_7 */ - -#define TX_CH28 0x3f /* Transmit Channel 28 */ -#define MUTE_CH28 0x80 /* Mute Channel 28 */ -#define TX_CH29 0x3f00 /* Transmit Channel 29 */ -#define MUTE_CH29 0x8000 /* Mute Channel 29 */ -#define TX_CH30 0x3f0000 /* Transmit Channel 30 */ -#define MUTE_CH30 0x800000 /* Mute Channel 30 */ -#define TX_CH31 0x3f000000 /* Transmit Channel 31 */ -#define MUTE_CH31 0x80000000 /* Mute Channel 31 */ - -/* Bit masks for MXVR_ROUTING_8 */ - -#define TX_CH32 0x3f /* Transmit Channel 32 */ -#define MUTE_CH32 0x80 /* Mute Channel 32 */ -#define TX_CH33 0x3f00 /* Transmit Channel 33 */ -#define MUTE_CH33 0x8000 /* Mute Channel 33 */ -#define TX_CH34 0x3f0000 /* Transmit Channel 34 */ -#define MUTE_CH34 0x800000 /* Mute Channel 34 */ -#define TX_CH35 0x3f000000 /* Transmit Channel 35 */ -#define MUTE_CH35 0x80000000 /* Mute Channel 35 */ - -/* Bit masks for MXVR_ROUTING_9 */ - -#define TX_CH36 0x3f /* Transmit Channel 36 */ -#define MUTE_CH36 0x80 /* Mute Channel 36 */ -#define TX_CH37 0x3f00 /* Transmit Channel 37 */ -#define MUTE_CH37 0x8000 /* Mute Channel 37 */ -#define TX_CH38 0x3f0000 /* Transmit Channel 38 */ -#define MUTE_CH38 0x800000 /* Mute Channel 38 */ -#define TX_CH39 0x3f000000 /* Transmit Channel 39 */ -#define MUTE_CH39 0x80000000 /* Mute Channel 39 */ - -/* Bit masks for MXVR_ROUTING_10 */ - -#define TX_CH40 0x3f /* Transmit Channel 40 */ -#define MUTE_CH40 0x80 /* Mute Channel 40 */ -#define TX_CH41 0x3f00 /* Transmit Channel 41 */ -#define MUTE_CH41 0x8000 /* Mute Channel 41 */ -#define TX_CH42 0x3f0000 /* Transmit Channel 42 */ -#define MUTE_CH42 0x800000 /* Mute Channel 42 */ -#define TX_CH43 0x3f000000 /* Transmit Channel 43 */ -#define MUTE_CH43 0x80000000 /* Mute Channel 43 */ - -/* Bit masks for MXVR_ROUTING_11 */ - -#define TX_CH44 0x3f /* Transmit Channel 44 */ -#define MUTE_CH44 0x80 /* Mute Channel 44 */ -#define TX_CH45 0x3f00 /* Transmit Channel 45 */ -#define MUTE_CH45 0x8000 /* Mute Channel 45 */ -#define TX_CH46 0x3f0000 /* Transmit Channel 46 */ -#define MUTE_CH46 0x800000 /* Mute Channel 46 */ -#define TX_CH47 0x3f000000 /* Transmit Channel 47 */ -#define MUTE_CH47 0x80000000 /* Mute Channel 47 */ - -/* Bit masks for MXVR_ROUTING_12 */ - -#define TX_CH48 0x3f /* Transmit Channel 48 */ -#define MUTE_CH48 0x80 /* Mute Channel 48 */ -#define TX_CH49 0x3f00 /* Transmit Channel 49 */ -#define MUTE_CH49 0x8000 /* Mute Channel 49 */ -#define TX_CH50 0x3f0000 /* Transmit Channel 50 */ -#define MUTE_CH50 0x800000 /* Mute Channel 50 */ -#define TX_CH51 0x3f000000 /* Transmit Channel 51 */ -#define MUTE_CH51 0x80000000 /* Mute Channel 51 */ - -/* Bit masks for MXVR_ROUTING_13 */ - -#define TX_CH52 0x3f /* Transmit Channel 52 */ -#define MUTE_CH52 0x80 /* Mute Channel 52 */ -#define TX_CH53 0x3f00 /* Transmit Channel 53 */ -#define MUTE_CH53 0x8000 /* Mute Channel 53 */ -#define TX_CH54 0x3f0000 /* Transmit Channel 54 */ -#define MUTE_CH54 0x800000 /* Mute Channel 54 */ -#define TX_CH55 0x3f000000 /* Transmit Channel 55 */ -#define MUTE_CH55 0x80000000 /* Mute Channel 55 */ - -/* Bit masks for MXVR_ROUTING_14 */ - -#define TX_CH56 0x3f /* Transmit Channel 56 */ -#define MUTE_CH56 0x80 /* Mute Channel 56 */ -#define TX_CH57 0x3f00 /* Transmit Channel 57 */ -#define MUTE_CH57 0x8000 /* Mute Channel 57 */ -#define TX_CH58 0x3f0000 /* Transmit Channel 58 */ -#define MUTE_CH58 0x800000 /* Mute Channel 58 */ -#define TX_CH59 0x3f000000 /* Transmit Channel 59 */ -#define MUTE_CH59 0x80000000 /* Mute Channel 59 */ - -/* Bit masks for MXVR_BLOCK_CNT */ - -#define BCNT 0xffff /* Block Count */ - -/* Bit masks for MXVR_CLK_CTL */ - -#define MXTALCEN 0x1 /* MXVR Crystal Oscillator Clock Enable */ -#define MXTALFEN 0x2 /* MXVR Crystal Oscillator Feedback Enable */ -#define MXTALMUL 0x30 /* MXVR Crystal Multiplier */ -#define CLKX3SEL 0x80 /* Clock Generation Source Select */ -#define MMCLKEN 0x100 /* Master Clock Enable */ -#define MMCLKMUL 0x1e00 /* Master Clock Multiplication Factor */ -#define PLLSMPS 0xe000 /* MXVR PLL State Machine Prescaler */ -#define MBCLKEN 0x10000 /* Bit Clock Enable */ -#define MBCLKDIV 0x1e0000 /* Bit Clock Divide Factor */ -#define INVRX 0x800000 /* Invert Receive Data */ -#define MFSEN 0x1000000 /* Frame Sync Enable */ -#define MFSDIV 0x1e000000 /* Frame Sync Divide Factor */ -#define MFSSEL 0x60000000 /* Frame Sync Select */ -#define MFSSYNC 0x80000000 /* Frame Sync Synchronization Select */ - -/* Bit masks for MXVR_CDRPLL_CTL */ - -#define CDRSMEN 0x1 /* MXVR CDRPLL State Machine Enable */ -#define CDRRSTB 0x2 /* MXVR CDRPLL Reset */ -#define CDRSVCO 0x4 /* MXVR CDRPLL Start VCO */ -#define CDRMODE 0x8 /* MXVR CDRPLL CDR Mode Select */ -#define CDRSCNT 0x3f0 /* MXVR CDRPLL Start Counter */ -#define CDRLCNT 0xfc00 /* MXVR CDRPLL Lock Counter */ -#define CDRSHPSEL 0x3f0000 /* MXVR CDRPLL Shaper Select */ -#define CDRSHPEN 0x800000 /* MXVR CDRPLL Shaper Enable */ -#define CDRCPSEL 0xff000000 /* MXVR CDRPLL Charge Pump Current Select */ - -/* Bit masks for MXVR_FMPLL_CTL */ - -#define FMSMEN 0x1 /* MXVR FMPLL State Machine Enable */ -#define FMRSTB 0x2 /* MXVR FMPLL Reset */ -#define FMSVCO 0x4 /* MXVR FMPLL Start VCO */ -#define FMSCNT 0x3f0 /* MXVR FMPLL Start Counter */ -#define FMLCNT 0xfc00 /* MXVR FMPLL Lock Counter */ -#define FMCPSEL 0xff000000 /* MXVR FMPLL Charge Pump Current Select */ - -/* Bit masks for MXVR_PIN_CTL */ - -#define MTXONBOD 0x1 /* MTXONB Open Drain Select */ -#define MTXONBG 0x2 /* MTXONB Gates MTX Select */ -#define MFSOE 0x10 /* MFS Output Enable */ -#define MFSGPSEL 0x20 /* MFS General Purpose Output Select */ -#define MFSGPDAT 0x40 /* MFS General Purpose Output Data */ - -/* Bit masks for MXVR_SCLK_CNT */ - -#define SCNT 0xffff /* System Clock Count */ - -/* ******************************************* */ -/* MULTI BIT MACRO ENUMERATIONS */ -/* ******************************************* */ - -/* ************************ */ -/* MXVR Address Offsets */ -/* ************************ */ - -/* Control Message Receive Buffer (CMRB) Address Offsets */ - -#define CMRB_STRIDE 0x00000016lu - -#define CMRB_DST_OFFSET 0x00000000lu -#define CMRB_SRC_OFFSET 0x00000002lu -#define CMRB_DATA_OFFSET 0x00000005lu - -/* Control Message Transmit Buffer (CMTB) Address Offsets */ - -#define CMTB_PRIO_OFFSET 0x00000000lu -#define CMTB_DST_OFFSET 0x00000002lu -#define CMTB_SRC_OFFSET 0x00000004lu -#define CMTB_TYPE_OFFSET 0x00000006lu -#define CMTB_DATA_OFFSET 0x00000007lu - -#define CMTB_ANSWER_OFFSET 0x0000000Alu - -#define CMTB_STAT_N_OFFSET 0x00000018lu -#define CMTB_STAT_A_OFFSET 0x00000016lu -#define CMTB_STAT_D_OFFSET 0x0000000Elu -#define CMTB_STAT_R_OFFSET 0x00000014lu -#define CMTB_STAT_W_OFFSET 0x00000014lu -#define CMTB_STAT_G_OFFSET 0x00000014lu - -/* Asynchronous Packet Receive Buffer (APRB) Address Offsets */ - -#define APRB_STRIDE 0x00000400lu - -#define APRB_DST_OFFSET 0x00000000lu -#define APRB_LEN_OFFSET 0x00000002lu -#define APRB_SRC_OFFSET 0x00000004lu -#define APRB_DATA_OFFSET 0x00000006lu - -/* Asynchronous Packet Transmit Buffer (APTB) Address Offsets */ - -#define APTB_PRIO_OFFSET 0x00000000lu -#define APTB_DST_OFFSET 0x00000002lu -#define APTB_LEN_OFFSET 0x00000004lu -#define APTB_SRC_OFFSET 0x00000006lu -#define APTB_DATA_OFFSET 0x00000008lu - -/* Remote Read Buffer (RRDB) Address Offsets */ - -#define RRDB_WADDR_OFFSET 0x00000100lu -#define RRDB_WLEN_OFFSET 0x00000101lu - -/* **************** */ -/* MXVR Macros */ -/* **************** */ - -/* MXVR_CONFIG Macros */ - -#define SET_MSB(x) ( ( (x) & 0xF ) << 9) - -/* MXVR_INT_STAT_1 Macros */ - -#define DONEX(x) (0x00000002 << (4 * (x))) -#define HDONEX(x) (0x00000001 << (4 * (x))) - -/* MXVR_INT_EN_1 Macros */ - -#define DONEENX(x) (0x00000002 << (4 * (x))) -#define HDONEENX(x) (0x00000001 << (4 * (x))) - -/* MXVR_CDRPLL_CTL Macros */ - -#define SET_CDRSHPSEL(x) ( ( (x) & 0x3F ) << 16) - -/* MXVR_FMPLL_CTL Macros */ - -#define SET_CDRCPSEL(x) ( ( (x) & 0xFF ) << 24) -#define SET_FMCPSEL(x) ( ( (x) & 0xFF ) << 24) - #endif /* _DEF_BF549_H */ -- cgit v0.10.2 From cfed440997f2d02900022a3a97600f78b3b18e5b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 15 Oct 2009 03:57:04 +0000 Subject: Blackfin: BF54x: punt useless "masks" for count/address MMRs There's no point in having mask defines when the entire MMR value is a count or address. i.e. applying a mask of -1 is pointless. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h index f07c0f7..855bc60 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h @@ -1815,10 +1815,6 @@ #define DEB3_MERROR 0x40 /* DEB3 Error (2nd) */ #define CORE_MERROR 0x80 /* Core Error (2nd) */ -/* Bit masks for EBIU_ERRADD */ - -#define ERROR_ADDRESS 0xffffffff /* Error Address */ - /* Bit masks for EBIU_RSTCTL */ #define DDRSRESET 0x1 /* DDR soft reset */ @@ -1827,98 +1823,6 @@ #define SRACK 0x10 /* Self-refresh acknowledge */ #define MDDRENABLE 0x20 /* Mobile DDR enable */ -/* Bit masks for EBIU_DDRBRC0 */ - -#define BRC0 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRBRC1 */ - -#define BRC1 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRBRC2 */ - -#define BRC2 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRBRC3 */ - -#define BRC3 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRBRC4 */ - -#define BRC4 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRBRC5 */ - -#define BRC5 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRBRC6 */ - -#define BRC6 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRBRC7 */ - -#define BRC7 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRBWC0 */ - -#define BWC0 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRBWC1 */ - -#define BWC1 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRBWC2 */ - -#define BWC2 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRBWC3 */ - -#define BWC3 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRBWC4 */ - -#define BWC4 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRBWC5 */ - -#define BWC5 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRBWC6 */ - -#define BWC6 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRBWC7 */ - -#define BWC7 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRACCT */ - -#define ACCT 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRTACT */ - -#define TECT 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRARCT */ - -#define ARCT 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRGC0 */ - -#define GC0 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRGC1 */ - -#define GC1 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRGC2 */ - -#define GC2 0xffffffff /* Count */ - -/* Bit masks for EBIU_DDRGC3 */ - -#define GC3 0xffffffff /* Count */ - /* Bit masks for EBIU_DDRMCEN */ #define B0WCENABLE 0x1 /* Bank 0 write count enable */ @@ -2408,14 +2312,6 @@ #define UCCT 0x40 /* Universal Counter CAN Trigger */ #define UCE 0x80 /* Universal Counter Enable */ -/* Bit masks for CAN0_UCCNT */ - -#define UCCNT 0xffff /* Universal Counter Count Value */ - -/* Bit masks for CAN0_UCRC */ - -#define UCVAL 0xffff /* Universal Counter Reload/Capture Value */ - /* Bit masks for CAN0_CEC */ #define RXECNT 0xff /* Receive Error Counter */ -- cgit v0.10.2 From 2abdf791151ea57f71e67136b4aaef96f534bba6 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 15 Oct 2009 04:13:18 +0000 Subject: Blackfin: H8606/ip0x: drop redundant SPI ctl_reg settings No need to set MSTR in .ctl_reg as the Blackfin SPI bus driver does this already for all parts. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c index 26a04f0..4adceb0 100644 --- a/arch/blackfin/mach-bf533/boards/H8606.c +++ b/arch/blackfin/mach-bf533/boards/H8606.c @@ -166,7 +166,6 @@ static struct bfin5xx_spi_chip spi_flash_chip_info = { #if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE) /* SPI ADC chip */ static struct bfin5xx_spi_chip spi_adc_chip_info = { - .ctl_reg = 0x1000, .enable_dma = 1, /* use dma transfer with this chip*/ .bits_per_word = 16, }; @@ -174,7 +173,6 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = { #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { - .ctl_reg = 0x1000, .enable_dma = 0, .bits_per_word = 16, }; diff --git a/arch/blackfin/mach-bf533/boards/ip0x.c b/arch/blackfin/mach-bf533/boards/ip0x.c index 644be5e..48cfbf8 100644 --- a/arch/blackfin/mach-bf533/boards/ip0x.c +++ b/arch/blackfin/mach-bf533/boards/ip0x.c @@ -107,20 +107,6 @@ static struct platform_device dm9000_device2 = { #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) static struct bfin5xx_spi_chip mmc_spi_chip_info = { -/* - * CPOL (Clock Polarity) - * 0 - Active high SCK - * 1 - Active low SCK - * CPHA (Clock Phase) Selects transfer format and operation mode - * 0 - SCLK toggles from middle of the first data bit, slave select - * pins controlled by hardware. - * 1 - SCLK toggles from beginning of first data bit, slave select - * pins controller by user software. - * .ctl_reg = 0x1c00, * CPOL=1,CPHA=1,Sandisk 1G work - * NO NO .ctl_reg = 0x1800, * CPOL=1,CPHA=0 - * NO NO .ctl_reg = 0x1400, * CPOL=0,CPHA=1 - */ - .ctl_reg = 0x1000, /* CPOL=0,CPHA=0,Sandisk 1G work */ .enable_dma = 0, /* if 1 - block!!! */ .bits_per_word = 8, }; -- cgit v0.10.2 From 761ec44add46d4dfdcb3a0607bfecb4cfc0dc0f0 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 15 Oct 2009 17:12:05 +0000 Subject: Blackfin: pull in asm/dpmc.h for power defines Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/clocks.h b/arch/blackfin/include/asm/clocks.h index f80dad5..6f0b618 100644 --- a/arch/blackfin/include/asm/clocks.h +++ b/arch/blackfin/include/asm/clocks.h @@ -9,6 +9,8 @@ #ifndef _BFIN_CLOCKS_H #define _BFIN_CLOCKS_H +#include + #ifdef CONFIG_CCLK_DIV_1 # define CONFIG_CCLK_ACT_DIV CCLK_DIV1 # define CONFIG_CCLK_DIV 1 diff --git a/arch/blackfin/mach-common/clocks-init.c b/arch/blackfin/mach-common/clocks-init.c index ef6870e..d5cfe61 100644 --- a/arch/blackfin/mach-common/clocks-init.c +++ b/arch/blackfin/mach-common/clocks-init.c @@ -13,6 +13,7 @@ #include #include #include +#include #define SDGCTL_WIDTH (1 << 31) /* SDRAM external data path width */ #define PLL_CTL_VAL \ diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c index 3d18d2b..7775828 100644 --- a/arch/blackfin/mach-common/cpufreq.c +++ b/arch/blackfin/mach-common/cpufreq.c @@ -13,7 +13,7 @@ #include #include #include - +#include /* this is the table of CCLK frequencies, in Hz */ /* .index is the entry in the auxillary dpm_state_table[] */ diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 660ea1b..0d84fb2 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -25,6 +25,7 @@ #include #include #include +#include #define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) -- cgit v0.10.2 From a8e8e491686bb34eb5aea37f58c9020f48629237 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 15 Oct 2009 06:47:28 +0000 Subject: Blackfin: unify duplicated power masks Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/dpmc.h b/arch/blackfin/include/asm/dpmc.h index 925e66c..1597ae5 100644 --- a/arch/blackfin/include/asm/dpmc.h +++ b/arch/blackfin/include/asm/dpmc.h @@ -1,7 +1,7 @@ /* * Miscellaneous IOCTL commands for Dynamic Power Management Controller Driver * - * Copyright (C) 2004-2008 Analog Device Inc. + * Copyright (C) 2004-2009 Analog Device Inc. * * Licensed under the GPL-2 */ @@ -9,7 +9,109 @@ #ifndef _BLACKFIN_DPMC_H_ #define _BLACKFIN_DPMC_H_ -#ifdef __KERNEL__ +/* PLL_CTL Masks */ +#define DF 0x0001 /* 0: PLL = CLKIN, 1: PLL = CLKIN/2 */ +#define PLL_OFF 0x0002 /* PLL Not Powered */ +#define STOPCK 0x0008 /* Core Clock Off */ +#define PDWN 0x0020 /* Enter Deep Sleep Mode */ +#ifdef __ADSPBF539__ +# define IN_DELAY 0x0014 /* Add 200ps Delay To EBIU Input Latches */ +# define OUT_DELAY 0x00C0 /* Add 200ps Delay To EBIU Output Signals */ +#else +# define IN_DELAY 0x0040 /* Add 200ps Delay To EBIU Input Latches */ +# define OUT_DELAY 0x0080 /* Add 200ps Delay To EBIU Output Signals */ +#endif +#define BYPASS 0x0100 /* Bypass the PLL */ +#define MSEL 0x7E00 /* Multiplier Select For CCLK/VCO Factors */ +#define SPORT_HYST 0x8000 /* Enable Additional Hysteresis on SPORT Input Pins */ +#define SET_MSEL(x) (((x)&0x3F) << 0x9) /* Set MSEL = 0-63 --> VCO = CLKIN*MSEL */ + +/* PLL_DIV Masks */ +#define SSEL 0x000F /* System Select */ +#define CSEL 0x0030 /* Core Select */ +#define CSEL_DIV1 0x0000 /* CCLK = VCO / 1 */ +#define CSEL_DIV2 0x0010 /* CCLK = VCO / 2 */ +#define CSEL_DIV4 0x0020 /* CCLK = VCO / 4 */ +#define CSEL_DIV8 0x0030 /* CCLK = VCO / 8 */ + +#define CCLK_DIV1 CSEL_DIV1 +#define CCLK_DIV2 CSEL_DIV2 +#define CCLK_DIV4 CSEL_DIV4 +#define CCLK_DIV8 CSEL_DIV8 + +#define SET_SSEL(x) ((x) & 0xF) /* Set SSEL = 0-15 --> SCLK = VCO/SSEL */ +#define SCLK_DIV(x) (x) /* SCLK = VCO / x */ + +/* PLL_STAT Masks */ +#define ACTIVE_PLLENABLED 0x0001 /* Processor In Active Mode With PLL Enabled */ +#define FULL_ON 0x0002 /* Processor In Full On Mode */ +#define ACTIVE_PLLDISABLED 0x0004 /* Processor In Active Mode With PLL Disabled */ +#define PLL_LOCKED 0x0020 /* PLL_LOCKCNT Has Been Reached */ + +#define RTCWS 0x0400 /* RTC/Reset Wake-Up Status */ +#define CANWS 0x0800 /* CAN Wake-Up Status */ +#define USBWS 0x2000 /* USB Wake-Up Status */ +#define KPADWS 0x4000 /* Keypad Wake-Up Status */ +#define ROTWS 0x8000 /* Rotary Wake-Up Status */ +#define GPWS 0x1000 /* General-Purpose Wake-Up Status */ + +/* VR_CTL Masks */ +#if defined(__ADSPBF52x__) || defined(__ADSPBF51x__) +#define FREQ 0x3000 /* Switching Oscillator Frequency For Regulator */ +#define FREQ_1000 0x3000 /* Switching Frequency Is 1 MHz */ +#else +#define FREQ 0x0003 /* Switching Oscillator Frequency For Regulator */ +#define FREQ_333 0x0001 /* Switching Frequency Is 333 kHz */ +#define FREQ_667 0x0002 /* Switching Frequency Is 667 kHz */ +#define FREQ_1000 0x0003 /* Switching Frequency Is 1 MHz */ +#endif +#define HIBERNATE 0x0000 /* Powerdown/Bypass On-Board Regulation */ + +#define GAIN 0x000C /* Voltage Level Gain */ +#define GAIN_5 0x0000 /* GAIN = 5 */ +#define GAIN_10 0x0004 /* GAIN = 1 */ +#define GAIN_20 0x0008 /* GAIN = 2 */ +#define GAIN_50 0x000C /* GAIN = 5 */ + +#define VLEV 0x00F0 /* Internal Voltage Level */ +#ifdef __ADSPBF52x__ +#define VLEV_085 0x0040 /* VLEV = 0.85 V (-5% - +10% Accuracy) */ +#define VLEV_090 0x0050 /* VLEV = 0.90 V (-5% - +10% Accuracy) */ +#define VLEV_095 0x0060 /* VLEV = 0.95 V (-5% - +10% Accuracy) */ +#define VLEV_100 0x0070 /* VLEV = 1.00 V (-5% - +10% Accuracy) */ +#define VLEV_105 0x0080 /* VLEV = 1.05 V (-5% - +10% Accuracy) */ +#define VLEV_110 0x0090 /* VLEV = 1.10 V (-5% - +10% Accuracy) */ +#define VLEV_115 0x00A0 /* VLEV = 1.15 V (-5% - +10% Accuracy) */ +#define VLEV_120 0x00B0 /* VLEV = 1.20 V (-5% - +10% Accuracy) */ +#else +#define VLEV_085 0x0060 /* VLEV = 0.85 V (-5% - +10% Accuracy) */ +#define VLEV_090 0x0070 /* VLEV = 0.90 V (-5% - +10% Accuracy) */ +#define VLEV_095 0x0080 /* VLEV = 0.95 V (-5% - +10% Accuracy) */ +#define VLEV_100 0x0090 /* VLEV = 1.00 V (-5% - +10% Accuracy) */ +#define VLEV_105 0x00A0 /* VLEV = 1.05 V (-5% - +10% Accuracy) */ +#define VLEV_110 0x00B0 /* VLEV = 1.10 V (-5% - +10% Accuracy) */ +#define VLEV_115 0x00C0 /* VLEV = 1.15 V (-5% - +10% Accuracy) */ +#define VLEV_120 0x00D0 /* VLEV = 1.20 V (-5% - +10% Accuracy) */ +#define VLEV_125 0x00E0 /* VLEV = 1.25 V (-5% - +10% Accuracy) */ +#define VLEV_130 0x00F0 /* VLEV = 1.30 V (-5% - +10% Accuracy) */ +#endif + +#define WAKE 0x0100 /* Enable RTC/Reset Wakeup From Hibernate */ +#define CANWE 0x0200 /* Enable CAN Wakeup From Hibernate */ +#define PHYWE 0x0400 /* Enable PHY Wakeup From Hibernate */ +#define GPWE 0x0400 /* General-Purpose Wake-Up Enable */ +#define MXVRWE 0x0400 /* Enable MXVR Wakeup From Hibernate */ +#define KPADWE 0x1000 /* Keypad Wake-Up Enable */ +#define ROTWE 0x2000 /* Rotary Wake-Up Enable */ +#define CLKBUFOE 0x4000 /* CLKIN Buffer Output Enable */ +#define SCKELOW 0x8000 /* Do Not Drive SCKE High During Reset After Hibernate */ + +#if defined(__ADSPBF52x__) || defined(__ADSPBF51x__) +#define USBWE 0x0200 /* Enable USB Wakeup From Hibernate */ +#else +#define USBWE 0x0800 /* Enable USB Wakeup From Hibernate */ +#endif + #ifndef __ASSEMBLY__ void sleep_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2); @@ -54,6 +156,5 @@ struct bfin_dpmc_platform_data { w[P0 + (x - PLL_CTL)] = R0;\ #endif -#endif /* __KERNEL__ */ #endif /*_BLACKFIN_DPMC_H_*/ diff --git a/arch/blackfin/mach-bf518/include/mach/blackfin.h b/arch/blackfin/mach-bf518/include/mach/blackfin.h index 6cfb246..9053462 100644 --- a/arch/blackfin/mach-bf518/include/mach/blackfin.h +++ b/arch/blackfin/mach-bf518/include/mach/blackfin.h @@ -58,10 +58,4 @@ #define OFFSET_SCR 0x1C /* SCR Scratch Register */ #define OFFSET_GCTL 0x24 /* Global Control Register */ -/* PLL_DIV Masks */ -#define CCLK_DIV1 CSEL_DIV1 /* CCLK = VCO / 1 */ -#define CCLK_DIV2 CSEL_DIV2 /* CCLK = VCO / 2 */ -#define CCLK_DIV4 CSEL_DIV4 /* CCLK = VCO / 4 */ -#define CCLK_DIV8 CSEL_DIV8 /* CCLK = VCO / 8 */ - #endif diff --git a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h index 78253e8..a97a2bb 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h @@ -585,58 +585,6 @@ ** modifier UNLESS the lower order bits are saved and ORed back in when ** the macro is used. *************************************************************************************/ -/* -** ********************* PLL AND RESET MASKS ****************************************/ -/* PLL_CTL Masks */ -#define DF 0x0001 /* 0: PLL = CLKIN, 1: PLL = CLKIN/2 */ -#define PLL_OFF 0x0002 /* PLL Not Powered */ -#define STOPCK 0x0008 /* Core Clock Off */ -#define PDWN 0x0020 /* Enter Deep Sleep Mode */ -#define IN_DELAY 0x0040 /* Add 200ps Delay To EBIU Input Latches */ -#define OUT_DELAY 0x0080 /* Add 200ps Delay To EBIU Output Signals */ -#define BYPASS 0x0100 /* Bypass the PLL */ -#define MSEL 0x7E00 /* Multiplier Select For CCLK/VCO Factors */ -/* PLL_CTL Macros (Only Use With Logic OR While Setting Lower Order Bits) */ -#define SET_MSEL(x) (((x)&0x3F) << 0x9) /* Set MSEL = 0-63 --> VCO = CLKIN*MSEL */ - -/* PLL_DIV Masks */ -#define SSEL 0x000F /* System Select */ -#define CSEL 0x0030 /* Core Select */ -#define CSEL_DIV1 0x0000 /* CCLK = VCO / 1 */ -#define CSEL_DIV2 0x0010 /* CCLK = VCO / 2 */ -#define CSEL_DIV4 0x0020 /* CCLK = VCO / 4 */ -#define CSEL_DIV8 0x0030 /* CCLK = VCO / 8 */ -/* PLL_DIV Macros */ -#define SET_SSEL(x) ((x)&0xF) /* Set SSEL = 0-15 --> SCLK = VCO/SSEL */ - -/* VR_CTL Masks */ -#define FREQ 0x3000 /* Switching Oscillator Frequency For Regulator */ -#define HIBERNATE 0x0000 /* Powerdown/Bypass On-Board Regulation */ - -#define VLEV 0x00F0 /* Internal Voltage Level */ -#define VLEV_085 0x0060 /* VLEV = 0.85 V (-5% - +10% Accuracy) */ -#define VLEV_090 0x0070 /* VLEV = 0.90 V (-5% - +10% Accuracy) */ -#define VLEV_095 0x0080 /* VLEV = 0.95 V (-5% - +10% Accuracy) */ -#define VLEV_100 0x0090 /* VLEV = 1.00 V (-5% - +10% Accuracy) */ -#define VLEV_105 0x00A0 /* VLEV = 1.05 V (-5% - +10% Accuracy) */ -#define VLEV_110 0x00B0 /* VLEV = 1.10 V (-5% - +10% Accuracy) */ -#define VLEV_115 0x00C0 /* VLEV = 1.15 V (-5% - +10% Accuracy) */ -#define VLEV_120 0x00D0 /* VLEV = 1.20 V (-5% - +10% Accuracy) */ -#define VLEV_125 0x00E0 /* VLEV = 1.25 V (-5% - +10% Accuracy) */ -#define VLEV_130 0x00F0 /* VLEV = 1.30 V (-5% - +10% Accuracy) */ - -#define WAKE 0x0100 /* Enable RTC/Reset Wakeup From Hibernate */ -#define USBWE 0x0200 /* Enable USB Wakeup From Hibernate */ -#define PHYWE 0x0400 /* Enable PHY Wakeup From Hibernate */ -#define CLKBUFOE 0x4000 /* CLKIN Buffer Output Enable */ -#define PHYCLKOE CLKBUFOE /* Alternative legacy name for the above */ -#define SCKELOW 0x8000 /* Enable Drive CKE Low During Reset */ - -/* PLL_STAT Masks */ -#define ACTIVE_PLLENABLED 0x0001 /* Processor In Active Mode With PLL Enabled */ -#define FULL_ON 0x0002 /* Processor In Full On Mode */ -#define ACTIVE_PLLDISABLED 0x0004 /* Processor In Active Mode With PLL Disabled */ -#define PLL_LOCKED 0x0020 /* PLL_LOCKCNT Has Been Reached */ /* CHIPID Masks */ #define CHIPID_VERSION 0xF0000000 diff --git a/arch/blackfin/mach-bf527/include/mach/blackfin.h b/arch/blackfin/mach-bf527/include/mach/blackfin.h index e7d6034..f714c5d 100644 --- a/arch/blackfin/mach-bf527/include/mach/blackfin.h +++ b/arch/blackfin/mach-bf527/include/mach/blackfin.h @@ -46,10 +46,4 @@ #define OFFSET_SCR 0x1C /* SCR Scratch Register */ #define OFFSET_GCTL 0x24 /* Global Control Register */ -/* PLL_DIV Masks */ -#define CCLK_DIV1 CSEL_DIV1 /* CCLK = VCO / 1 */ -#define CCLK_DIV2 CSEL_DIV2 /* CCLK = VCO / 2 */ -#define CCLK_DIV4 CSEL_DIV4 /* CCLK = VCO / 4 */ -#define CCLK_DIV8 CSEL_DIV8 /* CCLK = VCO / 8 */ - #endif diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h index 6e6a8df..da42e9c 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h @@ -586,58 +586,6 @@ ** modifier UNLESS the lower order bits are saved and ORed back in when ** the macro is used. *************************************************************************************/ -/* -** ********************* PLL AND RESET MASKS ****************************************/ -/* PLL_CTL Masks */ -#define DF 0x0001 /* 0: PLL = CLKIN, 1: PLL = CLKIN/2 */ -#define PLL_OFF 0x0002 /* PLL Not Powered */ -#define STOPCK 0x0008 /* Core Clock Off */ -#define PDWN 0x0020 /* Enter Deep Sleep Mode */ -#define IN_DELAY 0x0040 /* Add 200ps Delay To EBIU Input Latches */ -#define OUT_DELAY 0x0080 /* Add 200ps Delay To EBIU Output Signals */ -#define BYPASS 0x0100 /* Bypass the PLL */ -#define MSEL 0x7E00 /* Multiplier Select For CCLK/VCO Factors */ -/* PLL_CTL Macros (Only Use With Logic OR While Setting Lower Order Bits) */ -#define SET_MSEL(x) (((x)&0x3F) << 0x9) /* Set MSEL = 0-63 --> VCO = CLKIN*MSEL */ - -/* PLL_DIV Masks */ -#define SSEL 0x000F /* System Select */ -#define CSEL 0x0030 /* Core Select */ -#define CSEL_DIV1 0x0000 /* CCLK = VCO / 1 */ -#define CSEL_DIV2 0x0010 /* CCLK = VCO / 2 */ -#define CSEL_DIV4 0x0020 /* CCLK = VCO / 4 */ -#define CSEL_DIV8 0x0030 /* CCLK = VCO / 8 */ -/* PLL_DIV Macros */ -#define SET_SSEL(x) ((x)&0xF) /* Set SSEL = 0-15 --> SCLK = VCO/SSEL */ - -/* VR_CTL Masks */ -#define FREQ 0x3000 /* Switching Oscillator Frequency For Regulator */ -#define HIBERNATE 0x0000 /* Powerdown/Bypass On-Board Regulation */ - -#define VLEV 0x00F0 /* Internal Voltage Level */ -#define VLEV_085 0x0060 /* VLEV = 0.85 V (-5% - +10% Accuracy) */ -#define VLEV_090 0x0070 /* VLEV = 0.90 V (-5% - +10% Accuracy) */ -#define VLEV_095 0x0080 /* VLEV = 0.95 V (-5% - +10% Accuracy) */ -#define VLEV_100 0x0090 /* VLEV = 1.00 V (-5% - +10% Accuracy) */ -#define VLEV_105 0x00A0 /* VLEV = 1.05 V (-5% - +10% Accuracy) */ -#define VLEV_110 0x00B0 /* VLEV = 1.10 V (-5% - +10% Accuracy) */ -#define VLEV_115 0x00C0 /* VLEV = 1.15 V (-5% - +10% Accuracy) */ -#define VLEV_120 0x00D0 /* VLEV = 1.20 V (-5% - +10% Accuracy) */ -#define VLEV_125 0x00E0 /* VLEV = 1.25 V (-5% - +10% Accuracy) */ -#define VLEV_130 0x00F0 /* VLEV = 1.30 V (-5% - +10% Accuracy) */ - -#define WAKE 0x0100 /* Enable RTC/Reset Wakeup From Hibernate */ -#define USBWE 0x0200 /* Enable USB Wakeup From Hibernate */ -#define PHYWE 0x0400 /* Enable PHY Wakeup From Hibernate */ -#define CLKBUFOE 0x4000 /* CLKIN Buffer Output Enable */ -#define PHYCLKOE CLKBUFOE /* Alternative legacy name for the above */ -#define SCKELOW 0x8000 /* Enable Drive CKE Low During Reset */ - -/* PLL_STAT Masks */ -#define ACTIVE_PLLENABLED 0x0001 /* Processor In Active Mode With PLL Enabled */ -#define FULL_ON 0x0002 /* Processor In Full On Mode */ -#define ACTIVE_PLLDISABLED 0x0004 /* Processor In Active Mode With PLL Disabled */ -#define PLL_LOCKED 0x0020 /* PLL_LOCKCNT Has Been Reached */ /* CHIPID Masks */ #define CHIPID_VERSION 0xF0000000 diff --git a/arch/blackfin/mach-bf533/include/mach/defBF532.h b/arch/blackfin/mach-bf533/include/mach/defBF532.h index 02b328e..7e61fe7 100644 --- a/arch/blackfin/mach-bf533/include/mach/defBF532.h +++ b/arch/blackfin/mach-bf533/include/mach/defBF532.h @@ -370,72 +370,6 @@ /* System MMR Register Bits */ /******************************************************************************* */ -/* ********************* PLL AND RESET MASKS ************************ */ - -/* PLL_CTL Masks */ -#define PLL_CLKIN 0x0000 /* Pass CLKIN to PLL */ -#define PLL_CLKIN_DIV2 0x0001 /* Pass CLKIN/2 to PLL */ -#define DF 0x0001 /* 0: PLL = CLKIN, 1: PLL = CLKIN/2 */ -#define PLL_OFF 0x0002 /* Shut off PLL clocks */ -#define STOPCK_OFF 0x0008 /* Core clock off */ -#define STOPCK 0x0008 /* Core Clock Off */ -#define PDWN 0x0020 /* Put the PLL in a Deep Sleep state */ -#if !defined(__ADSPBF538__) -/* this file is included in defBF538.h but IN_DELAY/OUT_DELAY are different */ -# define IN_DELAY 0x0040 /* Add 200ps Delay To EBIU Input Latches */ -# define OUT_DELAY 0x0080 /* Add 200ps Delay To EBIU Output Signals */ -#endif -#define BYPASS 0x0100 /* Bypass the PLL */ -/* PLL_CTL Macros (Only Use With Logic OR While Setting Lower Order Bits) */ -#define SET_MSEL(x) (((x)&0x3F) << 0x9) /* Set MSEL = 0-63 --> VCO = CLKIN*MSEL */ - -/* PLL_DIV Masks */ -#define SSEL 0x000F /* System Select */ -#define CSEL 0x0030 /* Core Select */ - -#define SCLK_DIV(x) (x) /* SCLK = VCO / x */ - -#define CCLK_DIV1 0x00000000 /* CCLK = VCO / 1 */ -#define CCLK_DIV2 0x00000010 /* CCLK = VCO / 2 */ -#define CCLK_DIV4 0x00000020 /* CCLK = VCO / 4 */ -#define CCLK_DIV8 0x00000030 /* CCLK = VCO / 8 */ -/* PLL_DIV Macros */ -#define SET_SSEL(x) ((x)&0xF) /* Set SSEL = 0-15 --> SCLK = VCO/SSEL */ - -/* PLL_STAT Masks */ -#define ACTIVE_PLLENABLED 0x0001 /* Processor In Active Mode With PLL Enabled */ -#define FULL_ON 0x0002 /* Processor In Full On Mode */ -#define ACTIVE_PLLDISABLED 0x0004 /* Processor In Active Mode With PLL Disabled */ -#define PLL_LOCKED 0x0020 /* PLL_LOCKCNT Has Been Reached */ - -/* VR_CTL Masks */ -#define FREQ 0x0003 /* Switching Oscillator Frequency For Regulator */ -#define HIBERNATE 0x0000 /* Powerdown/Bypass On-Board Regulation */ -#define FREQ_333 0x0001 /* Switching Frequency Is 333 kHz */ -#define FREQ_667 0x0002 /* Switching Frequency Is 667 kHz */ -#define FREQ_1000 0x0003 /* Switching Frequency Is 1 MHz */ - -#define GAIN 0x000C /* Voltage Level Gain */ -#define GAIN_5 0x0000 /* GAIN = 5 */ -#define GAIN_10 0x0004 /* GAIN = 10 */ -#define GAIN_20 0x0008 /* GAIN = 20 */ -#define GAIN_50 0x000C /* GAIN = 50 */ - -#define VLEV 0x00F0 /* Internal Voltage Level */ -#define VLEV_085 0x0060 /* VLEV = 0.85 V (-5% - +10% Accuracy) */ -#define VLEV_090 0x0070 /* VLEV = 0.90 V (-5% - +10% Accuracy) */ -#define VLEV_095 0x0080 /* VLEV = 0.95 V (-5% - +10% Accuracy) */ -#define VLEV_100 0x0090 /* VLEV = 1.00 V (-5% - +10% Accuracy) */ -#define VLEV_105 0x00A0 /* VLEV = 1.05 V (-5% - +10% Accuracy) */ -#define VLEV_110 0x00B0 /* VLEV = 1.10 V (-5% - +10% Accuracy) */ -#define VLEV_115 0x00C0 /* VLEV = 1.15 V (-5% - +10% Accuracy) */ -#define VLEV_120 0x00D0 /* VLEV = 1.20 V (-5% - +10% Accuracy) */ -#define VLEV_125 0x00E0 /* VLEV = 1.25 V (-5% - +10% Accuracy) */ -#define VLEV_130 0x00F0 /* VLEV = 1.30 V (-5% - +10% Accuracy) */ - -#define WAKE 0x0100 /* Enable RTC/Reset Wakeup From Hibernate */ -#define SCKELOW 0x8000 /* Do Not Drive SCKE High During Reset After Hibernate */ - /* CHIPID Masks */ #define CHIPID_VERSION 0xF0000000 #define CHIPID_FAMILY 0x0FFFF000 diff --git a/arch/blackfin/mach-bf537/include/mach/blackfin.h b/arch/blackfin/mach-bf537/include/mach/blackfin.h index eab006d..a12d4b6 100644 --- a/arch/blackfin/mach-bf537/include/mach/blackfin.h +++ b/arch/blackfin/mach-bf537/include/mach/blackfin.h @@ -40,10 +40,4 @@ #define OFFSET_SCR 0x1C /* SCR Scratch Register */ #define OFFSET_GCTL 0x24 /* Global Control Register */ -/* PLL_DIV Masks */ -#define CCLK_DIV1 CSEL_DIV1 /* CCLK = VCO / 1 */ -#define CCLK_DIV2 CSEL_DIV2 /* CCLK = VCO / 2 */ -#define CCLK_DIV4 CSEL_DIV4 /* CCLK = VCO / 4 */ -#define CCLK_DIV8 CSEL_DIV8 /* CCLK = VCO / 8 */ - #endif diff --git a/arch/blackfin/mach-bf537/include/mach/defBF534.h b/arch/blackfin/mach-bf537/include/mach/defBF534.h index a6d20ca..868e1a1 100644 --- a/arch/blackfin/mach-bf537/include/mach/defBF534.h +++ b/arch/blackfin/mach-bf537/include/mach/defBF534.h @@ -958,67 +958,6 @@ ** modifier UNLESS the lower order bits are saved and ORed back in when ** the macro is used. *************************************************************************************/ -/* -** ********************* PLL AND RESET MASKS ****************************************/ -/* PLL_CTL Masks */ -#define DF 0x0001 /* 0: PLL = CLKIN, 1: PLL = CLKIN/2 */ -#define PLL_OFF 0x0002 /* PLL Not Powered */ -#define STOPCK 0x0008 /* Core Clock Off */ -#define PDWN 0x0020 /* Enter Deep Sleep Mode */ -#define IN_DELAY 0x0040 /* Add 200ps Delay To EBIU Input Latches */ -#define OUT_DELAY 0x0080 /* Add 200ps Delay To EBIU Output Signals */ -#define BYPASS 0x0100 /* Bypass the PLL */ -#define MSEL 0x7E00 /* Multiplier Select For CCLK/VCO Factors */ -/* PLL_CTL Macros (Only Use With Logic OR While Setting Lower Order Bits) */ -#define SET_MSEL(x) (((x)&0x3F) << 0x9) /* Set MSEL = 0-63 --> VCO = CLKIN*MSEL */ - -/* PLL_DIV Masks */ -#define SSEL 0x000F /* System Select */ -#define CSEL 0x0030 /* Core Select */ -#define CSEL_DIV1 0x0000 /* CCLK = VCO / 1 */ -#define CSEL_DIV2 0x0010 /* CCLK = VCO / 2 */ -#define CSEL_DIV4 0x0020 /* CCLK = VCO / 4 */ -#define CSEL_DIV8 0x0030 /* CCLK = VCO / 8 */ -/* PLL_DIV Macros */ -#define SET_SSEL(x) ((x)&0xF) /* Set SSEL = 0-15 --> SCLK = VCO/SSEL */ - -/* VR_CTL Masks */ -#define FREQ 0x0003 /* Switching Oscillator Frequency For Regulator */ -#define HIBERNATE 0x0000 /* Powerdown/Bypass On-Board Regulation */ -#define FREQ_333 0x0001 /* Switching Frequency Is 333 kHz */ -#define FREQ_667 0x0002 /* Switching Frequency Is 667 kHz */ -#define FREQ_1000 0x0003 /* Switching Frequency Is 1 MHz */ - -#define GAIN 0x000C /* Voltage Level Gain */ -#define GAIN_5 0x0000 /* GAIN = 5 */ -#define GAIN_10 0x0004 /* GAIN = 10 */ -#define GAIN_20 0x0008 /* GAIN = 20 */ -#define GAIN_50 0x000C /* GAIN = 50 */ - -#define VLEV 0x00F0 /* Internal Voltage Level */ -#define VLEV_085 0x0060 /* VLEV = 0.85 V (-5% - +10% Accuracy) */ -#define VLEV_090 0x0070 /* VLEV = 0.90 V (-5% - +10% Accuracy) */ -#define VLEV_095 0x0080 /* VLEV = 0.95 V (-5% - +10% Accuracy) */ -#define VLEV_100 0x0090 /* VLEV = 1.00 V (-5% - +10% Accuracy) */ -#define VLEV_105 0x00A0 /* VLEV = 1.05 V (-5% - +10% Accuracy) */ -#define VLEV_110 0x00B0 /* VLEV = 1.10 V (-5% - +10% Accuracy) */ -#define VLEV_115 0x00C0 /* VLEV = 1.15 V (-5% - +10% Accuracy) */ -#define VLEV_120 0x00D0 /* VLEV = 1.20 V (-5% - +10% Accuracy) */ -#define VLEV_125 0x00E0 /* VLEV = 1.25 V (-5% - +10% Accuracy) */ -#define VLEV_130 0x00F0 /* VLEV = 1.30 V (-5% - +10% Accuracy) */ - -#define WAKE 0x0100 /* Enable RTC/Reset Wakeup From Hibernate */ -#define CANWE 0x0200 /* Enable CAN Wakeup From Hibernate */ -#define PHYWE 0x0400 /* Enable PHY Wakeup From Hibernate */ -#define CLKBUFOE 0x4000 /* CLKIN Buffer Output Enable */ -#define PHYCLKOE CLKBUFOE /* Alternative legacy name for the above */ -#define SCKELOW 0x8000 /* Enable Drive CKE Low During Reset */ - -/* PLL_STAT Masks */ -#define ACTIVE_PLLENABLED 0x0001 /* Processor In Active Mode With PLL Enabled */ -#define FULL_ON 0x0002 /* Processor In Full On Mode */ -#define ACTIVE_PLLDISABLED 0x0004 /* Processor In Active Mode With PLL Disabled */ -#define PLL_LOCKED 0x0020 /* PLL_LOCKCNT Has Been Reached */ /* CHIPID Masks */ #define CHIPID_VERSION 0xF0000000 diff --git a/arch/blackfin/mach-bf538/include/mach/blackfin.h b/arch/blackfin/mach-bf538/include/mach/blackfin.h index 278e894..08b5eab 100644 --- a/arch/blackfin/mach-bf538/include/mach/blackfin.h +++ b/arch/blackfin/mach-bf538/include/mach/blackfin.h @@ -37,10 +37,4 @@ #define OFFSET_SCR 0x1C /* SCR Scratch Register */ #define OFFSET_GCTL 0x24 /* Global Control Register */ -/* PLL_DIV Masks */ -#define CCLK_DIV1 CSEL_DIV1 /* CCLK = VCO / 1 */ -#define CCLK_DIV2 CSEL_DIV2 /* CCLK = VCO / 2 */ -#define CCLK_DIV4 CSEL_DIV4 /* CCLK = VCO / 4 */ -#define CCLK_DIV8 CSEL_DIV8 /* CCLK = VCO / 8 */ - #endif diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h index 312686a..5375819b 100644 --- a/arch/blackfin/mach-bf538/include/mach/defBF539.h +++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h @@ -1422,81 +1422,6 @@ /* System MMR Register Bits and Macros */ /******************************************************************************* */ -/* ********************* PLL AND RESET MASKS ************************ */ -/* PLL_CTL Masks */ -#define PLL_CLKIN 0x0000 /* Pass CLKIN to PLL */ -#define PLL_CLKIN_DIV2 0x0001 /* Pass CLKIN/2 to PLL */ -#define DF 0x0001 /* 0: PLL = CLKIN, 1: PLL = CLKIN/2 */ -#define PLL_OFF 0x0002 /* Shut off PLL clocks */ - -#define STOPCK 0x0008 /* Core Clock Off */ -#define PDWN 0x0020 /* Put the PLL in a Deep Sleep state */ -#define IN_DELAY 0x0014 /* EBIU Input Delay Select */ -#define OUT_DELAY 0x00C0 /* EBIU Output Delay Select */ -#define BYPASS 0x0100 /* Bypass the PLL */ -#define MSEL 0x7E00 /* Multiplier Select For CCLK/VCO Factors */ - -/* PLL_CTL Macros */ -#ifdef _MISRA_RULES -#define SET_MSEL(x) (((x)&0x3Fu) << 0x9) /* Set MSEL = 0-63 --> VCO = CLKIN*MSEL */ -#define SET_OUT_DELAY(x) (((x)&0x03u) << 0x6) -#define SET_IN_DELAY(x) ((((x)&0x02u) << 0x3) | (((x)&0x01u) << 0x2)) -#else -#define SET_MSEL(x) (((x)&0x3F) << 0x9) /* Set MSEL = 0-63 --> VCO = CLKIN*MSEL */ -#define SET_OUT_DELAY(x) (((x)&0x03) << 0x6) -#define SET_IN_DELAY(x) ((((x)&0x02) << 0x3) | (((x)&0x01) << 0x2)) -#endif /* _MISRA_RULES */ - -/* PLL_DIV Masks */ -#define SSEL 0x000F /* System Select */ -#define CSEL 0x0030 /* Core Select */ -#define CSEL_DIV1 0x0000 /* CCLK = VCO / 1 */ -#define CSEL_DIV2 0x0010 /* CCLK = VCO / 2 */ -#define CSEL_DIV4 0x0020 /* CCLK = VCO / 4 */ -#define CSEL_DIV8 0x0030 /* CCLK = VCO / 8 */ - -#define SCLK_DIV(x) (x) /* SCLK = VCO / x */ - -/* PLL_DIV Macros */ -#ifdef _MISRA_RULES -#define SET_SSEL(x) ((x)&0xFu) /* Set SSEL = 0-15 --> SCLK = VCO/SSEL */ -#else -#define SET_SSEL(x) ((x)&0xF) /* Set SSEL = 0-15 --> SCLK = VCO/SSEL */ -#endif /* _MISRA_RULES */ - -/* PLL_STAT Masks */ -#define ACTIVE_PLLENABLED 0x0001 /* Processor In Active Mode With PLL Enabled */ -#define FULL_ON 0x0002 /* Processor In Full On Mode */ -#define ACTIVE_PLLDISABLED 0x0004 /* Processor In Active Mode With PLL Disabled */ -#define PLL_LOCKED 0x0020 /* PLL_LOCKCNT Has Been Reached */ - -/* VR_CTL Masks */ -#define FREQ 0x0003 /* Switching Oscillator Frequency For Regulator */ -#define HIBERNATE 0x0000 /* Powerdown/Bypass On-Board Regulation */ -#define FREQ_333 0x0001 /* Switching Frequency Is 333 kHz */ -#define FREQ_667 0x0002 /* Switching Frequency Is 667 kHz */ -#define FREQ_1000 0x0003 /* Switching Frequency Is 1 MHz */ - -#define GAIN 0x000C /* Voltage Level Gain */ -#define GAIN_5 0x0000 /* GAIN = 5 */ -#define GAIN_10 0x0004 /* GAIN = 10 */ -#define GAIN_20 0x0008 /* GAIN = 20 */ -#define GAIN_50 0x000C /* GAIN = 50 */ - -#define VLEV 0x00F0 /* Internal Voltage Level - Only Program Values Within Specifications */ -#define VLEV_100 0x0090 /* VLEV = 1.00 V (See Datasheet for Regulator Tolerance) */ -#define VLEV_105 0x00A0 /* VLEV = 1.05 V (See Datasheet for Regulator Tolerance) */ -#define VLEV_110 0x00B0 /* VLEV = 1.10 V (See Datasheet for Regulator Tolerance) */ -#define VLEV_115 0x00C0 /* VLEV = 1.15 V (See Datasheet for Regulator Tolerance) */ -#define VLEV_120 0x00D0 /* VLEV = 1.20 V (See Datasheet for Regulator Tolerance) */ -#define VLEV_125 0x00E0 /* VLEV = 1.25 V (See Datasheet for Regulator Tolerance) */ -#define VLEV_130 0x00F0 /* VLEV = 1.30 V (See Datasheet for Regulator Tolerance) */ - -#define WAKE 0x0100 /* Enable RTC/Reset Wakeup From Hibernate */ -#define CANWE 0x0200 /* Enable CAN Wakeup From Hibernate */ -#define MXVRWE 0x0400 /* Enable MXVR Wakeup From Hibernate */ -#define SCKELOW 0x8000 /* Do Not Drive SCKE High During Reset After Hibernate */ - /* SWRST Mask */ #define SYSTEM_RESET 0x0007 /* Initiates A System Software Reset */ #define DOUBLE_FAULT 0x0008 /* Core Double Fault Causes Reset */ diff --git a/arch/blackfin/mach-bf548/include/mach/blackfin.h b/arch/blackfin/mach-bf548/include/mach/blackfin.h index 13302b6..5684030 100644 --- a/arch/blackfin/mach-bf548/include/mach/blackfin.h +++ b/arch/blackfin/mach-bf548/include/mach/blackfin.h @@ -64,10 +64,4 @@ #define OFFSET_THR 0x28 /* Transmit Holding register */ #define OFFSET_RBR 0x2C /* Receive Buffer register */ -/* PLL_DIV Masks */ -#define CCLK_DIV1 CSEL_DIV1 /* CCLK = VCO / 1 */ -#define CCLK_DIV2 CSEL_DIV2 /* CCLK = VCO / 2 */ -#define CCLK_DIV4 CSEL_DIV4 /* CCLK = VCO / 4 */ -#define CCLK_DIV8 CSEL_DIV8 /* CCLK = VCO / 8 */ - #endif diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h index 855bc60..6d97b4e 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h @@ -2075,26 +2075,6 @@ #define AFEXIT 0x10 /* Authentication Firmware Exit */ #define SECSTAT 0xe0 /* Secure Status */ -/* Bit masks for PLL_DIV */ - -#define CSEL 0x30 /* Core Select */ -#define SSEL 0xf /* System Select */ -#define CSEL_DIV1 0x0000 /* CCLK = VCO / 1 */ -#define CSEL_DIV2 0x0010 /* CCLK = VCO / 2 */ -#define CSEL_DIV4 0x0020 /* CCLK = VCO / 4 */ -#define CSEL_DIV8 0x0030 /* CCLK = VCO / 8 */ - -/* Bit masks for PLL_CTL */ - -#define MSEL 0x7e00 /* Multiplier Select */ -#define BYPASS 0x100 /* PLL Bypass Enable */ -#define OUTPUT_DELAY 0x80 /* External Memory Output Delay Enable */ -#define INPUT_DELAY 0x40 /* External Memory Input Delay Enable */ -#define PDWN 0x20 /* Power Down */ -#define STOPCK 0x8 /* Stop Clock */ -#define PLL_OFF 0x2 /* Disable PLL */ -#define DF 0x1 /* Divide Frequency */ - /* SWRST Masks */ #define SYSTEM_RESET 0x0007 /* Initiates A System Software Reset */ #define DOUBLE_FAULT 0x0008 /* Core Double Fault Causes Reset */ @@ -2102,52 +2082,6 @@ #define RESET_WDOG 0x4000 /* SW Reset Generated By Watchdog Timer */ #define RESET_SOFTWARE 0x8000 /* SW Reset Occurred Since Last Read Of SWRST */ -/* Bit masks for PLL_STAT */ - -#define PLL_LOCKED 0x20 /* PLL Locked Status */ -#define ACTIVE_PLLDISABLED 0x4 /* Active Mode With PLL Disabled */ -#define FULL_ON 0x2 /* Full-On Mode */ -#define ACTIVE_PLLENABLED 0x1 /* Active Mode With PLL Enabled */ -#define RTCWS 0x400 /* RTC/Reset Wake-Up Status */ -#define CANWS 0x800 /* CAN Wake-Up Status */ -#define USBWS 0x2000 /* USB Wake-Up Status */ -#define KPADWS 0x4000 /* Keypad Wake-Up Status */ -#define ROTWS 0x8000 /* Rotary Wake-Up Status */ -#define GPWS 0x1000 /* General-Purpose Wake-Up Status */ - -/* Bit masks for VR_CTL */ - -#define FREQ 0x3 /* Regulator Switching Frequency */ -#define GAIN 0xc /* Voltage Output Level Gain */ -#define VLEV 0xf0 /* Internal Voltage Level */ -#define SCKELOW 0x8000 /* Drive SCKE Low During Reset Enable */ -#define WAKE 0x100 /* RTC/Reset Wake-Up Enable */ -#define CANWE 0x200 /* CAN0/1 Wake-Up Enable */ -#define GPWE 0x400 /* General-Purpose Wake-Up Enable */ -#define USBWE 0x800 /* USB Wake-Up Enable */ -#define KPADWE 0x1000 /* Keypad Wake-Up Enable */ -#define ROTWE 0x2000 /* Rotary Wake-Up Enable */ - -#define FREQ_333 0x0001 /* Switching Frequency Is 333 kHz */ -#define FREQ_667 0x0002 /* Switching Frequency Is 667 kHz */ -#define FREQ_1000 0x0003 /* Switching Frequency Is 1 MHz */ - -#define GAIN_5 0x0000 /* GAIN = 5*/ -#define GAIN_10 0x0004 /* GAIN = 1*/ -#define GAIN_20 0x0008 /* GAIN = 2*/ -#define GAIN_50 0x000C /* GAIN = 5*/ - -#define VLEV_085 0x0060 /* VLEV = 0.85 V (-5% - +10% Accuracy) */ -#define VLEV_090 0x0070 /* VLEV = 0.90 V (-5% - +10% Accuracy) */ -#define VLEV_095 0x0080 /* VLEV = 0.95 V (-5% - +10% Accuracy) */ -#define VLEV_100 0x0090 /* VLEV = 1.00 V (-5% - +10% Accuracy) */ -#define VLEV_105 0x00A0 /* VLEV = 1.05 V (-5% - +10% Accuracy) */ -#define VLEV_110 0x00B0 /* VLEV = 1.10 V (-5% - +10% Accuracy) */ -#define VLEV_115 0x00C0 /* VLEV = 1.15 V (-5% - +10% Accuracy) */ -#define VLEV_120 0x00D0 /* VLEV = 1.20 V (-5% - +10% Accuracy) */ -#define VLEV_125 0x00E0 /* VLEV = 1.25 V (-5% - +10% Accuracy) */ -#define VLEV_130 0x00F0 /* VLEV = 1.30 V (-5% - +10% Accuracy) */ - /* Bit masks for NFC_CTL */ #define WR_DLY 0xf /* Write Strobe Delay */ diff --git a/arch/blackfin/mach-bf561/include/mach/defBF561.h b/arch/blackfin/mach-bf561/include/mach/defBF561.h index a31e509..c2f9c8f 100644 --- a/arch/blackfin/mach-bf561/include/mach/defBF561.h +++ b/arch/blackfin/mach-bf561/include/mach/defBF561.h @@ -884,65 +884,11 @@ /* System MMR Register Bits */ /******************************************************************************* */ -/* ********************* PLL AND RESET MASKS ************************ */ - -/* PLL_CTL Masks */ -#define PLL_CLKIN 0x00000000 /* Pass CLKIN to PLL */ -#define PLL_CLKIN_DIV2 0x00000001 /* Pass CLKIN/2 to PLL */ -#define PLL_OFF 0x00000002 /* Shut off PLL clocks */ -#define STOPCK_OFF 0x00000008 /* Core clock off */ -#define PDWN 0x00000020 /* Put the PLL in a Deep Sleep state */ -#define BYPASS 0x00000100 /* Bypass the PLL */ - /* CHIPID Masks */ #define CHIPID_VERSION 0xF0000000 #define CHIPID_FAMILY 0x0FFFF000 #define CHIPID_MANUFACTURE 0x00000FFE -/* VR_CTL Masks */ -#define FREQ 0x0003 /* Switching Oscillator Frequency For Regulator */ -#define HIBERNATE 0x0000 /* Powerdown/Bypass On-Board Regulation */ -#define FREQ_333 0x0001 /* Switching Frequency Is 333 kHz */ -#define FREQ_667 0x0002 /* Switching Frequency Is 667 kHz */ -#define FREQ_1000 0x0003 /* Switching Frequency Is 1 MHz */ - -#define GAIN 0x000C /* Voltage Level Gain */ -#define GAIN_5 0x0000 /* GAIN = 5*/ -#define GAIN_10 0x0004 /* GAIN = 1*/ -#define GAIN_20 0x0008 /* GAIN = 2*/ -#define GAIN_50 0x000C /* GAIN = 5*/ - -#define VLEV 0x00F0 /* Internal Voltage Level */ -#define VLEV_085 0x0060 /* VLEV = 0.85 V (-5% - +10% Accuracy) */ -#define VLEV_090 0x0070 /* VLEV = 0.90 V (-5% - +10% Accuracy) */ -#define VLEV_095 0x0080 /* VLEV = 0.95 V (-5% - +10% Accuracy) */ -#define VLEV_100 0x0090 /* VLEV = 1.00 V (-5% - +10% Accuracy) */ -#define VLEV_105 0x00A0 /* VLEV = 1.05 V (-5% - +10% Accuracy) */ -#define VLEV_110 0x00B0 /* VLEV = 1.10 V (-5% - +10% Accuracy) */ -#define VLEV_115 0x00C0 /* VLEV = 1.15 V (-5% - +10% Accuracy) */ -#define VLEV_120 0x00D0 /* VLEV = 1.20 V (-5% - +10% Accuracy) */ -#define VLEV_125 0x00E0 /* VLEV = 1.25 V (-5% - +10% Accuracy) */ -#define VLEV_130 0x00F0 /* VLEV = 1.30 V (-5% - +10% Accuracy) */ - -#define WAKE 0x0100 /* Enable RTC/Reset Wakeup From Hibernate */ -#define SCKELOW 0x8000 /* Do Not Drive SCKE High During Reset After Hibernate */ - -/* PLL_DIV Masks */ -#define SCLK_DIV(x) (x) /* SCLK = VCO / x */ - -#define CSEL 0x30 /* Core Select */ -#define SSEL 0xf /* System Select */ -#define CCLK_DIV1 0x00000000 /* CCLK = VCO / 1 */ -#define CCLK_DIV2 0x00000010 /* CCLK = VCO / 2 */ -#define CCLK_DIV4 0x00000020 /* CCLK = VCO / 4 */ -#define CCLK_DIV8 0x00000030 /* CCLK = VCO / 8 */ - -/* PLL_STAT Masks */ -#define ACTIVE_PLLENABLED 0x0001 /* Processor In Active Mode With PLL Enabled */ -#define FULL_ON 0x0002 /* Processor In Full On Mode */ -#define ACTIVE_PLLDISABLED 0x0004 /* Processor In Active Mode With PLL Disabled */ -#define PLL_LOCKED 0x0020 /* PLL_LOCKCNT Has Been Reached */ - /* SICA_SYSCR Masks */ #define COREB_SRAM_INIT 0x0020 -- cgit v0.10.2 From c6feb7682885f732a264ef589ee44edb1a3d45f2 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 15 Oct 2009 10:37:33 +0000 Subject: Blackfin: fix typo in isp1760 platform name The driver changed from "isp1760-hcd" to "isp1760", so update resources to match. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c index 40b9934..7ab0800 100644 --- a/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c @@ -62,7 +62,7 @@ static struct isp1760_platform_data isp1760_priv = { }; static struct platform_device bfin_isp1760_device = { - .name = "isp1760-hcd", + .name = "isp1760", .id = 0, .dev = { .platform_data = &isp1760_priv, diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 1c2ec24..5294fdd 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -60,7 +60,7 @@ static struct isp1760_platform_data isp1760_priv = { }; static struct platform_device bfin_isp1760_device = { - .name = "isp1760-hcd", + .name = "isp1760", .id = 0, .dev = { .platform_data = &isp1760_priv, diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index f02f20f..d5a4c82 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -66,7 +66,7 @@ static struct isp1760_platform_data isp1760_priv = { }; static struct platform_device bfin_isp1760_device = { - .name = "isp1760-hcd", + .name = "isp1760", .id = 0, .dev = { .platform_data = &isp1760_priv, diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index e926d39..0d65cfa 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -62,7 +62,7 @@ static struct isp1760_platform_data isp1760_priv = { }; static struct platform_device bfin_isp1760_device = { - .name = "isp1760-hcd", + .name = "isp1760", .id = 0, .dev = { .platform_data = &isp1760_priv, diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c index 9e2d8cf..6c5b508 100644 --- a/arch/blackfin/mach-bf561/boards/ezkit.c +++ b/arch/blackfin/mach-bf561/boards/ezkit.c @@ -49,7 +49,7 @@ static struct isp1760_platform_data isp1760_priv = { }; static struct platform_device bfin_isp1760_device = { - .name = "isp1760-hcd", + .name = "isp1760", .id = 0, .dev = { .platform_data = &isp1760_priv, -- cgit v0.10.2 From 00d2460454676344a55a03f03fa284ad69325592 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 20 Oct 2009 17:20:21 +0000 Subject: Blackfin: unify DMA masks Every Blackfin variant has the same DMA bit masks, so avoid duplicating them over and over in each mach header. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index e3c0dfa..5eb2950 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -16,36 +16,65 @@ #define MAX_DMA_ADDRESS PAGE_OFFSET -/***************************************************************************** -* Generic DMA Declarations -* -****************************************************************************/ +/* DMA_CONFIG Masks */ +#define DMAEN 0x0001 /* DMA Channel Enable */ +#define WNR 0x0002 /* Channel Direction (W/R*) */ +#define WDSIZE_8 0x0000 /* Transfer Word Size = 8 */ +#define WDSIZE_16 0x0004 /* Transfer Word Size = 16 */ +#define WDSIZE_32 0x0008 /* Transfer Word Size = 32 */ +#define DMA2D 0x0010 /* DMA Mode (2D/1D*) */ +#define RESTART 0x0020 /* DMA Buffer Clear */ +#define DI_SEL 0x0040 /* Data Interrupt Timing Select */ +#define DI_EN 0x0080 /* Data Interrupt Enable */ +#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */ +#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */ +#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */ +#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */ +#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */ +#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */ +#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */ +#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */ +#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */ +#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */ +#define NDSIZE 0x0f00 /* Next Descriptor Size */ +#define DMAFLOW 0x7000 /* Flow Control */ +#define DMAFLOW_STOP 0x0000 /* Stop Mode */ +#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */ +#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */ +#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */ +#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */ + +/* DMA_IRQ_STATUS Masks */ +#define DMA_DONE 0x0001 /* DMA Completion Interrupt Status */ +#define DMA_ERR 0x0002 /* DMA Error Interrupt Status */ +#define DFETCH 0x0004 /* DMA Descriptor Fetch Indicator */ +#define DMA_RUN 0x0008 /* DMA Channel Running Indicator */ /*------------------------- * config reg bits value *-------------------------*/ -#define DATA_SIZE_8 0 -#define DATA_SIZE_16 1 -#define DATA_SIZE_32 2 +#define DATA_SIZE_8 0 +#define DATA_SIZE_16 1 +#define DATA_SIZE_32 2 -#define DMA_FLOW_STOP 0 -#define DMA_FLOW_AUTO 1 -#define DMA_FLOW_ARRAY 4 -#define DMA_FLOW_SMALL 6 -#define DMA_FLOW_LARGE 7 +#define DMA_FLOW_STOP 0 +#define DMA_FLOW_AUTO 1 +#define DMA_FLOW_ARRAY 4 +#define DMA_FLOW_SMALL 6 +#define DMA_FLOW_LARGE 7 -#define DIMENSION_LINEAR 0 -#define DIMENSION_2D 1 +#define DIMENSION_LINEAR 0 +#define DIMENSION_2D 1 -#define DIR_READ 0 -#define DIR_WRITE 1 +#define DIR_READ 0 +#define DIR_WRITE 1 -#define INTR_DISABLE 0 -#define INTR_ON_BUF 2 -#define INTR_ON_ROW 3 +#define INTR_DISABLE 0 +#define INTR_ON_BUF 2 +#define INTR_ON_ROW 3 #define DMA_NOSYNC_KEEP_DMA_BUF 0 -#define DMA_SYNC_RESTART 1 +#define DMA_SYNC_RESTART 1 struct dmasg { void *next_desc_addr; diff --git a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h index a97a2bb..9241205 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h @@ -1260,33 +1260,6 @@ /* ************************** DMA CONTROLLER MASKS ********************************/ -/* DMAx_CONFIG, MDMA_yy_CONFIG Masks */ -#define DMAEN 0x0001 /* DMA Channel Enable */ -#define WNR 0x0002 /* Channel Direction (W/R*) */ -#define WDSIZE_8 0x0000 /* Transfer Word Size = 8 */ -#define WDSIZE_16 0x0004 /* Transfer Word Size = 16 */ -#define WDSIZE_32 0x0008 /* Transfer Word Size = 32 */ -#define DMA2D 0x0010 /* DMA Mode (2D/1D*) */ -#define RESTART 0x0020 /* DMA Buffer Clear */ -#define DI_SEL 0x0040 /* Data Interrupt Timing Select */ -#define DI_EN 0x0080 /* Data Interrupt Enable */ -#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */ -#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */ -#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */ -#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */ -#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */ -#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */ -#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */ -#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */ -#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */ -#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */ -#define NDSIZE 0x0900 /* Next Descriptor Size */ -#define DMAFLOW 0x7000 /* Flow Control */ -#define DMAFLOW_STOP 0x0000 /* Stop Mode */ -#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */ -#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */ -#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */ -#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */ /* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */ #define CTYPE 0x0040 /* DMA Channel Type Indicator (Memory/Peripheral*) */ @@ -1304,13 +1277,6 @@ #define PMAP_UART1RX 0xA000 /* UART1 Port Receive DMA */ #define PMAP_UART1TX 0xB000 /* UART1 Port Transmit DMA */ -/* DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS Masks */ -#define DMA_DONE 0x0001 /* DMA Completion Interrupt Status */ -#define DMA_ERR 0x0002 /* DMA Error Interrupt Status */ -#define DFETCH 0x0004 /* DMA Descriptor Fetch Indicator */ -#define DMA_RUN 0x0008 /* DMA Channel Running Indicator */ - - /* ************ PARALLEL PERIPHERAL INTERFACE (PPI) MASKS *************/ /* PPI_CONTROL Masks */ #define PORT_EN 0x0001 /* PPI Port Enable */ diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h index da42e9c..8b18b53 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h @@ -1269,33 +1269,6 @@ /* ************************** DMA CONTROLLER MASKS ********************************/ -/* DMAx_CONFIG, MDMA_yy_CONFIG Masks */ -#define DMAEN 0x0001 /* DMA Channel Enable */ -#define WNR 0x0002 /* Channel Direction (W/R*) */ -#define WDSIZE_8 0x0000 /* Transfer Word Size = 8 */ -#define WDSIZE_16 0x0004 /* Transfer Word Size = 16 */ -#define WDSIZE_32 0x0008 /* Transfer Word Size = 32 */ -#define DMA2D 0x0010 /* DMA Mode (2D/1D*) */ -#define RESTART 0x0020 /* DMA Buffer Clear */ -#define DI_SEL 0x0040 /* Data Interrupt Timing Select */ -#define DI_EN 0x0080 /* Data Interrupt Enable */ -#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */ -#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */ -#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */ -#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */ -#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */ -#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */ -#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */ -#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */ -#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */ -#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */ -#define NDSIZE 0x0900 /* Next Descriptor Size */ -#define DMAFLOW 0x7000 /* Flow Control */ -#define DMAFLOW_STOP 0x0000 /* Stop Mode */ -#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */ -#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */ -#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */ -#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */ /* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */ #define CTYPE 0x0040 /* DMA Channel Type Indicator (Memory/Peripheral*) */ @@ -1313,13 +1286,6 @@ #define PMAP_UART1RX 0xA000 /* UART1 Port Receive DMA */ #define PMAP_UART1TX 0xB000 /* UART1 Port Transmit DMA */ -/* DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS Masks */ -#define DMA_DONE 0x0001 /* DMA Completion Interrupt Status */ -#define DMA_ERR 0x0002 /* DMA Error Interrupt Status */ -#define DFETCH 0x0004 /* DMA Descriptor Fetch Indicator */ -#define DMA_RUN 0x0008 /* DMA Channel Running Indicator */ - - /* ************ PARALLEL PERIPHERAL INTERFACE (PPI) MASKS *************/ /* PPI_CONTROL Masks */ #define PORT_EN 0x0001 /* PPI Port Enable */ diff --git a/arch/blackfin/mach-bf533/include/mach/defBF532.h b/arch/blackfin/mach-bf533/include/mach/defBF532.h index 7e61fe7..e9ff491 100644 --- a/arch/blackfin/mach-bf533/include/mach/defBF532.h +++ b/arch/blackfin/mach-bf533/include/mach/defBF532.h @@ -637,54 +637,7 @@ /* ********** DMA CONTROLLER MASKS *********************8 */ -/*DMAx_CONFIG, MDMA_yy_CONFIG Masks */ -#define DMAEN 0x00000001 /* Channel Enable */ -#define WNR 0x00000002 /* Channel Direction (W/R*) */ -#define WDSIZE_8 0x00000000 /* Word Size 8 bits */ -#define WDSIZE_16 0x00000004 /* Word Size 16 bits */ -#define WDSIZE_32 0x00000008 /* Word Size 32 bits */ -#define DMA2D 0x00000010 /* 2D/1D* Mode */ -#define RESTART 0x00000020 /* Restart */ -#define DI_SEL 0x00000040 /* Data Interrupt Select */ -#define DI_EN 0x00000080 /* Data Interrupt Enable */ -#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */ -#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */ -#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */ -#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */ -#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */ -#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */ -#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */ -#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */ -#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */ -#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */ -#define NDSIZE 0x00000900 /* Next Descriptor Size */ -#define DMAFLOW 0x00007000 /* Flow Control */ -#define DMAFLOW_STOP 0x0000 /* Stop Mode */ -#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */ -#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */ -#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */ -#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */ - -#define DMAEN_P 0 /* Channel Enable */ -#define WNR_P 1 /* Channel Direction (W/R*) */ -#define DMA2D_P 4 /* 2D/1D* Mode */ -#define RESTART_P 5 /* Restart */ -#define DI_SEL_P 6 /* Data Interrupt Select */ -#define DI_EN_P 7 /* Data Interrupt Enable */ - -/*DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS Masks */ - -#define DMA_DONE 0x00000001 /* DMA Done Indicator */ -#define DMA_ERR 0x00000002 /* DMA Error Indicator */ -#define DFETCH 0x00000004 /* Descriptor Fetch Indicator */ -#define DMA_RUN 0x00000008 /* DMA Running Indicator */ - -#define DMA_DONE_P 0 /* DMA Done Indicator */ -#define DMA_ERR_P 1 /* DMA Error Indicator */ -#define DFETCH_P 2 /* Descriptor Fetch Indicator */ -#define DMA_RUN_P 3 /* DMA Running Indicator */ - -/*DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */ +/* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */ #define CTYPE 0x00000040 /* DMA Channel Type Indicator */ #define CTYPE_P 6 /* DMA Channel Type Indicator BIT POSITION */ diff --git a/arch/blackfin/mach-bf537/include/mach/defBF534.h b/arch/blackfin/mach-bf537/include/mach/defBF534.h index 868e1a1..066d5c2 100644 --- a/arch/blackfin/mach-bf537/include/mach/defBF534.h +++ b/arch/blackfin/mach-bf537/include/mach/defBF534.h @@ -1584,34 +1584,6 @@ #define BGSTAT 0x0020 /* Bus Grant Status */ /* ************************** DMA CONTROLLER MASKS ********************************/ -/* DMAx_CONFIG, MDMA_yy_CONFIG Masks */ -#define DMAEN 0x0001 /* DMA Channel Enable */ -#define WNR 0x0002 /* Channel Direction (W/R*) */ -#define WDSIZE_8 0x0000 /* Transfer Word Size = 8 */ -#define WDSIZE_16 0x0004 /* Transfer Word Size = 16 */ -#define WDSIZE_32 0x0008 /* Transfer Word Size = 32 */ -#define DMA2D 0x0010 /* DMA Mode (2D/1D*) */ -#define RESTART 0x0020 /* DMA Buffer Clear */ -#define DI_SEL 0x0040 /* Data Interrupt Timing Select */ -#define DI_EN 0x0080 /* Data Interrupt Enable */ -#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */ -#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */ -#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */ -#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */ -#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */ -#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */ -#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */ -#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */ -#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */ -#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */ -#define NDSIZE 0x0900 /* Next Descriptor Size */ - -#define DMAFLOW 0x7000 /* Flow Control */ -#define DMAFLOW_STOP 0x0000 /* Stop Mode */ -#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */ -#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */ -#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */ -#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */ /* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */ #define CTYPE 0x0040 /* DMA Channel Type Indicator (Memory/Peripheral*) */ @@ -1629,12 +1601,6 @@ #define PMAP_UART1RX 0xA000 /* UART1 Port Receive DMA */ #define PMAP_UART1TX 0xB000 /* UART1 Port Transmit DMA */ -/* DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS Masks */ -#define DMA_DONE 0x0001 /* DMA Completion Interrupt Status */ -#define DMA_ERR 0x0002 /* DMA Error Interrupt Status */ -#define DFETCH 0x0004 /* DMA Descriptor Fetch Indicator */ -#define DMA_RUN 0x0008 /* DMA Channel Running Indicator */ - /* ************ PARALLEL PERIPHERAL INTERFACE (PPI) MASKS *************/ /* PPI_CONTROL Masks */ #define PORT_EN 0x0001 /* PPI Port Enable */ diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h index 5375819b..fac563e 100644 --- a/arch/blackfin/mach-bf538/include/mach/defBF539.h +++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h @@ -1757,52 +1757,6 @@ /* ********** DMA CONTROLLER MASKS ***********************/ -/* DMAx_CONFIG, MDMA_yy_CONFIG Masks */ -#define DMAEN 0x0001 /* Channel Enable */ -#define WNR 0x0002 /* Channel Direction (W/R*) */ -#define WDSIZE_8 0x0000 /* Word Size 8 bits */ -#define WDSIZE_16 0x0004 /* Word Size 16 bits */ -#define WDSIZE_32 0x0008 /* Word Size 32 bits */ -#define DMA2D 0x0010 /* 2D/1D* Mode */ -#define RESTART 0x0020 /* Restart */ -#define DI_SEL 0x0040 /* Data Interrupt Select */ -#define DI_EN 0x0080 /* Data Interrupt Enable */ -#define NDSIZE 0x0900 /* Next Descriptor Size */ -#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */ -#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */ -#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */ -#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */ -#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */ -#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */ -#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */ -#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */ -#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */ -#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */ - -#define DMAFLOW 0x7000 /* Flow Control */ -#define DMAFLOW_STOP 0x0000 /* Stop Mode */ -#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */ -#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */ -#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */ -#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */ - -#define DMAEN_P 0x0 /* Channel Enable */ -#define WNR_P 0x1 /* Channel Direction (W/R*) */ -#define DMA2D_P 0x4 /* 2D/1D* Mode */ -#define RESTART_P 0x5 /* Restart */ -#define DI_SEL_P 0x6 /* Data Interrupt Select */ -#define DI_EN_P 0x7 /* Data Interrupt Enable */ - -/* DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS Masks */ -#define DMA_DONE 0x0001 /* DMA Done Indicator */ -#define DMA_ERR 0x0002 /* DMA Error Indicator */ -#define DFETCH 0x0004 /* Descriptor Fetch Indicator */ -#define DMA_RUN 0x0008 /* DMA Running Indicator */ - -#define DMA_DONE_P 0x0 /* DMA Done Indicator */ -#define DMA_ERR_P 0x1 /* DMA Error Indicator */ -#define DFETCH_P 0x2 /* Descriptor Fetch Indicator */ -#define DMA_RUN_P 0x3 /* DMA Running Indicator */ /* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */ diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h index 6d97b4e..ab04d13 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h @@ -1609,44 +1609,6 @@ #define PINT2 0x40000000 /* Pin Interrupt 2 */ #define PINT3 0x80000000 /* Pin Interrupt 3 */ -/* Bit masks for DMAx_CONFIG, MDMA_Sx_CONFIG, MDMA_Dx_CONFIG */ - -#define DMAEN 0x1 /* DMA Channel Enable */ -#define WNR 0x2 /* DMA Direction */ -#define WDSIZE_8 0x0 /* Transfer Word Size = 8 */ -#define WDSIZE_16 0x4 /* Transfer Word Size = 16 */ -#define WDSIZE_32 0x8 /* Transfer Word Size = 32 */ -#define DMA2D 0x10 /* DMA Mode */ -#define RESTART 0x20 /* Work Unit Transitions */ -#define DI_SEL 0x40 /* Data Interrupt Timing Select */ -#define DI_EN 0x80 /* Data Interrupt Enable */ - -#define NDSIZE 0xf00 /* Flex Descriptor Size */ -#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */ -#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */ -#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */ -#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */ -#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */ -#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */ -#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */ -#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */ -#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */ -#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */ - -#define DMAFLOW 0xf000 /* Next Operation */ -#define DMAFLOW_STOP 0x0000 /* Stop Mode */ -#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */ -#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */ -#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */ -#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */ - -/* Bit masks for DMAx_IRQ_STATUS, MDMA_Sx_IRQ_STATUS, MDMA_Dx_IRQ_STATUS */ - -#define DMA_DONE 0x1 /* DMA Completion Interrupt Status */ -#define DMA_ERR 0x2 /* DMA Error Interrupt Status */ -#define DFETCH 0x4 /* DMA Descriptor Fetch */ -#define DMA_RUN 0x8 /* DMA Channel Running */ - /* Bit masks for DMAx_PERIPHERAL_MAP, MDMA_Sx_IRQ_STATUS, MDMA_Dx_IRQ_STATUS */ #define CTYPE 0x40 /* DMA Channel Type */ diff --git a/arch/blackfin/mach-bf561/include/mach/defBF561.h b/arch/blackfin/mach-bf561/include/mach/defBF561.h index c2f9c8f..4c8e36b 100644 --- a/arch/blackfin/mach-bf561/include/mach/defBF561.h +++ b/arch/blackfin/mach-bf561/include/mach/defBF561.h @@ -1096,53 +1096,6 @@ /* ********** DMA CONTROLLER MASKS *********************8 */ -/* DMAx_CONFIG, MDMA_yy_CONFIG, IMDMA_yy_CONFIG Masks */ -#define DMAEN 0x00000001 /* Channel Enable */ -#define WNR 0x00000002 /* Channel Direction (W/R*) */ -#define WDSIZE_8 0x00000000 /* Word Size 8 bits */ -#define WDSIZE_16 0x00000004 /* Word Size 16 bits */ -#define WDSIZE_32 0x00000008 /* Word Size 32 bits */ -#define DMA2D 0x00000010 /* 2D/1D* Mode */ -#define RESTART 0x00000020 /* Restart */ -#define DI_SEL 0x00000040 /* Data Interrupt Select */ -#define DI_EN 0x00000080 /* Data Interrupt Enable */ -#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */ -#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */ -#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */ -#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */ -#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */ -#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */ -#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */ -#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */ -#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */ -#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */ -#define NDSIZE 0x00000900 /* Next Descriptor Size */ -#define DMAFLOW 0x00007000 /* Flow Control */ -#define DMAFLOW_STOP 0x0000 /* Stop Mode */ -#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */ -#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */ -#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */ -#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */ - -#define DMAEN_P 0 /* Channel Enable */ -#define WNR_P 1 /* Channel Direction (W/R*) */ -#define DMA2D_P 4 /* 2D/1D* Mode */ -#define RESTART_P 5 /* Restart */ -#define DI_SEL_P 6 /* Data Interrupt Select */ -#define DI_EN_P 7 /* Data Interrupt Enable */ - -/* DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS, IMDMA_yy_IRQ_STATUS Masks */ - -#define DMA_DONE 0x00000001 /* DMA Done Indicator */ -#define DMA_ERR 0x00000002 /* DMA Error Indicator */ -#define DFETCH 0x00000004 /* Descriptor Fetch Indicator */ -#define DMA_RUN 0x00000008 /* DMA Running Indicator */ - -#define DMA_DONE_P 0 /* DMA Done Indicator */ -#define DMA_ERR_P 1 /* DMA Error Indicator */ -#define DFETCH_P 2 /* Descriptor Fetch Indicator */ -#define DMA_RUN_P 3 /* DMA Running Indicator */ - /* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP, IMDMA_yy_PERIPHERAL_MAP Masks */ #define CTYPE 0x00000040 /* DMA Channel Type Indicator */ -- cgit v0.10.2 From 7a1a8cc1902af3a2a19636da3674008b2f1246db Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Tue, 20 Oct 2009 17:22:18 +0000 Subject: Blackfin: announce current cpu rev when booting User reports rarely include full information, so include this important tidbit up front. It's also good to know at a glance in general. Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 5fda774..a7ae73a 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -910,7 +910,7 @@ void __init setup_arch(char **cmdline_p) printk(KERN_INFO "Blackfin support (C) 2004-2009 Analog Devices, Inc.\n"); if (bfin_compiled_revid() == 0xffff) - printk(KERN_INFO "Compiled for ADSP-%s Rev any\n", CPU); + printk(KERN_INFO "Compiled for ADSP-%s Rev any, running on 0.%d\n", CPU, bfin_revid()); else if (bfin_compiled_revid() == -1) printk(KERN_INFO "Compiled for ADSP-%s Rev none\n", CPU); else -- cgit v0.10.2 From 4b60779d5ea76908c3bc82d93280b733335fce48 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 21 Oct 2009 21:22:35 +0000 Subject: Blackfin: add an example showing how to use the gptimers API Signed-off-by: Mike Frysinger diff --git a/Documentation/blackfin/Makefile b/Documentation/blackfin/Makefile new file mode 100644 index 0000000..773dbb1 --- /dev/null +++ b/Documentation/blackfin/Makefile @@ -0,0 +1,6 @@ +obj-m := gptimers-example.o + +all: modules + +modules clean: + $(MAKE) -C ../.. SUBDIRS=$(PWD) $@ diff --git a/Documentation/blackfin/gptimers-example.c b/Documentation/blackfin/gptimers-example.c new file mode 100644 index 0000000..b1bd634 --- /dev/null +++ b/Documentation/blackfin/gptimers-example.c @@ -0,0 +1,83 @@ +/* + * Simple gptimers example + * http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:gptimers + * + * Copyright 2007-2009 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include + +#include +#include + +/* ... random driver includes ... */ + +#define DRIVER_NAME "gptimer_example" + +struct gptimer_data { + uint32_t period, width; +}; +static struct gptimer_data data; + +/* ... random driver state ... */ + +static irqreturn_t gptimer_example_irq(int irq, void *dev_id) +{ + struct gptimer_data *data = dev_id; + + /* make sure it was our timer which caused the interrupt */ + if (!get_gptimer_intr(TIMER5_id)) + return IRQ_NONE; + + /* read the width/period values that were captured for the waveform */ + data->width = get_gptimer_pwidth(TIMER5_id); + data->period = get_gptimer_period(TIMER5_id); + + /* acknowledge the interrupt */ + clear_gptimer_intr(TIMER5_id); + + /* tell the upper layers we took care of things */ + return IRQ_HANDLED; +} + +/* ... random driver code ... */ + +static int __init gptimer_example_init(void) +{ + int ret; + + /* grab the peripheral pins */ + ret = peripheral_request(P_TMR5, DRIVER_NAME); + if (ret) { + printk(KERN_NOTICE DRIVER_NAME ": peripheral request failed\n"); + return ret; + } + + /* grab the IRQ for the timer */ + ret = request_irq(IRQ_TIMER5, gptimer_example_irq, IRQF_SHARED, DRIVER_NAME, &data); + if (ret) { + printk(KERN_NOTICE DRIVER_NAME ": IRQ request failed\n"); + peripheral_free(P_TMR5); + return ret; + } + + /* setup the timer and enable it */ + set_gptimer_config(TIMER5_id, WDTH_CAP | PULSE_HI | PERIOD_CNT | IRQ_ENA); + enable_gptimers(TIMER5bit); + + return 0; +} +module_init(gptimer_example_init); + +static void __exit gptimer_example_exit(void) +{ + disable_gptimers(TIMER5bit); + free_irq(IRQ_TIMER5, &data); + peripheral_free(P_TMR5); +} +module_exit(gptimer_example_exit); + +MODULE_LICENSE("BSD"); -- cgit v0.10.2 From 13a1320cf59023bda187a0bd5ad0cdee95beb9b1 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 22 Oct 2009 10:14:53 +0000 Subject: Blackfin: don't give CPU its own line in traps output Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 78cb3d3..89835ac 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -976,12 +976,12 @@ void dump_bfin_process(struct pt_regs *fp) !((unsigned long)current & 0x3) && current->pid) { verbose_printk(KERN_NOTICE "CURRENT PROCESS:\n"); if (current->comm >= (char *)FIXED_CODE_START) - verbose_printk(KERN_NOTICE "COMM=%s PID=%d\n", + verbose_printk(KERN_NOTICE "COMM=%s PID=%d", current->comm, current->pid); else - verbose_printk(KERN_NOTICE "COMM= invalid\n"); + verbose_printk(KERN_NOTICE "COMM= invalid"); - printk(KERN_NOTICE "CPU = %d\n", current_thread_info()->cpu); + printk(KERN_CONT " CPU=%d\n", current_thread_info()->cpu); if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START) verbose_printk(KERN_NOTICE "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" -- cgit v0.10.2 From b2e8dbd20452ba3893e1b7cd006ef20168b43240 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 26 Oct 2009 21:16:04 +0000 Subject: Blackfin: add an uncompressed vmImage target This is useful for quick tests where networks are faster than compression, and/or the compression code is broken. Reported-by: Magnus Damm Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index f063b77..9507e21 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile @@ -137,7 +137,7 @@ archclean: INSTALL_PATH ?= /tftpboot boot := arch/$(ARCH)/boot -BOOT_TARGETS = vmImage vmImage.bz2 vmImage.gz vmImage.lzma +BOOT_TARGETS = vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma PHONY += $(BOOT_TARGETS) install KBUILD_IMAGE := $(boot)/vmImage @@ -151,6 +151,7 @@ install: define archhelp echo '* vmImage - Alias to selected kernel format (vmImage.gz by default)' + echo ' vmImage.bin - Uncompressed Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.bin)' echo ' vmImage.bz2 - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.bz2)' echo '* vmImage.gz - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.gz)' echo ' vmImage.lzma - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.lzma)' diff --git a/arch/blackfin/boot/Makefile b/arch/blackfin/boot/Makefile index fd9ccc5..e9c48c6 100644 --- a/arch/blackfin/boot/Makefile +++ b/arch/blackfin/boot/Makefile @@ -8,7 +8,7 @@ MKIMAGE := $(srctree)/scripts/mkuboot.sh -targets := vmImage vmImage.bz2 vmImage.gz vmImage.lzma +targets := vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma quiet_cmd_uimage = UIMAGE $@ @@ -29,6 +29,9 @@ $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE $(call if_changed,lzma) +$(obj)/vmImage.bin: $(obj)/vmlinux.bin + $(call if_changed,uimage,none) + $(obj)/vmImage.bz2: $(obj)/vmlinux.bin.bz2 $(call if_changed,uimage,bzip2) @@ -38,6 +41,7 @@ $(obj)/vmImage.gz: $(obj)/vmlinux.bin.gz $(obj)/vmImage.lzma: $(obj)/vmlinux.bin.lzma $(call if_changed,uimage,lzma) +suffix-y := bin suffix-$(CONFIG_KERNEL_GZIP) := gz suffix-$(CONFIG_KERNEL_BZIP2) := bz2 suffix-$(CONFIG_KERNEL_LZMA) := lzma -- cgit v0.10.2 From ab843c7940394584d5ec548f443cb431c0752ca5 Mon Sep 17 00:00:00 2001 From: Valentin Yakovenkov Date: Tue, 27 Oct 2009 07:06:34 +0000 Subject: Blackfin: add support for the Acvilon BF561 board Signed-off-by: Valentin Yakovenkov Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/configs/BF561-ACVILON_defconfig b/arch/blackfin/configs/BF561-ACVILON_defconfig new file mode 100644 index 0000000..b9b0f93 --- /dev/null +++ b/arch/blackfin/configs/BF561-ACVILON_defconfig @@ -0,0 +1,1643 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.31.4 +# Sat Oct 24 12:15:32 2009 +# +# CONFIG_MMU is not set +# CONFIG_FPU is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BLACKFIN=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_BUG=y +CONFIG_ZONE_DMA=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_GENERIC_GPIO=y +CONFIG_FORCE_MAX_ZONEORDER=14 +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_BASE_FULL=y +# CONFIG_FUTEX is not set +CONFIG_EPOLL=y +# CONFIG_SIGNALFD is not set +# CONFIG_TIMERFD is not set +# CONFIG_EVENTFD is not set +# CONFIG_AIO is not set + +# +# Performance Counters +# +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_DEADLINE is not set +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +# CONFIG_FREEZER is not set + +# +# Blackfin Processor Options +# + +# +# Processor and Board Settings +# +# CONFIG_BF512 is not set +# CONFIG_BF514 is not set +# CONFIG_BF516 is not set +# CONFIG_BF518 is not set +# CONFIG_BF522 is not set +# CONFIG_BF523 is not set +# CONFIG_BF524 is not set +# CONFIG_BF525 is not set +# CONFIG_BF526 is not set +# CONFIG_BF527 is not set +# CONFIG_BF531 is not set +# CONFIG_BF532 is not set +# CONFIG_BF533 is not set +# CONFIG_BF534 is not set +# CONFIG_BF536 is not set +# CONFIG_BF537 is not set +# CONFIG_BF538 is not set +# CONFIG_BF539 is not set +# CONFIG_BF542 is not set +# CONFIG_BF542M is not set +# CONFIG_BF544 is not set +# CONFIG_BF544M is not set +# CONFIG_BF547 is not set +# CONFIG_BF547M is not set +# CONFIG_BF548 is not set +# CONFIG_BF548M is not set +# CONFIG_BF549 is not set +# CONFIG_BF549M is not set +CONFIG_BF561=y +# CONFIG_SMP is not set +CONFIG_BF_REV_MIN=3 +CONFIG_BF_REV_MAX=5 +# CONFIG_BF_REV_0_0 is not set +# CONFIG_BF_REV_0_1 is not set +# CONFIG_BF_REV_0_2 is not set +# CONFIG_BF_REV_0_3 is not set +# CONFIG_BF_REV_0_4 is not set +CONFIG_BF_REV_0_5=y +# CONFIG_BF_REV_0_6 is not set +# CONFIG_BF_REV_ANY is not set +# CONFIG_BF_REV_NONE is not set +CONFIG_IRQ_PLL_WAKEUP=7 +CONFIG_IRQ_SPORT0_ERROR=7 +CONFIG_IRQ_SPORT1_ERROR=7 +CONFIG_IRQ_TIMER0=10 +CONFIG_IRQ_TIMER1=10 +CONFIG_IRQ_TIMER2=10 +CONFIG_IRQ_TIMER3=10 +CONFIG_IRQ_TIMER4=10 +CONFIG_IRQ_TIMER5=10 +CONFIG_IRQ_TIMER6=10 +CONFIG_IRQ_TIMER7=10 +CONFIG_IRQ_SPI_ERROR=7 +# CONFIG_BFIN561_EZKIT is not set +# CONFIG_BFIN561_TEPLA is not set +# CONFIG_BFIN561_BLUETECHNIX_CM is not set +CONFIG_BFIN561_ACVILON=y + +# +# BF561 Specific Configuration +# + +# +# Core B Support +# +# CONFIG_BF561_COREB is not set + +# +# Interrupt Priority Assignment +# + +# +# Priority +# +CONFIG_IRQ_DMA1_ERROR=7 +CONFIG_IRQ_DMA2_ERROR=7 +CONFIG_IRQ_IMDMA_ERROR=7 +CONFIG_IRQ_PPI0_ERROR=7 +CONFIG_IRQ_PPI1_ERROR=7 +CONFIG_IRQ_UART_ERROR=7 +CONFIG_IRQ_RESERVED_ERROR=7 +CONFIG_IRQ_DMA1_0=8 +CONFIG_IRQ_DMA1_1=8 +CONFIG_IRQ_DMA1_2=8 +CONFIG_IRQ_DMA1_3=8 +CONFIG_IRQ_DMA1_4=8 +CONFIG_IRQ_DMA1_5=8 +CONFIG_IRQ_DMA1_6=8 +CONFIG_IRQ_DMA1_7=8 +CONFIG_IRQ_DMA1_8=8 +CONFIG_IRQ_DMA1_9=8 +CONFIG_IRQ_DMA1_10=8 +CONFIG_IRQ_DMA1_11=8 +CONFIG_IRQ_DMA2_0=9 +CONFIG_IRQ_DMA2_1=9 +CONFIG_IRQ_DMA2_2=9 +CONFIG_IRQ_DMA2_3=9 +CONFIG_IRQ_DMA2_4=9 +CONFIG_IRQ_DMA2_5=9 +CONFIG_IRQ_DMA2_6=9 +CONFIG_IRQ_DMA2_7=9 +CONFIG_IRQ_DMA2_8=9 +CONFIG_IRQ_DMA2_9=9 +CONFIG_IRQ_DMA2_10=9 +CONFIG_IRQ_DMA2_11=9 +CONFIG_IRQ_TIMER8=10 +CONFIG_IRQ_TIMER9=10 +CONFIG_IRQ_TIMER10=10 +CONFIG_IRQ_TIMER11=10 +CONFIG_IRQ_PROG0_INTA=11 +CONFIG_IRQ_PROG0_INTB=11 +CONFIG_IRQ_PROG1_INTA=11 +CONFIG_IRQ_PROG1_INTB=11 +CONFIG_IRQ_PROG2_INTA=11 +CONFIG_IRQ_PROG2_INTB=11 +CONFIG_IRQ_DMA1_WRRD0=8 +CONFIG_IRQ_DMA1_WRRD1=8 +CONFIG_IRQ_DMA2_WRRD0=9 +CONFIG_IRQ_DMA2_WRRD1=9 +CONFIG_IRQ_IMDMA_WRRD0=12 +CONFIG_IRQ_IMDMA_WRRD1=12 +CONFIG_IRQ_WDTIMER=13 + +# +# Board customizations +# +# CONFIG_CMDLINE_BOOL is not set +CONFIG_BOOT_LOAD=0x1000 + +# +# Clock/PLL Setup +# +CONFIG_CLKIN_HZ=12000000 +# CONFIG_BFIN_KERNEL_CLOCK is not set +CONFIG_MAX_VCO_HZ=600000000 +CONFIG_MIN_VCO_HZ=50000000 +CONFIG_MAX_SCLK_HZ=133333333 +CONFIG_MIN_SCLK_HZ=27000000 + +# +# Kernel Timer/Scheduler +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_TICKSOURCE_GPTMR0 is not set +CONFIG_TICKSOURCE_CORETMR=y +CONFIG_CYCLES_CLOCKSOURCE=y +# CONFIG_GPTMR0_CLOCKSOURCE is not set +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y + +# +# Misc +# +CONFIG_BFIN_SCRATCH_REG_RETN=y +# CONFIG_BFIN_SCRATCH_REG_RETE is not set +# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set + +# +# Blackfin Kernel Optimizations +# + +# +# Memory Optimizations +# +CONFIG_I_ENTRY_L1=y +CONFIG_EXCPT_IRQ_SYSC_L1=y +CONFIG_DO_IRQ_L1=y +CONFIG_CORE_TIMER_IRQ_L1=y +CONFIG_IDLE_L1=y +CONFIG_SCHEDULE_L1=y +CONFIG_ARITHMETIC_OPS_L1=y +CONFIG_ACCESS_OK_L1=y +CONFIG_MEMSET_L1=y +CONFIG_MEMCPY_L1=y +CONFIG_SYS_BFIN_SPINLOCK_L1=y +# CONFIG_IP_CHECKSUM_L1 is not set +CONFIG_CACHELINE_ALIGNED_L1=y +# CONFIG_SYSCALL_TAB_L1 is not set +# CONFIG_CPLB_SWITCH_TAB_L1 is not set +CONFIG_APP_STACK_L1=y + +# +# Speed Optimizations +# +CONFIG_BFIN_INS_LOWOVERHEAD=y +CONFIG_RAMKERNEL=y +# CONFIG_ROMKERNEL is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_VIRT_TO_BUS=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 +CONFIG_BFIN_GPTIMERS=y +CONFIG_DMA_UNCACHED_4M=y +# CONFIG_DMA_UNCACHED_2M is not set +# CONFIG_DMA_UNCACHED_1M is not set +# CONFIG_DMA_UNCACHED_NONE is not set + +# +# Cache Support +# +CONFIG_BFIN_ICACHE=y +CONFIG_BFIN_EXTMEM_ICACHEABLE=y +# CONFIG_BFIN_L2_ICACHEABLE is not set +CONFIG_BFIN_DCACHE=y +# CONFIG_BFIN_DCACHE_BANKA is not set +CONFIG_BFIN_EXTMEM_DCACHEABLE=y +CONFIG_BFIN_EXTMEM_WRITEBACK=y +# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set +# CONFIG_BFIN_L2_DCACHEABLE is not set + +# +# Memory Protection Unit +# +# CONFIG_MPU is not set + +# +# Asynchronous Memory Configuration +# + +# +# EBIU_AMGCTL Global Control +# +CONFIG_C_AMCKEN=y +CONFIG_C_CDPRIO=y +CONFIG_C_B0PEN=y +CONFIG_C_B1PEN=y +CONFIG_C_B2PEN=y +# CONFIG_C_B3PEN is not set +# CONFIG_C_AMBEN is not set +# CONFIG_C_AMBEN_B0 is not set +# CONFIG_C_AMBEN_B0_B1 is not set +# CONFIG_C_AMBEN_B0_B1_B2 is not set +CONFIG_C_AMBEN_ALL=y + +# +# EBIU_AMBCTL Control +# +CONFIG_BANK_0=0x99b2 +CONFIG_BANK_1=0x3350 +CONFIG_BANK_2=0x7BB0 +CONFIG_BANK_3=0xAAC2 + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF_FDPIC=y +CONFIG_BINFMT_FLAT=y +CONFIG_BINFMT_ZFLAT=y +# CONFIG_BINFMT_SHARED_FLAT is not set +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETLABEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_RAM=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_UCLINUX is not set +CONFIG_MTD_PLATRAM=y + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SLRAM is not set +CONFIG_MTD_PHRAM=y +# CONFIG_MTD_MTDRAM is not set +CONFIG_MTD_BLOCK2MTD=y + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_VERIFY_WRITE=y +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +CONFIG_MTD_NAND_PLATFORM=y +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=2 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=y + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +CONFIG_SMSC911X=y +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_BFIN_DMA_INTERFACE is not set +# CONFIG_BFIN_PPI is not set +# CONFIG_BFIN_PPIFCD is not set +CONFIG_BFIN_SIMPLE_TIMER=y +# CONFIG_BFIN_SPI_ADC is not set +# CONFIG_BFIN_SPORT is not set +# CONFIG_BFIN_TWI_LCD is not set +# CONFIG_VT is not set +# CONFIG_DEVKMEM is not set +# CONFIG_BFIN_JTAG_COMM is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_BFIN=y +CONFIG_SERIAL_BFIN_CONSOLE=y +# CONFIG_SERIAL_BFIN_DMA is not set +CONFIG_SERIAL_BFIN_PIO=y +CONFIG_SERIAL_BFIN_UART0=y +# CONFIG_BFIN_UART0_CTSRTS is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_BFIN_SPORT is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# CAN, the car bus and industrial fieldbus +# +# CONFIG_CAN4LINUX is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOPCA=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +CONFIG_I2C_PCA_PLATFORM=y +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BFIN=y +# CONFIG_SPI_BFIN_LOCK is not set +# CONFIG_SPI_BFIN_SPORT is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +CONFIG_GPIO_PCF857X=y +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +CONFIG_SENSORS_LM75=y +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_BFIN_WDT=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +# CONFIG_SND_SEQUENCER is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +# CONFIG_SND_DRIVERS is not set +CONFIG_SND_SPI=y + +# +# ALSA Blackfin devices +# +# CONFIG_SND_BFIN_AD73322 is not set +# CONFIG_SND_USB is not set +CONFIG_SND_SOC=y +CONFIG_SND_BF5XX_I2S=y +# CONFIG_SND_BF5XX_SOC_SSM2602 is not set +# CONFIG_SND_BF5XX_SOC_AD73311 is not set +# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set +# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set +# CONFIG_SND_BF5XX_TDM is not set +# CONFIG_SND_BF5XX_AC97 is not set +CONFIG_SND_BF5XX_SOC_SPORT=y +CONFIG_SND_BF5XX_SPORT_NUM=1 +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE is not set +# CONFIG_USB_EZUSB is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP210X is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=y +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +CONFIG_USB_SERIAL_PL2303=y +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +CONFIG_RTC_DRV_DS1307=y +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_SIGMA is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_FS is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=866 +CONFIG_FAT_DEFAULT_IOCHARSET="cp1251" +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=y +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +# CONFIG_JFFS2_ZLIB is not set +CONFIG_JFFS2_LZO=y +# CONFIG_JFFS2_RTIME is not set +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="cp1251" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +CONFIG_NLS_CODEPAGE_866=y +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +CONFIG_NLS_CODEPAGE_1251=y +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +CONFIG_NLS_KOI8_R=y +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_SHIRQ=y +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_NOMMU_REGIONS is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_FRAME_POINTER is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_KMEMCHECK is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_VERBOSE=y +CONFIG_DEBUG_MMRS=y +# CONFIG_DEBUG_HWERR is not set +# CONFIG_DEBUG_DOUBLEFAULT is not set +CONFIG_DEBUG_HUNT_FOR_ZERO=y +CONFIG_DEBUG_BFIN_HWTRACE_ON=y +CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y +# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set +# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set +CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 +# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set +# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set +# CONFIG_EARLY_PRINTK is not set +CONFIG_CPLB_INFO=y +CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set + +# +# Security options +# +# CONFIG_KEYS is not set +CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_SECURITY_ROOTPLUG is not set +# CONFIG_SECURITY_TOMOYO is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/mach-bf561/boards/Kconfig b/arch/blackfin/mach-bf561/boards/Kconfig index e4bc6d7..1aa529b 100644 --- a/arch/blackfin/mach-bf561/boards/Kconfig +++ b/arch/blackfin/mach-bf561/boards/Kconfig @@ -19,4 +19,11 @@ config BFIN561_BLUETECHNIX_CM help CM-BF561 support for EVAL- and DEV-Board. +config BFIN561_ACVILON + bool "BF561-ACVILON" + help + BF561-ACVILON System On Module support (SO-DIMM 144). + For more information about Acvilon BF561 SoM + please go to http://www.niistt.ru/ + endchoice diff --git a/arch/blackfin/mach-bf561/boards/Makefile b/arch/blackfin/mach-bf561/boards/Makefile index 3a15255..a5879f7 100644 --- a/arch/blackfin/mach-bf561/boards/Makefile +++ b/arch/blackfin/mach-bf561/boards/Makefile @@ -2,6 +2,7 @@ # arch/blackfin/mach-bf561/boards/Makefile # +obj-$(CONFIG_BFIN561_ACVILON) += acvilon.o obj-$(CONFIG_BFIN561_BLUETECHNIX_CM) += cm_bf561.o obj-$(CONFIG_BFIN561_EZKIT) += ezkit.o obj-$(CONFIG_BFIN561_TEPLA) += tepla.o diff --git a/arch/blackfin/mach-bf561/boards/acvilon.c b/arch/blackfin/mach-bf561/boards/acvilon.c new file mode 100644 index 0000000..07e8dc8 --- /dev/null +++ b/arch/blackfin/mach-bf561/boards/acvilon.c @@ -0,0 +1,551 @@ +/* + * File: arch/blackfin/mach-bf561/acvilon.c + * Based on: arch/blackfin/mach-bf561/ezkit.c + * Author: + * + * Created: + * Description: + * + * Modified: + * Copyright 2004-2006 Analog Devices Inc. + * Copyright 2009 CJSC "NII STT" + * + * Bugs: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * For more information about Acvilon BF561 SoM please + * go to http://www.niistt.ru/ + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Name the Board for the /proc/cpuinfo + */ +const char bfin_board_name[] = "Acvilon board"; + +#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) +#include +static struct resource bfin_isp1760_resources[] = { + [0] = { + .start = 0x20000000, + .end = 0x20000000 + 0x000fffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_PF15, + .end = IRQ_PF15, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + }, +}; + +static struct isp1760_platform_data isp1760_priv = { + .is_isp1761 = 0, + .port1_disable = 0, + .bus_width_16 = 1, + .port1_otg = 0, + .analog_oc = 0, + .dack_polarity_high = 0, + .dreq_polarity_high = 0, +}; + +static struct platform_device bfin_isp1760_device = { + .name = "isp1760-hcd", + .id = 0, + .dev = { + .platform_data = &isp1760_priv, + }, + .num_resources = ARRAY_SIZE(bfin_isp1760_resources), + .resource = bfin_isp1760_resources, +}; +#endif + +static struct resource bfin_i2c_pca_resources[] = { + { + .name = "pca9564-regs", + .start = 0x2C000000, + .end = 0x2C000000 + 16, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, + }, { + + .start = IRQ_PF8, + .end = IRQ_PF8, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + }, +}; + +struct i2c_pca9564_pf_platform_data pca9564_platform_data = { + .gpio = -1, + .i2c_clock_speed = 330000, + .timeout = 10000 +}; + +/* PCA9564 I2C Bus driver */ +static struct platform_device bfin_i2c_pca_device = { + .name = "i2c-pca-platform", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_i2c_pca_resources), + .resource = bfin_i2c_pca_resources, + .dev = { + .platform_data = &pca9564_platform_data, + } +}; + +/* I2C devices fitted. */ +static struct i2c_board_info acvilon_i2c_devs[] __initdata = { + { + I2C_BOARD_INFO("ds1339", 0x68), + }, + { + I2C_BOARD_INFO("tcn75", 0x49), + }, +}; + +#if defined(CONFIG_MTD_PLATRAM) || defined(CONFIG_MTD_PLATRAM_MODULE) +static struct platdata_mtd_ram mtd_ram_data = { + .mapname = "rootfs(RAM)", + .bankwidth = 4, +}; + +static struct resource mtd_ram_resource = { + .start = 0x4000000, + .end = 0x5ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device mtd_ram_device = { + .name = "mtd-ram", + .id = 0, + .dev = { + .platform_data = &mtd_ram_data, + }, + .num_resources = 1, + .resource = &mtd_ram_resource, +}; +#endif + +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) +#include +static struct resource smsc911x_resources[] = { + { + .name = "smsc911x-memory", + .start = 0x28000000, + .end = 0x28000000 + 0xFF, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_PF7, + .end = IRQ_PF7, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + }, +}; + +static struct smsc911x_platform_config smsc911x_config = { + .flags = SMSC911X_USE_32BIT, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + +static struct platform_device smsc911x_device = { + .name = "smsc911x", + .id = 0, + .num_resources = ARRAY_SIZE(smsc911x_resources), + .resource = smsc911x_resources, + .dev = { + .platform_data = &smsc911x_config, + }, +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { + { + .start = BFIN_UART_THR, + .end = BFIN_UART_GCTL + 2, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_UART_RX, + .end = IRQ_UART_RX + 1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART_ERROR, + .end = IRQ_UART_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART_TX, + .end = CH_UART_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART_RX, + .end = CH_UART_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + /* Passed to driver */ + .platform_data = &bfin_uart0_peripherals, + }, +}; +#endif +#endif + +#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE) + +#ifdef CONFIG_MTD_PARTITIONS +const char *part_probes[] = { "cmdlinepart", NULL }; + +static struct mtd_partition bfin_plat_nand_partitions[] = { + { + .name = "params(nand)", + .size = 32 * 1024 * 1024, + .offset = 0, + }, { + .name = "userfs(nand)", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + }, +}; +#endif + +#define BFIN_NAND_PLAT_CLE 2 +#define BFIN_NAND_PLAT_ALE 3 + +static void bfin_plat_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, + unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_CLE) + writeb(cmd, this->IO_ADDR_W + (1 << BFIN_NAND_PLAT_CLE)); + else + writeb(cmd, this->IO_ADDR_W + (1 << BFIN_NAND_PLAT_ALE)); +} + +#define BFIN_NAND_PLAT_READY GPIO_PF10 +static int bfin_plat_nand_dev_ready(struct mtd_info *mtd) +{ + return gpio_get_value(BFIN_NAND_PLAT_READY); +} + +static struct platform_nand_data bfin_plat_nand_data = { + .chip = { + .chip_delay = 30, +#ifdef CONFIG_MTD_PARTITIONS + .part_probe_types = part_probes, + .partitions = bfin_plat_nand_partitions, + .nr_partitions = ARRAY_SIZE(bfin_plat_nand_partitions), +#endif + }, + .ctrl = { + .cmd_ctrl = bfin_plat_nand_cmd_ctrl, + .dev_ready = bfin_plat_nand_dev_ready, + }, +}; + +#define MAX(x, y) (x > y ? x : y) +static struct resource bfin_plat_nand_resources = { + .start = 0x24000000, + .end = 0x24000000 + (1 << MAX(BFIN_NAND_PLAT_CLE, BFIN_NAND_PLAT_ALE)), + .flags = IORESOURCE_IO, +}; + +static struct platform_device bfin_async_nand_device = { + .name = "gen_nand", + .id = -1, + .num_resources = 1, + .resource = &bfin_plat_nand_resources, + .dev = { + .platform_data = &bfin_plat_nand_data, + }, +}; + +static void bfin_plat_nand_init(void) +{ + gpio_request(BFIN_NAND_PLAT_READY, "bfin_nand_plat"); +} +#else +static void bfin_plat_nand_init(void) +{ +} +#endif + +#if defined(CONFIG_MTD_DATAFLASH) || defined(CONFIG_MTD_DATAFLASH_MODULE) +static struct mtd_partition bfin_spi_dataflash_partitions[] = { + { + .name = "bootloader", + .size = 0x4200, + .offset = 0, + .mask_flags = MTD_CAP_ROM}, + { + .name = "u-boot", + .size = 0x42000, + .offset = MTDPART_OFS_APPEND, + }, + { + .name = "u-boot(params)", + .size = 0x4200, + .offset = MTDPART_OFS_APPEND, + }, + { + .name = "kernel", + .size = 0x294000, + .offset = MTDPART_OFS_APPEND, + }, + { + .name = "params", + .size = 0x42000, + .offset = MTDPART_OFS_APPEND, + }, + { + .name = "rootfs", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct flash_platform_data bfin_spi_dataflash_data = { + .name = "SPI Dataflash", + .parts = bfin_spi_dataflash_partitions, + .nr_parts = ARRAY_SIZE(bfin_spi_dataflash_partitions), +}; + +/* DataFlash chip */ +static struct bfin5xx_spi_chip data_flash_chip_info = { + .enable_dma = 0, /* use dma transfer with this chip */ + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) +static struct bfin5xx_spi_chip spidev_chip_info = { + .enable_dma = 0, + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* SPI (0) */ +static struct resource bfin_spi0_resource[] = { + [0] = { + .start = SPI0_REGBASE, + .end = SPI0_REGBASE + 0xFF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = CH_SPI, + .end = CH_SPI, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = IRQ_SPI, + .end = IRQ_SPI, + .flags = IORESOURCE_IRQ, + }, +}; + +/* SPI controller data */ +static struct bfin5xx_spi_master bfin_spi0_info = { + .num_chipselect = 8, + .enable_dma = 1, /* master has the ability to do dma transfer */ + .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0}, +}; + +static struct platform_device bfin_spi0_device = { + .name = "bfin-spi", + .id = 0, /* Bus number */ + .num_resources = ARRAY_SIZE(bfin_spi0_resource), + .resource = bfin_spi0_resource, + .dev = { + .platform_data = &bfin_spi0_info, /* Passed to driver */ + }, +}; +#endif + +static struct spi_board_info bfin_spi_board_info[] __initdata = { +#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) + { + .modalias = "spidev", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 3, + .controller_data = &spidev_chip_info, + }, +#endif +#if defined(CONFIG_MTD_DATAFLASH) || defined(CONFIG_MTD_DATAFLASH_MODULE) + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .max_speed_hz = 33250000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, /* Framework bus number */ + .chip_select = 2, /* Framework chip select */ + .platform_data = &bfin_spi_dataflash_data, + .controller_data = &data_flash_chip_info, + .mode = SPI_MODE_3, + }, +#endif +}; + +static struct resource bfin_gpios_resources = { + .start = 31, +/* .end = MAX_BLACKFIN_GPIOS - 1, */ + .end = 32, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device bfin_gpios_device = { + .name = "simple-gpio", + .id = -1, + .num_resources = 1, + .resource = &bfin_gpios_resources, +}; + +static const unsigned int cclk_vlev_datasheet[] = { + VRPAIR(VLEV_085, 250000000), + VRPAIR(VLEV_090, 300000000), + VRPAIR(VLEV_095, 313000000), + VRPAIR(VLEV_100, 350000000), + VRPAIR(VLEV_105, 400000000), + VRPAIR(VLEV_110, 444000000), + VRPAIR(VLEV_115, 450000000), + VRPAIR(VLEV_120, 475000000), + VRPAIR(VLEV_125, 500000000), + VRPAIR(VLEV_130, 600000000), +}; + +static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { + .tuple_tab = cclk_vlev_datasheet, + .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), + .vr_settling_time = 25 /* us */ , +}; + +static struct platform_device bfin_dpmc = { + .name = "bfin dpmc", + .dev = { + .platform_data = &bfin_dmpc_vreg_data, + }, +}; + +static struct platform_device *acvilon_devices[] __initdata = { + &bfin_dpmc, + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + &bfin_spi0_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#endif + + &bfin_gpios_device, + +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) + &smsc911x_device, +#endif + + &bfin_i2c_pca_device, + +#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE) + &bfin_async_nand_device, +#endif + +#if defined(CONFIG_MTD_PLATRAM) || defined(CONFIG_MTD_PLATRAM_MODULE) + &mtd_ram_device, +#endif + +}; + +static int __init acvilon_init(void) +{ + int ret; + + printk(KERN_INFO "%s(): registering device resources\n", __func__); + + bfin_plat_nand_init(); + ret = + platform_add_devices(acvilon_devices, ARRAY_SIZE(acvilon_devices)); + if (ret < 0) + return ret; + + i2c_register_board_info(0, acvilon_i2c_devs, + ARRAY_SIZE(acvilon_i2c_devs)); + + bfin_write_FIO0_FLAG_C(1 << 14); + msleep(5); + bfin_write_FIO0_FLAG_S(1 << 14); + + spi_register_board_info(bfin_spi_board_info, + ARRAY_SIZE(bfin_spi_board_info)); + return 0; +} + +arch_initcall(acvilon_init); + +static struct platform_device *acvilon_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(acvilon_early_devices, + ARRAY_SIZE(acvilon_early_devices)); +} -- cgit v0.10.2 From d2685fb7b4df2850359d6ee297269a285886032d Mon Sep 17 00:00:00 2001 From: Philippe Gerum Date: Tue, 27 Oct 2009 22:05:31 +0100 Subject: Blackfin/ipipe: prepare status bitops for SMP support Signed-off-by: Philippe Gerum Signed-off-by: Li Yi Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/ipipe.h b/arch/blackfin/include/asm/ipipe.h index 4617ba6..07bd2e6 100644 --- a/arch/blackfin/include/asm/ipipe.h +++ b/arch/blackfin/include/asm/ipipe.h @@ -124,16 +124,6 @@ static inline int __ipipe_check_tickdev(const char *devname) return 1; } -static inline void __ipipe_lock_root(void) -{ - set_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status)); -} - -static inline void __ipipe_unlock_root(void) -{ - clear_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status)); -} - void __ipipe_enable_pipeline(void); #define __ipipe_hook_critical_ipi(ipd) do { } while (0) diff --git a/arch/blackfin/include/asm/ipipe_base.h b/arch/blackfin/include/asm/ipipe_base.h index 490098f..0040920 100644 --- a/arch/blackfin/include/asm/ipipe_base.h +++ b/arch/blackfin/include/asm/ipipe_base.h @@ -51,23 +51,15 @@ extern unsigned long __ipipe_root_status; /* Alias to ipipe_root_cpudom_var(status) */ -#define __ipipe_stall_root() \ - do { \ - volatile unsigned long *p = &__ipipe_root_status; \ - set_bit(0, p); \ - } while (0) - -#define __ipipe_test_and_stall_root() \ - ({ \ - volatile unsigned long *p = &__ipipe_root_status; \ - test_and_set_bit(0, p); \ - }) - -#define __ipipe_test_root() \ - ({ \ - const unsigned long *p = &__ipipe_root_status; \ - test_bit(0, p); \ - }) +void __ipipe_stall_root(void); + +unsigned long __ipipe_test_and_stall_root(void); + +unsigned long __ipipe_test_root(void); + +void __ipipe_lock_root(void); + +void __ipipe_unlock_root(void); #endif /* !__ASSEMBLY__ */ diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c index 5d73823..a77307a 100644 --- a/arch/blackfin/kernel/ipipe.c +++ b/arch/blackfin/kernel/ipipe.c @@ -335,3 +335,70 @@ void __ipipe_enable_root_irqs_hw(void) __clear_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)); bfin_sti(bfin_irq_flags); } + +/* + * We could use standard atomic bitops in the following root status + * manipulation routines, but let's prepare for SMP support in the + * same move, preventing CPU migration as required. + */ +void __ipipe_stall_root(void) +{ + unsigned long *p, flags; + + local_irq_save_hw(flags); + p = &__ipipe_root_status; + __set_bit(IPIPE_STALL_FLAG, p); + local_irq_restore_hw(flags); +} +EXPORT_SYMBOL(__ipipe_stall_root); + +unsigned long __ipipe_test_and_stall_root(void) +{ + unsigned long *p, flags; + int x; + + local_irq_save_hw(flags); + p = &__ipipe_root_status; + x = __test_and_set_bit(IPIPE_STALL_FLAG, p); + local_irq_restore_hw(flags); + + return x; +} +EXPORT_SYMBOL(__ipipe_test_and_stall_root); + +unsigned long __ipipe_test_root(void) +{ + const unsigned long *p; + unsigned long flags; + int x; + + local_irq_save_hw_smp(flags); + p = &__ipipe_root_status; + x = test_bit(IPIPE_STALL_FLAG, p); + local_irq_restore_hw_smp(flags); + + return x; +} +EXPORT_SYMBOL(__ipipe_test_root); + +void __ipipe_lock_root(void) +{ + unsigned long *p, flags; + + local_irq_save_hw(flags); + p = &__ipipe_root_status; + __set_bit(IPIPE_SYNCDEFER_FLAG, p); + local_irq_restore_hw(flags); +} +EXPORT_SYMBOL(__ipipe_lock_root); + +void __ipipe_unlock_root(void) +{ + unsigned long *p, flags; + + local_irq_save_hw(flags); + p = &__ipipe_root_status; + __clear_bit(IPIPE_SYNCDEFER_FLAG, p); + local_irq_restore_hw(flags); +} +EXPORT_SYMBOL(__ipipe_unlock_root); -- cgit v0.10.2 From 7d4a005c4334be228d36dc04e8b540775d005790 Mon Sep 17 00:00:00 2001 From: Philippe Gerum Date: Tue, 27 Oct 2009 22:05:32 +0100 Subject: Blackfin/ipipe: fix forward ref to barrier() Signed-off-by: Philippe Gerum Signed-off-by: Li Yi Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/irqflags.h b/arch/blackfin/include/asm/irqflags.h index 9b19a19..813a1af 100644 --- a/arch/blackfin/include/asm/irqflags.h +++ b/arch/blackfin/include/asm/irqflags.h @@ -33,6 +33,7 @@ static inline unsigned long bfin_cli(void) #ifdef CONFIG_IPIPE +#include #include #include @@ -49,12 +50,12 @@ static inline unsigned long bfin_cli(void) barrier(); \ } while (0) -static inline void raw_local_irq_enable(void) -{ - barrier(); - ipipe_check_context(ipipe_root_domain); - __ipipe_unstall_root(); -} +#define raw_local_irq_enable() \ + do { \ + barrier(); \ + ipipe_check_context(ipipe_root_domain); \ + __ipipe_unstall_root(); \ + } while (0) #define raw_local_save_flags_ptr(x) \ do { \ -- cgit v0.10.2 From 4815b883edeb0dd0d1997aae078f18c92da9b6b8 Mon Sep 17 00:00:00 2001 From: Philippe Gerum Date: Tue, 27 Oct 2009 22:05:33 +0100 Subject: Blackfin/ipipe: introduce support for CONFIG_MPU Signed-off-by: Philippe Gerum Signed-off-by: Li Yi Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/mmu_context.h b/arch/blackfin/include/asm/mmu_context.h index 4a3be37..ae8ef4f 100644 --- a/arch/blackfin/include/asm/mmu_context.h +++ b/arch/blackfin/include/asm/mmu_context.h @@ -66,8 +66,8 @@ activate_l1stack(struct mm_struct *mm, unsigned long sp_base) #define activate_mm(prev, next) switch_mm(prev, next, NULL) -static inline void switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm, - struct task_struct *tsk) +static inline void __switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm, + struct task_struct *tsk) { #ifdef CONFIG_MPU unsigned int cpu = smp_processor_id(); @@ -95,7 +95,24 @@ static inline void switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_m #endif } +#ifdef CONFIG_IPIPE +#define lock_mm_switch(flags) local_irq_save_hw_cond(flags) +#define unlock_mm_switch(flags) local_irq_restore_hw_cond(flags) +#else +#define lock_mm_switch(flags) do { (void)(flags); } while (0) +#define unlock_mm_switch(flags) do { (void)(flags); } while (0) +#endif /* CONFIG_IPIPE */ + #ifdef CONFIG_MPU +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk) +{ + unsigned long flags; + lock_mm_switch(flags); + __switch_mm(prev, next, tsk); + unlock_mm_switch(flags); +} + static inline void protect_page(struct mm_struct *mm, unsigned long addr, unsigned long flags) { @@ -128,6 +145,12 @@ static inline void update_protections(struct mm_struct *mm) set_mask_dcplbs(mm->context.page_rwx_mask, cpu); } } +#else /* !CONFIG_MPU */ +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk) +{ + __switch_mm(prev, next, tsk); +} #endif static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) @@ -173,4 +196,10 @@ static inline void destroy_context(struct mm_struct *mm) #endif } +#define ipipe_mm_switch_protect(flags) \ + local_irq_save_hw_cond(flags) + +#define ipipe_mm_switch_unprotect(flags) \ + local_irq_restore_hw_cond(flags) + #endif -- cgit v0.10.2 From 2c29661e0bfbc04c18247c0eac6855d82adf4aa8 Mon Sep 17 00:00:00 2001 From: Philippe Gerum Date: Tue, 27 Oct 2009 22:05:34 +0100 Subject: Blackfin/ipipe: update version stamp Signed-off-by: Philippe Gerum Signed-off-by: Li Yi Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/ipipe.h b/arch/blackfin/include/asm/ipipe.h index 07bd2e6..d3b40449 100644 --- a/arch/blackfin/include/asm/ipipe.h +++ b/arch/blackfin/include/asm/ipipe.h @@ -35,9 +35,9 @@ #include #include -#define IPIPE_ARCH_STRING "1.11-00" +#define IPIPE_ARCH_STRING "1.12-00" #define IPIPE_MAJOR_NUMBER 1 -#define IPIPE_MINOR_NUMBER 11 +#define IPIPE_MINOR_NUMBER 12 #define IPIPE_PATCH_NUMBER 0 #ifdef CONFIG_SMP -- cgit v0.10.2 From ee3773367b8eb90fcb3ad61e7e632e8239323fa3 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 29 Oct 2009 11:37:24 +0000 Subject: Blackfin: comment the FDPIC PTRACE defines This matches similar documentation for the FRV FDPIC code. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/ptrace.h b/arch/blackfin/include/asm/ptrace.h index 27290c9..b33a448 100644 --- a/arch/blackfin/include/asm/ptrace.h +++ b/arch/blackfin/include/asm/ptrace.h @@ -89,9 +89,9 @@ struct pt_regs { #define PTRACE_GETREGS 12 #define PTRACE_SETREGS 13 /* ptrace signal */ -#define PTRACE_GETFDPIC 31 -#define PTRACE_GETFDPIC_EXEC 0 -#define PTRACE_GETFDPIC_INTERP 1 +#define PTRACE_GETFDPIC 31 /* get the ELF fdpic loadmap address */ +#define PTRACE_GETFDPIC_EXEC 0 /* [addr] request the executable loadmap */ +#define PTRACE_GETFDPIC_INTERP 1 /* [addr] request the interpreter loadmap */ #define PS_S (0x0002) -- cgit v0.10.2 From e92d32fcb9925884a0ad9e1ad8f10d837d7de7a6 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 30 Oct 2009 04:30:54 +0000 Subject: Blackfin: force BFD target when linking modules This allows us to use any Blackfin toolchain to create kernel modules (such as the FDPIC bfin-linux-uclibc toolchain). Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index 9507e21..d4c7177 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile @@ -16,6 +16,7 @@ GZFLAGS := -9 KBUILD_CFLAGS += $(call cc-option,-mno-fdpic) KBUILD_AFLAGS += $(call cc-option,-mno-fdpic) CFLAGS_MODULE += -mlong-calls +LDFLAGS_MODULE += -m elf32bfin KALLSYMS += --symbol-prefix=_ KBUILD_DEFCONFIG := BF537-STAMP_defconfig -- cgit v0.10.2 From dbc5e6989e2261c965bae5269d26ed1641e1534c Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Thu, 5 Nov 2009 15:44:44 +0000 Subject: Blackfin: don't walk VMAs when oopsing If we're double faulting, then we have to assume the VMAs are not safe as broken pointers here will prevent full trace output for the double fault. Shouldn't be a big problem though as rarely is a double fault caused by code in userspace. Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 89835ac..427294c 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -119,6 +119,15 @@ static void decode_address(char *buf, unsigned long address) return; } + /* + * Don't walk any of the vmas if we are oopsing, it has been known + * to cause problems - corrupt vmas (kernel crashes) cause double faults + */ + if (oops_in_progress) { + strcat(buf, "/* kernel dynamic memory (maybe user-space) */"); + return; + } + /* looks like we're off in user-land, so let's walk all the * mappings of all our processes and see if we can't be a whee * bit more specific -- cgit v0.10.2 From 8c0b4351ccec30e2926d0d0742ee1fa145f6e8e3 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 15 Nov 2009 07:35:22 +0000 Subject: Blackfin: gptimers: use unsigned timer/group ids Since we always use these ids as unsigned values, and we have some assert code to make sure they don't exceed a limit, avoid signed issues. Reported-by: Roel Kluin Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/gptimers.h b/arch/blackfin/include/asm/gptimers.h index 89f08de..c722acd 100644 --- a/arch/blackfin/include/asm/gptimers.h +++ b/arch/blackfin/include/asm/gptimers.h @@ -172,25 +172,25 @@ /* The actual gptimer API */ -void set_gptimer_pwidth(int timer_id, uint32_t width); -uint32_t get_gptimer_pwidth(int timer_id); -void set_gptimer_period(int timer_id, uint32_t period); -uint32_t get_gptimer_period(int timer_id); -uint32_t get_gptimer_count(int timer_id); -int get_gptimer_intr(int timer_id); -void clear_gptimer_intr(int timer_id); -int get_gptimer_over(int timer_id); -void clear_gptimer_over(int timer_id); -void set_gptimer_config(int timer_id, uint16_t config); -uint16_t get_gptimer_config(int timer_id); -int get_gptimer_run(int timer_id); -void set_gptimer_pulse_hi(int timer_id); -void clear_gptimer_pulse_hi(int timer_id); +void set_gptimer_pwidth(unsigned int timer_id, uint32_t width); +uint32_t get_gptimer_pwidth(unsigned int timer_id); +void set_gptimer_period(unsigned int timer_id, uint32_t period); +uint32_t get_gptimer_period(unsigned int timer_id); +uint32_t get_gptimer_count(unsigned int timer_id); +int get_gptimer_intr(unsigned int timer_id); +void clear_gptimer_intr(unsigned int timer_id); +int get_gptimer_over(unsigned int timer_id); +void clear_gptimer_over(unsigned int timer_id); +void set_gptimer_config(unsigned int timer_id, uint16_t config); +uint16_t get_gptimer_config(unsigned int timer_id); +int get_gptimer_run(unsigned int timer_id); +void set_gptimer_pulse_hi(unsigned int timer_id); +void clear_gptimer_pulse_hi(unsigned int timer_id); void enable_gptimers(uint16_t mask); void disable_gptimers(uint16_t mask); void disable_gptimers_sync(uint16_t mask); uint16_t get_enabled_gptimers(void); -uint32_t get_gptimer_status(int group); -void set_gptimer_status(int group, uint32_t value); +uint32_t get_gptimer_status(unsigned int group); +void set_gptimer_status(unsigned int group, uint32_t value); #endif diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c index 7281a91..cdbe075 100644 --- a/arch/blackfin/kernel/gptimers.c +++ b/arch/blackfin/kernel/gptimers.c @@ -137,7 +137,7 @@ static uint32_t const timil_mask[MAX_BLACKFIN_GPTIMERS] = #endif }; -void set_gptimer_pwidth(int timer_id, uint32_t value) +void set_gptimer_pwidth(unsigned int timer_id, uint32_t value) { tassert(timer_id < MAX_BLACKFIN_GPTIMERS); timer_regs[timer_id]->width = value; @@ -145,14 +145,14 @@ void set_gptimer_pwidth(int timer_id, uint32_t value) } EXPORT_SYMBOL(set_gptimer_pwidth); -uint32_t get_gptimer_pwidth(int timer_id) +uint32_t get_gptimer_pwidth(unsigned int timer_id) { tassert(timer_id < MAX_BLACKFIN_GPTIMERS); return timer_regs[timer_id]->width; } EXPORT_SYMBOL(get_gptimer_pwidth); -void set_gptimer_period(int timer_id, uint32_t period) +void set_gptimer_period(unsigned int timer_id, uint32_t period) { tassert(timer_id < MAX_BLACKFIN_GPTIMERS); timer_regs[timer_id]->period = period; @@ -160,28 +160,28 @@ void set_gptimer_period(int timer_id, uint32_t period) } EXPORT_SYMBOL(set_gptimer_period); -uint32_t get_gptimer_period(int timer_id) +uint32_t get_gptimer_period(unsigned int timer_id) { tassert(timer_id < MAX_BLACKFIN_GPTIMERS); return timer_regs[timer_id]->period; } EXPORT_SYMBOL(get_gptimer_period); -uint32_t get_gptimer_count(int timer_id) +uint32_t get_gptimer_count(unsigned int timer_id) { tassert(timer_id < MAX_BLACKFIN_GPTIMERS); return timer_regs[timer_id]->counter; } EXPORT_SYMBOL(get_gptimer_count); -uint32_t get_gptimer_status(int group) +uint32_t get_gptimer_status(unsigned int group) { tassert(group < BFIN_TIMER_NUM_GROUP); return group_regs[group]->status; } EXPORT_SYMBOL(get_gptimer_status); -void set_gptimer_status(int group, uint32_t value) +void set_gptimer_status(unsigned int group, uint32_t value) { tassert(group < BFIN_TIMER_NUM_GROUP); group_regs[group]->status = value; @@ -189,42 +189,42 @@ void set_gptimer_status(int group, uint32_t value) } EXPORT_SYMBOL(set_gptimer_status); -int get_gptimer_intr(int timer_id) +int get_gptimer_intr(unsigned int timer_id) { tassert(timer_id < MAX_BLACKFIN_GPTIMERS); return !!(group_regs[BFIN_TIMER_OCTET(timer_id)]->status & timil_mask[timer_id]); } EXPORT_SYMBOL(get_gptimer_intr); -void clear_gptimer_intr(int timer_id) +void clear_gptimer_intr(unsigned int timer_id) { tassert(timer_id < MAX_BLACKFIN_GPTIMERS); group_regs[BFIN_TIMER_OCTET(timer_id)]->status = timil_mask[timer_id]; } EXPORT_SYMBOL(clear_gptimer_intr); -int get_gptimer_over(int timer_id) +int get_gptimer_over(unsigned int timer_id) { tassert(timer_id < MAX_BLACKFIN_GPTIMERS); return !!(group_regs[BFIN_TIMER_OCTET(timer_id)]->status & tovf_mask[timer_id]); } EXPORT_SYMBOL(get_gptimer_over); -void clear_gptimer_over(int timer_id) +void clear_gptimer_over(unsigned int timer_id) { tassert(timer_id < MAX_BLACKFIN_GPTIMERS); group_regs[BFIN_TIMER_OCTET(timer_id)]->status = tovf_mask[timer_id]; } EXPORT_SYMBOL(clear_gptimer_over); -int get_gptimer_run(int timer_id) +int get_gptimer_run(unsigned int timer_id) { tassert(timer_id < MAX_BLACKFIN_GPTIMERS); return !!(group_regs[BFIN_TIMER_OCTET(timer_id)]->status & trun_mask[timer_id]); } EXPORT_SYMBOL(get_gptimer_run); -void set_gptimer_config(int timer_id, uint16_t config) +void set_gptimer_config(unsigned int timer_id, uint16_t config) { tassert(timer_id < MAX_BLACKFIN_GPTIMERS); timer_regs[timer_id]->config = config; @@ -232,7 +232,7 @@ void set_gptimer_config(int timer_id, uint16_t config) } EXPORT_SYMBOL(set_gptimer_config); -uint16_t get_gptimer_config(int timer_id) +uint16_t get_gptimer_config(unsigned int timer_id) { tassert(timer_id < MAX_BLACKFIN_GPTIMERS); return timer_regs[timer_id]->config; @@ -280,7 +280,7 @@ void disable_gptimers_sync(uint16_t mask) } EXPORT_SYMBOL(disable_gptimers_sync); -void set_gptimer_pulse_hi(int timer_id) +void set_gptimer_pulse_hi(unsigned int timer_id) { tassert(timer_id < MAX_BLACKFIN_GPTIMERS); timer_regs[timer_id]->config |= TIMER_PULSE_HI; @@ -288,7 +288,7 @@ void set_gptimer_pulse_hi(int timer_id) } EXPORT_SYMBOL(set_gptimer_pulse_hi); -void clear_gptimer_pulse_hi(int timer_id) +void clear_gptimer_pulse_hi(unsigned int timer_id) { tassert(timer_id < MAX_BLACKFIN_GPTIMERS); timer_regs[timer_id]->config &= ~TIMER_PULSE_HI; -- cgit v0.10.2 From 43acb9cdef3e5775f20d88fe6eb845f248c4a83d Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 15 Nov 2009 07:42:34 +0000 Subject: Blackfin: punt dead/unused flash mem_init settings I don't think these defines were ever used. At any rate, we have common bit defines for all parts as well as a Kconfig option to declare the EBIU async timings, and no one has really complained about this so far. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/mem_init.h b/arch/blackfin/include/asm/mem_init.h index 4179e32..7c8fe83 100644 --- a/arch/blackfin/include/asm/mem_init.h +++ b/arch/blackfin/include/asm/mem_init.h @@ -295,156 +295,3 @@ #else #define PLL_BYPASS 0 #endif - -/***************************************Currently Not Being Used *********************************/ - -#if defined(CONFIG_FLASH_SPEED_BWAT) && \ -defined(CONFIG_FLASH_SPEED_BRAT) && \ -defined(CONFIG_FLASH_SPEED_BHT) && \ -defined(CONFIG_FLASH_SPEED_BST) && \ -defined(CONFIG_FLASH_SPEED_BTT) - -#define flash_EBIU_AMBCTL_WAT ((CONFIG_FLASH_SPEED_BWAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 -#define flash_EBIU_AMBCTL_RAT ((CONFIG_FLASH_SPEED_BRAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 -#define flash_EBIU_AMBCTL_HT ((CONFIG_FLASH_SPEED_BHT * 4) / (4000000000 / CONFIG_SCLK_HZ)) -#define flash_EBIU_AMBCTL_ST ((CONFIG_FLASH_SPEED_BST * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 -#define flash_EBIU_AMBCTL_TT ((CONFIG_FLASH_SPEED_BTT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1 - -#if (flash_EBIU_AMBCTL_TT > 3) -#define flash_EBIU_AMBCTL0_TT B0TT_4 -#endif -#if (flash_EBIU_AMBCTL_TT == 3) -#define flash_EBIU_AMBCTL0_TT B0TT_3 -#endif -#if (flash_EBIU_AMBCTL_TT == 2) -#define flash_EBIU_AMBCTL0_TT B0TT_2 -#endif -#if (flash_EBIU_AMBCTL_TT < 2) -#define flash_EBIU_AMBCTL0_TT B0TT_1 -#endif - -#if (flash_EBIU_AMBCTL_ST > 3) -#define flash_EBIU_AMBCTL0_ST B0ST_4 -#endif -#if (flash_EBIU_AMBCTL_ST == 3) -#define flash_EBIU_AMBCTL0_ST B0ST_3 -#endif -#if (flash_EBIU_AMBCTL_ST == 2) -#define flash_EBIU_AMBCTL0_ST B0ST_2 -#endif -#if (flash_EBIU_AMBCTL_ST < 2) -#define flash_EBIU_AMBCTL0_ST B0ST_1 -#endif - -#if (flash_EBIU_AMBCTL_HT > 2) -#define flash_EBIU_AMBCTL0_HT B0HT_3 -#endif -#if (flash_EBIU_AMBCTL_HT == 2) -#define flash_EBIU_AMBCTL0_HT B0HT_2 -#endif -#if (flash_EBIU_AMBCTL_HT == 1) -#define flash_EBIU_AMBCTL0_HT B0HT_1 -#endif -#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT == 0) -#define flash_EBIU_AMBCTL0_HT B0HT_0 -#endif -#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT != 0) -#define flash_EBIU_AMBCTL0_HT B0HT_1 -#endif - -#if (flash_EBIU_AMBCTL_WAT > 14) -#define flash_EBIU_AMBCTL0_WAT B0WAT_15 -#endif -#if (flash_EBIU_AMBCTL_WAT == 14) -#define flash_EBIU_AMBCTL0_WAT B0WAT_14 -#endif -#if (flash_EBIU_AMBCTL_WAT == 13) -#define flash_EBIU_AMBCTL0_WAT B0WAT_13 -#endif -#if (flash_EBIU_AMBCTL_WAT == 12) -#define flash_EBIU_AMBCTL0_WAT B0WAT_12 -#endif -#if (flash_EBIU_AMBCTL_WAT == 11) -#define flash_EBIU_AMBCTL0_WAT B0WAT_11 -#endif -#if (flash_EBIU_AMBCTL_WAT == 10) -#define flash_EBIU_AMBCTL0_WAT B0WAT_10 -#endif -#if (flash_EBIU_AMBCTL_WAT == 9) -#define flash_EBIU_AMBCTL0_WAT B0WAT_9 -#endif -#if (flash_EBIU_AMBCTL_WAT == 8) -#define flash_EBIU_AMBCTL0_WAT B0WAT_8 -#endif -#if (flash_EBIU_AMBCTL_WAT == 7) -#define flash_EBIU_AMBCTL0_WAT B0WAT_7 -#endif -#if (flash_EBIU_AMBCTL_WAT == 6) -#define flash_EBIU_AMBCTL0_WAT B0WAT_6 -#endif -#if (flash_EBIU_AMBCTL_WAT == 5) -#define flash_EBIU_AMBCTL0_WAT B0WAT_5 -#endif -#if (flash_EBIU_AMBCTL_WAT == 4) -#define flash_EBIU_AMBCTL0_WAT B0WAT_4 -#endif -#if (flash_EBIU_AMBCTL_WAT == 3) -#define flash_EBIU_AMBCTL0_WAT B0WAT_3 -#endif -#if (flash_EBIU_AMBCTL_WAT == 2) -#define flash_EBIU_AMBCTL0_WAT B0WAT_2 -#endif -#if (flash_EBIU_AMBCTL_WAT == 1) -#define flash_EBIU_AMBCTL0_WAT B0WAT_1 -#endif - -#if (flash_EBIU_AMBCTL_RAT > 14) -#define flash_EBIU_AMBCTL0_RAT B0RAT_15 -#endif -#if (flash_EBIU_AMBCTL_RAT == 14) -#define flash_EBIU_AMBCTL0_RAT B0RAT_14 -#endif -#if (flash_EBIU_AMBCTL_RAT == 13) -#define flash_EBIU_AMBCTL0_RAT B0RAT_13 -#endif -#if (flash_EBIU_AMBCTL_RAT == 12) -#define flash_EBIU_AMBCTL0_RAT B0RAT_12 -#endif -#if (flash_EBIU_AMBCTL_RAT == 11) -#define flash_EBIU_AMBCTL0_RAT B0RAT_11 -#endif -#if (flash_EBIU_AMBCTL_RAT == 10) -#define flash_EBIU_AMBCTL0_RAT B0RAT_10 -#endif -#if (flash_EBIU_AMBCTL_RAT == 9) -#define flash_EBIU_AMBCTL0_RAT B0RAT_9 -#endif -#if (flash_EBIU_AMBCTL_RAT == 8) -#define flash_EBIU_AMBCTL0_RAT B0RAT_8 -#endif -#if (flash_EBIU_AMBCTL_RAT == 7) -#define flash_EBIU_AMBCTL0_RAT B0RAT_7 -#endif -#if (flash_EBIU_AMBCTL_RAT == 6) -#define flash_EBIU_AMBCTL0_RAT B0RAT_6 -#endif -#if (flash_EBIU_AMBCTL_RAT == 5) -#define flash_EBIU_AMBCTL0_RAT B0RAT_5 -#endif -#if (flash_EBIU_AMBCTL_RAT == 4) -#define flash_EBIU_AMBCTL0_RAT B0RAT_4 -#endif -#if (flash_EBIU_AMBCTL_RAT == 3) -#define flash_EBIU_AMBCTL0_RAT B0RAT_3 -#endif -#if (flash_EBIU_AMBCTL_RAT == 2) -#define flash_EBIU_AMBCTL0_RAT B0RAT_2 -#endif -#if (flash_EBIU_AMBCTL_RAT == 1) -#define flash_EBIU_AMBCTL0_RAT B0RAT_1 -#endif - -#define flash_EBIU_AMBCTL0 \ - (flash_EBIU_AMBCTL0_WAT | flash_EBIU_AMBCTL0_RAT | flash_EBIU_AMBCTL0_HT | \ - flash_EBIU_AMBCTL0_ST | flash_EBIU_AMBCTL0_TT | CONFIG_FLASH_SPEED_RDYEN) -#endif -- cgit v0.10.2 From f69b2d7e974e2ce22f4b17ad28c087b1077731bb Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 20 Nov 2009 19:09:56 +0000 Subject: bfin-otp: add BF51x to the supported arch list Signed-off-by: Mike Frysinger diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 6f31c94..31be3ac 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -502,7 +502,7 @@ config BRIQ_PANEL config BFIN_OTP tristate "Blackfin On-Chip OTP Memory Support" - depends on BLACKFIN && (BF52x || BF54x) + depends on BLACKFIN && (BF51x || BF52x || BF54x) default y help If you say Y here, you will get support for a character device -- cgit v0.10.2 From e34132f40b12d6066059f623d73da73de5b71e9a Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 24 Nov 2009 18:36:36 +0000 Subject: Blackfin: reject NULL callback in set_dma_callback() It makes no sense to call this function with a NULL callback. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index 639dcee..924c002 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -138,21 +138,20 @@ EXPORT_SYMBOL(request_dma); int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data) { - BUG_ON(channel >= MAX_DMA_CHANNELS || + int ret; + unsigned int irq; + + BUG_ON(channel >= MAX_DMA_CHANNELS || !callback || !atomic_read(&dma_ch[channel].chan_status)); - if (callback != NULL) { - int ret; - unsigned int irq = channel2irq(channel); + irq = channel2irq(channel); + ret = request_irq(irq, callback, 0, dma_ch[channel].device_id, data); + if (ret) + return ret; - ret = request_irq(irq, callback, IRQF_DISABLED, - dma_ch[channel].device_id, data); - if (ret) - return ret; + dma_ch[channel].irq = irq; + dma_ch[channel].data = data; - dma_ch[channel].irq = irq; - dma_ch[channel].data = data; - } return 0; } EXPORT_SYMBOL(set_dma_callback); -- cgit v0.10.2 From 0d5e35940b3ec3a0695cfcd8f6273ba083638c22 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Mon, 23 Nov 2009 06:07:53 +0000 Subject: Blackfin: kgdb: punt dead code None of these vars/funcs were being used. Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/kgdb.h b/arch/blackfin/include/asm/kgdb.h index c8b256d..8651afe 100644 --- a/arch/blackfin/include/asm/kgdb.h +++ b/arch/blackfin/include/asm/kgdb.h @@ -10,9 +10,6 @@ #include -/* gdb locks */ -#define KGDB_MAX_NO_CPUS 8 - /* * BUFMAX defines the maximum number of characters in inbound/outbound buffers. * At least NUMREGBYTES*2 are needed for register packets. diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c index cce79d0..f1036b6 100644 --- a/arch/blackfin/kernel/kgdb.c +++ b/arch/blackfin/kernel/kgdb.c @@ -24,16 +24,6 @@ #include #include -/* Put the error code here just in case the user cares. */ -int gdb_bfin_errcode; -/* Likewise, the vector number here (since GDB only gets the signal - number through the usual means, and that's not very specific). */ -int gdb_bfin_vector = -1; - -#if KGDB_MAX_NO_CPUS != 8 -#error change the definition of slavecpulocks -#endif - void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) { gdb_regs[BFIN_R0] = regs->r0; @@ -369,13 +359,6 @@ void kgdb_roundup_cpu(int cpu, unsigned long flags) } #endif -void kgdb_post_primary_code(struct pt_regs *regs, int eVector, int err_code) -{ - /* Master processor is completely in the debugger */ - gdb_bfin_vector = eVector; - gdb_bfin_errcode = err_code; -} - int kgdb_arch_handle_exception(int vector, int signo, int err_code, char *remcom_in_buffer, char *remcom_out_buffer, -- cgit v0.10.2 From 2f5a0864025743aeae20669984c1a998fe263194 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 19 Nov 2009 19:15:26 +0000 Subject: Blackfin: finish_atomic_sections: optimize the RTS step No point in returning to userspace just to have it immediately perform the RTS step. We have to update the PC anyways, so do the RTS too. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index a577238..b56b0e4 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -258,9 +258,12 @@ void finish_atomic_sections (struct pt_regs *regs) int __user *up0 = (int __user *)regs->p0; switch (regs->pc) { + default: + /* not in middle of an atomic step, so resume like normal */ + return; + case ATOMIC_XCHG32 + 2: put_user(regs->r1, up0); - regs->pc = ATOMIC_XCHG32 + 4; break; case ATOMIC_CAS32 + 2: @@ -268,7 +271,6 @@ void finish_atomic_sections (struct pt_regs *regs) if (regs->r0 == regs->r1) case ATOMIC_CAS32 + 6: put_user(regs->r2, up0); - regs->pc = ATOMIC_CAS32 + 8; break; case ATOMIC_ADD32 + 2: @@ -276,7 +278,6 @@ void finish_atomic_sections (struct pt_regs *regs) /* fall through */ case ATOMIC_ADD32 + 4: put_user(regs->r0, up0); - regs->pc = ATOMIC_ADD32 + 6; break; case ATOMIC_SUB32 + 2: @@ -284,7 +285,6 @@ void finish_atomic_sections (struct pt_regs *regs) /* fall through */ case ATOMIC_SUB32 + 4: put_user(regs->r0, up0); - regs->pc = ATOMIC_SUB32 + 6; break; case ATOMIC_IOR32 + 2: @@ -292,7 +292,6 @@ void finish_atomic_sections (struct pt_regs *regs) /* fall through */ case ATOMIC_IOR32 + 4: put_user(regs->r0, up0); - regs->pc = ATOMIC_IOR32 + 6; break; case ATOMIC_AND32 + 2: @@ -300,7 +299,6 @@ void finish_atomic_sections (struct pt_regs *regs) /* fall through */ case ATOMIC_AND32 + 4: put_user(regs->r0, up0); - regs->pc = ATOMIC_AND32 + 6; break; case ATOMIC_XOR32 + 2: @@ -308,9 +306,15 @@ void finish_atomic_sections (struct pt_regs *regs) /* fall through */ case ATOMIC_XOR32 + 4: put_user(regs->r0, up0); - regs->pc = ATOMIC_XOR32 + 6; break; } + + /* + * We've finished the atomic section, and the only thing left for + * userspace is to do a RTS, so we might as well handle that too + * since we need to update the PC anyways. + */ + regs->pc = regs->rets; } static inline -- cgit v0.10.2 From 5df326aca48b8631c9e3c90c76d7e9f0b466a721 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 16 Nov 2009 23:49:41 +0000 Subject: Blackfin: push BF5Xx configs down into mach-specific Kconfigs While we're moving the BF54x code, have the BF54xM variants select the normal BF54x values so that the rest of the Kconfig tree doesn't need to check the BF54xM variant everytime it wants to check the BF54x. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index af44a06..d703247 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -176,7 +176,7 @@ config BF539 help BF539 Processor Support. -config BF542 +config BF542_std bool "BF542" help BF542 Processor Support. @@ -186,7 +186,7 @@ config BF542M help BF542 Processor Support. -config BF544 +config BF544_std bool "BF544" help BF544 Processor Support. @@ -196,7 +196,7 @@ config BF544M help BF544 Processor Support. -config BF547 +config BF547_std bool "BF547" help BF547 Processor Support. @@ -206,7 +206,7 @@ config BF547M help BF547 Processor Support. -config BF548 +config BF548_std bool "BF548" help BF548 Processor Support. @@ -216,7 +216,7 @@ config BF548M help BF548 Processor Support. -config BF549 +config BF549_std bool "BF549" help BF549 Processor Support. @@ -310,31 +310,11 @@ config BF_REV_NONE endchoice -config BF51x - bool - depends on (BF512 || BF514 || BF516 || BF518) - default y - -config BF52x - bool - depends on (BF522 || BF523 || BF524 || BF525 || BF526 || BF527) - default y - config BF53x bool depends on (BF531 || BF532 || BF533 || BF534 || BF536 || BF537) default y -config BF54xM - bool - depends on (BF542M || BF544M || BF547M || BF548M || BF549M) - default y - -config BF54x - bool - depends on (BF542 || BF544 || BF547 || BF548 || BF549 || BF54xM) - default y - config MEM_GENERIC_BOARD bool depends on GENERIC_BOARD diff --git a/arch/blackfin/mach-bf518/Kconfig b/arch/blackfin/mach-bf518/Kconfig index 4c76fef..4ab2d16 100644 --- a/arch/blackfin/mach-bf518/Kconfig +++ b/arch/blackfin/mach-bf518/Kconfig @@ -1,3 +1,7 @@ +config BF51x + def_bool y + depends on (BF512 || BF514 || BF516 || BF518) + if (BF51x) source "arch/blackfin/mach-bf518/boards/Kconfig" diff --git a/arch/blackfin/mach-bf527/Kconfig b/arch/blackfin/mach-bf527/Kconfig index 848ac6f..1f8cbe9 100644 --- a/arch/blackfin/mach-bf527/Kconfig +++ b/arch/blackfin/mach-bf527/Kconfig @@ -1,3 +1,7 @@ +config BF52x + def_bool y + depends on (BF522 || BF523 || BF524 || BF525 || BF526 || BF527) + if (BF52x) source "arch/blackfin/mach-bf527/boards/Kconfig" diff --git a/arch/blackfin/mach-bf548/Kconfig b/arch/blackfin/mach-bf548/Kconfig index a09623d..70189a0 100644 --- a/arch/blackfin/mach-bf548/Kconfig +++ b/arch/blackfin/mach-bf548/Kconfig @@ -1,3 +1,27 @@ +config BF542 + def_bool y + depends on BF542_std || BF542M +config BF544 + def_bool y + depends on BF544_std || BF544M +config BF547 + def_bool y + depends on BF547_std || BF547M +config BF548 + def_bool y + depends on BF548_std || BF548M +config BF549 + def_bool y + depends on BF549_std || BF549M + +config BF54xM + def_bool y + depends on (BF542M || BF544M || BF547M || BF548M || BF549M) + +config BF54x + def_bool y + depends on (BF542 || BF544 || BF547 || BF548 || BF549) + if (BF54x) source "arch/blackfin/mach-bf548/boards/Kconfig" diff --git a/arch/blackfin/mach-bf548/include/mach/bf548.h b/arch/blackfin/mach-bf548/include/mach/bf548.h index 7bead5c..751e5e1 100644 --- a/arch/blackfin/mach-bf548/include/mach/bf548.h +++ b/arch/blackfin/mach-bf548/include/mach/bf548.h @@ -81,18 +81,6 @@ #define AMGCTLVAL (V_AMBEN | V_AMCKEN) -#if defined(CONFIG_BF542M) -# define CONFIG_BF542 -#elif defined(CONFIG_BF544M) -# define CONFIG_BF544 -#elif defined(CONFIG_BF547M) -# define CONFIG_BF547 -#elif defined(CONFIG_BF548M) -# define CONFIG_BF548 -#elif defined(CONFIG_BF549M) -# define CONFIG_BF549 -#endif - #if defined(CONFIG_BF542) # define CPU "BF542" # define CPUID 0x27de -- cgit v0.10.2 From c45c06596e0d45125d25beb0fe24a68aef1f1046 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 2 Dec 2009 09:13:36 +0000 Subject: Blackfin: support smaller uncached DMA chunks for memory constrained systems When working with 8 meg systems, forcing a 1 meg DMA chunk heavily cuts into the available resources. So support smaller chunks to better cover needs for these systems. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index d703247..8141b1e 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -896,6 +896,12 @@ config DMA_UNCACHED_2M bool "Enable 2M DMA region" config DMA_UNCACHED_1M bool "Enable 1M DMA region" +config DMA_UNCACHED_512K + bool "Enable 512K DMA region" +config DMA_UNCACHED_256K + bool "Enable 256K DMA region" +config DMA_UNCACHED_128K + bool "Enable 128K DMA region" config DMA_UNCACHED_NONE bool "Disable DMA region" endchoice diff --git a/arch/blackfin/include/asm/bfin-global.h b/arch/blackfin/include/asm/bfin-global.h index 741c021..e6485c3 100644 --- a/arch/blackfin/include/asm/bfin-global.h +++ b/arch/blackfin/include/asm/bfin-global.h @@ -20,6 +20,12 @@ # define DMA_UNCACHED_REGION (2 * 1024 * 1024) #elif defined(CONFIG_DMA_UNCACHED_1M) # define DMA_UNCACHED_REGION (1024 * 1024) +#elif defined(CONFIG_DMA_UNCACHED_512K) +# define DMA_UNCACHED_REGION (512 * 1024) +#elif defined(CONFIG_DMA_UNCACHED_256K) +# define DMA_UNCACHED_REGION (256 * 1024) +#elif defined(CONFIG_DMA_UNCACHED_128K) +# define DMA_UNCACHED_REGION (128 * 1024) #else # define DMA_UNCACHED_REGION (0) #endif diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index fd9a2f3..c9b0a4d 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c @@ -89,15 +89,25 @@ void __init generate_cplb_tables_cpu(unsigned int cpu) void __init generate_cplb_tables_all(void) { + unsigned long uncached_end; int i_d, i_i; i_d = 0; /* Normal RAM, including MTD FS. */ #ifdef CONFIG_MTD_UCLINUX - dcplb_bounds[i_d].eaddr = memory_mtd_start + mtd_size; + uncached_end = memory_mtd_start + mtd_size; #else - dcplb_bounds[i_d].eaddr = memory_end; + uncached_end = memory_end; #endif + /* + * if DMA uncached is less than 1MB, mark the 1MB chunk as uncached + * so that we don't have to use 4kB pages and cause CPLB thrashing + */ + if ((DMA_UNCACHED_REGION >= 1 * 1024 * 1024) || !DMA_UNCACHED_REGION || + ((_ramend - uncached_end) >= 1 * 1024 * 1024)) + dcplb_bounds[i_d].eaddr = uncached_end; + else + dcplb_bounds[i_d].eaddr = uncached_end & ~(1 * 1024 * 1024); dcplb_bounds[i_d++].data = SDRAM_DGENERIC; /* DMA uncached region. */ if (DMA_UNCACHED_REGION) { @@ -135,11 +145,7 @@ void __init generate_cplb_tables_all(void) i_i = 0; /* Normal RAM, including MTD FS. */ -#ifdef CONFIG_MTD_UCLINUX - icplb_bounds[i_i].eaddr = memory_mtd_start + mtd_size; -#else - icplb_bounds[i_i].eaddr = memory_end; -#endif + icplb_bounds[i_i].eaddr = uncached_end; icplb_bounds[i_i++].data = SDRAM_IGENERIC; /* DMA uncached region. */ if (DMA_UNCACHED_REGION) { -- cgit v0.10.2 From d45e8db1b20c510a189d769d877af2e8e9df985f Mon Sep 17 00:00:00 2001 From: Barry Song Date: Fri, 27 Nov 2009 04:37:52 +0000 Subject: Blackfin: drop 4KB reserve at end of memory The point of this small chunk was to avoid anomaly 05000310. This never really seemed to do what it was intended though -- no valid CPLBs exist over the reserved memory, and there is often memory before it anyways (due to the uClinux MTD and/or reserved DMA region). Plus, it doesn't address the L1 instruction case. So drop this chunk as it wastes memory and is affront to humanity. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index a7ae73a..95448ae 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -601,11 +601,6 @@ static __init void memory_setup(void) page_mask_order = get_order(3 * page_mask_nelts * sizeof(long)); #endif -#if !defined(CONFIG_MTD_UCLINUX) - /*In case there is no valid CPLB behind memory_end make sure we don't get to close*/ - memory_end -= SIZE_4K; -#endif - init_mm.start_code = (unsigned long)_stext; init_mm.end_code = (unsigned long)_etext; init_mm.end_data = (unsigned long)_edata; -- cgit v0.10.2 From e187837b6f23c99c219ffc1d42aa18567f6e299d Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 2 Dec 2009 02:50:43 +0000 Subject: Blackfin: MPU: support XIP in async flash memory The NOMPU code already supported executing in the async banks, so this brings the MPU code in line. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c index 69e0e53..930c01c 100644 --- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c +++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c @@ -113,11 +113,11 @@ static noinline int dcplb_miss(unsigned int cpu) addr = L2_START; d_data = L2_DMEMORY; } else if (addr >= physical_mem_end) { - if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE - && (status & FAULT_USERSUPV)) { - addr &= ~0x3fffff; + if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) { + addr &= ~(4 * 1024 * 1024 - 1); d_data &= ~PAGE_SIZE_4KB; d_data |= PAGE_SIZE_4MB; + d_data |= CPLB_USER_RD | CPLB_USER_WR; } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH && (status & (FAULT_RW | FAULT_USERSUPV)) == FAULT_USERSUPV) { addr &= ~(1 * 1024 * 1024 - 1); @@ -203,7 +203,12 @@ static noinline int icplb_miss(unsigned int cpu) addr = L2_START; i_data = L2_IMEMORY; } else if (addr >= physical_mem_end) { - if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH + if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) { + addr &= ~(4 * 1024 * 1024 - 1); + i_data &= ~PAGE_SIZE_4KB; + i_data |= PAGE_SIZE_4MB; + i_data |= CPLB_USER_RD; + } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH && (status & FAULT_USERSUPV)) { addr &= ~(1 * 1024 * 1024 - 1); i_data &= ~PAGE_SIZE_4KB; -- cgit v0.10.2 From 340a1be1eed07bb46c2f2d853e60234c1d5bb1c3 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 25 Nov 2009 05:39:03 +0000 Subject: Blackfin: drop ptrace() write support for fixed code/bootrom These regions are either read-only and won't work anyways (bootrom), or we don't want people screwing with them because they're shared between all processes (fixed code). Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index 56b0ba1..65567dc 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c @@ -316,19 +316,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case BFIN_MEM_ACCESS_CORE_ONLY: copied = access_process_vm(child, addr, &data, to_copy, 1); - if (copied) - break; - - /* hrm, why didn't that work ... maybe no mapping */ - if (addr >= FIXED_CODE_START && - addr + to_copy <= FIXED_CODE_END) { - copy_to_user_page(0, 0, 0, paddr, &data, to_copy); - copied = to_copy; - } else if (addr >= BOOT_ROM_START) { - memcpy(paddr, &data, to_copy); - copied = to_copy; - } - break; case BFIN_MEM_ACCESS_DMA: if (safe_dma_memcpy(paddr, &data, to_copy)) -- cgit v0.10.2 From a00b4fe5ce4b98f7c4457fffdb392d7bfece2e78 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Fri, 27 Nov 2009 09:18:21 +0000 Subject: Blackfin: workaround anomaly 05000310 While fetching instructions at the boundary of L1 instruction SRAM, a false External Memory Addressing Error might be triggered. We should ignore this and continue on our way to avoid random crashes. Because hardware errors are not exact in the Blackfin architecture, we need to catch a few more common cases when the code flow changes and the signal is finally delivered. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 427294c..e4fd516 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -524,6 +524,36 @@ asmlinkage notrace void trap_c(struct pt_regs *fp) break; /* External Memory Addressing Error */ case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): + if (ANOMALY_05000310) { + static unsigned long anomaly_rets; + + if ((fp->pc >= (L1_CODE_START + L1_CODE_LENGTH - 512)) && + (fp->pc < (L1_CODE_START + L1_CODE_LENGTH))) { + /* + * A false hardware error will happen while fetching at + * the L1 instruction SRAM boundary. Ignore it. + */ + anomaly_rets = fp->rets; + goto traps_done; + } else if (fp->rets == anomaly_rets) { + /* + * While boundary code returns to a function, at the ret + * point, a new false hardware error might occur too based + * on tests. Ignore it too. + */ + goto traps_done; + } else if ((fp->rets >= (L1_CODE_START + L1_CODE_LENGTH - 512)) && + (fp->rets < (L1_CODE_START + L1_CODE_LENGTH))) { + /* + * If boundary code calls a function, at the entry point, + * a new false hardware error maybe happen based on tests. + * Ignore it too. + */ + goto traps_done; + } else + anomaly_rets = 0; + } + info.si_code = BUS_ADRERR; sig = SIGBUS; strerror = KERN_NOTICE HWC_x3(KERN_NOTICE); -- cgit v0.10.2 From dd3b0e3e6a322184313e47e2fd5955ab113ad463 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Mon, 23 Nov 2009 03:47:24 +0000 Subject: Blackfin: dma-mapping.h: flesh out missing DMA mapping functions Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/dma-mapping.h b/arch/blackfin/include/asm/dma-mapping.h index 7a23d82..f9172ff 100644 --- a/arch/blackfin/include/asm/dma-mapping.h +++ b/arch/blackfin/include/asm/dma-mapping.h @@ -7,9 +7,9 @@ #ifndef _BLACKFIN_DMA_MAPPING_H #define _BLACKFIN_DMA_MAPPING_H -#include +#include +struct scatterlist; -void dma_alloc_init(unsigned long start, unsigned long end); void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp); void dma_free_coherent(struct device *dev, size_t size, void *vaddr, @@ -20,13 +20,51 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr, */ #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) +#define dma_supported(d, m) (1) +#define dma_get_cache_alignment() (32) +#define dma_is_consistent(d, h) (1) -static inline -int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +static inline int +dma_set_mask(struct device *dev, u64 dma_mask) { + if (!dev->dma_mask || !dma_supported(dev, dma_mask)) + return -EIO; + + *dev->dma_mask = dma_mask; + return 0; } +static inline int +dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + return 0; +} + +extern void +__dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir); +static inline void +_dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir) +{ + if (!__builtin_constant_p(dir)) { + __dma_sync(addr, size, dir); + return; + } + + switch (dir) { + case DMA_NONE: + BUG(); + case DMA_TO_DEVICE: /* writeback only */ + flush_dcache_range(addr, addr + size); + break; + case DMA_FROM_DEVICE: /* invalidate only */ + case DMA_BIDIRECTIONAL: /* flush and invalidate */ + /* Blackfin has no dedicated invalidate (it includes a flush) */ + invalidate_dcache_range(addr, addr + size); + break; + } +} + /* * Map a single buffer of the indicated size for DMA in streaming mode. * The 32-bit bus address to use is returned. @@ -34,8 +72,13 @@ int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) * Once the device is given the dma address, the device owns this memory * until either pci_unmap_single or pci_dma_sync_single is performed. */ -extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, - enum dma_data_direction direction); +static inline dma_addr_t +dma_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction dir) +{ + _dma_sync((dma_addr_t)ptr, size, dir); + return (dma_addr_t) ptr; +} static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, @@ -53,8 +96,12 @@ dma_map_page(struct device *dev, struct page *page, * After this call, reads by the cpu to the buffer are guarenteed to see * whatever the device wrote there. */ -extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, - enum dma_data_direction direction); +static inline void +dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction dir) +{ + BUG_ON(!valid_dma_direction(dir)); +} static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, @@ -80,38 +127,66 @@ dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, * the same here. */ extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, - enum dma_data_direction direction); + enum dma_data_direction dir); /* * Unmap a set of streaming mode DMA translations. * Again, cpu read rules concerning calls here are the same as for * pci_unmap_single() above. */ -extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg, - int nhwentries, enum dma_data_direction direction); +static inline void +dma_unmap_sg(struct device *dev, struct scatterlist *sg, + int nhwentries, enum dma_data_direction dir) +{ + BUG_ON(!valid_dma_direction(dir)); +} -static inline void dma_sync_single_for_cpu(struct device *dev, - dma_addr_t handle, size_t size, - enum dma_data_direction dir) +static inline void +dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t handle, + unsigned long offset, size_t size, + enum dma_data_direction dir) { + BUG_ON(!valid_dma_direction(dir)); } -static inline void dma_sync_single_for_device(struct device *dev, - dma_addr_t handle, size_t size, - enum dma_data_direction dir) +static inline void +dma_sync_single_range_for_device(struct device *dev, dma_addr_t handle, + unsigned long offset, size_t size, + enum dma_data_direction dir) { + _dma_sync(handle + offset, size, dir); } -static inline void dma_sync_sg_for_cpu(struct device *dev, - struct scatterlist *sg, - int nents, enum dma_data_direction dir) +static inline void +dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size, + enum dma_data_direction dir) { + dma_sync_single_range_for_cpu(dev, handle, 0, size, dir); } -static inline void dma_sync_sg_for_device(struct device *dev, - struct scatterlist *sg, - int nents, enum dma_data_direction dir) +static inline void +dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size, + enum dma_data_direction dir) +{ + dma_sync_single_range_for_device(dev, handle, 0, size, dir); +} + +static inline void +dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir) +{ + BUG_ON(!valid_dma_direction(dir)); +} + +extern void +dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir); + +static inline void +dma_cache_sync(struct device *dev, void *vaddr, size_t size, + enum dma_data_direction dir) { + _dma_sync((dma_addr_t)vaddr, size, dir); } #endif /* _BLACKFIN_DMA_MAPPING_H */ diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index 5eb2950..bd2e622 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -13,8 +13,7 @@ #include #include #include - -#define MAX_DMA_ADDRESS PAGE_OFFSET +#include /* DMA_CONFIG Masks */ #define DMAEN 0x0001 /* DMA Channel Enable */ @@ -257,8 +256,6 @@ static inline void enable_dma(unsigned int channel) dma_ch[channel].regs->curr_y_count = 0; dma_ch[channel].regs->cfg |= DMAEN; } -void free_dma(unsigned int channel); -int request_dma(unsigned int channel, const char *device_id); int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data); static inline void dma_disable_irq(unsigned int channel) diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c index 755a0f4..e937f32 100644 --- a/arch/blackfin/kernel/dma-mapping.c +++ b/arch/blackfin/kernel/dma-mapping.c @@ -7,17 +7,11 @@ */ #include -#include +#include #include -#include #include -#include #include -#include #include -#include -#include -#include static spinlock_t dma_page_lock; static unsigned long *dma_page; @@ -26,7 +20,7 @@ static unsigned long dma_base; static unsigned long dma_size; static unsigned int dma_initialized; -void dma_alloc_init(unsigned long start, unsigned long end) +static void dma_alloc_init(unsigned long start, unsigned long end) { spin_lock_init(&dma_page_lock); dma_initialized = 0; @@ -93,7 +87,7 @@ static void __free_dma_pages(unsigned long addr, unsigned int pages) } void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t * dma_handle, gfp_t gfp) + dma_addr_t *dma_handle, gfp_t gfp) { void *ret; @@ -117,21 +111,14 @@ dma_free_coherent(struct device *dev, size_t size, void *vaddr, EXPORT_SYMBOL(dma_free_coherent); /* - * Dummy functions defined for some existing drivers + * Streaming DMA mappings */ - -dma_addr_t -dma_map_single(struct device *dev, void *ptr, size_t size, - enum dma_data_direction direction) +void __dma_sync(dma_addr_t addr, size_t size, + enum dma_data_direction dir) { - BUG_ON(direction == DMA_NONE); - - invalidate_dcache_range((unsigned long)ptr, - (unsigned long)ptr + size); - - return (dma_addr_t) ptr; + _dma_sync(addr, size, dir); } -EXPORT_SYMBOL(dma_map_single); +EXPORT_SYMBOL(__dma_sync); int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, @@ -139,30 +126,23 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, { int i; - BUG_ON(direction == DMA_NONE); - for (i = 0; i < nents; i++, sg++) { sg->dma_address = (dma_addr_t) sg_virt(sg); - - invalidate_dcache_range(sg_dma_address(sg), - sg_dma_address(sg) + - sg_dma_len(sg)); + __dma_sync(sg_dma_address(sg), sg_dma_len(sg), direction); } return nents; } EXPORT_SYMBOL(dma_map_sg); -void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, - enum dma_data_direction direction) +void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, + int nelems, enum dma_data_direction direction) { - BUG_ON(direction == DMA_NONE); -} -EXPORT_SYMBOL(dma_unmap_single); + int i; -void dma_unmap_sg(struct device *dev, struct scatterlist *sg, - int nhwentries, enum dma_data_direction direction) -{ - BUG_ON(direction == DMA_NONE); + for (i = 0; i < nelems; i++, sg++) { + sg->dma_address = (dma_addr_t) sg_virt(sg); + __dma_sync(sg_dma_address(sg), sg_dma_len(sg), direction); + } } -EXPORT_SYMBOL(dma_unmap_sg); +EXPORT_SYMBOL(dma_sync_sg_for_device); -- cgit v0.10.2 From 2d40292b5a7bf104e3a386bf272641f5de532ae9 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 30 Nov 2009 18:41:58 +0000 Subject: Blackfin: io.h: fix random busted whitespace Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/io.h b/arch/blackfin/include/asm/io.h index d1f5029..29e55b9 100644 --- a/arch/blackfin/include/asm/io.h +++ b/arch/blackfin/include/asm/io.h @@ -31,12 +31,14 @@ static inline unsigned char readb(const volatile void __iomem *addr) unsigned int val; int tmp; - __asm__ __volatile__ ("cli %1;\n\t" - "NOP; NOP; SSYNC;\n\t" - "%0 = b [%2] (z);\n\t" - "sti %1;\n\t" - : "=d"(val), "=d"(tmp): "a"(addr) - ); + __asm__ __volatile__ ( + "cli %1;" + "NOP; NOP; SSYNC;" + "%0 = b [%2] (z);" + "sti %1;" + : "=d"(val), "=d"(tmp) + : "a"(addr) + ); return (unsigned char) val; } @@ -46,12 +48,14 @@ static inline unsigned short readw(const volatile void __iomem *addr) unsigned int val; int tmp; - __asm__ __volatile__ ("cli %1;\n\t" - "NOP; NOP; SSYNC;\n\t" - "%0 = w [%2] (z);\n\t" - "sti %1;\n\t" - : "=d"(val), "=d"(tmp): "a"(addr) - ); + __asm__ __volatile__ ( + "cli %1;" + "NOP; NOP; SSYNC;" + "%0 = w [%2] (z);" + "sti %1;" + : "=d"(val), "=d"(tmp) + : "a"(addr) + ); return (unsigned short) val; } @@ -61,20 +65,23 @@ static inline unsigned int readl(const volatile void __iomem *addr) unsigned int val; int tmp; - __asm__ __volatile__ ("cli %1;\n\t" - "NOP; NOP; SSYNC;\n\t" - "%0 = [%2];\n\t" - "sti %1;\n\t" - : "=d"(val), "=d"(tmp): "a"(addr) - ); + __asm__ __volatile__ ( + "cli %1;" + "NOP; NOP; SSYNC;" + "%0 = [%2];" + "sti %1;" + : "=d"(val), "=d"(tmp) + : "a"(addr) + ); + return val; } #endif /* __ASSEMBLY__ */ -#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b)) -#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b)) -#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) +#define writeb(b, addr) (void)((*(volatile unsigned char *) (addr)) = (b)) +#define writew(b, addr) (void)((*(volatile unsigned short *) (addr)) = (b)) +#define writel(b, addr) (void)((*(volatile unsigned int *) (addr)) = (b)) #define __raw_readb readb #define __raw_readw readw @@ -82,9 +89,9 @@ static inline unsigned int readl(const volatile void __iomem *addr) #define __raw_writeb writeb #define __raw_writew writew #define __raw_writel writel -#define memset_io(a,b,c) memset((void *)(a),(b),(c)) -#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) -#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) +#define memset_io(a, b, c) memset((void *)(a), (b), (c)) +#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c)) +#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c)) /* Convert "I/O port addresses" to actual addresses. i.e. ugly casts. */ #define __io(port) ((void *)(unsigned long)(port)) @@ -92,30 +99,30 @@ static inline unsigned int readl(const volatile void __iomem *addr) #define inb(port) readb(__io(port)) #define inw(port) readw(__io(port)) #define inl(port) readl(__io(port)) -#define outb(x,port) writeb(x,__io(port)) -#define outw(x,port) writew(x,__io(port)) -#define outl(x,port) writel(x,__io(port)) +#define outb(x, port) writeb(x, __io(port)) +#define outw(x, port) writew(x, __io(port)) +#define outl(x, port) writel(x, __io(port)) #define inb_p(port) inb(__io(port)) #define inw_p(port) inw(__io(port)) #define inl_p(port) inl(__io(port)) -#define outb_p(x,port) outb(x,__io(port)) -#define outw_p(x,port) outw(x,__io(port)) -#define outl_p(x,port) outl(x,__io(port)) - -#define ioread8_rep(a,d,c) readsb(a,d,c) -#define ioread16_rep(a,d,c) readsw(a,d,c) -#define ioread32_rep(a,d,c) readsl(a,d,c) -#define iowrite8_rep(a,s,c) writesb(a,s,c) -#define iowrite16_rep(a,s,c) writesw(a,s,c) -#define iowrite32_rep(a,s,c) writesl(a,s,c) - -#define ioread8(X) readb(X) -#define ioread16(X) readw(X) -#define ioread32(X) readl(X) -#define iowrite8(val,X) writeb(val,X) -#define iowrite16(val,X) writew(val,X) -#define iowrite32(val,X) writel(val,X) +#define outb_p(x, port) outb(x, __io(port)) +#define outw_p(x, port) outw(x, __io(port)) +#define outl_p(x, port) outl(x, __io(port)) + +#define ioread8_rep(a, d, c) readsb(a, d, c) +#define ioread16_rep(a, d, c) readsw(a, d, c) +#define ioread32_rep(a, d, c) readsl(a, d, c) +#define iowrite8_rep(a, s, c) writesb(a, s, c) +#define iowrite16_rep(a, s, c) writesw(a, s, c) +#define iowrite32_rep(a, s, c) writesl(a, s, c) + +#define ioread8(x) readb(x) +#define ioread16(x) readw(x) +#define ioread32(x) readl(x) +#define iowrite8(val, x) writeb(val, x) +#define iowrite16(val, x) writew(val, x) +#define iowrite32(val, x) writel(val, x) #define mmiowb() wmb() -- cgit v0.10.2 From ad774b7cb0604d02c3596b79921fcb812df4dc71 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 25 Nov 2009 03:02:58 +0000 Subject: Blackfin: convert to asm-generic pci headers Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/pci.h b/arch/blackfin/include/asm/pci.h index 6127735..99cae2e 100644 --- a/arch/blackfin/include/asm/pci.h +++ b/arch/blackfin/include/asm/pci.h @@ -4,145 +4,19 @@ #define _ASM_BFIN_PCI_H #include +#include +#include -/* - * - * Written by Wout Klaren. - */ - -/* Added by Chang Junxiao */ #define PCIBIOS_MIN_IO 0x00001000 #define PCIBIOS_MIN_MEM 0x10000000 -#define PCI_DMA_BUS_IS_PHYS (1) -struct pci_ops; - -/* - * Structure with hardware dependent information and functions of the - * PCI bus. - */ -struct pci_bus_info { - - /* - * Resources of the PCI bus. - */ - struct resource mem_space; - struct resource io_space; - - /* - * System dependent functions. - */ - struct pci_ops *bfin_pci_ops; - void (*fixup) (int pci_modify); - void (*conf_device) (unsigned char bus, unsigned char device_fn); -}; - -#define pcibios_assign_all_busses() 0 static inline void pcibios_set_master(struct pci_dev *dev) { - /* No special bus mastering setup handling */ } static inline void pcibios_penalize_isa_irq(int irq) { - /* We don't do dynamic PCI IRQ allocation */ } -static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, - size_t size, int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - - /* return virt_to_bus(ptr); */ - return (dma_addr_t) ptr; -} - -/* Unmap a single streaming mode DMA translation. The dma_addr and size - * must match what was provided for in a previous pci_map_single call. All - * other usages are undefined. - * - * After this call, reads by the cpu to the buffer are guarenteed to see - * whatever the device wrote there. - */ -static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, - size_t size, int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - - /* Nothing to do */ -} - -/* Map a set of buffers described by scatterlist in streaming - * mode for DMA. This is the scather-gather version of the - * above pci_map_single interface. Here the scatter gather list - * elements are each tagged with the appropriate dma address - * and length. They are obtained via sg_dma_{address,length}(SG). - * - * NOTE: An implementation may be able to use a smaller number of - * DMA address/length pairs than there are SG table elements. - * (for example via virtual mapping capabilities) - * The routine returns the number of addr/length pairs actually - * used, at most nents. - * - * Device ownership issues as mentioned above for pci_map_single are - * the same here. - */ -static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nents, int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - return nents; -} - -/* Unmap a set of streaming mode DMA translations. - * Again, cpu read rules concerning calls here are the same as for - * pci_unmap_single() above. - */ -static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nents, int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - - /* Nothing to do */ -} - -/* Make physical memory consistent for a single - * streaming mode DMA translation after a transfer. - * - * If you perform a pci_map_single() but wish to interrogate the - * buffer using the cpu, yet do not wish to teardown the PCI dma - * mapping, you must call this function before doing so. At the - * next point you give the PCI dma address back to the card, the - * device again owns the buffer. - */ -static inline void pci_dma_sync_single(struct pci_dev *hwdev, - dma_addr_t dma_handle, size_t size, - int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - - /* Nothing to do */ -} - -/* Make physical memory consistent for a set of streaming - * mode DMA translations after a transfer. - * - * The same as pci_dma_sync_single but for a scatter-gather list, - * same rules and usage. - */ -static inline void pci_dma_sync_sg(struct pci_dev *hwdev, - struct scatterlist *sg, int nelems, - int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - - /* Nothing to do */ -} #endif /* _ASM_BFIN_PCI_H */ -- cgit v0.10.2 From 578d36f5e160208821e8f51037ac1038e065ecaf Mon Sep 17 00:00:00 2001 From: Yi Li Date: Wed, 2 Dec 2009 07:58:12 +0000 Subject: Blackfin: SMP: don't start up core b until its state has been completely onlined When testing PREEMPT_RT kernel on BF561-EZKit, the kernel blocks while booting. When the kernel initializes the ethernet driver, it sleeps and never wakes up. The issue happens when the kernel waits for a timer for Core B to timeout (the timers are per-cpu based: static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases). However, the ksoftirqd thread for Core B (note, the ksoftirqd thread is also per-cpu based) cannot work properly, and the timers for Core B never times out. When ksoftirqd() for the first time runs on core B, it is possible core A is still initializing core B (see smp_init() -> cpu_up() -> __cpu_up()). So the "cpu_is_offline()" check may return true and ksoftirqd moves to "wait_to_die". So delay the core b start up until the per-cpu timers have been set up fully. Signed-off-by: Yi Li Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c index 510f576..0192532 100644 --- a/arch/blackfin/mach-bf561/smp.c +++ b/arch/blackfin/mach-bf561/smp.c @@ -52,8 +52,6 @@ int __init setup_profiling_timer(unsigned int multiplier) /* not supported */ void __cpuinit platform_secondary_init(unsigned int cpu) { - local_irq_disable(); - /* Clone setup for peripheral interrupt sources from CoreA. */ bfin_write_SICB_IMASK0(bfin_read_SICA_IMASK0()); bfin_write_SICB_IMASK1(bfin_read_SICA_IMASK1()); @@ -70,11 +68,6 @@ void __cpuinit platform_secondary_init(unsigned int cpu) bfin_write_SICB_IAR7(bfin_read_SICA_IAR7()); SSYNC(); - local_irq_enable(); - - /* Calibrate loops per jiffy value. */ - calibrate_delay(); - /* Store CPU-private information to the cpu_data array. */ bfin_setup_cpudata(cpu); @@ -108,9 +101,13 @@ int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle barrier(); } - spin_unlock(&boot_lock); - - return cpu_isset(cpu, cpu_callin_map) ? 0 : -ENOSYS; + if (cpu_isset(cpu, cpu_callin_map)) { + cpu_set(cpu, cpu_online_map); + /* release the lock and let coreb run */ + spin_unlock(&boot_lock); + return 0; + } else + panic("CPU%u: processor failed to boot\n", cpu); } void __init platform_request_ipi(irq_handler_t handler) diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index d92b168..369e687 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c @@ -336,13 +336,6 @@ int __cpuinit __cpu_up(unsigned int cpu) ret = platform_boot_secondary(cpu, idle); - if (ret) { - cpu_clear(cpu, cpu_present_map); - printk(KERN_CRIT "CPU%u: processor failed to boot (%d)\n", cpu, ret); - free_task(idle); - } else - cpu_set(cpu, cpu_online_map); - secondary_stack = NULL; return ret; @@ -418,9 +411,16 @@ void __cpuinit secondary_start_kernel(void) setup_secondary(cpu); + platform_secondary_init(cpu); + local_irq_enable(); - platform_secondary_init(cpu); + /* + * Calibrate loops per jiffy value. + * IRQs need to be enabled here - D-cache can be invalidated + * in timer irq handler, so core B can read correct jiffies. + */ + calibrate_delay(); cpu_idle(); } -- cgit v0.10.2 From 7eb87fd3f1f680a74992b37e28fc09c943cf6e08 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 3 Nov 2009 09:29:50 +0000 Subject: Blackfin: BF537: push down error masks to avoid namespace pollution The error masks are only needed in the BF537 demux error code, so instead of needing all the short peripheral defines in global space, push these masks into the one file where they are actually needed. This fixes a bunch of define collisions with common code (can/serial/etc...). Signed-off-by: Mike Frysinger Signed-off-by: Barry Song diff --git a/arch/blackfin/mach-bf537/include/mach/bf537.h b/arch/blackfin/mach-bf537/include/mach/bf537.h index 17fab44..8b29141 100644 --- a/arch/blackfin/mach-bf537/include/mach/bf537.h +++ b/arch/blackfin/mach-bf537/include/mach/bf537.h @@ -9,16 +9,6 @@ #ifndef __MACH_BF537_H__ #define __MACH_BF537_H__ -/* Masks for generic ERROR IRQ demultiplexing used in int-priority-sc.c */ - -#define SPI_ERR_MASK (TXCOL | RBSY | MODF | TXE) /* SPI_STAT */ -#define SPORT_ERR_MASK (ROVF | RUVF | TOVF | TUVF) /* SPORTx_STAT */ -#define PPI_ERR_MASK (0xFFFF & ~FLD) /* PPI_STATUS */ -#define EMAC_ERR_MASK (PHYINT | MMCINT | RXFSINT | TXFSINT | WAKEDET | RXDMAERR | TXDMAERR | STMDONE) /* EMAC_SYSTAT */ -#define UART_ERR_MASK_STAT1 (0x4) /* UARTx_IIR */ -#define UART_ERR_MASK_STAT0 (0x2) /* UARTx_IIR */ -#define CAN_ERR_MASK (EWTIF | EWRIF | EPIF | BOIF | WUIF | UIAIF | AAIF | RMLIF | UCEIF | EXTIF | ADIF) /* CAN_GIF */ - #define OFFSET_(x) ((x) & 0x0000FFFF) /*some misc defines*/ diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 0d84fb2..1873b2c 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -26,11 +26,19 @@ #include #include #include +#include +#include #define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) #ifdef BF537_FAMILY # define BF537_GENERIC_ERROR_INT_DEMUX +# define SPI_ERR_MASK (BIT_STAT_TXCOL | BIT_STAT_RBSY | BIT_STAT_MODF | BIT_STAT_TXE) /* SPI_STAT */ +# define SPORT_ERR_MASK (ROVF | RUVF | TOVF | TUVF) /* SPORT_STAT */ +# define PPI_ERR_MASK (0xFFFF & ~FLD) /* PPI_STATUS */ +# define EMAC_ERR_MASK (PHYINT | MMCINT | RXFSINT | TXFSINT | WAKEDET | RXDMAERR | TXDMAERR | STMDONE) /* EMAC_SYSTAT */ +# define UART_ERR_MASK (0x6) /* UART_IIR */ +# define CAN_ERR_MASK (EWTIF | EWRIF | EPIF | BOIF | WUIF | UIAIF | AAIF | RMLIF | UCEIF | EXTIF | ADIF) /* CAN_GIF */ #else # undef BF537_GENERIC_ERROR_INT_DEMUX #endif @@ -325,11 +333,9 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, irq = IRQ_CAN_ERROR; else if (bfin_read_SPI_STAT() & SPI_ERR_MASK) irq = IRQ_SPI_ERROR; - else if ((bfin_read_UART0_IIR() & UART_ERR_MASK_STAT1) && - (bfin_read_UART0_IIR() & UART_ERR_MASK_STAT0)) + else if ((bfin_read_UART0_IIR() & UART_ERR_MASK) == UART_ERR_MASK) irq = IRQ_UART0_ERROR; - else if ((bfin_read_UART1_IIR() & UART_ERR_MASK_STAT1) && - (bfin_read_UART1_IIR() & UART_ERR_MASK_STAT0)) + else if ((bfin_read_UART1_IIR() & UART_ERR_MASK) == UART_ERR_MASK) irq = IRQ_UART1_ERROR; if (irq) { -- cgit v0.10.2 From b1740549d493d3ea5d16bee1cdc7b1f200163ad5 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 17 Nov 2009 06:24:51 +0000 Subject: Blackfin: BF52x: unify def/cdef headers Whole lot of duplicated code here just went bye bye. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF525.h b/arch/blackfin/mach-bf527/include/mach/cdefBF525.h index dc3119e9..d7e2751 100644 --- a/arch/blackfin/mach-bf527/include/mach/cdefBF525.h +++ b/arch/blackfin/mach-bf527/include/mach/cdefBF525.h @@ -10,15 +10,8 @@ /* include all Core registers and bit definitions */ #include "defBF525.h" -/* include core specific register pointer definitions */ -#include - -/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF525 */ - -/* include cdefBF52x_base.h for the set of #defines that are common to all ADSP-BF52x processors */ -#include "cdefBF52x_base.h" - -/* The following are the #defines needed by ADSP-BF525 that are not in the common header */ +/* BF525 is BF522 + USB */ +#include "cdefBF522.h" /* USB Control Registers */ diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF527.h b/arch/blackfin/mach-bf527/include/mach/cdefBF527.h index d6579449..c7ba544 100644 --- a/arch/blackfin/mach-bf527/include/mach/cdefBF527.h +++ b/arch/blackfin/mach-bf527/include/mach/cdefBF527.h @@ -10,15 +10,8 @@ /* include all Core registers and bit definitions */ #include "defBF527.h" -/* include core specific register pointer definitions */ -#include - -/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF527 */ - -/* include cdefBF52x_base.h for the set of #defines that are common to all ADSP-BF52x processors */ -#include "cdefBF52x_base.h" - -/* The following are the #defines needed by ADSP-BF527 that are not in the common header */ +/* BF527 is BF525 + EMAC */ +#include "cdefBF525.h" /* 10/100 Ethernet Controller (0xFFC03000 - 0xFFC031FF) */ @@ -185,417 +178,4 @@ #define bfin_read_EMAC_TXC_ABORT() bfin_read32(EMAC_TXC_ABORT) #define bfin_write_EMAC_TXC_ABORT(val) bfin_write32(EMAC_TXC_ABORT, val) -/* USB Control Registers */ - -#define bfin_read_USB_FADDR() bfin_read16(USB_FADDR) -#define bfin_write_USB_FADDR(val) bfin_write16(USB_FADDR, val) -#define bfin_read_USB_POWER() bfin_read16(USB_POWER) -#define bfin_write_USB_POWER(val) bfin_write16(USB_POWER, val) -#define bfin_read_USB_INTRTX() bfin_read16(USB_INTRTX) -#define bfin_write_USB_INTRTX(val) bfin_write16(USB_INTRTX, val) -#define bfin_read_USB_INTRRX() bfin_read16(USB_INTRRX) -#define bfin_write_USB_INTRRX(val) bfin_write16(USB_INTRRX, val) -#define bfin_read_USB_INTRTXE() bfin_read16(USB_INTRTXE) -#define bfin_write_USB_INTRTXE(val) bfin_write16(USB_INTRTXE, val) -#define bfin_read_USB_INTRRXE() bfin_read16(USB_INTRRXE) -#define bfin_write_USB_INTRRXE(val) bfin_write16(USB_INTRRXE, val) -#define bfin_read_USB_INTRUSB() bfin_read16(USB_INTRUSB) -#define bfin_write_USB_INTRUSB(val) bfin_write16(USB_INTRUSB, val) -#define bfin_read_USB_INTRUSBE() bfin_read16(USB_INTRUSBE) -#define bfin_write_USB_INTRUSBE(val) bfin_write16(USB_INTRUSBE, val) -#define bfin_read_USB_FRAME() bfin_read16(USB_FRAME) -#define bfin_write_USB_FRAME(val) bfin_write16(USB_FRAME, val) -#define bfin_read_USB_INDEX() bfin_read16(USB_INDEX) -#define bfin_write_USB_INDEX(val) bfin_write16(USB_INDEX, val) -#define bfin_read_USB_TESTMODE() bfin_read16(USB_TESTMODE) -#define bfin_write_USB_TESTMODE(val) bfin_write16(USB_TESTMODE, val) -#define bfin_read_USB_GLOBINTR() bfin_read16(USB_GLOBINTR) -#define bfin_write_USB_GLOBINTR(val) bfin_write16(USB_GLOBINTR, val) -#define bfin_read_USB_GLOBAL_CTL() bfin_read16(USB_GLOBAL_CTL) -#define bfin_write_USB_GLOBAL_CTL(val) bfin_write16(USB_GLOBAL_CTL, val) - -/* USB Packet Control Registers */ - -#define bfin_read_USB_TX_MAX_PACKET() bfin_read16(USB_TX_MAX_PACKET) -#define bfin_write_USB_TX_MAX_PACKET(val) bfin_write16(USB_TX_MAX_PACKET, val) -#define bfin_read_USB_CSR0() bfin_read16(USB_CSR0) -#define bfin_write_USB_CSR0(val) bfin_write16(USB_CSR0, val) -#define bfin_read_USB_TXCSR() bfin_read16(USB_TXCSR) -#define bfin_write_USB_TXCSR(val) bfin_write16(USB_TXCSR, val) -#define bfin_read_USB_RX_MAX_PACKET() bfin_read16(USB_RX_MAX_PACKET) -#define bfin_write_USB_RX_MAX_PACKET(val) bfin_write16(USB_RX_MAX_PACKET, val) -#define bfin_read_USB_RXCSR() bfin_read16(USB_RXCSR) -#define bfin_write_USB_RXCSR(val) bfin_write16(USB_RXCSR, val) -#define bfin_read_USB_COUNT0() bfin_read16(USB_COUNT0) -#define bfin_write_USB_COUNT0(val) bfin_write16(USB_COUNT0, val) -#define bfin_read_USB_RXCOUNT() bfin_read16(USB_RXCOUNT) -#define bfin_write_USB_RXCOUNT(val) bfin_write16(USB_RXCOUNT, val) -#define bfin_read_USB_TXTYPE() bfin_read16(USB_TXTYPE) -#define bfin_write_USB_TXTYPE(val) bfin_write16(USB_TXTYPE, val) -#define bfin_read_USB_NAKLIMIT0() bfin_read16(USB_NAKLIMIT0) -#define bfin_write_USB_NAKLIMIT0(val) bfin_write16(USB_NAKLIMIT0, val) -#define bfin_read_USB_TXINTERVAL() bfin_read16(USB_TXINTERVAL) -#define bfin_write_USB_TXINTERVAL(val) bfin_write16(USB_TXINTERVAL, val) -#define bfin_read_USB_RXTYPE() bfin_read16(USB_RXTYPE) -#define bfin_write_USB_RXTYPE(val) bfin_write16(USB_RXTYPE, val) -#define bfin_read_USB_RXINTERVAL() bfin_read16(USB_RXINTERVAL) -#define bfin_write_USB_RXINTERVAL(val) bfin_write16(USB_RXINTERVAL, val) -#define bfin_read_USB_TXCOUNT() bfin_read16(USB_TXCOUNT) -#define bfin_write_USB_TXCOUNT(val) bfin_write16(USB_TXCOUNT, val) - -/* USB Endpoint FIFO Registers */ - -#define bfin_read_USB_EP0_FIFO() bfin_read16(USB_EP0_FIFO) -#define bfin_write_USB_EP0_FIFO(val) bfin_write16(USB_EP0_FIFO, val) -#define bfin_read_USB_EP1_FIFO() bfin_read16(USB_EP1_FIFO) -#define bfin_write_USB_EP1_FIFO(val) bfin_write16(USB_EP1_FIFO, val) -#define bfin_read_USB_EP2_FIFO() bfin_read16(USB_EP2_FIFO) -#define bfin_write_USB_EP2_FIFO(val) bfin_write16(USB_EP2_FIFO, val) -#define bfin_read_USB_EP3_FIFO() bfin_read16(USB_EP3_FIFO) -#define bfin_write_USB_EP3_FIFO(val) bfin_write16(USB_EP3_FIFO, val) -#define bfin_read_USB_EP4_FIFO() bfin_read16(USB_EP4_FIFO) -#define bfin_write_USB_EP4_FIFO(val) bfin_write16(USB_EP4_FIFO, val) -#define bfin_read_USB_EP5_FIFO() bfin_read16(USB_EP5_FIFO) -#define bfin_write_USB_EP5_FIFO(val) bfin_write16(USB_EP5_FIFO, val) -#define bfin_read_USB_EP6_FIFO() bfin_read16(USB_EP6_FIFO) -#define bfin_write_USB_EP6_FIFO(val) bfin_write16(USB_EP6_FIFO, val) -#define bfin_read_USB_EP7_FIFO() bfin_read16(USB_EP7_FIFO) -#define bfin_write_USB_EP7_FIFO(val) bfin_write16(USB_EP7_FIFO, val) - -/* USB OTG Control Registers */ - -#define bfin_read_USB_OTG_DEV_CTL() bfin_read16(USB_OTG_DEV_CTL) -#define bfin_write_USB_OTG_DEV_CTL(val) bfin_write16(USB_OTG_DEV_CTL, val) -#define bfin_read_USB_OTG_VBUS_IRQ() bfin_read16(USB_OTG_VBUS_IRQ) -#define bfin_write_USB_OTG_VBUS_IRQ(val) bfin_write16(USB_OTG_VBUS_IRQ, val) -#define bfin_read_USB_OTG_VBUS_MASK() bfin_read16(USB_OTG_VBUS_MASK) -#define bfin_write_USB_OTG_VBUS_MASK(val) bfin_write16(USB_OTG_VBUS_MASK, val) - -/* USB Phy Control Registers */ - -#define bfin_read_USB_LINKINFO() bfin_read16(USB_LINKINFO) -#define bfin_write_USB_LINKINFO(val) bfin_write16(USB_LINKINFO, val) -#define bfin_read_USB_VPLEN() bfin_read16(USB_VPLEN) -#define bfin_write_USB_VPLEN(val) bfin_write16(USB_VPLEN, val) -#define bfin_read_USB_HS_EOF1() bfin_read16(USB_HS_EOF1) -#define bfin_write_USB_HS_EOF1(val) bfin_write16(USB_HS_EOF1, val) -#define bfin_read_USB_FS_EOF1() bfin_read16(USB_FS_EOF1) -#define bfin_write_USB_FS_EOF1(val) bfin_write16(USB_FS_EOF1, val) -#define bfin_read_USB_LS_EOF1() bfin_read16(USB_LS_EOF1) -#define bfin_write_USB_LS_EOF1(val) bfin_write16(USB_LS_EOF1, val) - -/* (APHY_CNTRL is for ADI usage only) */ - -#define bfin_read_USB_APHY_CNTRL() bfin_read16(USB_APHY_CNTRL) -#define bfin_write_USB_APHY_CNTRL(val) bfin_write16(USB_APHY_CNTRL, val) - -/* (APHY_CALIB is for ADI usage only) */ - -#define bfin_read_USB_APHY_CALIB() bfin_read16(USB_APHY_CALIB) -#define bfin_write_USB_APHY_CALIB(val) bfin_write16(USB_APHY_CALIB, val) - -#define bfin_read_USB_APHY_CNTRL2() bfin_read16(USB_APHY_CNTRL2) -#define bfin_write_USB_APHY_CNTRL2(val) bfin_write16(USB_APHY_CNTRL2, val) - -/* (PHY_TEST is for ADI usage only) */ - -#define bfin_read_USB_PHY_TEST() bfin_read16(USB_PHY_TEST) -#define bfin_write_USB_PHY_TEST(val) bfin_write16(USB_PHY_TEST, val) - -#define bfin_read_USB_PLLOSC_CTRL() bfin_read16(USB_PLLOSC_CTRL) -#define bfin_write_USB_PLLOSC_CTRL(val) bfin_write16(USB_PLLOSC_CTRL, val) -#define bfin_read_USB_SRP_CLKDIV() bfin_read16(USB_SRP_CLKDIV) -#define bfin_write_USB_SRP_CLKDIV(val) bfin_write16(USB_SRP_CLKDIV, val) - -/* USB Endpoint 0 Control Registers */ - -#define bfin_read_USB_EP_NI0_TXMAXP() bfin_read16(USB_EP_NI0_TXMAXP) -#define bfin_write_USB_EP_NI0_TXMAXP(val) bfin_write16(USB_EP_NI0_TXMAXP, val) -#define bfin_read_USB_EP_NI0_TXCSR() bfin_read16(USB_EP_NI0_TXCSR) -#define bfin_write_USB_EP_NI0_TXCSR(val) bfin_write16(USB_EP_NI0_TXCSR, val) -#define bfin_read_USB_EP_NI0_RXMAXP() bfin_read16(USB_EP_NI0_RXMAXP) -#define bfin_write_USB_EP_NI0_RXMAXP(val) bfin_write16(USB_EP_NI0_RXMAXP, val) -#define bfin_read_USB_EP_NI0_RXCSR() bfin_read16(USB_EP_NI0_RXCSR) -#define bfin_write_USB_EP_NI0_RXCSR(val) bfin_write16(USB_EP_NI0_RXCSR, val) -#define bfin_read_USB_EP_NI0_RXCOUNT() bfin_read16(USB_EP_NI0_RXCOUNT) -#define bfin_write_USB_EP_NI0_RXCOUNT(val) bfin_write16(USB_EP_NI0_RXCOUNT, val) -#define bfin_read_USB_EP_NI0_TXTYPE() bfin_read16(USB_EP_NI0_TXTYPE) -#define bfin_write_USB_EP_NI0_TXTYPE(val) bfin_write16(USB_EP_NI0_TXTYPE, val) -#define bfin_read_USB_EP_NI0_TXINTERVAL() bfin_read16(USB_EP_NI0_TXINTERVAL) -#define bfin_write_USB_EP_NI0_TXINTERVAL(val) bfin_write16(USB_EP_NI0_TXINTERVAL, val) -#define bfin_read_USB_EP_NI0_RXTYPE() bfin_read16(USB_EP_NI0_RXTYPE) -#define bfin_write_USB_EP_NI0_RXTYPE(val) bfin_write16(USB_EP_NI0_RXTYPE, val) -#define bfin_read_USB_EP_NI0_RXINTERVAL() bfin_read16(USB_EP_NI0_RXINTERVAL) -#define bfin_write_USB_EP_NI0_RXINTERVAL(val) bfin_write16(USB_EP_NI0_RXINTERVAL, val) -#define bfin_read_USB_EP_NI0_TXCOUNT() bfin_read16(USB_EP_NI0_TXCOUNT) -#define bfin_write_USB_EP_NI0_TXCOUNT(val) bfin_write16(USB_EP_NI0_TXCOUNT, val) - -/* USB Endpoint 1 Control Registers */ - -#define bfin_read_USB_EP_NI1_TXMAXP() bfin_read16(USB_EP_NI1_TXMAXP) -#define bfin_write_USB_EP_NI1_TXMAXP(val) bfin_write16(USB_EP_NI1_TXMAXP, val) -#define bfin_read_USB_EP_NI1_TXCSR() bfin_read16(USB_EP_NI1_TXCSR) -#define bfin_write_USB_EP_NI1_TXCSR(val) bfin_write16(USB_EP_NI1_TXCSR, val) -#define bfin_read_USB_EP_NI1_RXMAXP() bfin_read16(USB_EP_NI1_RXMAXP) -#define bfin_write_USB_EP_NI1_RXMAXP(val) bfin_write16(USB_EP_NI1_RXMAXP, val) -#define bfin_read_USB_EP_NI1_RXCSR() bfin_read16(USB_EP_NI1_RXCSR) -#define bfin_write_USB_EP_NI1_RXCSR(val) bfin_write16(USB_EP_NI1_RXCSR, val) -#define bfin_read_USB_EP_NI1_RXCOUNT() bfin_read16(USB_EP_NI1_RXCOUNT) -#define bfin_write_USB_EP_NI1_RXCOUNT(val) bfin_write16(USB_EP_NI1_RXCOUNT, val) -#define bfin_read_USB_EP_NI1_TXTYPE() bfin_read16(USB_EP_NI1_TXTYPE) -#define bfin_write_USB_EP_NI1_TXTYPE(val) bfin_write16(USB_EP_NI1_TXTYPE, val) -#define bfin_read_USB_EP_NI1_TXINTERVAL() bfin_read16(USB_EP_NI1_TXINTERVAL) -#define bfin_write_USB_EP_NI1_TXINTERVAL(val) bfin_write16(USB_EP_NI1_TXINTERVAL, val) -#define bfin_read_USB_EP_NI1_RXTYPE() bfin_read16(USB_EP_NI1_RXTYPE) -#define bfin_write_USB_EP_NI1_RXTYPE(val) bfin_write16(USB_EP_NI1_RXTYPE, val) -#define bfin_read_USB_EP_NI1_RXINTERVAL() bfin_read16(USB_EP_NI1_RXINTERVAL) -#define bfin_write_USB_EP_NI1_RXINTERVAL(val) bfin_write16(USB_EP_NI1_RXINTERVAL, val) -#define bfin_read_USB_EP_NI1_TXCOUNT() bfin_read16(USB_EP_NI1_TXCOUNT) -#define bfin_write_USB_EP_NI1_TXCOUNT(val) bfin_write16(USB_EP_NI1_TXCOUNT, val) - -/* USB Endpoint 2 Control Registers */ - -#define bfin_read_USB_EP_NI2_TXMAXP() bfin_read16(USB_EP_NI2_TXMAXP) -#define bfin_write_USB_EP_NI2_TXMAXP(val) bfin_write16(USB_EP_NI2_TXMAXP, val) -#define bfin_read_USB_EP_NI2_TXCSR() bfin_read16(USB_EP_NI2_TXCSR) -#define bfin_write_USB_EP_NI2_TXCSR(val) bfin_write16(USB_EP_NI2_TXCSR, val) -#define bfin_read_USB_EP_NI2_RXMAXP() bfin_read16(USB_EP_NI2_RXMAXP) -#define bfin_write_USB_EP_NI2_RXMAXP(val) bfin_write16(USB_EP_NI2_RXMAXP, val) -#define bfin_read_USB_EP_NI2_RXCSR() bfin_read16(USB_EP_NI2_RXCSR) -#define bfin_write_USB_EP_NI2_RXCSR(val) bfin_write16(USB_EP_NI2_RXCSR, val) -#define bfin_read_USB_EP_NI2_RXCOUNT() bfin_read16(USB_EP_NI2_RXCOUNT) -#define bfin_write_USB_EP_NI2_RXCOUNT(val) bfin_write16(USB_EP_NI2_RXCOUNT, val) -#define bfin_read_USB_EP_NI2_TXTYPE() bfin_read16(USB_EP_NI2_TXTYPE) -#define bfin_write_USB_EP_NI2_TXTYPE(val) bfin_write16(USB_EP_NI2_TXTYPE, val) -#define bfin_read_USB_EP_NI2_TXINTERVAL() bfin_read16(USB_EP_NI2_TXINTERVAL) -#define bfin_write_USB_EP_NI2_TXINTERVAL(val) bfin_write16(USB_EP_NI2_TXINTERVAL, val) -#define bfin_read_USB_EP_NI2_RXTYPE() bfin_read16(USB_EP_NI2_RXTYPE) -#define bfin_write_USB_EP_NI2_RXTYPE(val) bfin_write16(USB_EP_NI2_RXTYPE, val) -#define bfin_read_USB_EP_NI2_RXINTERVAL() bfin_read16(USB_EP_NI2_RXINTERVAL) -#define bfin_write_USB_EP_NI2_RXINTERVAL(val) bfin_write16(USB_EP_NI2_RXINTERVAL, val) -#define bfin_read_USB_EP_NI2_TXCOUNT() bfin_read16(USB_EP_NI2_TXCOUNT) -#define bfin_write_USB_EP_NI2_TXCOUNT(val) bfin_write16(USB_EP_NI2_TXCOUNT, val) - -/* USB Endpoint 3 Control Registers */ - -#define bfin_read_USB_EP_NI3_TXMAXP() bfin_read16(USB_EP_NI3_TXMAXP) -#define bfin_write_USB_EP_NI3_TXMAXP(val) bfin_write16(USB_EP_NI3_TXMAXP, val) -#define bfin_read_USB_EP_NI3_TXCSR() bfin_read16(USB_EP_NI3_TXCSR) -#define bfin_write_USB_EP_NI3_TXCSR(val) bfin_write16(USB_EP_NI3_TXCSR, val) -#define bfin_read_USB_EP_NI3_RXMAXP() bfin_read16(USB_EP_NI3_RXMAXP) -#define bfin_write_USB_EP_NI3_RXMAXP(val) bfin_write16(USB_EP_NI3_RXMAXP, val) -#define bfin_read_USB_EP_NI3_RXCSR() bfin_read16(USB_EP_NI3_RXCSR) -#define bfin_write_USB_EP_NI3_RXCSR(val) bfin_write16(USB_EP_NI3_RXCSR, val) -#define bfin_read_USB_EP_NI3_RXCOUNT() bfin_read16(USB_EP_NI3_RXCOUNT) -#define bfin_write_USB_EP_NI3_RXCOUNT(val) bfin_write16(USB_EP_NI3_RXCOUNT, val) -#define bfin_read_USB_EP_NI3_TXTYPE() bfin_read16(USB_EP_NI3_TXTYPE) -#define bfin_write_USB_EP_NI3_TXTYPE(val) bfin_write16(USB_EP_NI3_TXTYPE, val) -#define bfin_read_USB_EP_NI3_TXINTERVAL() bfin_read16(USB_EP_NI3_TXINTERVAL) -#define bfin_write_USB_EP_NI3_TXINTERVAL(val) bfin_write16(USB_EP_NI3_TXINTERVAL, val) -#define bfin_read_USB_EP_NI3_RXTYPE() bfin_read16(USB_EP_NI3_RXTYPE) -#define bfin_write_USB_EP_NI3_RXTYPE(val) bfin_write16(USB_EP_NI3_RXTYPE, val) -#define bfin_read_USB_EP_NI3_RXINTERVAL() bfin_read16(USB_EP_NI3_RXINTERVAL) -#define bfin_write_USB_EP_NI3_RXINTERVAL(val) bfin_write16(USB_EP_NI3_RXINTERVAL, val) -#define bfin_read_USB_EP_NI3_TXCOUNT() bfin_read16(USB_EP_NI3_TXCOUNT) -#define bfin_write_USB_EP_NI3_TXCOUNT(val) bfin_write16(USB_EP_NI3_TXCOUNT, val) - -/* USB Endpoint 4 Control Registers */ - -#define bfin_read_USB_EP_NI4_TXMAXP() bfin_read16(USB_EP_NI4_TXMAXP) -#define bfin_write_USB_EP_NI4_TXMAXP(val) bfin_write16(USB_EP_NI4_TXMAXP, val) -#define bfin_read_USB_EP_NI4_TXCSR() bfin_read16(USB_EP_NI4_TXCSR) -#define bfin_write_USB_EP_NI4_TXCSR(val) bfin_write16(USB_EP_NI4_TXCSR, val) -#define bfin_read_USB_EP_NI4_RXMAXP() bfin_read16(USB_EP_NI4_RXMAXP) -#define bfin_write_USB_EP_NI4_RXMAXP(val) bfin_write16(USB_EP_NI4_RXMAXP, val) -#define bfin_read_USB_EP_NI4_RXCSR() bfin_read16(USB_EP_NI4_RXCSR) -#define bfin_write_USB_EP_NI4_RXCSR(val) bfin_write16(USB_EP_NI4_RXCSR, val) -#define bfin_read_USB_EP_NI4_RXCOUNT() bfin_read16(USB_EP_NI4_RXCOUNT) -#define bfin_write_USB_EP_NI4_RXCOUNT(val) bfin_write16(USB_EP_NI4_RXCOUNT, val) -#define bfin_read_USB_EP_NI4_TXTYPE() bfin_read16(USB_EP_NI4_TXTYPE) -#define bfin_write_USB_EP_NI4_TXTYPE(val) bfin_write16(USB_EP_NI4_TXTYPE, val) -#define bfin_read_USB_EP_NI4_TXINTERVAL() bfin_read16(USB_EP_NI4_TXINTERVAL) -#define bfin_write_USB_EP_NI4_TXINTERVAL(val) bfin_write16(USB_EP_NI4_TXINTERVAL, val) -#define bfin_read_USB_EP_NI4_RXTYPE() bfin_read16(USB_EP_NI4_RXTYPE) -#define bfin_write_USB_EP_NI4_RXTYPE(val) bfin_write16(USB_EP_NI4_RXTYPE, val) -#define bfin_read_USB_EP_NI4_RXINTERVAL() bfin_read16(USB_EP_NI4_RXINTERVAL) -#define bfin_write_USB_EP_NI4_RXINTERVAL(val) bfin_write16(USB_EP_NI4_RXINTERVAL, val) -#define bfin_read_USB_EP_NI4_TXCOUNT() bfin_read16(USB_EP_NI4_TXCOUNT) -#define bfin_write_USB_EP_NI4_TXCOUNT(val) bfin_write16(USB_EP_NI4_TXCOUNT, val) - -/* USB Endpoint 5 Control Registers */ - -#define bfin_read_USB_EP_NI5_TXMAXP() bfin_read16(USB_EP_NI5_TXMAXP) -#define bfin_write_USB_EP_NI5_TXMAXP(val) bfin_write16(USB_EP_NI5_TXMAXP, val) -#define bfin_read_USB_EP_NI5_TXCSR() bfin_read16(USB_EP_NI5_TXCSR) -#define bfin_write_USB_EP_NI5_TXCSR(val) bfin_write16(USB_EP_NI5_TXCSR, val) -#define bfin_read_USB_EP_NI5_RXMAXP() bfin_read16(USB_EP_NI5_RXMAXP) -#define bfin_write_USB_EP_NI5_RXMAXP(val) bfin_write16(USB_EP_NI5_RXMAXP, val) -#define bfin_read_USB_EP_NI5_RXCSR() bfin_read16(USB_EP_NI5_RXCSR) -#define bfin_write_USB_EP_NI5_RXCSR(val) bfin_write16(USB_EP_NI5_RXCSR, val) -#define bfin_read_USB_EP_NI5_RXCOUNT() bfin_read16(USB_EP_NI5_RXCOUNT) -#define bfin_write_USB_EP_NI5_RXCOUNT(val) bfin_write16(USB_EP_NI5_RXCOUNT, val) -#define bfin_read_USB_EP_NI5_TXTYPE() bfin_read16(USB_EP_NI5_TXTYPE) -#define bfin_write_USB_EP_NI5_TXTYPE(val) bfin_write16(USB_EP_NI5_TXTYPE, val) -#define bfin_read_USB_EP_NI5_TXINTERVAL() bfin_read16(USB_EP_NI5_TXINTERVAL) -#define bfin_write_USB_EP_NI5_TXINTERVAL(val) bfin_write16(USB_EP_NI5_TXINTERVAL, val) -#define bfin_read_USB_EP_NI5_RXTYPE() bfin_read16(USB_EP_NI5_RXTYPE) -#define bfin_write_USB_EP_NI5_RXTYPE(val) bfin_write16(USB_EP_NI5_RXTYPE, val) -#define bfin_read_USB_EP_NI5_RXINTERVAL() bfin_read16(USB_EP_NI5_RXINTERVAL) -#define bfin_write_USB_EP_NI5_RXINTERVAL(val) bfin_write16(USB_EP_NI5_RXINTERVAL, val) -#define bfin_read_USB_EP_NI5_TXCOUNT() bfin_read16(USB_EP_NI5_TXCOUNT) -#define bfin_write_USB_EP_NI5_TXCOUNT(val) bfin_write16(USB_EP_NI5_TXCOUNT, val) - -/* USB Endpoint 6 Control Registers */ - -#define bfin_read_USB_EP_NI6_TXMAXP() bfin_read16(USB_EP_NI6_TXMAXP) -#define bfin_write_USB_EP_NI6_TXMAXP(val) bfin_write16(USB_EP_NI6_TXMAXP, val) -#define bfin_read_USB_EP_NI6_TXCSR() bfin_read16(USB_EP_NI6_TXCSR) -#define bfin_write_USB_EP_NI6_TXCSR(val) bfin_write16(USB_EP_NI6_TXCSR, val) -#define bfin_read_USB_EP_NI6_RXMAXP() bfin_read16(USB_EP_NI6_RXMAXP) -#define bfin_write_USB_EP_NI6_RXMAXP(val) bfin_write16(USB_EP_NI6_RXMAXP, val) -#define bfin_read_USB_EP_NI6_RXCSR() bfin_read16(USB_EP_NI6_RXCSR) -#define bfin_write_USB_EP_NI6_RXCSR(val) bfin_write16(USB_EP_NI6_RXCSR, val) -#define bfin_read_USB_EP_NI6_RXCOUNT() bfin_read16(USB_EP_NI6_RXCOUNT) -#define bfin_write_USB_EP_NI6_RXCOUNT(val) bfin_write16(USB_EP_NI6_RXCOUNT, val) -#define bfin_read_USB_EP_NI6_TXTYPE() bfin_read16(USB_EP_NI6_TXTYPE) -#define bfin_write_USB_EP_NI6_TXTYPE(val) bfin_write16(USB_EP_NI6_TXTYPE, val) -#define bfin_read_USB_EP_NI6_TXINTERVAL() bfin_read16(USB_EP_NI6_TXINTERVAL) -#define bfin_write_USB_EP_NI6_TXINTERVAL(val) bfin_write16(USB_EP_NI6_TXINTERVAL, val) -#define bfin_read_USB_EP_NI6_RXTYPE() bfin_read16(USB_EP_NI6_RXTYPE) -#define bfin_write_USB_EP_NI6_RXTYPE(val) bfin_write16(USB_EP_NI6_RXTYPE, val) -#define bfin_read_USB_EP_NI6_RXINTERVAL() bfin_read16(USB_EP_NI6_RXINTERVAL) -#define bfin_write_USB_EP_NI6_RXINTERVAL(val) bfin_write16(USB_EP_NI6_RXINTERVAL, val) -#define bfin_read_USB_EP_NI6_TXCOUNT() bfin_read16(USB_EP_NI6_TXCOUNT) -#define bfin_write_USB_EP_NI6_TXCOUNT(val) bfin_write16(USB_EP_NI6_TXCOUNT, val) - -/* USB Endpoint 7 Control Registers */ - -#define bfin_read_USB_EP_NI7_TXMAXP() bfin_read16(USB_EP_NI7_TXMAXP) -#define bfin_write_USB_EP_NI7_TXMAXP(val) bfin_write16(USB_EP_NI7_TXMAXP, val) -#define bfin_read_USB_EP_NI7_TXCSR() bfin_read16(USB_EP_NI7_TXCSR) -#define bfin_write_USB_EP_NI7_TXCSR(val) bfin_write16(USB_EP_NI7_TXCSR, val) -#define bfin_read_USB_EP_NI7_RXMAXP() bfin_read16(USB_EP_NI7_RXMAXP) -#define bfin_write_USB_EP_NI7_RXMAXP(val) bfin_write16(USB_EP_NI7_RXMAXP, val) -#define bfin_read_USB_EP_NI7_RXCSR() bfin_read16(USB_EP_NI7_RXCSR) -#define bfin_write_USB_EP_NI7_RXCSR(val) bfin_write16(USB_EP_NI7_RXCSR, val) -#define bfin_read_USB_EP_NI7_RXCOUNT() bfin_read16(USB_EP_NI7_RXCOUNT) -#define bfin_write_USB_EP_NI7_RXCOUNT(val) bfin_write16(USB_EP_NI7_RXCOUNT, val) -#define bfin_read_USB_EP_NI7_TXTYPE() bfin_read16(USB_EP_NI7_TXTYPE) -#define bfin_write_USB_EP_NI7_TXTYPE(val) bfin_write16(USB_EP_NI7_TXTYPE, val) -#define bfin_read_USB_EP_NI7_TXINTERVAL() bfin_read16(USB_EP_NI7_TXINTERVAL) -#define bfin_write_USB_EP_NI7_TXINTERVAL(val) bfin_write16(USB_EP_NI7_TXINTERVAL, val) -#define bfin_read_USB_EP_NI7_RXTYPE() bfin_read16(USB_EP_NI7_RXTYPE) -#define bfin_write_USB_EP_NI7_RXTYPE(val) bfin_write16(USB_EP_NI7_RXTYPE, val) -#define bfin_read_USB_EP_NI7_RXINTERVAL() bfin_read16(USB_EP_NI7_RXINTERVAL) -#define bfin_write_USB_EP_NI7_RXINTERVAL(val) bfin_write16(USB_EP_NI7_RXINTERVAL, val) -#define bfin_read_USB_EP_NI7_TXCOUNT() bfin_read16(USB_EP_NI7_TXCOUNT) -#define bfin_write_USB_EP_NI7_TXCOUNT(val) bfin_write16(USB_EP_NI7_TXCOUNT, val) - -#define bfin_read_USB_DMA_INTERRUPT() bfin_read16(USB_DMA_INTERRUPT) -#define bfin_write_USB_DMA_INTERRUPT(val) bfin_write16(USB_DMA_INTERRUPT, val) - -/* USB Channel 0 Config Registers */ - -#define bfin_read_USB_DMA0CONTROL() bfin_read16(USB_DMA0CONTROL) -#define bfin_write_USB_DMA0CONTROL(val) bfin_write16(USB_DMA0CONTROL, val) -#define bfin_read_USB_DMA0ADDRLOW() bfin_read16(USB_DMA0ADDRLOW) -#define bfin_write_USB_DMA0ADDRLOW(val) bfin_write16(USB_DMA0ADDRLOW, val) -#define bfin_read_USB_DMA0ADDRHIGH() bfin_read16(USB_DMA0ADDRHIGH) -#define bfin_write_USB_DMA0ADDRHIGH(val) bfin_write16(USB_DMA0ADDRHIGH, val) -#define bfin_read_USB_DMA0COUNTLOW() bfin_read16(USB_DMA0COUNTLOW) -#define bfin_write_USB_DMA0COUNTLOW(val) bfin_write16(USB_DMA0COUNTLOW, val) -#define bfin_read_USB_DMA0COUNTHIGH() bfin_read16(USB_DMA0COUNTHIGH) -#define bfin_write_USB_DMA0COUNTHIGH(val) bfin_write16(USB_DMA0COUNTHIGH, val) - -/* USB Channel 1 Config Registers */ - -#define bfin_read_USB_DMA1CONTROL() bfin_read16(USB_DMA1CONTROL) -#define bfin_write_USB_DMA1CONTROL(val) bfin_write16(USB_DMA1CONTROL, val) -#define bfin_read_USB_DMA1ADDRLOW() bfin_read16(USB_DMA1ADDRLOW) -#define bfin_write_USB_DMA1ADDRLOW(val) bfin_write16(USB_DMA1ADDRLOW, val) -#define bfin_read_USB_DMA1ADDRHIGH() bfin_read16(USB_DMA1ADDRHIGH) -#define bfin_write_USB_DMA1ADDRHIGH(val) bfin_write16(USB_DMA1ADDRHIGH, val) -#define bfin_read_USB_DMA1COUNTLOW() bfin_read16(USB_DMA1COUNTLOW) -#define bfin_write_USB_DMA1COUNTLOW(val) bfin_write16(USB_DMA1COUNTLOW, val) -#define bfin_read_USB_DMA1COUNTHIGH() bfin_read16(USB_DMA1COUNTHIGH) -#define bfin_write_USB_DMA1COUNTHIGH(val) bfin_write16(USB_DMA1COUNTHIGH, val) - -/* USB Channel 2 Config Registers */ - -#define bfin_read_USB_DMA2CONTROL() bfin_read16(USB_DMA2CONTROL) -#define bfin_write_USB_DMA2CONTROL(val) bfin_write16(USB_DMA2CONTROL, val) -#define bfin_read_USB_DMA2ADDRLOW() bfin_read16(USB_DMA2ADDRLOW) -#define bfin_write_USB_DMA2ADDRLOW(val) bfin_write16(USB_DMA2ADDRLOW, val) -#define bfin_read_USB_DMA2ADDRHIGH() bfin_read16(USB_DMA2ADDRHIGH) -#define bfin_write_USB_DMA2ADDRHIGH(val) bfin_write16(USB_DMA2ADDRHIGH, val) -#define bfin_read_USB_DMA2COUNTLOW() bfin_read16(USB_DMA2COUNTLOW) -#define bfin_write_USB_DMA2COUNTLOW(val) bfin_write16(USB_DMA2COUNTLOW, val) -#define bfin_read_USB_DMA2COUNTHIGH() bfin_read16(USB_DMA2COUNTHIGH) -#define bfin_write_USB_DMA2COUNTHIGH(val) bfin_write16(USB_DMA2COUNTHIGH, val) - -/* USB Channel 3 Config Registers */ - -#define bfin_read_USB_DMA3CONTROL() bfin_read16(USB_DMA3CONTROL) -#define bfin_write_USB_DMA3CONTROL(val) bfin_write16(USB_DMA3CONTROL, val) -#define bfin_read_USB_DMA3ADDRLOW() bfin_read16(USB_DMA3ADDRLOW) -#define bfin_write_USB_DMA3ADDRLOW(val) bfin_write16(USB_DMA3ADDRLOW, val) -#define bfin_read_USB_DMA3ADDRHIGH() bfin_read16(USB_DMA3ADDRHIGH) -#define bfin_write_USB_DMA3ADDRHIGH(val) bfin_write16(USB_DMA3ADDRHIGH, val) -#define bfin_read_USB_DMA3COUNTLOW() bfin_read16(USB_DMA3COUNTLOW) -#define bfin_write_USB_DMA3COUNTLOW(val) bfin_write16(USB_DMA3COUNTLOW, val) -#define bfin_read_USB_DMA3COUNTHIGH() bfin_read16(USB_DMA3COUNTHIGH) -#define bfin_write_USB_DMA3COUNTHIGH(val) bfin_write16(USB_DMA3COUNTHIGH, val) - -/* USB Channel 4 Config Registers */ - -#define bfin_read_USB_DMA4CONTROL() bfin_read16(USB_DMA4CONTROL) -#define bfin_write_USB_DMA4CONTROL(val) bfin_write16(USB_DMA4CONTROL, val) -#define bfin_read_USB_DMA4ADDRLOW() bfin_read16(USB_DMA4ADDRLOW) -#define bfin_write_USB_DMA4ADDRLOW(val) bfin_write16(USB_DMA4ADDRLOW, val) -#define bfin_read_USB_DMA4ADDRHIGH() bfin_read16(USB_DMA4ADDRHIGH) -#define bfin_write_USB_DMA4ADDRHIGH(val) bfin_write16(USB_DMA4ADDRHIGH, val) -#define bfin_read_USB_DMA4COUNTLOW() bfin_read16(USB_DMA4COUNTLOW) -#define bfin_write_USB_DMA4COUNTLOW(val) bfin_write16(USB_DMA4COUNTLOW, val) -#define bfin_read_USB_DMA4COUNTHIGH() bfin_read16(USB_DMA4COUNTHIGH) -#define bfin_write_USB_DMA4COUNTHIGH(val) bfin_write16(USB_DMA4COUNTHIGH, val) - -/* USB Channel 5 Config Registers */ - -#define bfin_read_USB_DMA5CONTROL() bfin_read16(USB_DMA5CONTROL) -#define bfin_write_USB_DMA5CONTROL(val) bfin_write16(USB_DMA5CONTROL, val) -#define bfin_read_USB_DMA5ADDRLOW() bfin_read16(USB_DMA5ADDRLOW) -#define bfin_write_USB_DMA5ADDRLOW(val) bfin_write16(USB_DMA5ADDRLOW, val) -#define bfin_read_USB_DMA5ADDRHIGH() bfin_read16(USB_DMA5ADDRHIGH) -#define bfin_write_USB_DMA5ADDRHIGH(val) bfin_write16(USB_DMA5ADDRHIGH, val) -#define bfin_read_USB_DMA5COUNTLOW() bfin_read16(USB_DMA5COUNTLOW) -#define bfin_write_USB_DMA5COUNTLOW(val) bfin_write16(USB_DMA5COUNTLOW, val) -#define bfin_read_USB_DMA5COUNTHIGH() bfin_read16(USB_DMA5COUNTHIGH) -#define bfin_write_USB_DMA5COUNTHIGH(val) bfin_write16(USB_DMA5COUNTHIGH, val) - -/* USB Channel 6 Config Registers */ - -#define bfin_read_USB_DMA6CONTROL() bfin_read16(USB_DMA6CONTROL) -#define bfin_write_USB_DMA6CONTROL(val) bfin_write16(USB_DMA6CONTROL, val) -#define bfin_read_USB_DMA6ADDRLOW() bfin_read16(USB_DMA6ADDRLOW) -#define bfin_write_USB_DMA6ADDRLOW(val) bfin_write16(USB_DMA6ADDRLOW, val) -#define bfin_read_USB_DMA6ADDRHIGH() bfin_read16(USB_DMA6ADDRHIGH) -#define bfin_write_USB_DMA6ADDRHIGH(val) bfin_write16(USB_DMA6ADDRHIGH, val) -#define bfin_read_USB_DMA6COUNTLOW() bfin_read16(USB_DMA6COUNTLOW) -#define bfin_write_USB_DMA6COUNTLOW(val) bfin_write16(USB_DMA6COUNTLOW, val) -#define bfin_read_USB_DMA6COUNTHIGH() bfin_read16(USB_DMA6COUNTHIGH) -#define bfin_write_USB_DMA6COUNTHIGH(val) bfin_write16(USB_DMA6COUNTHIGH, val) - -/* USB Channel 7 Config Registers */ - -#define bfin_read_USB_DMA7CONTROL() bfin_read16(USB_DMA7CONTROL) -#define bfin_write_USB_DMA7CONTROL(val) bfin_write16(USB_DMA7CONTROL, val) -#define bfin_read_USB_DMA7ADDRLOW() bfin_read16(USB_DMA7ADDRLOW) -#define bfin_write_USB_DMA7ADDRLOW(val) bfin_write16(USB_DMA7ADDRLOW, val) -#define bfin_read_USB_DMA7ADDRHIGH() bfin_read16(USB_DMA7ADDRHIGH) -#define bfin_write_USB_DMA7ADDRHIGH(val) bfin_write16(USB_DMA7ADDRHIGH, val) -#define bfin_read_USB_DMA7COUNTLOW() bfin_read16(USB_DMA7COUNTLOW) -#define bfin_write_USB_DMA7COUNTLOW(val) bfin_write16(USB_DMA7COUNTLOW, val) -#define bfin_read_USB_DMA7COUNTHIGH() bfin_read16(USB_DMA7COUNTHIGH) -#define bfin_write_USB_DMA7COUNTHIGH(val) bfin_write16(USB_DMA7COUNTHIGH, val) - #endif /* _CDEF_BF527_H */ diff --git a/arch/blackfin/mach-bf527/include/mach/defBF525.h b/arch/blackfin/mach-bf527/include/mach/defBF525.h index 82abefc..c136f70 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF525.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF525.h @@ -7,15 +7,8 @@ #ifndef _DEF_BF525_H #define _DEF_BF525_H -/* Include all Core registers and bit definitions */ -#include - -/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF525 */ - -/* Include defBF52x_base.h for the set of #defines that are common to all ADSP-BF52x processors */ -#include "defBF52x_base.h" - -/* The following are the #defines needed by ADSP-BF525 that are not in the common header */ +/* BF525 is BF522 + USB */ +#include "defBF522.h" /* USB Control Registers */ diff --git a/arch/blackfin/mach-bf527/include/mach/defBF527.h b/arch/blackfin/mach-bf527/include/mach/defBF527.h index 570a125..4dd58fb 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF527.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF527.h @@ -7,15 +7,9 @@ #ifndef _DEF_BF527_H #define _DEF_BF527_H -/* Include all Core registers and bit definitions */ -#include +/* BF527 is BF525 + EMAC */ +#include "defBF525.h" -/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF527 */ - -/* Include defBF52x_base.h for the set of #defines that are common to all ADSP-BF52x processors */ -#include "defBF52x_base.h" - -/* The following are the #defines needed by ADSP-BF527 that are not in the common header */ /* 10/100 Ethernet Controller (0xFFC03000 - 0xFFC031FF) */ #define EMAC_OPMODE 0xFFC03000 /* Operating Mode Register */ @@ -394,673 +388,4 @@ #define TX_GE1024_CNT 0x00200000 /* 1024-Max-Byte TX Frames Sent */ #define TX_ABORT_CNT 0x00400000 /* TX Frames Aborted */ -/* USB Control Registers */ - -#define USB_FADDR 0xffc03800 /* Function address register */ -#define USB_POWER 0xffc03804 /* Power management register */ -#define USB_INTRTX 0xffc03808 /* Interrupt register for endpoint 0 and Tx endpoint 1 to 7 */ -#define USB_INTRRX 0xffc0380c /* Interrupt register for Rx endpoints 1 to 7 */ -#define USB_INTRTXE 0xffc03810 /* Interrupt enable register for IntrTx */ -#define USB_INTRRXE 0xffc03814 /* Interrupt enable register for IntrRx */ -#define USB_INTRUSB 0xffc03818 /* Interrupt register for common USB interrupts */ -#define USB_INTRUSBE 0xffc0381c /* Interrupt enable register for IntrUSB */ -#define USB_FRAME 0xffc03820 /* USB frame number */ -#define USB_INDEX 0xffc03824 /* Index register for selecting the indexed endpoint registers */ -#define USB_TESTMODE 0xffc03828 /* Enabled USB 20 test modes */ -#define USB_GLOBINTR 0xffc0382c /* Global Interrupt Mask register and Wakeup Exception Interrupt */ -#define USB_GLOBAL_CTL 0xffc03830 /* Global Clock Control for the core */ - -/* USB Packet Control Registers */ - -#define USB_TX_MAX_PACKET 0xffc03840 /* Maximum packet size for Host Tx endpoint */ -#define USB_CSR0 0xffc03844 /* Control Status register for endpoint 0 and Control Status register for Host Tx endpoint */ -#define USB_TXCSR 0xffc03844 /* Control Status register for endpoint 0 and Control Status register for Host Tx endpoint */ -#define USB_RX_MAX_PACKET 0xffc03848 /* Maximum packet size for Host Rx endpoint */ -#define USB_RXCSR 0xffc0384c /* Control Status register for Host Rx endpoint */ -#define USB_COUNT0 0xffc03850 /* Number of bytes received in endpoint 0 FIFO and Number of bytes received in Host Tx endpoint */ -#define USB_RXCOUNT 0xffc03850 /* Number of bytes received in endpoint 0 FIFO and Number of bytes received in Host Tx endpoint */ -#define USB_TXTYPE 0xffc03854 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint */ -#define USB_NAKLIMIT0 0xffc03858 /* Sets the NAK response timeout on Endpoint 0 and on Bulk transfers for Host Tx endpoint */ -#define USB_TXINTERVAL 0xffc03858 /* Sets the NAK response timeout on Endpoint 0 and on Bulk transfers for Host Tx endpoint */ -#define USB_RXTYPE 0xffc0385c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint */ -#define USB_RXINTERVAL 0xffc03860 /* Sets the polling interval for Interrupt and Isochronous transfers or the NAK response timeout on Bulk transfers */ -#define USB_TXCOUNT 0xffc03868 /* Number of bytes to be written to the selected endpoint Tx FIFO */ - -/* USB Endpoint FIFO Registers */ - -#define USB_EP0_FIFO 0xffc03880 /* Endpoint 0 FIFO */ -#define USB_EP1_FIFO 0xffc03888 /* Endpoint 1 FIFO */ -#define USB_EP2_FIFO 0xffc03890 /* Endpoint 2 FIFO */ -#define USB_EP3_FIFO 0xffc03898 /* Endpoint 3 FIFO */ -#define USB_EP4_FIFO 0xffc038a0 /* Endpoint 4 FIFO */ -#define USB_EP5_FIFO 0xffc038a8 /* Endpoint 5 FIFO */ -#define USB_EP6_FIFO 0xffc038b0 /* Endpoint 6 FIFO */ -#define USB_EP7_FIFO 0xffc038b8 /* Endpoint 7 FIFO */ - -/* USB OTG Control Registers */ - -#define USB_OTG_DEV_CTL 0xffc03900 /* OTG Device Control Register */ -#define USB_OTG_VBUS_IRQ 0xffc03904 /* OTG VBUS Control Interrupts */ -#define USB_OTG_VBUS_MASK 0xffc03908 /* VBUS Control Interrupt Enable */ - -/* USB Phy Control Registers */ - -#define USB_LINKINFO 0xffc03948 /* Enables programming of some PHY-side delays */ -#define USB_VPLEN 0xffc0394c /* Determines duration of VBUS pulse for VBUS charging */ -#define USB_HS_EOF1 0xffc03950 /* Time buffer for High-Speed transactions */ -#define USB_FS_EOF1 0xffc03954 /* Time buffer for Full-Speed transactions */ -#define USB_LS_EOF1 0xffc03958 /* Time buffer for Low-Speed transactions */ - -/* (APHY_CNTRL is for ADI usage only) */ - -#define USB_APHY_CNTRL 0xffc039e0 /* Register that increases visibility of Analog PHY */ - -/* (APHY_CALIB is for ADI usage only) */ - -#define USB_APHY_CALIB 0xffc039e4 /* Register used to set some calibration values */ - -#define USB_APHY_CNTRL2 0xffc039e8 /* Register used to prevent re-enumeration once Moab goes into hibernate mode */ - -/* (PHY_TEST is for ADI usage only) */ - -#define USB_PHY_TEST 0xffc039ec /* Used for reducing simulation time and simplifies FIFO testability */ - -#define USB_PLLOSC_CTRL 0xffc039f0 /* Used to program different parameters for USB PLL and Oscillator */ -#define USB_SRP_CLKDIV 0xffc039f4 /* Used to program clock divide value for the clock fed to the SRP detection logic */ - -/* USB Endpoint 0 Control Registers */ - -#define USB_EP_NI0_TXMAXP 0xffc03a00 /* Maximum packet size for Host Tx endpoint0 */ -#define USB_EP_NI0_TXCSR 0xffc03a04 /* Control Status register for endpoint 0 */ -#define USB_EP_NI0_RXMAXP 0xffc03a08 /* Maximum packet size for Host Rx endpoint0 */ -#define USB_EP_NI0_RXCSR 0xffc03a0c /* Control Status register for Host Rx endpoint0 */ -#define USB_EP_NI0_RXCOUNT 0xffc03a10 /* Number of bytes received in endpoint 0 FIFO */ -#define USB_EP_NI0_TXTYPE 0xffc03a14 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint0 */ -#define USB_EP_NI0_TXINTERVAL 0xffc03a18 /* Sets the NAK response timeout on Endpoint 0 */ -#define USB_EP_NI0_RXTYPE 0xffc03a1c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint0 */ -#define USB_EP_NI0_RXINTERVAL 0xffc03a20 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint0 */ -#define USB_EP_NI0_TXCOUNT 0xffc03a28 /* Number of bytes to be written to the endpoint0 Tx FIFO */ - -/* USB Endpoint 1 Control Registers */ - -#define USB_EP_NI1_TXMAXP 0xffc03a40 /* Maximum packet size for Host Tx endpoint1 */ -#define USB_EP_NI1_TXCSR 0xffc03a44 /* Control Status register for endpoint1 */ -#define USB_EP_NI1_RXMAXP 0xffc03a48 /* Maximum packet size for Host Rx endpoint1 */ -#define USB_EP_NI1_RXCSR 0xffc03a4c /* Control Status register for Host Rx endpoint1 */ -#define USB_EP_NI1_RXCOUNT 0xffc03a50 /* Number of bytes received in endpoint1 FIFO */ -#define USB_EP_NI1_TXTYPE 0xffc03a54 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint1 */ -#define USB_EP_NI1_TXINTERVAL 0xffc03a58 /* Sets the NAK response timeout on Endpoint1 */ -#define USB_EP_NI1_RXTYPE 0xffc03a5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint1 */ -#define USB_EP_NI1_RXINTERVAL 0xffc03a60 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint1 */ -#define USB_EP_NI1_TXCOUNT 0xffc03a68 /* Number of bytes to be written to the+H102 endpoint1 Tx FIFO */ - -/* USB Endpoint 2 Control Registers */ - -#define USB_EP_NI2_TXMAXP 0xffc03a80 /* Maximum packet size for Host Tx endpoint2 */ -#define USB_EP_NI2_TXCSR 0xffc03a84 /* Control Status register for endpoint2 */ -#define USB_EP_NI2_RXMAXP 0xffc03a88 /* Maximum packet size for Host Rx endpoint2 */ -#define USB_EP_NI2_RXCSR 0xffc03a8c /* Control Status register for Host Rx endpoint2 */ -#define USB_EP_NI2_RXCOUNT 0xffc03a90 /* Number of bytes received in endpoint2 FIFO */ -#define USB_EP_NI2_TXTYPE 0xffc03a94 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint2 */ -#define USB_EP_NI2_TXINTERVAL 0xffc03a98 /* Sets the NAK response timeout on Endpoint2 */ -#define USB_EP_NI2_RXTYPE 0xffc03a9c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint2 */ -#define USB_EP_NI2_RXINTERVAL 0xffc03aa0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint2 */ -#define USB_EP_NI2_TXCOUNT 0xffc03aa8 /* Number of bytes to be written to the endpoint2 Tx FIFO */ - -/* USB Endpoint 3 Control Registers */ - -#define USB_EP_NI3_TXMAXP 0xffc03ac0 /* Maximum packet size for Host Tx endpoint3 */ -#define USB_EP_NI3_TXCSR 0xffc03ac4 /* Control Status register for endpoint3 */ -#define USB_EP_NI3_RXMAXP 0xffc03ac8 /* Maximum packet size for Host Rx endpoint3 */ -#define USB_EP_NI3_RXCSR 0xffc03acc /* Control Status register for Host Rx endpoint3 */ -#define USB_EP_NI3_RXCOUNT 0xffc03ad0 /* Number of bytes received in endpoint3 FIFO */ -#define USB_EP_NI3_TXTYPE 0xffc03ad4 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint3 */ -#define USB_EP_NI3_TXINTERVAL 0xffc03ad8 /* Sets the NAK response timeout on Endpoint3 */ -#define USB_EP_NI3_RXTYPE 0xffc03adc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint3 */ -#define USB_EP_NI3_RXINTERVAL 0xffc03ae0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint3 */ -#define USB_EP_NI3_TXCOUNT 0xffc03ae8 /* Number of bytes to be written to the H124endpoint3 Tx FIFO */ - -/* USB Endpoint 4 Control Registers */ - -#define USB_EP_NI4_TXMAXP 0xffc03b00 /* Maximum packet size for Host Tx endpoint4 */ -#define USB_EP_NI4_TXCSR 0xffc03b04 /* Control Status register for endpoint4 */ -#define USB_EP_NI4_RXMAXP 0xffc03b08 /* Maximum packet size for Host Rx endpoint4 */ -#define USB_EP_NI4_RXCSR 0xffc03b0c /* Control Status register for Host Rx endpoint4 */ -#define USB_EP_NI4_RXCOUNT 0xffc03b10 /* Number of bytes received in endpoint4 FIFO */ -#define USB_EP_NI4_TXTYPE 0xffc03b14 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint4 */ -#define USB_EP_NI4_TXINTERVAL 0xffc03b18 /* Sets the NAK response timeout on Endpoint4 */ -#define USB_EP_NI4_RXTYPE 0xffc03b1c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint4 */ -#define USB_EP_NI4_RXINTERVAL 0xffc03b20 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint4 */ -#define USB_EP_NI4_TXCOUNT 0xffc03b28 /* Number of bytes to be written to the endpoint4 Tx FIFO */ - -/* USB Endpoint 5 Control Registers */ - -#define USB_EP_NI5_TXMAXP 0xffc03b40 /* Maximum packet size for Host Tx endpoint5 */ -#define USB_EP_NI5_TXCSR 0xffc03b44 /* Control Status register for endpoint5 */ -#define USB_EP_NI5_RXMAXP 0xffc03b48 /* Maximum packet size for Host Rx endpoint5 */ -#define USB_EP_NI5_RXCSR 0xffc03b4c /* Control Status register for Host Rx endpoint5 */ -#define USB_EP_NI5_RXCOUNT 0xffc03b50 /* Number of bytes received in endpoint5 FIFO */ -#define USB_EP_NI5_TXTYPE 0xffc03b54 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint5 */ -#define USB_EP_NI5_TXINTERVAL 0xffc03b58 /* Sets the NAK response timeout on Endpoint5 */ -#define USB_EP_NI5_RXTYPE 0xffc03b5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint5 */ -#define USB_EP_NI5_RXINTERVAL 0xffc03b60 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint5 */ -#define USB_EP_NI5_TXCOUNT 0xffc03b68 /* Number of bytes to be written to the endpoint5 Tx FIFO */ - -/* USB Endpoint 6 Control Registers */ - -#define USB_EP_NI6_TXMAXP 0xffc03b80 /* Maximum packet size for Host Tx endpoint6 */ -#define USB_EP_NI6_TXCSR 0xffc03b84 /* Control Status register for endpoint6 */ -#define USB_EP_NI6_RXMAXP 0xffc03b88 /* Maximum packet size for Host Rx endpoint6 */ -#define USB_EP_NI6_RXCSR 0xffc03b8c /* Control Status register for Host Rx endpoint6 */ -#define USB_EP_NI6_RXCOUNT 0xffc03b90 /* Number of bytes received in endpoint6 FIFO */ -#define USB_EP_NI6_TXTYPE 0xffc03b94 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint6 */ -#define USB_EP_NI6_TXINTERVAL 0xffc03b98 /* Sets the NAK response timeout on Endpoint6 */ -#define USB_EP_NI6_RXTYPE 0xffc03b9c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint6 */ -#define USB_EP_NI6_RXINTERVAL 0xffc03ba0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint6 */ -#define USB_EP_NI6_TXCOUNT 0xffc03ba8 /* Number of bytes to be written to the endpoint6 Tx FIFO */ - -/* USB Endpoint 7 Control Registers */ - -#define USB_EP_NI7_TXMAXP 0xffc03bc0 /* Maximum packet size for Host Tx endpoint7 */ -#define USB_EP_NI7_TXCSR 0xffc03bc4 /* Control Status register for endpoint7 */ -#define USB_EP_NI7_RXMAXP 0xffc03bc8 /* Maximum packet size for Host Rx endpoint7 */ -#define USB_EP_NI7_RXCSR 0xffc03bcc /* Control Status register for Host Rx endpoint7 */ -#define USB_EP_NI7_RXCOUNT 0xffc03bd0 /* Number of bytes received in endpoint7 FIFO */ -#define USB_EP_NI7_TXTYPE 0xffc03bd4 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */ -#define USB_EP_NI7_TXINTERVAL 0xffc03bd8 /* Sets the NAK response timeout on Endpoint7 */ -#define USB_EP_NI7_RXTYPE 0xffc03bdc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */ -#define USB_EP_NI7_RXINTERVAL 0xffc03bf0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */ -#define USB_EP_NI7_TXCOUNT 0xffc03bf8 /* Number of bytes to be written to the endpoint7 Tx FIFO */ - -#define USB_DMA_INTERRUPT 0xffc03c00 /* Indicates pending interrupts for the DMA channels */ - -/* USB Channel 0 Config Registers */ - -#define USB_DMA0CONTROL 0xffc03c04 /* DMA master channel 0 configuration */ -#define USB_DMA0ADDRLOW 0xffc03c08 /* Lower 16-bits of memory source/destination address for DMA master channel 0 */ -#define USB_DMA0ADDRHIGH 0xffc03c0c /* Upper 16-bits of memory source/destination address for DMA master channel 0 */ -#define USB_DMA0COUNTLOW 0xffc03c10 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 0 */ -#define USB_DMA0COUNTHIGH 0xffc03c14 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 0 */ - -/* USB Channel 1 Config Registers */ - -#define USB_DMA1CONTROL 0xffc03c24 /* DMA master channel 1 configuration */ -#define USB_DMA1ADDRLOW 0xffc03c28 /* Lower 16-bits of memory source/destination address for DMA master channel 1 */ -#define USB_DMA1ADDRHIGH 0xffc03c2c /* Upper 16-bits of memory source/destination address for DMA master channel 1 */ -#define USB_DMA1COUNTLOW 0xffc03c30 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 1 */ -#define USB_DMA1COUNTHIGH 0xffc03c34 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 1 */ - -/* USB Channel 2 Config Registers */ - -#define USB_DMA2CONTROL 0xffc03c44 /* DMA master channel 2 configuration */ -#define USB_DMA2ADDRLOW 0xffc03c48 /* Lower 16-bits of memory source/destination address for DMA master channel 2 */ -#define USB_DMA2ADDRHIGH 0xffc03c4c /* Upper 16-bits of memory source/destination address for DMA master channel 2 */ -#define USB_DMA2COUNTLOW 0xffc03c50 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 2 */ -#define USB_DMA2COUNTHIGH 0xffc03c54 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 2 */ - -/* USB Channel 3 Config Registers */ - -#define USB_DMA3CONTROL 0xffc03c64 /* DMA master channel 3 configuration */ -#define USB_DMA3ADDRLOW 0xffc03c68 /* Lower 16-bits of memory source/destination address for DMA master channel 3 */ -#define USB_DMA3ADDRHIGH 0xffc03c6c /* Upper 16-bits of memory source/destination address for DMA master channel 3 */ -#define USB_DMA3COUNTLOW 0xffc03c70 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 3 */ -#define USB_DMA3COUNTHIGH 0xffc03c74 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 3 */ - -/* USB Channel 4 Config Registers */ - -#define USB_DMA4CONTROL 0xffc03c84 /* DMA master channel 4 configuration */ -#define USB_DMA4ADDRLOW 0xffc03c88 /* Lower 16-bits of memory source/destination address for DMA master channel 4 */ -#define USB_DMA4ADDRHIGH 0xffc03c8c /* Upper 16-bits of memory source/destination address for DMA master channel 4 */ -#define USB_DMA4COUNTLOW 0xffc03c90 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 4 */ -#define USB_DMA4COUNTHIGH 0xffc03c94 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 4 */ - -/* USB Channel 5 Config Registers */ - -#define USB_DMA5CONTROL 0xffc03ca4 /* DMA master channel 5 configuration */ -#define USB_DMA5ADDRLOW 0xffc03ca8 /* Lower 16-bits of memory source/destination address for DMA master channel 5 */ -#define USB_DMA5ADDRHIGH 0xffc03cac /* Upper 16-bits of memory source/destination address for DMA master channel 5 */ -#define USB_DMA5COUNTLOW 0xffc03cb0 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 5 */ -#define USB_DMA5COUNTHIGH 0xffc03cb4 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 5 */ - -/* USB Channel 6 Config Registers */ - -#define USB_DMA6CONTROL 0xffc03cc4 /* DMA master channel 6 configuration */ -#define USB_DMA6ADDRLOW 0xffc03cc8 /* Lower 16-bits of memory source/destination address for DMA master channel 6 */ -#define USB_DMA6ADDRHIGH 0xffc03ccc /* Upper 16-bits of memory source/destination address for DMA master channel 6 */ -#define USB_DMA6COUNTLOW 0xffc03cd0 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 6 */ -#define USB_DMA6COUNTHIGH 0xffc03cd4 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 6 */ - -/* USB Channel 7 Config Registers */ - -#define USB_DMA7CONTROL 0xffc03ce4 /* DMA master channel 7 configuration */ -#define USB_DMA7ADDRLOW 0xffc03ce8 /* Lower 16-bits of memory source/destination address for DMA master channel 7 */ -#define USB_DMA7ADDRHIGH 0xffc03cec /* Upper 16-bits of memory source/destination address for DMA master channel 7 */ -#define USB_DMA7COUNTLOW 0xffc03cf0 /* Lower 16-bits of byte count of DMA transfer for DMA master channel 7 */ -#define USB_DMA7COUNTHIGH 0xffc03cf4 /* Upper 16-bits of byte count of DMA transfer for DMA master channel 7 */ - -/* Bit masks for USB_FADDR */ - -#define FUNCTION_ADDRESS 0x7f /* Function address */ - -/* Bit masks for USB_POWER */ - -#define ENABLE_SUSPENDM 0x1 /* enable SuspendM output */ -#define nENABLE_SUSPENDM 0x0 -#define SUSPEND_MODE 0x2 /* Suspend Mode indicator */ -#define nSUSPEND_MODE 0x0 -#define RESUME_MODE 0x4 /* DMA Mode */ -#define nRESUME_MODE 0x0 -#define RESET 0x8 /* Reset indicator */ -#define nRESET 0x0 -#define HS_MODE 0x10 /* High Speed mode indicator */ -#define nHS_MODE 0x0 -#define HS_ENABLE 0x20 /* high Speed Enable */ -#define nHS_ENABLE 0x0 -#define SOFT_CONN 0x40 /* Soft connect */ -#define nSOFT_CONN 0x0 -#define ISO_UPDATE 0x80 /* Isochronous update */ -#define nISO_UPDATE 0x0 - -/* Bit masks for USB_INTRTX */ - -#define EP0_TX 0x1 /* Tx Endpoint 0 interrupt */ -#define nEP0_TX 0x0 -#define EP1_TX 0x2 /* Tx Endpoint 1 interrupt */ -#define nEP1_TX 0x0 -#define EP2_TX 0x4 /* Tx Endpoint 2 interrupt */ -#define nEP2_TX 0x0 -#define EP3_TX 0x8 /* Tx Endpoint 3 interrupt */ -#define nEP3_TX 0x0 -#define EP4_TX 0x10 /* Tx Endpoint 4 interrupt */ -#define nEP4_TX 0x0 -#define EP5_TX 0x20 /* Tx Endpoint 5 interrupt */ -#define nEP5_TX 0x0 -#define EP6_TX 0x40 /* Tx Endpoint 6 interrupt */ -#define nEP6_TX 0x0 -#define EP7_TX 0x80 /* Tx Endpoint 7 interrupt */ -#define nEP7_TX 0x0 - -/* Bit masks for USB_INTRRX */ - -#define EP1_RX 0x2 /* Rx Endpoint 1 interrupt */ -#define nEP1_RX 0x0 -#define EP2_RX 0x4 /* Rx Endpoint 2 interrupt */ -#define nEP2_RX 0x0 -#define EP3_RX 0x8 /* Rx Endpoint 3 interrupt */ -#define nEP3_RX 0x0 -#define EP4_RX 0x10 /* Rx Endpoint 4 interrupt */ -#define nEP4_RX 0x0 -#define EP5_RX 0x20 /* Rx Endpoint 5 interrupt */ -#define nEP5_RX 0x0 -#define EP6_RX 0x40 /* Rx Endpoint 6 interrupt */ -#define nEP6_RX 0x0 -#define EP7_RX 0x80 /* Rx Endpoint 7 interrupt */ -#define nEP7_RX 0x0 - -/* Bit masks for USB_INTRTXE */ - -#define EP0_TX_E 0x1 /* Endpoint 0 interrupt Enable */ -#define nEP0_TX_E 0x0 -#define EP1_TX_E 0x2 /* Tx Endpoint 1 interrupt Enable */ -#define nEP1_TX_E 0x0 -#define EP2_TX_E 0x4 /* Tx Endpoint 2 interrupt Enable */ -#define nEP2_TX_E 0x0 -#define EP3_TX_E 0x8 /* Tx Endpoint 3 interrupt Enable */ -#define nEP3_TX_E 0x0 -#define EP4_TX_E 0x10 /* Tx Endpoint 4 interrupt Enable */ -#define nEP4_TX_E 0x0 -#define EP5_TX_E 0x20 /* Tx Endpoint 5 interrupt Enable */ -#define nEP5_TX_E 0x0 -#define EP6_TX_E 0x40 /* Tx Endpoint 6 interrupt Enable */ -#define nEP6_TX_E 0x0 -#define EP7_TX_E 0x80 /* Tx Endpoint 7 interrupt Enable */ -#define nEP7_TX_E 0x0 - -/* Bit masks for USB_INTRRXE */ - -#define EP1_RX_E 0x2 /* Rx Endpoint 1 interrupt Enable */ -#define nEP1_RX_E 0x0 -#define EP2_RX_E 0x4 /* Rx Endpoint 2 interrupt Enable */ -#define nEP2_RX_E 0x0 -#define EP3_RX_E 0x8 /* Rx Endpoint 3 interrupt Enable */ -#define nEP3_RX_E 0x0 -#define EP4_RX_E 0x10 /* Rx Endpoint 4 interrupt Enable */ -#define nEP4_RX_E 0x0 -#define EP5_RX_E 0x20 /* Rx Endpoint 5 interrupt Enable */ -#define nEP5_RX_E 0x0 -#define EP6_RX_E 0x40 /* Rx Endpoint 6 interrupt Enable */ -#define nEP6_RX_E 0x0 -#define EP7_RX_E 0x80 /* Rx Endpoint 7 interrupt Enable */ -#define nEP7_RX_E 0x0 - -/* Bit masks for USB_INTRUSB */ - -#define SUSPEND_B 0x1 /* Suspend indicator */ -#define nSUSPEND_B 0x0 -#define RESUME_B 0x2 /* Resume indicator */ -#define nRESUME_B 0x0 -#define RESET_OR_BABLE_B 0x4 /* Reset/babble indicator */ -#define nRESET_OR_BABLE_B 0x0 -#define SOF_B 0x8 /* Start of frame */ -#define nSOF_B 0x0 -#define CONN_B 0x10 /* Connection indicator */ -#define nCONN_B 0x0 -#define DISCON_B 0x20 /* Disconnect indicator */ -#define nDISCON_B 0x0 -#define SESSION_REQ_B 0x40 /* Session Request */ -#define nSESSION_REQ_B 0x0 -#define VBUS_ERROR_B 0x80 /* Vbus threshold indicator */ -#define nVBUS_ERROR_B 0x0 - -/* Bit masks for USB_INTRUSBE */ - -#define SUSPEND_BE 0x1 /* Suspend indicator int enable */ -#define nSUSPEND_BE 0x0 -#define RESUME_BE 0x2 /* Resume indicator int enable */ -#define nRESUME_BE 0x0 -#define RESET_OR_BABLE_BE 0x4 /* Reset/babble indicator int enable */ -#define nRESET_OR_BABLE_BE 0x0 -#define SOF_BE 0x8 /* Start of frame int enable */ -#define nSOF_BE 0x0 -#define CONN_BE 0x10 /* Connection indicator int enable */ -#define nCONN_BE 0x0 -#define DISCON_BE 0x20 /* Disconnect indicator int enable */ -#define nDISCON_BE 0x0 -#define SESSION_REQ_BE 0x40 /* Session Request int enable */ -#define nSESSION_REQ_BE 0x0 -#define VBUS_ERROR_BE 0x80 /* Vbus threshold indicator int enable */ -#define nVBUS_ERROR_BE 0x0 - -/* Bit masks for USB_FRAME */ - -#define FRAME_NUMBER 0x7ff /* Frame number */ - -/* Bit masks for USB_INDEX */ - -#define SELECTED_ENDPOINT 0xf /* selected endpoint */ - -/* Bit masks for USB_GLOBAL_CTL */ - -#define GLOBAL_ENA 0x1 /* enables USB module */ -#define nGLOBAL_ENA 0x0 -#define EP1_TX_ENA 0x2 /* Transmit endpoint 1 enable */ -#define nEP1_TX_ENA 0x0 -#define EP2_TX_ENA 0x4 /* Transmit endpoint 2 enable */ -#define nEP2_TX_ENA 0x0 -#define EP3_TX_ENA 0x8 /* Transmit endpoint 3 enable */ -#define nEP3_TX_ENA 0x0 -#define EP4_TX_ENA 0x10 /* Transmit endpoint 4 enable */ -#define nEP4_TX_ENA 0x0 -#define EP5_TX_ENA 0x20 /* Transmit endpoint 5 enable */ -#define nEP5_TX_ENA 0x0 -#define EP6_TX_ENA 0x40 /* Transmit endpoint 6 enable */ -#define nEP6_TX_ENA 0x0 -#define EP7_TX_ENA 0x80 /* Transmit endpoint 7 enable */ -#define nEP7_TX_ENA 0x0 -#define EP1_RX_ENA 0x100 /* Receive endpoint 1 enable */ -#define nEP1_RX_ENA 0x0 -#define EP2_RX_ENA 0x200 /* Receive endpoint 2 enable */ -#define nEP2_RX_ENA 0x0 -#define EP3_RX_ENA 0x400 /* Receive endpoint 3 enable */ -#define nEP3_RX_ENA 0x0 -#define EP4_RX_ENA 0x800 /* Receive endpoint 4 enable */ -#define nEP4_RX_ENA 0x0 -#define EP5_RX_ENA 0x1000 /* Receive endpoint 5 enable */ -#define nEP5_RX_ENA 0x0 -#define EP6_RX_ENA 0x2000 /* Receive endpoint 6 enable */ -#define nEP6_RX_ENA 0x0 -#define EP7_RX_ENA 0x4000 /* Receive endpoint 7 enable */ -#define nEP7_RX_ENA 0x0 - -/* Bit masks for USB_OTG_DEV_CTL */ - -#define SESSION 0x1 /* session indicator */ -#define nSESSION 0x0 -#define HOST_REQ 0x2 /* Host negotiation request */ -#define nHOST_REQ 0x0 -#define HOST_MODE 0x4 /* indicates USBDRC is a host */ -#define nHOST_MODE 0x0 -#define VBUS0 0x8 /* Vbus level indicator[0] */ -#define nVBUS0 0x0 -#define VBUS1 0x10 /* Vbus level indicator[1] */ -#define nVBUS1 0x0 -#define LSDEV 0x20 /* Low-speed indicator */ -#define nLSDEV 0x0 -#define FSDEV 0x40 /* Full or High-speed indicator */ -#define nFSDEV 0x0 -#define B_DEVICE 0x80 /* A' or 'B' device indicator */ -#define nB_DEVICE 0x0 - -/* Bit masks for USB_OTG_VBUS_IRQ */ - -#define DRIVE_VBUS_ON 0x1 /* indicator to drive VBUS control circuit */ -#define nDRIVE_VBUS_ON 0x0 -#define DRIVE_VBUS_OFF 0x2 /* indicator to shut off charge pump */ -#define nDRIVE_VBUS_OFF 0x0 -#define CHRG_VBUS_START 0x4 /* indicator for external circuit to start charging VBUS */ -#define nCHRG_VBUS_START 0x0 -#define CHRG_VBUS_END 0x8 /* indicator for external circuit to end charging VBUS */ -#define nCHRG_VBUS_END 0x0 -#define DISCHRG_VBUS_START 0x10 /* indicator to start discharging VBUS */ -#define nDISCHRG_VBUS_START 0x0 -#define DISCHRG_VBUS_END 0x20 /* indicator to stop discharging VBUS */ -#define nDISCHRG_VBUS_END 0x0 - -/* Bit masks for USB_OTG_VBUS_MASK */ - -#define DRIVE_VBUS_ON_ENA 0x1 /* enable DRIVE_VBUS_ON interrupt */ -#define nDRIVE_VBUS_ON_ENA 0x0 -#define DRIVE_VBUS_OFF_ENA 0x2 /* enable DRIVE_VBUS_OFF interrupt */ -#define nDRIVE_VBUS_OFF_ENA 0x0 -#define CHRG_VBUS_START_ENA 0x4 /* enable CHRG_VBUS_START interrupt */ -#define nCHRG_VBUS_START_ENA 0x0 -#define CHRG_VBUS_END_ENA 0x8 /* enable CHRG_VBUS_END interrupt */ -#define nCHRG_VBUS_END_ENA 0x0 -#define DISCHRG_VBUS_START_ENA 0x10 /* enable DISCHRG_VBUS_START interrupt */ -#define nDISCHRG_VBUS_START_ENA 0x0 -#define DISCHRG_VBUS_END_ENA 0x20 /* enable DISCHRG_VBUS_END interrupt */ -#define nDISCHRG_VBUS_END_ENA 0x0 - -/* Bit masks for USB_CSR0 */ - -#define RXPKTRDY 0x1 /* data packet receive indicator */ -#define nRXPKTRDY 0x0 -#define TXPKTRDY 0x2 /* data packet in FIFO indicator */ -#define nTXPKTRDY 0x0 -#define STALL_SENT 0x4 /* STALL handshake sent */ -#define nSTALL_SENT 0x0 -#define DATAEND 0x8 /* Data end indicator */ -#define nDATAEND 0x0 -#define SETUPEND 0x10 /* Setup end */ -#define nSETUPEND 0x0 -#define SENDSTALL 0x20 /* Send STALL handshake */ -#define nSENDSTALL 0x0 -#define SERVICED_RXPKTRDY 0x40 /* used to clear the RxPktRdy bit */ -#define nSERVICED_RXPKTRDY 0x0 -#define SERVICED_SETUPEND 0x80 /* used to clear the SetupEnd bit */ -#define nSERVICED_SETUPEND 0x0 -#define FLUSHFIFO 0x100 /* flush endpoint FIFO */ -#define nFLUSHFIFO 0x0 -#define STALL_RECEIVED_H 0x4 /* STALL handshake received host mode */ -#define nSTALL_RECEIVED_H 0x0 -#define SETUPPKT_H 0x8 /* send Setup token host mode */ -#define nSETUPPKT_H 0x0 -#define ERROR_H 0x10 /* timeout error indicator host mode */ -#define nERROR_H 0x0 -#define REQPKT_H 0x20 /* Request an IN transaction host mode */ -#define nREQPKT_H 0x0 -#define STATUSPKT_H 0x40 /* Status stage transaction host mode */ -#define nSTATUSPKT_H 0x0 -#define NAK_TIMEOUT_H 0x80 /* EP0 halted after a NAK host mode */ -#define nNAK_TIMEOUT_H 0x0 - -/* Bit masks for USB_COUNT0 */ - -#define EP0_RX_COUNT 0x7f /* number of received bytes in EP0 FIFO */ - -/* Bit masks for USB_NAKLIMIT0 */ - -#define EP0_NAK_LIMIT 0x1f /* number of frames/micro frames after which EP0 timeouts */ - -/* Bit masks for USB_TX_MAX_PACKET */ - -#define MAX_PACKET_SIZE_T 0x7ff /* maximum data pay load in a frame */ - -/* Bit masks for USB_RX_MAX_PACKET */ - -#define MAX_PACKET_SIZE_R 0x7ff /* maximum data pay load in a frame */ - -/* Bit masks for USB_TXCSR */ - -#define TXPKTRDY_T 0x1 /* data packet in FIFO indicator */ -#define nTXPKTRDY_T 0x0 -#define FIFO_NOT_EMPTY_T 0x2 /* FIFO not empty */ -#define nFIFO_NOT_EMPTY_T 0x0 -#define UNDERRUN_T 0x4 /* TxPktRdy not set for an IN token */ -#define nUNDERRUN_T 0x0 -#define FLUSHFIFO_T 0x8 /* flush endpoint FIFO */ -#define nFLUSHFIFO_T 0x0 -#define STALL_SEND_T 0x10 /* issue a Stall handshake */ -#define nSTALL_SEND_T 0x0 -#define STALL_SENT_T 0x20 /* Stall handshake transmitted */ -#define nSTALL_SENT_T 0x0 -#define CLEAR_DATATOGGLE_T 0x40 /* clear endpoint data toggle */ -#define nCLEAR_DATATOGGLE_T 0x0 -#define INCOMPTX_T 0x80 /* indicates that a large packet is split */ -#define nINCOMPTX_T 0x0 -#define DMAREQMODE_T 0x400 /* DMA mode (0 or 1) selection */ -#define nDMAREQMODE_T 0x0 -#define FORCE_DATATOGGLE_T 0x800 /* Force data toggle */ -#define nFORCE_DATATOGGLE_T 0x0 -#define DMAREQ_ENA_T 0x1000 /* Enable DMA request for Tx EP */ -#define nDMAREQ_ENA_T 0x0 -#define ISO_T 0x4000 /* enable Isochronous transfers */ -#define nISO_T 0x0 -#define AUTOSET_T 0x8000 /* allows TxPktRdy to be set automatically */ -#define nAUTOSET_T 0x0 -#define ERROR_TH 0x4 /* error condition host mode */ -#define nERROR_TH 0x0 -#define STALL_RECEIVED_TH 0x20 /* Stall handshake received host mode */ -#define nSTALL_RECEIVED_TH 0x0 -#define NAK_TIMEOUT_TH 0x80 /* NAK timeout host mode */ -#define nNAK_TIMEOUT_TH 0x0 - -/* Bit masks for USB_TXCOUNT */ - -#define TX_COUNT 0x1fff /* Number of bytes to be written to the selected endpoint Tx FIFO */ - -/* Bit masks for USB_RXCSR */ - -#define RXPKTRDY_R 0x1 /* data packet in FIFO indicator */ -#define nRXPKTRDY_R 0x0 -#define FIFO_FULL_R 0x2 /* FIFO not empty */ -#define nFIFO_FULL_R 0x0 -#define OVERRUN_R 0x4 /* TxPktRdy not set for an IN token */ -#define nOVERRUN_R 0x0 -#define DATAERROR_R 0x8 /* Out packet cannot be loaded into Rx FIFO */ -#define nDATAERROR_R 0x0 -#define FLUSHFIFO_R 0x10 /* flush endpoint FIFO */ -#define nFLUSHFIFO_R 0x0 -#define STALL_SEND_R 0x20 /* issue a Stall handshake */ -#define nSTALL_SEND_R 0x0 -#define STALL_SENT_R 0x40 /* Stall handshake transmitted */ -#define nSTALL_SENT_R 0x0 -#define CLEAR_DATATOGGLE_R 0x80 /* clear endpoint data toggle */ -#define nCLEAR_DATATOGGLE_R 0x0 -#define INCOMPRX_R 0x100 /* indicates that a large packet is split */ -#define nINCOMPRX_R 0x0 -#define DMAREQMODE_R 0x800 /* DMA mode (0 or 1) selection */ -#define nDMAREQMODE_R 0x0 -#define DISNYET_R 0x1000 /* disable Nyet handshakes */ -#define nDISNYET_R 0x0 -#define DMAREQ_ENA_R 0x2000 /* Enable DMA request for Tx EP */ -#define nDMAREQ_ENA_R 0x0 -#define ISO_R 0x4000 /* enable Isochronous transfers */ -#define nISO_R 0x0 -#define AUTOCLEAR_R 0x8000 /* allows TxPktRdy to be set automatically */ -#define nAUTOCLEAR_R 0x0 -#define ERROR_RH 0x4 /* TxPktRdy not set for an IN token host mode */ -#define nERROR_RH 0x0 -#define REQPKT_RH 0x20 /* request an IN transaction host mode */ -#define nREQPKT_RH 0x0 -#define STALL_RECEIVED_RH 0x40 /* Stall handshake received host mode */ -#define nSTALL_RECEIVED_RH 0x0 -#define INCOMPRX_RH 0x100 /* indicates that a large packet is split host mode */ -#define nINCOMPRX_RH 0x0 -#define DMAREQMODE_RH 0x800 /* DMA mode (0 or 1) selection host mode */ -#define nDMAREQMODE_RH 0x0 -#define AUTOREQ_RH 0x4000 /* sets ReqPkt automatically host mode */ -#define nAUTOREQ_RH 0x0 - -/* Bit masks for USB_RXCOUNT */ - -#define RX_COUNT 0x1fff /* Number of received bytes in the packet in the Rx FIFO */ - -/* Bit masks for USB_TXTYPE */ - -#define TARGET_EP_NO_T 0xf /* EP number */ -#define PROTOCOL_T 0xc /* transfer type */ - -/* Bit masks for USB_TXINTERVAL */ - -#define TX_POLL_INTERVAL 0xff /* polling interval for selected Tx EP */ - -/* Bit masks for USB_RXTYPE */ - -#define TARGET_EP_NO_R 0xf /* EP number */ -#define PROTOCOL_R 0xc /* transfer type */ - -/* Bit masks for USB_RXINTERVAL */ - -#define RX_POLL_INTERVAL 0xff /* polling interval for selected Rx EP */ - -/* Bit masks for USB_DMA_INTERRUPT */ - -#define DMA0_INT 0x1 /* DMA0 pending interrupt */ -#define nDMA0_INT 0x0 -#define DMA1_INT 0x2 /* DMA1 pending interrupt */ -#define nDMA1_INT 0x0 -#define DMA2_INT 0x4 /* DMA2 pending interrupt */ -#define nDMA2_INT 0x0 -#define DMA3_INT 0x8 /* DMA3 pending interrupt */ -#define nDMA3_INT 0x0 -#define DMA4_INT 0x10 /* DMA4 pending interrupt */ -#define nDMA4_INT 0x0 -#define DMA5_INT 0x20 /* DMA5 pending interrupt */ -#define nDMA5_INT 0x0 -#define DMA6_INT 0x40 /* DMA6 pending interrupt */ -#define nDMA6_INT 0x0 -#define DMA7_INT 0x80 /* DMA7 pending interrupt */ -#define nDMA7_INT 0x0 - -/* Bit masks for USB_DMAxCONTROL */ - -#define DMA_ENA 0x1 /* DMA enable */ -#define nDMA_ENA 0x0 -#define DIRECTION 0x2 /* direction of DMA transfer */ -#define nDIRECTION 0x0 -#define MODE 0x4 /* DMA Bus error */ -#define nMODE 0x0 -#define INT_ENA 0x8 /* Interrupt enable */ -#define nINT_ENA 0x0 -#define EPNUM 0xf0 /* EP number */ -#define BUSERROR 0x100 /* DMA Bus error */ -#define nBUSERROR 0x0 - -/* Bit masks for USB_DMAxADDRHIGH */ - -#define DMA_ADDR_HIGH 0xffff /* Upper 16-bits of memory source/destination address for the DMA master channel */ - -/* Bit masks for USB_DMAxADDRLOW */ - -#define DMA_ADDR_LOW 0xffff /* Lower 16-bits of memory source/destination address for the DMA master channel */ - -/* Bit masks for USB_DMAxCOUNTHIGH */ - -#define DMA_COUNT_HIGH 0xffff /* Upper 16-bits of byte count of DMA transfer for DMA master channel */ - -/* Bit masks for USB_DMAxCOUNTLOW */ - -#define DMA_COUNT_LOW 0xffff /* Lower 16-bits of byte count of DMA transfer for DMA master channel */ - #endif /* _DEF_BF527_H */ -- cgit v0.10.2 From 31ad0e27ed71c30cd328b503ce6163392b4dd9e2 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 17 Nov 2009 06:15:01 +0000 Subject: Blackfin: BF51x: unify def/cdef headers Whole lot of duplicated code here just went bye bye. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF514.h b/arch/blackfin/mach-bf518/include/mach/cdefBF514.h index e1d9991..108fa4b 100644 --- a/arch/blackfin/mach-bf518/include/mach/cdefBF514.h +++ b/arch/blackfin/mach-bf518/include/mach/cdefBF514.h @@ -1,7 +1,7 @@ /* * Copyright 2008-2009 Analog Devices Inc. * - * Licensed under the GPL-2 or later + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _CDEF_BF514_H @@ -10,15 +10,8 @@ /* include all Core registers and bit definitions */ #include "defBF514.h" -/* include core specific register pointer definitions */ -#include - -/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF514 */ - -/* include cdefBF51x_base.h for the set of #defines that are common to all ADSP-BF51x processors */ -#include "cdefBF51x_base.h" - -/* The following are the #defines needed by ADSP-BF514 that are not in the common header */ +/* BF514 is BF512 + RSI */ +#include "cdefBF512.h" /* Removable Storage Interface Registers */ diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF516.h b/arch/blackfin/mach-bf518/include/mach/cdefBF516.h index 6b364ed..2751592 100644 --- a/arch/blackfin/mach-bf518/include/mach/cdefBF516.h +++ b/arch/blackfin/mach-bf518/include/mach/cdefBF516.h @@ -1,7 +1,7 @@ /* * Copyright 2008-2009 Analog Devices Inc. * - * Licensed under the GPL-2 or later + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _CDEF_BF516_H @@ -10,15 +10,8 @@ /* include all Core registers and bit definitions */ #include "defBF516.h" -/* include core specific register pointer definitions */ -#include - -/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF516 */ - -/* include cdefBF51x_base.h for the set of #defines that are common to all ADSP-BF51x processors */ -#include "cdefBF51x_base.h" - -/* The following are the #defines needed by ADSP-BF516 that are not in the common header */ +/* BF516 is BF514 + EMAC */ +#include "cdefBF514.h" /* 10/100 Ethernet Controller (0xFFC03000 - 0xFFC031FF) */ @@ -185,71 +178,4 @@ #define bfin_read_EMAC_TXC_ABORT() bfin_read32(EMAC_TXC_ABORT) #define bfin_write_EMAC_TXC_ABORT(val) bfin_write32(EMAC_TXC_ABORT, val) -/* Removable Storage Interface Registers */ - -#define bfin_read_RSI_PWR_CTL() bfin_read16(RSI_PWR_CONTROL) -#define bfin_write_RSI_PWR_CTL(val) bfin_write16(RSI_PWR_CONTROL, val) -#define bfin_read_RSI_CLK_CTL() bfin_read16(RSI_CLK_CONTROL) -#define bfin_write_RSI_CLK_CTL(val) bfin_write16(RSI_CLK_CONTROL, val) -#define bfin_read_RSI_ARGUMENT() bfin_read32(RSI_ARGUMENT) -#define bfin_write_RSI_ARGUMENT(val) bfin_write32(RSI_ARGUMENT, val) -#define bfin_read_RSI_COMMAND() bfin_read16(RSI_COMMAND) -#define bfin_write_RSI_COMMAND(val) bfin_write16(RSI_COMMAND, val) -#define bfin_read_RSI_RESP_CMD() bfin_read16(RSI_RESP_CMD) -#define bfin_write_RSI_RESP_CMD(val) bfin_write16(RSI_RESP_CMD, val) -#define bfin_read_RSI_RESPONSE0() bfin_read32(RSI_RESPONSE0) -#define bfin_write_RSI_RESPONSE0(val) bfin_write32(RSI_RESPONSE0, val) -#define bfin_read_RSI_RESPONSE1() bfin_read32(RSI_RESPONSE1) -#define bfin_write_RSI_RESPONSE1(val) bfin_write32(RSI_RESPONSE1, val) -#define bfin_read_RSI_RESPONSE2() bfin_read32(RSI_RESPONSE2) -#define bfin_write_RSI_RESPONSE2(val) bfin_write32(RSI_RESPONSE2, val) -#define bfin_read_RSI_RESPONSE3() bfin_read32(RSI_RESPONSE3) -#define bfin_write_RSI_RESPONSE3(val) bfin_write32(RSI_RESPONSE3, val) -#define bfin_read_RSI_DATA_TIMER() bfin_read32(RSI_DATA_TIMER) -#define bfin_write_RSI_DATA_TIMER(val) bfin_write32(RSI_DATA_TIMER, val) -#define bfin_read_RSI_DATA_LGTH() bfin_read16(RSI_DATA_LGTH) -#define bfin_write_RSI_DATA_LGTH(val) bfin_write16(RSI_DATA_LGTH, val) -#define bfin_read_RSI_DATA_CTL() bfin_read16(RSI_DATA_CONTROL) -#define bfin_write_RSI_DATA_CTL(val) bfin_write16(RSI_DATA_CONTROL, val) -#define bfin_read_RSI_DATA_CNT() bfin_read16(RSI_DATA_CNT) -#define bfin_write_RSI_DATA_CNT(val) bfin_write16(RSI_DATA_CNT, val) -#define bfin_read_RSI_STATUS() bfin_read32(RSI_STATUS) -#define bfin_write_RSI_STATUS(val) bfin_write32(RSI_STATUS, val) -#define bfin_read_RSI_STATUS_CLR() bfin_read16(RSI_STATUSCL) -#define bfin_write_RSI_STATUS_CLR(val) bfin_write16(RSI_STATUSCL, val) -#define bfin_read_RSI_MASK0() bfin_read32(RSI_MASK0) -#define bfin_write_RSI_MASK0(val) bfin_write32(RSI_MASK0, val) -#define bfin_read_RSI_MASK1() bfin_read32(RSI_MASK1) -#define bfin_write_RSI_MASK1(val) bfin_write32(RSI_MASK1, val) -#define bfin_read_RSI_FIFO_CNT() bfin_read16(RSI_FIFO_CNT) -#define bfin_write_RSI_FIFO_CNT(val) bfin_write16(RSI_FIFO_CNT, val) -#define bfin_read_RSI_CEATA_CTL() bfin_read16(RSI_CEATA_CONTROL) -#define bfin_write_RSI_CEATA_CTL(val) bfin_write16(RSI_CEATA_CONTROL, val) -#define bfin_read_RSI_FIFO() bfin_read32(RSI_FIFO) -#define bfin_write_RSI_FIFO(val) bfin_write32(RSI_FIFO, val) -#define bfin_read_RSI_E_STATUS() bfin_read16(RSI_ESTAT) -#define bfin_write_RSI_E_STATUS(val) bfin_write16(RSI_ESTAT, val) -#define bfin_read_RSI_E_MASK() bfin_read16(RSI_EMASK) -#define bfin_write_RSI_E_MASK(val) bfin_write16(RSI_EMASK, val) -#define bfin_read_RSI_CFG() bfin_read16(RSI_CONFIG) -#define bfin_write_RSI_CFG(val) bfin_write16(RSI_CONFIG, val) -#define bfin_read_RSI_RD_WAIT_EN() bfin_read16(RSI_RD_WAIT_EN) -#define bfin_write_RSI_RD_WAIT_EN(val) bfin_write16(RSI_RD_WAIT_EN, val) -#define bfin_read_RSI_PID0() bfin_read16(RSI_PID0) -#define bfin_write_RSI_PID0(val) bfin_write16(RSI_PID0, val) -#define bfin_read_RSI_PID1() bfin_read16(RSI_PID1) -#define bfin_write_RSI_PID1(val) bfin_write16(RSI_PID1, val) -#define bfin_read_RSI_PID2() bfin_read16(RSI_PID2) -#define bfin_write_RSI_PID2(val) bfin_write16(RSI_PID2, val) -#define bfin_read_RSI_PID3() bfin_read16(RSI_PID3) -#define bfin_write_RSI_PID3(val) bfin_write16(RSI_PID3, val) -#define bfin_read_RSI_PID4() bfin_read16(RSI_PID4) -#define bfin_write_RSI_PID4(val) bfin_write16(RSI_PID4, val) -#define bfin_read_RSI_PID5() bfin_read16(RSI_PID5) -#define bfin_write_RSI_PID5(val) bfin_write16(RSI_PID5, val) -#define bfin_read_RSI_PID6() bfin_read16(RSI_PID6) -#define bfin_write_RSI_PID6(val) bfin_write16(RSI_PID6, val) -#define bfin_read_RSI_PID7() bfin_read16(RSI_PID7) -#define bfin_write_RSI_PID7(val) bfin_write16(RSI_PID7, val) - #endif /* _CDEF_BF516_H */ diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF518.h b/arch/blackfin/mach-bf518/include/mach/cdefBF518.h index 929b906..7fb7f0e 100644 --- a/arch/blackfin/mach-bf518/include/mach/cdefBF518.h +++ b/arch/blackfin/mach-bf518/include/mach/cdefBF518.h @@ -1,7 +1,7 @@ /* * Copyright 2008-2009 Analog Devices Inc. * - * Licensed under the GPL-2 or later + * Licensed under the ADI BSD license or the GPL-2 (or later) */ #ifndef _CDEF_BF518_H @@ -10,181 +10,10 @@ /* include all Core registers and bit definitions */ #include "defBF518.h" -/* include core specific register pointer definitions */ -#include +/* BF518 is BF516 + IEEE-1588 */ +#include "cdefBF516.h" -/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF518 */ - -/* include cdefBF51x_base.h for the set of #defines that are common to all ADSP-BF51x processors */ -#include "cdefBF51x_base.h" - -/* The following are the #defines needed by ADSP-BF518 that are not in the common header */ - - -/* 10/100 Ethernet Controller (0xFFC03000 - 0xFFC031FF) */ - -#define bfin_read_EMAC_OPMODE() bfin_read32(EMAC_OPMODE) -#define bfin_write_EMAC_OPMODE(val) bfin_write32(EMAC_OPMODE, val) -#define bfin_read_EMAC_ADDRLO() bfin_read32(EMAC_ADDRLO) -#define bfin_write_EMAC_ADDRLO(val) bfin_write32(EMAC_ADDRLO, val) -#define bfin_read_EMAC_ADDRHI() bfin_read32(EMAC_ADDRHI) -#define bfin_write_EMAC_ADDRHI(val) bfin_write32(EMAC_ADDRHI, val) -#define bfin_read_EMAC_HASHLO() bfin_read32(EMAC_HASHLO) -#define bfin_write_EMAC_HASHLO(val) bfin_write32(EMAC_HASHLO, val) -#define bfin_read_EMAC_HASHHI() bfin_read32(EMAC_HASHHI) -#define bfin_write_EMAC_HASHHI(val) bfin_write32(EMAC_HASHHI, val) -#define bfin_read_EMAC_STAADD() bfin_read32(EMAC_STAADD) -#define bfin_write_EMAC_STAADD(val) bfin_write32(EMAC_STAADD, val) -#define bfin_read_EMAC_STADAT() bfin_read32(EMAC_STADAT) -#define bfin_write_EMAC_STADAT(val) bfin_write32(EMAC_STADAT, val) -#define bfin_read_EMAC_FLC() bfin_read32(EMAC_FLC) -#define bfin_write_EMAC_FLC(val) bfin_write32(EMAC_FLC, val) -#define bfin_read_EMAC_VLAN1() bfin_read32(EMAC_VLAN1) -#define bfin_write_EMAC_VLAN1(val) bfin_write32(EMAC_VLAN1, val) -#define bfin_read_EMAC_VLAN2() bfin_read32(EMAC_VLAN2) -#define bfin_write_EMAC_VLAN2(val) bfin_write32(EMAC_VLAN2, val) -#define bfin_read_EMAC_WKUP_CTL() bfin_read32(EMAC_WKUP_CTL) -#define bfin_write_EMAC_WKUP_CTL(val) bfin_write32(EMAC_WKUP_CTL, val) -#define bfin_read_EMAC_WKUP_FFMSK0() bfin_read32(EMAC_WKUP_FFMSK0) -#define bfin_write_EMAC_WKUP_FFMSK0(val) bfin_write32(EMAC_WKUP_FFMSK0, val) -#define bfin_read_EMAC_WKUP_FFMSK1() bfin_read32(EMAC_WKUP_FFMSK1) -#define bfin_write_EMAC_WKUP_FFMSK1(val) bfin_write32(EMAC_WKUP_FFMSK1, val) -#define bfin_read_EMAC_WKUP_FFMSK2() bfin_read32(EMAC_WKUP_FFMSK2) -#define bfin_write_EMAC_WKUP_FFMSK2(val) bfin_write32(EMAC_WKUP_FFMSK2, val) -#define bfin_read_EMAC_WKUP_FFMSK3() bfin_read32(EMAC_WKUP_FFMSK3) -#define bfin_write_EMAC_WKUP_FFMSK3(val) bfin_write32(EMAC_WKUP_FFMSK3, val) -#define bfin_read_EMAC_WKUP_FFCMD() bfin_read32(EMAC_WKUP_FFCMD) -#define bfin_write_EMAC_WKUP_FFCMD(val) bfin_write32(EMAC_WKUP_FFCMD, val) -#define bfin_read_EMAC_WKUP_FFOFF() bfin_read32(EMAC_WKUP_FFOFF) -#define bfin_write_EMAC_WKUP_FFOFF(val) bfin_write32(EMAC_WKUP_FFOFF, val) -#define bfin_read_EMAC_WKUP_FFCRC0() bfin_read32(EMAC_WKUP_FFCRC0) -#define bfin_write_EMAC_WKUP_FFCRC0(val) bfin_write32(EMAC_WKUP_FFCRC0, val) -#define bfin_read_EMAC_WKUP_FFCRC1() bfin_read32(EMAC_WKUP_FFCRC1) -#define bfin_write_EMAC_WKUP_FFCRC1(val) bfin_write32(EMAC_WKUP_FFCRC1, val) - -#define bfin_read_EMAC_SYSCTL() bfin_read32(EMAC_SYSCTL) -#define bfin_write_EMAC_SYSCTL(val) bfin_write32(EMAC_SYSCTL, val) -#define bfin_read_EMAC_SYSTAT() bfin_read32(EMAC_SYSTAT) -#define bfin_write_EMAC_SYSTAT(val) bfin_write32(EMAC_SYSTAT, val) -#define bfin_read_EMAC_RX_STAT() bfin_read32(EMAC_RX_STAT) -#define bfin_write_EMAC_RX_STAT(val) bfin_write32(EMAC_RX_STAT, val) -#define bfin_read_EMAC_RX_STKY() bfin_read32(EMAC_RX_STKY) -#define bfin_write_EMAC_RX_STKY(val) bfin_write32(EMAC_RX_STKY, val) -#define bfin_read_EMAC_RX_IRQE() bfin_read32(EMAC_RX_IRQE) -#define bfin_write_EMAC_RX_IRQE(val) bfin_write32(EMAC_RX_IRQE, val) -#define bfin_read_EMAC_TX_STAT() bfin_read32(EMAC_TX_STAT) -#define bfin_write_EMAC_TX_STAT(val) bfin_write32(EMAC_TX_STAT, val) -#define bfin_read_EMAC_TX_STKY() bfin_read32(EMAC_TX_STKY) -#define bfin_write_EMAC_TX_STKY(val) bfin_write32(EMAC_TX_STKY, val) -#define bfin_read_EMAC_TX_IRQE() bfin_read32(EMAC_TX_IRQE) -#define bfin_write_EMAC_TX_IRQE(val) bfin_write32(EMAC_TX_IRQE, val) - -#define bfin_read_EMAC_MMC_CTL() bfin_read32(EMAC_MMC_CTL) -#define bfin_write_EMAC_MMC_CTL(val) bfin_write32(EMAC_MMC_CTL, val) -#define bfin_read_EMAC_MMC_RIRQS() bfin_read32(EMAC_MMC_RIRQS) -#define bfin_write_EMAC_MMC_RIRQS(val) bfin_write32(EMAC_MMC_RIRQS, val) -#define bfin_read_EMAC_MMC_RIRQE() bfin_read32(EMAC_MMC_RIRQE) -#define bfin_write_EMAC_MMC_RIRQE(val) bfin_write32(EMAC_MMC_RIRQE, val) -#define bfin_read_EMAC_MMC_TIRQS() bfin_read32(EMAC_MMC_TIRQS) -#define bfin_write_EMAC_MMC_TIRQS(val) bfin_write32(EMAC_MMC_TIRQS, val) -#define bfin_read_EMAC_MMC_TIRQE() bfin_read32(EMAC_MMC_TIRQE) -#define bfin_write_EMAC_MMC_TIRQE(val) bfin_write32(EMAC_MMC_TIRQE, val) - -#define bfin_read_EMAC_RXC_OK() bfin_read32(EMAC_RXC_OK) -#define bfin_write_EMAC_RXC_OK(val) bfin_write32(EMAC_RXC_OK, val) -#define bfin_read_EMAC_RXC_FCS() bfin_read32(EMAC_RXC_FCS) -#define bfin_write_EMAC_RXC_FCS(val) bfin_write32(EMAC_RXC_FCS, val) -#define bfin_read_EMAC_RXC_ALIGN() bfin_read32(EMAC_RXC_ALIGN) -#define bfin_write_EMAC_RXC_ALIGN(val) bfin_write32(EMAC_RXC_ALIGN, val) -#define bfin_read_EMAC_RXC_OCTET() bfin_read32(EMAC_RXC_OCTET) -#define bfin_write_EMAC_RXC_OCTET(val) bfin_write32(EMAC_RXC_OCTET, val) -#define bfin_read_EMAC_RXC_DMAOVF() bfin_read32(EMAC_RXC_DMAOVF) -#define bfin_write_EMAC_RXC_DMAOVF(val) bfin_write32(EMAC_RXC_DMAOVF, val) -#define bfin_read_EMAC_RXC_UNICST() bfin_read32(EMAC_RXC_UNICST) -#define bfin_write_EMAC_RXC_UNICST(val) bfin_write32(EMAC_RXC_UNICST, val) -#define bfin_read_EMAC_RXC_MULTI() bfin_read32(EMAC_RXC_MULTI) -#define bfin_write_EMAC_RXC_MULTI(val) bfin_write32(EMAC_RXC_MULTI, val) -#define bfin_read_EMAC_RXC_BROAD() bfin_read32(EMAC_RXC_BROAD) -#define bfin_write_EMAC_RXC_BROAD(val) bfin_write32(EMAC_RXC_BROAD, val) -#define bfin_read_EMAC_RXC_LNERRI() bfin_read32(EMAC_RXC_LNERRI) -#define bfin_write_EMAC_RXC_LNERRI(val) bfin_write32(EMAC_RXC_LNERRI, val) -#define bfin_read_EMAC_RXC_LNERRO() bfin_read32(EMAC_RXC_LNERRO) -#define bfin_write_EMAC_RXC_LNERRO(val) bfin_write32(EMAC_RXC_LNERRO, val) -#define bfin_read_EMAC_RXC_LONG() bfin_read32(EMAC_RXC_LONG) -#define bfin_write_EMAC_RXC_LONG(val) bfin_write32(EMAC_RXC_LONG, val) -#define bfin_read_EMAC_RXC_MACCTL() bfin_read32(EMAC_RXC_MACCTL) -#define bfin_write_EMAC_RXC_MACCTL(val) bfin_write32(EMAC_RXC_MACCTL, val) -#define bfin_read_EMAC_RXC_OPCODE() bfin_read32(EMAC_RXC_OPCODE) -#define bfin_write_EMAC_RXC_OPCODE(val) bfin_write32(EMAC_RXC_OPCODE, val) -#define bfin_read_EMAC_RXC_PAUSE() bfin_read32(EMAC_RXC_PAUSE) -#define bfin_write_EMAC_RXC_PAUSE(val) bfin_write32(EMAC_RXC_PAUSE, val) -#define bfin_read_EMAC_RXC_ALLFRM() bfin_read32(EMAC_RXC_ALLFRM) -#define bfin_write_EMAC_RXC_ALLFRM(val) bfin_write32(EMAC_RXC_ALLFRM, val) -#define bfin_read_EMAC_RXC_ALLOCT() bfin_read32(EMAC_RXC_ALLOCT) -#define bfin_write_EMAC_RXC_ALLOCT(val) bfin_write32(EMAC_RXC_ALLOCT, val) -#define bfin_read_EMAC_RXC_TYPED() bfin_read32(EMAC_RXC_TYPED) -#define bfin_write_EMAC_RXC_TYPED(val) bfin_write32(EMAC_RXC_TYPED, val) -#define bfin_read_EMAC_RXC_SHORT() bfin_read32(EMAC_RXC_SHORT) -#define bfin_write_EMAC_RXC_SHORT(val) bfin_write32(EMAC_RXC_SHORT, val) -#define bfin_read_EMAC_RXC_EQ64() bfin_read32(EMAC_RXC_EQ64) -#define bfin_write_EMAC_RXC_EQ64(val) bfin_write32(EMAC_RXC_EQ64, val) -#define bfin_read_EMAC_RXC_LT128() bfin_read32(EMAC_RXC_LT128) -#define bfin_write_EMAC_RXC_LT128(val) bfin_write32(EMAC_RXC_LT128, val) -#define bfin_read_EMAC_RXC_LT256() bfin_read32(EMAC_RXC_LT256) -#define bfin_write_EMAC_RXC_LT256(val) bfin_write32(EMAC_RXC_LT256, val) -#define bfin_read_EMAC_RXC_LT512() bfin_read32(EMAC_RXC_LT512) -#define bfin_write_EMAC_RXC_LT512(val) bfin_write32(EMAC_RXC_LT512, val) -#define bfin_read_EMAC_RXC_LT1024() bfin_read32(EMAC_RXC_LT1024) -#define bfin_write_EMAC_RXC_LT1024(val) bfin_write32(EMAC_RXC_LT1024, val) -#define bfin_read_EMAC_RXC_GE1024() bfin_read32(EMAC_RXC_GE1024) -#define bfin_write_EMAC_RXC_GE1024(val) bfin_write32(EMAC_RXC_GE1024, val) - -#define bfin_read_EMAC_TXC_OK() bfin_read32(EMAC_TXC_OK) -#define bfin_write_EMAC_TXC_OK(val) bfin_write32(EMAC_TXC_OK, val) -#define bfin_read_EMAC_TXC_1COL() bfin_read32(EMAC_TXC_1COL) -#define bfin_write_EMAC_TXC_1COL(val) bfin_write32(EMAC_TXC_1COL, val) -#define bfin_read_EMAC_TXC_GT1COL() bfin_read32(EMAC_TXC_GT1COL) -#define bfin_write_EMAC_TXC_GT1COL(val) bfin_write32(EMAC_TXC_GT1COL, val) -#define bfin_read_EMAC_TXC_OCTET() bfin_read32(EMAC_TXC_OCTET) -#define bfin_write_EMAC_TXC_OCTET(val) bfin_write32(EMAC_TXC_OCTET, val) -#define bfin_read_EMAC_TXC_DEFER() bfin_read32(EMAC_TXC_DEFER) -#define bfin_write_EMAC_TXC_DEFER(val) bfin_write32(EMAC_TXC_DEFER, val) -#define bfin_read_EMAC_TXC_LATECL() bfin_read32(EMAC_TXC_LATECL) -#define bfin_write_EMAC_TXC_LATECL(val) bfin_write32(EMAC_TXC_LATECL, val) -#define bfin_read_EMAC_TXC_XS_COL() bfin_read32(EMAC_TXC_XS_COL) -#define bfin_write_EMAC_TXC_XS_COL(val) bfin_write32(EMAC_TXC_XS_COL, val) -#define bfin_read_EMAC_TXC_DMAUND() bfin_read32(EMAC_TXC_DMAUND) -#define bfin_write_EMAC_TXC_DMAUND(val) bfin_write32(EMAC_TXC_DMAUND, val) -#define bfin_read_EMAC_TXC_CRSERR() bfin_read32(EMAC_TXC_CRSERR) -#define bfin_write_EMAC_TXC_CRSERR(val) bfin_write32(EMAC_TXC_CRSERR, val) -#define bfin_read_EMAC_TXC_UNICST() bfin_read32(EMAC_TXC_UNICST) -#define bfin_write_EMAC_TXC_UNICST(val) bfin_write32(EMAC_TXC_UNICST, val) -#define bfin_read_EMAC_TXC_MULTI() bfin_read32(EMAC_TXC_MULTI) -#define bfin_write_EMAC_TXC_MULTI(val) bfin_write32(EMAC_TXC_MULTI, val) -#define bfin_read_EMAC_TXC_BROAD() bfin_read32(EMAC_TXC_BROAD) -#define bfin_write_EMAC_TXC_BROAD(val) bfin_write32(EMAC_TXC_BROAD, val) -#define bfin_read_EMAC_TXC_XS_DFR() bfin_read32(EMAC_TXC_XS_DFR) -#define bfin_write_EMAC_TXC_XS_DFR(val) bfin_write32(EMAC_TXC_XS_DFR, val) -#define bfin_read_EMAC_TXC_MACCTL() bfin_read32(EMAC_TXC_MACCTL) -#define bfin_write_EMAC_TXC_MACCTL(val) bfin_write32(EMAC_TXC_MACCTL, val) -#define bfin_read_EMAC_TXC_ALLFRM() bfin_read32(EMAC_TXC_ALLFRM) -#define bfin_write_EMAC_TXC_ALLFRM(val) bfin_write32(EMAC_TXC_ALLFRM, val) -#define bfin_read_EMAC_TXC_ALLOCT() bfin_read32(EMAC_TXC_ALLOCT) -#define bfin_write_EMAC_TXC_ALLOCT(val) bfin_write32(EMAC_TXC_ALLOCT, val) -#define bfin_read_EMAC_TXC_EQ64() bfin_read32(EMAC_TXC_EQ64) -#define bfin_write_EMAC_TXC_EQ64(val) bfin_write32(EMAC_TXC_EQ64, val) -#define bfin_read_EMAC_TXC_LT128() bfin_read32(EMAC_TXC_LT128) -#define bfin_write_EMAC_TXC_LT128(val) bfin_write32(EMAC_TXC_LT128, val) -#define bfin_read_EMAC_TXC_LT256() bfin_read32(EMAC_TXC_LT256) -#define bfin_write_EMAC_TXC_LT256(val) bfin_write32(EMAC_TXC_LT256, val) -#define bfin_read_EMAC_TXC_LT512() bfin_read32(EMAC_TXC_LT512) -#define bfin_write_EMAC_TXC_LT512(val) bfin_write32(EMAC_TXC_LT512, val) -#define bfin_read_EMAC_TXC_LT1024() bfin_read32(EMAC_TXC_LT1024) -#define bfin_write_EMAC_TXC_LT1024(val) bfin_write32(EMAC_TXC_LT1024, val) -#define bfin_read_EMAC_TXC_GE1024() bfin_read32(EMAC_TXC_GE1024) -#define bfin_write_EMAC_TXC_GE1024(val) bfin_write32(EMAC_TXC_GE1024, val) -#define bfin_read_EMAC_TXC_ABORT() bfin_read32(EMAC_TXC_ABORT) -#define bfin_write_EMAC_TXC_ABORT(val) bfin_write32(EMAC_TXC_ABORT, val) +/* PTP TSYNC Registers */ #define bfin_read_EMAC_PTP_CTL() bfin_read16(EMAC_PTP_CTL) #define bfin_write_EMAC_PTP_CTL(val) bfin_write16(EMAC_PTP_CTL, val) @@ -227,72 +56,4 @@ #define bfin_read_EMAC_PTP_PPS_PERIOD() bfin_read32(EMAC_PTP_PPS_PERIOD) #define bfin_write_EMAC_PTP_PPS_PERIOD(val) bfin_write32(EMAC_PTP_PPS_PERIOD, val) -/* Removable Storage Interface Registers */ - -#define bfin_read_RSI_PWR_CTL() bfin_read16(RSI_PWR_CONTROL) -#define bfin_write_RSI_PWR_CTL(val) bfin_write16(RSI_PWR_CONTROL, val) -#define bfin_read_RSI_CLK_CTL() bfin_read16(RSI_CLK_CONTROL) -#define bfin_write_RSI_CLK_CTL(val) bfin_write16(RSI_CLK_CONTROL, val) -#define bfin_read_RSI_ARGUMENT() bfin_read32(RSI_ARGUMENT) -#define bfin_write_RSI_ARGUMENT(val) bfin_write32(RSI_ARGUMENT, val) -#define bfin_read_RSI_COMMAND() bfin_read16(RSI_COMMAND) -#define bfin_write_RSI_COMMAND(val) bfin_write16(RSI_COMMAND, val) -#define bfin_read_RSI_RESP_CMD() bfin_read16(RSI_RESP_CMD) -#define bfin_write_RSI_RESP_CMD(val) bfin_write16(RSI_RESP_CMD, val) -#define bfin_read_RSI_RESPONSE0() bfin_read32(RSI_RESPONSE0) -#define bfin_write_RSI_RESPONSE0(val) bfin_write32(RSI_RESPONSE0, val) -#define bfin_read_RSI_RESPONSE1() bfin_read32(RSI_RESPONSE1) -#define bfin_write_RSI_RESPONSE1(val) bfin_write32(RSI_RESPONSE1, val) -#define bfin_read_RSI_RESPONSE2() bfin_read32(RSI_RESPONSE2) -#define bfin_write_RSI_RESPONSE2(val) bfin_write32(RSI_RESPONSE2, val) -#define bfin_read_RSI_RESPONSE3() bfin_read32(RSI_RESPONSE3) -#define bfin_write_RSI_RESPONSE3(val) bfin_write32(RSI_RESPONSE3, val) -#define bfin_read_RSI_DATA_TIMER() bfin_read32(RSI_DATA_TIMER) -#define bfin_write_RSI_DATA_TIMER(val) bfin_write32(RSI_DATA_TIMER, val) -#define bfin_read_RSI_DATA_LGTH() bfin_read16(RSI_DATA_LGTH) -#define bfin_write_RSI_DATA_LGTH(val) bfin_write16(RSI_DATA_LGTH, val) -#define bfin_read_RSI_DATA_CTL() bfin_read16(RSI_DATA_CONTROL) -#define bfin_write_RSI_DATA_CTL(val) bfin_write16(RSI_DATA_CONTROL, val) -#define bfin_read_RSI_DATA_CNT() bfin_read16(RSI_DATA_CNT) -#define bfin_write_RSI_DATA_CNT(val) bfin_write16(RSI_DATA_CNT, val) -#define bfin_read_RSI_STATUS() bfin_read32(RSI_STATUS) -#define bfin_write_RSI_STATUS(val) bfin_write32(RSI_STATUS, val) -#define bfin_read_RSI_STATUS_CLR() bfin_read16(RSI_STATUSCL) -#define bfin_write_RSI_STATUS_CLR(val) bfin_write16(RSI_STATUSCL, val) -#define bfin_read_RSI_MASK0() bfin_read32(RSI_MASK0) -#define bfin_write_RSI_MASK0(val) bfin_write32(RSI_MASK0, val) -#define bfin_read_RSI_MASK1() bfin_read32(RSI_MASK1) -#define bfin_write_RSI_MASK1(val) bfin_write32(RSI_MASK1, val) -#define bfin_read_RSI_FIFO_CNT() bfin_read16(RSI_FIFO_CNT) -#define bfin_write_RSI_FIFO_CNT(val) bfin_write16(RSI_FIFO_CNT, val) -#define bfin_read_RSI_CEATA_CTL() bfin_read16(RSI_CEATA_CONTROL) -#define bfin_write_RSI_CEATA_CTL(val) bfin_write16(RSI_CEATA_CONTROL, val) -#define bfin_read_RSI_FIFO() bfin_read32(RSI_FIFO) -#define bfin_write_RSI_FIFO(val) bfin_write32(RSI_FIFO, val) -#define bfin_read_RSI_E_STATUS() bfin_read16(RSI_ESTAT) -#define bfin_write_RSI_E_STATUS(val) bfin_write16(RSI_ESTAT, val) -#define bfin_read_RSI_E_MASK() bfin_read16(RSI_EMASK) -#define bfin_write_RSI_E_MASK(val) bfin_write16(RSI_EMASK, val) -#define bfin_read_RSI_CFG() bfin_read16(RSI_CONFIG) -#define bfin_write_RSI_CFG(val) bfin_write16(RSI_CONFIG, val) -#define bfin_read_RSI_RD_WAIT_EN() bfin_read16(RSI_RD_WAIT_EN) -#define bfin_write_RSI_RD_WAIT_EN(val) bfin_write16(RSI_RD_WAIT_EN, val) -#define bfin_read_RSI_PID0() bfin_read16(RSI_PID0) -#define bfin_write_RSI_PID0(val) bfin_write16(RSI_PID0, val) -#define bfin_read_RSI_PID1() bfin_read16(RSI_PID1) -#define bfin_write_RSI_PID1(val) bfin_write16(RSI_PID1, val) -#define bfin_read_RSI_PID2() bfin_read16(RSI_PID2) -#define bfin_write_RSI_PID2(val) bfin_write16(RSI_PID2, val) -#define bfin_read_RSI_PID3() bfin_read16(RSI_PID3) -#define bfin_write_RSI_PID3(val) bfin_write16(RSI_PID3, val) -#define bfin_read_RSI_PID4() bfin_read16(RSI_PID4) -#define bfin_write_RSI_PID4(val) bfin_write16(RSI_PID4, val) -#define bfin_read_RSI_PID5() bfin_read16(RSI_PID5) -#define bfin_write_RSI_PID5(val) bfin_write16(RSI_PID5, val) -#define bfin_read_RSI_PID6() bfin_read16(RSI_PID6) -#define bfin_write_RSI_PID6(val) bfin_write16(RSI_PID6, val) -#define bfin_read_RSI_PID7() bfin_read16(RSI_PID7) -#define bfin_write_RSI_PID7(val) bfin_write16(RSI_PID7, val) - - #endif /* _CDEF_BF518_H */ diff --git a/arch/blackfin/mach-bf518/include/mach/defBF514.h b/arch/blackfin/mach-bf518/include/mach/defBF514.h index b5adca2..92e950d 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF514.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF514.h @@ -7,49 +7,8 @@ #ifndef _DEF_BF514_H #define _DEF_BF514_H -/* Include all Core registers and bit definitions */ -#include - -/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF514 */ - -/* Include defBF51x_base.h for the set of #defines that are common to all ADSP-BF51x processors */ -#include "defBF51x_base.h" - -/* The following are the #defines needed by ADSP-BF514 that are not in the common header */ - -/* SDH Registers */ - -#define SDH_PWR_CTL 0xFFC03900 /* SDH Power Control */ -#define SDH_CLK_CTL 0xFFC03904 /* SDH Clock Control */ -#define SDH_ARGUMENT 0xFFC03908 /* SDH Argument */ -#define SDH_COMMAND 0xFFC0390C /* SDH Command */ -#define SDH_RESP_CMD 0xFFC03910 /* SDH Response Command */ -#define SDH_RESPONSE0 0xFFC03914 /* SDH Response0 */ -#define SDH_RESPONSE1 0xFFC03918 /* SDH Response1 */ -#define SDH_RESPONSE2 0xFFC0391C /* SDH Response2 */ -#define SDH_RESPONSE3 0xFFC03920 /* SDH Response3 */ -#define SDH_DATA_TIMER 0xFFC03924 /* SDH Data Timer */ -#define SDH_DATA_LGTH 0xFFC03928 /* SDH Data Length */ -#define SDH_DATA_CTL 0xFFC0392C /* SDH Data Control */ -#define SDH_DATA_CNT 0xFFC03930 /* SDH Data Counter */ -#define SDH_STATUS 0xFFC03934 /* SDH Status */ -#define SDH_STATUS_CLR 0xFFC03938 /* SDH Status Clear */ -#define SDH_MASK0 0xFFC0393C /* SDH Interrupt0 Mask */ -#define SDH_MASK1 0xFFC03940 /* SDH Interrupt1 Mask */ -#define SDH_FIFO_CNT 0xFFC03948 /* SDH FIFO Counter */ -#define SDH_FIFO 0xFFC03980 /* SDH Data FIFO */ -#define SDH_E_STATUS 0xFFC039C0 /* SDH Exception Status */ -#define SDH_E_MASK 0xFFC039C4 /* SDH Exception Mask */ -#define SDH_CFG 0xFFC039C8 /* SDH Configuration */ -#define SDH_RD_WAIT_EN 0xFFC039CC /* SDH Read Wait Enable */ -#define SDH_PID0 0xFFC039D0 /* SDH Peripheral Identification0 */ -#define SDH_PID1 0xFFC039D4 /* SDH Peripheral Identification1 */ -#define SDH_PID2 0xFFC039D8 /* SDH Peripheral Identification2 */ -#define SDH_PID3 0xFFC039DC /* SDH Peripheral Identification3 */ -#define SDH_PID4 0xFFC039E0 /* SDH Peripheral Identification4 */ -#define SDH_PID5 0xFFC039E4 /* SDH Peripheral Identification5 */ -#define SDH_PID6 0xFFC039E8 /* SDH Peripheral Identification6 */ -#define SDH_PID7 0xFFC039EC /* SDH Peripheral Identification7 */ +/* BF514 is BF512 + RSI */ +#include "defBF512.h" /* Removable Storage Interface Registers */ diff --git a/arch/blackfin/mach-bf518/include/mach/defBF516.h b/arch/blackfin/mach-bf518/include/mach/defBF516.h index 7eb1877..22a3aa0 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF516.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF516.h @@ -7,13 +7,8 @@ #ifndef _DEF_BF516_H #define _DEF_BF516_H -/* Include all Core registers and bit definitions */ -#include - -/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF516 */ - -/* Include defBF51x_base.h for the set of #defines that are common to all ADSP-BF51x processors */ -#include "defBF51x_base.h" +/* BF516 is BF514 + EMAC */ +#include "defBF514.h" /* The following are the #defines needed by ADSP-BF516 that are not in the common header */ /* 10/100 Ethernet Controller (0xFFC03000 - 0xFFC031FF) */ @@ -394,208 +389,4 @@ #define TX_GE1024_CNT 0x00200000 /* 1024-Max-Byte TX Frames Sent */ #define TX_ABORT_CNT 0x00400000 /* TX Frames Aborted */ -/* SDH Registers */ - -#define SDH_PWR_CTL 0xFFC03900 /* SDH Power Control */ -#define SDH_CLK_CTL 0xFFC03904 /* SDH Clock Control */ -#define SDH_ARGUMENT 0xFFC03908 /* SDH Argument */ -#define SDH_COMMAND 0xFFC0390C /* SDH Command */ -#define SDH_RESP_CMD 0xFFC03910 /* SDH Response Command */ -#define SDH_RESPONSE0 0xFFC03914 /* SDH Response0 */ -#define SDH_RESPONSE1 0xFFC03918 /* SDH Response1 */ -#define SDH_RESPONSE2 0xFFC0391C /* SDH Response2 */ -#define SDH_RESPONSE3 0xFFC03920 /* SDH Response3 */ -#define SDH_DATA_TIMER 0xFFC03924 /* SDH Data Timer */ -#define SDH_DATA_LGTH 0xFFC03928 /* SDH Data Length */ -#define SDH_DATA_CTL 0xFFC0392C /* SDH Data Control */ -#define SDH_DATA_CNT 0xFFC03930 /* SDH Data Counter */ -#define SDH_STATUS 0xFFC03934 /* SDH Status */ -#define SDH_STATUS_CLR 0xFFC03938 /* SDH Status Clear */ -#define SDH_MASK0 0xFFC0393C /* SDH Interrupt0 Mask */ -#define SDH_MASK1 0xFFC03940 /* SDH Interrupt1 Mask */ -#define SDH_FIFO_CNT 0xFFC03948 /* SDH FIFO Counter */ -#define SDH_FIFO 0xFFC03980 /* SDH Data FIFO */ -#define SDH_E_STATUS 0xFFC039C0 /* SDH Exception Status */ -#define SDH_E_MASK 0xFFC039C4 /* SDH Exception Mask */ -#define SDH_CFG 0xFFC039C8 /* SDH Configuration */ -#define SDH_RD_WAIT_EN 0xFFC039CC /* SDH Read Wait Enable */ -#define SDH_PID0 0xFFC039D0 /* SDH Peripheral Identification0 */ -#define SDH_PID1 0xFFC039D4 /* SDH Peripheral Identification1 */ -#define SDH_PID2 0xFFC039D8 /* SDH Peripheral Identification2 */ -#define SDH_PID3 0xFFC039DC /* SDH Peripheral Identification3 */ -#define SDH_PID4 0xFFC039E0 /* SDH Peripheral Identification4 */ -#define SDH_PID5 0xFFC039E4 /* SDH Peripheral Identification5 */ -#define SDH_PID6 0xFFC039E8 /* SDH Peripheral Identification6 */ -#define SDH_PID7 0xFFC039EC /* SDH Peripheral Identification7 */ - -/* Removable Storage Interface Registers */ - -#define RSI_PWR_CONTROL 0xFFC03800 /* RSI Power Control Register */ -#define RSI_CLK_CONTROL 0xFFC03804 /* RSI Clock Control Register */ -#define RSI_ARGUMENT 0xFFC03808 /* RSI Argument Register */ -#define RSI_COMMAND 0xFFC0380C /* RSI Command Register */ -#define RSI_RESP_CMD 0xFFC03810 /* RSI Response Command Register */ -#define RSI_RESPONSE0 0xFFC03814 /* RSI Response Register */ -#define RSI_RESPONSE1 0xFFC03818 /* RSI Response Register */ -#define RSI_RESPONSE2 0xFFC0381C /* RSI Response Register */ -#define RSI_RESPONSE3 0xFFC03820 /* RSI Response Register */ -#define RSI_DATA_TIMER 0xFFC03824 /* RSI Data Timer Register */ -#define RSI_DATA_LGTH 0xFFC03828 /* RSI Data Length Register */ -#define RSI_DATA_CONTROL 0xFFC0382C /* RSI Data Control Register */ -#define RSI_DATA_CNT 0xFFC03830 /* RSI Data Counter Register */ -#define RSI_STATUS 0xFFC03834 /* RSI Status Register */ -#define RSI_STATUSCL 0xFFC03838 /* RSI Status Clear Register */ -#define RSI_MASK0 0xFFC0383C /* RSI Interrupt 0 Mask Register */ -#define RSI_MASK1 0xFFC03840 /* RSI Interrupt 1 Mask Register */ -#define RSI_FIFO_CNT 0xFFC03848 /* RSI FIFO Counter Register */ -#define RSI_CEATA_CONTROL 0xFFC0384C /* RSI CEATA Register */ -#define RSI_FIFO 0xFFC03880 /* RSI Data FIFO Register */ -#define RSI_ESTAT 0xFFC038C0 /* RSI Exception Status Register */ -#define RSI_EMASK 0xFFC038C4 /* RSI Exception Mask Register */ -#define RSI_CONFIG 0xFFC038C8 /* RSI Configuration Register */ -#define RSI_RD_WAIT_EN 0xFFC038CC /* RSI Read Wait Enable Register */ -#define RSI_PID0 0xFFC03FE0 /* RSI Peripheral ID Register 0 */ -#define RSI_PID1 0xFFC03FE4 /* RSI Peripheral ID Register 1 */ -#define RSI_PID2 0xFFC03FE8 /* RSI Peripheral ID Register 2 */ -#define RSI_PID3 0xFFC03FEC /* RSI Peripheral ID Register 3 */ -#define RSI_PID4 0xFFC03FF0 /* RSI Peripheral ID Register 4 */ -#define RSI_PID5 0xFFC03FF4 /* RSI Peripheral ID Register 5 */ -#define RSI_PID6 0xFFC03FF8 /* RSI Peripheral ID Register 6 */ -#define RSI_PID7 0xFFC03FFC /* RSI Peripheral ID Register 7 */ - -/* ********************************************************** */ -/* SINGLE BIT MACRO PAIRS (bit mask and negated one) */ -/* and MULTI BIT READ MACROS */ -/* ********************************************************** */ - -/* Bit masks for SDH_COMMAND */ - -#define CMD_IDX 0x3f /* Command Index */ -#define CMD_RSP 0x40 /* Response */ -#define CMD_L_RSP 0x80 /* Long Response */ -#define CMD_INT_E 0x100 /* Command Interrupt */ -#define CMD_PEND_E 0x200 /* Command Pending */ -#define CMD_E 0x400 /* Command Enable */ - -/* Bit masks for SDH_PWR_CTL */ - -#define PWR_ON 0x3 /* Power On */ -#if 0 -#define TBD 0x3c /* TBD */ -#endif -#define SD_CMD_OD 0x40 /* Open Drain Output */ -#define ROD_CTL 0x80 /* Rod Control */ - -/* Bit masks for SDH_CLK_CTL */ - -#define CLKDIV 0xff /* MC_CLK Divisor */ -#define CLK_E 0x100 /* MC_CLK Bus Clock Enable */ -#define PWR_SV_E 0x200 /* Power Save Enable */ -#define CLKDIV_BYPASS 0x400 /* Bypass Divisor */ -#define WIDE_BUS 0x800 /* Wide Bus Mode Enable */ - -/* Bit masks for SDH_RESP_CMD */ - -#define RESP_CMD 0x3f /* Response Command */ - -/* Bit masks for SDH_DATA_CTL */ - -#define DTX_E 0x1 /* Data Transfer Enable */ -#define DTX_DIR 0x2 /* Data Transfer Direction */ -#define DTX_MODE 0x4 /* Data Transfer Mode */ -#define DTX_DMA_E 0x8 /* Data Transfer DMA Enable */ -#define DTX_BLK_LGTH 0xf0 /* Data Transfer Block Length */ - -/* Bit masks for SDH_STATUS */ - -#define CMD_CRC_FAIL 0x1 /* CMD CRC Fail */ -#define DAT_CRC_FAIL 0x2 /* Data CRC Fail */ -#define CMD_TIME_OUT 0x4 /* CMD Time Out */ -#define DAT_TIME_OUT 0x8 /* Data Time Out */ -#define TX_UNDERRUN 0x10 /* Transmit Underrun */ -#define RX_OVERRUN 0x20 /* Receive Overrun */ -#define CMD_RESP_END 0x40 /* CMD Response End */ -#define CMD_SENT 0x80 /* CMD Sent */ -#define DAT_END 0x100 /* Data End */ -#define START_BIT_ERR 0x200 /* Start Bit Error */ -#define DAT_BLK_END 0x400 /* Data Block End */ -#define CMD_ACT 0x800 /* CMD Active */ -#define TX_ACT 0x1000 /* Transmit Active */ -#define RX_ACT 0x2000 /* Receive Active */ -#define TX_FIFO_STAT 0x4000 /* Transmit FIFO Status */ -#define RX_FIFO_STAT 0x8000 /* Receive FIFO Status */ -#define TX_FIFO_FULL 0x10000 /* Transmit FIFO Full */ -#define RX_FIFO_FULL 0x20000 /* Receive FIFO Full */ -#define TX_FIFO_ZERO 0x40000 /* Transmit FIFO Empty */ -#define RX_DAT_ZERO 0x80000 /* Receive FIFO Empty */ -#define TX_DAT_RDY 0x100000 /* Transmit Data Available */ -#define RX_FIFO_RDY 0x200000 /* Receive Data Available */ - -/* Bit masks for SDH_STATUS_CLR */ - -#define CMD_CRC_FAIL_STAT 0x1 /* CMD CRC Fail Status */ -#define DAT_CRC_FAIL_STAT 0x2 /* Data CRC Fail Status */ -#define CMD_TIMEOUT_STAT 0x4 /* CMD Time Out Status */ -#define DAT_TIMEOUT_STAT 0x8 /* Data Time Out status */ -#define TX_UNDERRUN_STAT 0x10 /* Transmit Underrun Status */ -#define RX_OVERRUN_STAT 0x20 /* Receive Overrun Status */ -#define CMD_RESP_END_STAT 0x40 /* CMD Response End Status */ -#define CMD_SENT_STAT 0x80 /* CMD Sent Status */ -#define DAT_END_STAT 0x100 /* Data End Status */ -#define START_BIT_ERR_STAT 0x200 /* Start Bit Error Status */ -#define DAT_BLK_END_STAT 0x400 /* Data Block End Status */ - -/* Bit masks for SDH_MASK0 */ - -#define CMD_CRC_FAIL_MASK 0x1 /* CMD CRC Fail Mask */ -#define DAT_CRC_FAIL_MASK 0x2 /* Data CRC Fail Mask */ -#define CMD_TIMEOUT_MASK 0x4 /* CMD Time Out Mask */ -#define DAT_TIMEOUT_MASK 0x8 /* Data Time Out Mask */ -#define TX_UNDERRUN_MASK 0x10 /* Transmit Underrun Mask */ -#define RX_OVERRUN_MASK 0x20 /* Receive Overrun Mask */ -#define CMD_RESP_END_MASK 0x40 /* CMD Response End Mask */ -#define CMD_SENT_MASK 0x80 /* CMD Sent Mask */ -#define DAT_END_MASK 0x100 /* Data End Mask */ -#define START_BIT_ERR_MASK 0x200 /* Start Bit Error Mask */ -#define DAT_BLK_END_MASK 0x400 /* Data Block End Mask */ -#define CMD_ACT_MASK 0x800 /* CMD Active Mask */ -#define TX_ACT_MASK 0x1000 /* Transmit Active Mask */ -#define RX_ACT_MASK 0x2000 /* Receive Active Mask */ -#define TX_FIFO_STAT_MASK 0x4000 /* Transmit FIFO Status Mask */ -#define RX_FIFO_STAT_MASK 0x8000 /* Receive FIFO Status Mask */ -#define TX_FIFO_FULL_MASK 0x10000 /* Transmit FIFO Full Mask */ -#define RX_FIFO_FULL_MASK 0x20000 /* Receive FIFO Full Mask */ -#define TX_FIFO_ZERO_MASK 0x40000 /* Transmit FIFO Empty Mask */ -#define RX_DAT_ZERO_MASK 0x80000 /* Receive FIFO Empty Mask */ -#define TX_DAT_RDY_MASK 0x100000 /* Transmit Data Available Mask */ -#define RX_FIFO_RDY_MASK 0x200000 /* Receive Data Available Mask */ - -/* Bit masks for SDH_FIFO_CNT */ - -#define FIFO_COUNT 0x7fff /* FIFO Count */ - -/* Bit masks for SDH_E_STATUS */ - -#define SDIO_INT_DET 0x2 /* SDIO Int Detected */ -#define SD_CARD_DET 0x10 /* SD Card Detect */ - -/* Bit masks for SDH_E_MASK */ - -#define SDIO_MSK 0x2 /* Mask SDIO Int Detected */ -#define SCD_MSK 0x40 /* Mask Card Detect */ - -/* Bit masks for SDH_CFG */ - -#define CLKS_EN 0x1 /* Clocks Enable */ -#define SD4E 0x4 /* SDIO 4-Bit Enable */ -#define MWE 0x8 /* Moving Window Enable */ -#define SD_RST 0x10 /* SDMMC Reset */ -#define PUP_SDDAT 0x20 /* Pull-up SD_DAT */ -#define PUP_SDDAT3 0x40 /* Pull-up SD_DAT3 */ -#define PD_SDDAT3 0x80 /* Pull-down SD_DAT3 */ - -/* Bit masks for SDH_RD_WAIT_EN */ - -#define RWR 0x1 /* Read Wait Request */ - #endif /* _DEF_BF516_H */ diff --git a/arch/blackfin/mach-bf518/include/mach/defBF518.h b/arch/blackfin/mach-bf518/include/mach/defBF518.h index 794cf06..cb18270 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF518.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF518.h @@ -7,461 +7,8 @@ #ifndef _DEF_BF518_H #define _DEF_BF518_H -/* Include all Core registers and bit definitions */ -#include - -/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF518 */ - -/* Include defBF51x_base.h for the set of #defines that are common to all ADSP-BF51x processors */ -#include "defBF51x_base.h" - -/* The following are the #defines needed by ADSP-BF518 that are not in the common header */ -/* 10/100 Ethernet Controller (0xFFC03000 - 0xFFC031FF) */ - -#define EMAC_OPMODE 0xFFC03000 /* Operating Mode Register */ -#define EMAC_ADDRLO 0xFFC03004 /* Address Low (32 LSBs) Register */ -#define EMAC_ADDRHI 0xFFC03008 /* Address High (16 MSBs) Register */ -#define EMAC_HASHLO 0xFFC0300C /* Multicast Hash Table Low (Bins 31-0) Register */ -#define EMAC_HASHHI 0xFFC03010 /* Multicast Hash Table High (Bins 63-32) Register */ -#define EMAC_STAADD 0xFFC03014 /* Station Management Address Register */ -#define EMAC_STADAT 0xFFC03018 /* Station Management Data Register */ -#define EMAC_FLC 0xFFC0301C /* Flow Control Register */ -#define EMAC_VLAN1 0xFFC03020 /* VLAN1 Tag Register */ -#define EMAC_VLAN2 0xFFC03024 /* VLAN2 Tag Register */ -#define EMAC_WKUP_CTL 0xFFC0302C /* Wake-Up Control/Status Register */ -#define EMAC_WKUP_FFMSK0 0xFFC03030 /* Wake-Up Frame Filter 0 Byte Mask Register */ -#define EMAC_WKUP_FFMSK1 0xFFC03034 /* Wake-Up Frame Filter 1 Byte Mask Register */ -#define EMAC_WKUP_FFMSK2 0xFFC03038 /* Wake-Up Frame Filter 2 Byte Mask Register */ -#define EMAC_WKUP_FFMSK3 0xFFC0303C /* Wake-Up Frame Filter 3 Byte Mask Register */ -#define EMAC_WKUP_FFCMD 0xFFC03040 /* Wake-Up Frame Filter Commands Register */ -#define EMAC_WKUP_FFOFF 0xFFC03044 /* Wake-Up Frame Filter Offsets Register */ -#define EMAC_WKUP_FFCRC0 0xFFC03048 /* Wake-Up Frame Filter 0,1 CRC-16 Register */ -#define EMAC_WKUP_FFCRC1 0xFFC0304C /* Wake-Up Frame Filter 2,3 CRC-16 Register */ - -#define EMAC_SYSCTL 0xFFC03060 /* EMAC System Control Register */ -#define EMAC_SYSTAT 0xFFC03064 /* EMAC System Status Register */ -#define EMAC_RX_STAT 0xFFC03068 /* RX Current Frame Status Register */ -#define EMAC_RX_STKY 0xFFC0306C /* RX Sticky Frame Status Register */ -#define EMAC_RX_IRQE 0xFFC03070 /* RX Frame Status Interrupt Enables Register */ -#define EMAC_TX_STAT 0xFFC03074 /* TX Current Frame Status Register */ -#define EMAC_TX_STKY 0xFFC03078 /* TX Sticky Frame Status Register */ -#define EMAC_TX_IRQE 0xFFC0307C /* TX Frame Status Interrupt Enables Register */ - -#define EMAC_MMC_CTL 0xFFC03080 /* MMC Counter Control Register */ -#define EMAC_MMC_RIRQS 0xFFC03084 /* MMC RX Interrupt Status Register */ -#define EMAC_MMC_RIRQE 0xFFC03088 /* MMC RX Interrupt Enables Register */ -#define EMAC_MMC_TIRQS 0xFFC0308C /* MMC TX Interrupt Status Register */ -#define EMAC_MMC_TIRQE 0xFFC03090 /* MMC TX Interrupt Enables Register */ - -#define EMAC_RXC_OK 0xFFC03100 /* RX Frame Successful Count */ -#define EMAC_RXC_FCS 0xFFC03104 /* RX Frame FCS Failure Count */ -#define EMAC_RXC_ALIGN 0xFFC03108 /* RX Alignment Error Count */ -#define EMAC_RXC_OCTET 0xFFC0310C /* RX Octets Successfully Received Count */ -#define EMAC_RXC_DMAOVF 0xFFC03110 /* Internal MAC Sublayer Error RX Frame Count */ -#define EMAC_RXC_UNICST 0xFFC03114 /* Unicast RX Frame Count */ -#define EMAC_RXC_MULTI 0xFFC03118 /* Multicast RX Frame Count */ -#define EMAC_RXC_BROAD 0xFFC0311C /* Broadcast RX Frame Count */ -#define EMAC_RXC_LNERRI 0xFFC03120 /* RX Frame In Range Error Count */ -#define EMAC_RXC_LNERRO 0xFFC03124 /* RX Frame Out Of Range Error Count */ -#define EMAC_RXC_LONG 0xFFC03128 /* RX Frame Too Long Count */ -#define EMAC_RXC_MACCTL 0xFFC0312C /* MAC Control RX Frame Count */ -#define EMAC_RXC_OPCODE 0xFFC03130 /* Unsupported Op-Code RX Frame Count */ -#define EMAC_RXC_PAUSE 0xFFC03134 /* MAC Control Pause RX Frame Count */ -#define EMAC_RXC_ALLFRM 0xFFC03138 /* Overall RX Frame Count */ -#define EMAC_RXC_ALLOCT 0xFFC0313C /* Overall RX Octet Count */ -#define EMAC_RXC_TYPED 0xFFC03140 /* Type/Length Consistent RX Frame Count */ -#define EMAC_RXC_SHORT 0xFFC03144 /* RX Frame Fragment Count - Byte Count x < 64 */ -#define EMAC_RXC_EQ64 0xFFC03148 /* Good RX Frame Count - Byte Count x = 64 */ -#define EMAC_RXC_LT128 0xFFC0314C /* Good RX Frame Count - Byte Count 64 < x < 128 */ -#define EMAC_RXC_LT256 0xFFC03150 /* Good RX Frame Count - Byte Count 128 <= x < 256 */ -#define EMAC_RXC_LT512 0xFFC03154 /* Good RX Frame Count - Byte Count 256 <= x < 512 */ -#define EMAC_RXC_LT1024 0xFFC03158 /* Good RX Frame Count - Byte Count 512 <= x < 1024 */ -#define EMAC_RXC_GE1024 0xFFC0315C /* Good RX Frame Count - Byte Count x >= 1024 */ - -#define EMAC_TXC_OK 0xFFC03180 /* TX Frame Successful Count */ -#define EMAC_TXC_1COL 0xFFC03184 /* TX Frames Successful After Single Collision Count */ -#define EMAC_TXC_GT1COL 0xFFC03188 /* TX Frames Successful After Multiple Collisions Count */ -#define EMAC_TXC_OCTET 0xFFC0318C /* TX Octets Successfully Received Count */ -#define EMAC_TXC_DEFER 0xFFC03190 /* TX Frame Delayed Due To Busy Count */ -#define EMAC_TXC_LATECL 0xFFC03194 /* Late TX Collisions Count */ -#define EMAC_TXC_XS_COL 0xFFC03198 /* TX Frame Failed Due To Excessive Collisions Count */ -#define EMAC_TXC_DMAUND 0xFFC0319C /* Internal MAC Sublayer Error TX Frame Count */ -#define EMAC_TXC_CRSERR 0xFFC031A0 /* Carrier Sense Deasserted During TX Frame Count */ -#define EMAC_TXC_UNICST 0xFFC031A4 /* Unicast TX Frame Count */ -#define EMAC_TXC_MULTI 0xFFC031A8 /* Multicast TX Frame Count */ -#define EMAC_TXC_BROAD 0xFFC031AC /* Broadcast TX Frame Count */ -#define EMAC_TXC_XS_DFR 0xFFC031B0 /* TX Frames With Excessive Deferral Count */ -#define EMAC_TXC_MACCTL 0xFFC031B4 /* MAC Control TX Frame Count */ -#define EMAC_TXC_ALLFRM 0xFFC031B8 /* Overall TX Frame Count */ -#define EMAC_TXC_ALLOCT 0xFFC031BC /* Overall TX Octet Count */ -#define EMAC_TXC_EQ64 0xFFC031C0 /* Good TX Frame Count - Byte Count x = 64 */ -#define EMAC_TXC_LT128 0xFFC031C4 /* Good TX Frame Count - Byte Count 64 < x < 128 */ -#define EMAC_TXC_LT256 0xFFC031C8 /* Good TX Frame Count - Byte Count 128 <= x < 256 */ -#define EMAC_TXC_LT512 0xFFC031CC /* Good TX Frame Count - Byte Count 256 <= x < 512 */ -#define EMAC_TXC_LT1024 0xFFC031D0 /* Good TX Frame Count - Byte Count 512 <= x < 1024 */ -#define EMAC_TXC_GE1024 0xFFC031D4 /* Good TX Frame Count - Byte Count x >= 1024 */ -#define EMAC_TXC_ABORT 0xFFC031D8 /* Total TX Frames Aborted Count */ - -/* Listing for IEEE-Supported Count Registers */ - -#define FramesReceivedOK EMAC_RXC_OK /* RX Frame Successful Count */ -#define FrameCheckSequenceErrors EMAC_RXC_FCS /* RX Frame FCS Failure Count */ -#define AlignmentErrors EMAC_RXC_ALIGN /* RX Alignment Error Count */ -#define OctetsReceivedOK EMAC_RXC_OCTET /* RX Octets Successfully Received Count */ -#define FramesLostDueToIntMACRcvError EMAC_RXC_DMAOVF /* Internal MAC Sublayer Error RX Frame Count */ -#define UnicastFramesReceivedOK EMAC_RXC_UNICST /* Unicast RX Frame Count */ -#define MulticastFramesReceivedOK EMAC_RXC_MULTI /* Multicast RX Frame Count */ -#define BroadcastFramesReceivedOK EMAC_RXC_BROAD /* Broadcast RX Frame Count */ -#define InRangeLengthErrors EMAC_RXC_LNERRI /* RX Frame In Range Error Count */ -#define OutOfRangeLengthField EMAC_RXC_LNERRO /* RX Frame Out Of Range Error Count */ -#define FrameTooLongErrors EMAC_RXC_LONG /* RX Frame Too Long Count */ -#define MACControlFramesReceived EMAC_RXC_MACCTL /* MAC Control RX Frame Count */ -#define UnsupportedOpcodesReceived EMAC_RXC_OPCODE /* Unsupported Op-Code RX Frame Count */ -#define PAUSEMACCtrlFramesReceived EMAC_RXC_PAUSE /* MAC Control Pause RX Frame Count */ -#define FramesReceivedAll EMAC_RXC_ALLFRM /* Overall RX Frame Count */ -#define OctetsReceivedAll EMAC_RXC_ALLOCT /* Overall RX Octet Count */ -#define TypedFramesReceived EMAC_RXC_TYPED /* Type/Length Consistent RX Frame Count */ -#define FramesLenLt64Received EMAC_RXC_SHORT /* RX Frame Fragment Count - Byte Count x < 64 */ -#define FramesLenEq64Received EMAC_RXC_EQ64 /* Good RX Frame Count - Byte Count x = 64 */ -#define FramesLen65_127Received EMAC_RXC_LT128 /* Good RX Frame Count - Byte Count 64 < x < 128 */ -#define FramesLen128_255Received EMAC_RXC_LT256 /* Good RX Frame Count - Byte Count 128 <= x < 256 */ -#define FramesLen256_511Received EMAC_RXC_LT512 /* Good RX Frame Count - Byte Count 256 <= x < 512 */ -#define FramesLen512_1023Received EMAC_RXC_LT1024 /* Good RX Frame Count - Byte Count 512 <= x < 1024 */ -#define FramesLen1024_MaxReceived EMAC_RXC_GE1024 /* Good RX Frame Count - Byte Count x >= 1024 */ - -#define FramesTransmittedOK EMAC_TXC_OK /* TX Frame Successful Count */ -#define SingleCollisionFrames EMAC_TXC_1COL /* TX Frames Successful After Single Collision Count */ -#define MultipleCollisionFrames EMAC_TXC_GT1COL /* TX Frames Successful After Multiple Collisions Count */ -#define OctetsTransmittedOK EMAC_TXC_OCTET /* TX Octets Successfully Received Count */ -#define FramesWithDeferredXmissions EMAC_TXC_DEFER /* TX Frame Delayed Due To Busy Count */ -#define LateCollisions EMAC_TXC_LATECL /* Late TX Collisions Count */ -#define FramesAbortedDueToXSColls EMAC_TXC_XS_COL /* TX Frame Failed Due To Excessive Collisions Count */ -#define FramesLostDueToIntMacXmitError EMAC_TXC_DMAUND /* Internal MAC Sublayer Error TX Frame Count */ -#define CarrierSenseErrors EMAC_TXC_CRSERR /* Carrier Sense Deasserted During TX Frame Count */ -#define UnicastFramesXmittedOK EMAC_TXC_UNICST /* Unicast TX Frame Count */ -#define MulticastFramesXmittedOK EMAC_TXC_MULTI /* Multicast TX Frame Count */ -#define BroadcastFramesXmittedOK EMAC_TXC_BROAD /* Broadcast TX Frame Count */ -#define FramesWithExcessiveDeferral EMAC_TXC_XS_DFR /* TX Frames With Excessive Deferral Count */ -#define MACControlFramesTransmitted EMAC_TXC_MACCTL /* MAC Control TX Frame Count */ -#define FramesTransmittedAll EMAC_TXC_ALLFRM /* Overall TX Frame Count */ -#define OctetsTransmittedAll EMAC_TXC_ALLOCT /* Overall TX Octet Count */ -#define FramesLenEq64Transmitted EMAC_TXC_EQ64 /* Good TX Frame Count - Byte Count x = 64 */ -#define FramesLen65_127Transmitted EMAC_TXC_LT128 /* Good TX Frame Count - Byte Count 64 < x < 128 */ -#define FramesLen128_255Transmitted EMAC_TXC_LT256 /* Good TX Frame Count - Byte Count 128 <= x < 256 */ -#define FramesLen256_511Transmitted EMAC_TXC_LT512 /* Good TX Frame Count - Byte Count 256 <= x < 512 */ -#define FramesLen512_1023Transmitted EMAC_TXC_LT1024 /* Good TX Frame Count - Byte Count 512 <= x < 1024 */ -#define FramesLen1024_MaxTransmitted EMAC_TXC_GE1024 /* Good TX Frame Count - Byte Count x >= 1024 */ -#define TxAbortedFrames EMAC_TXC_ABORT /* Total TX Frames Aborted Count */ - -/*********************************************************************************** -** System MMR Register Bits And Macros -** -** Disclaimer: All macros are intended to make C and Assembly code more readable. -** Use these macros carefully, as any that do left shifts for field -** depositing will result in the lower order bits being destroyed. Any -** macro that shifts left to properly position the bit-field should be -** used as part of an OR to initialize a register and NOT as a dynamic -** modifier UNLESS the lower order bits are saved and ORed back in when -** the macro is used. -*************************************************************************************/ - -/************************ ETHERNET 10/100 CONTROLLER MASKS ************************/ - -/* EMAC_OPMODE Masks */ - -#define RE 0x00000001 /* Receiver Enable */ -#define ASTP 0x00000002 /* Enable Automatic Pad Stripping On RX Frames */ -#define HU 0x00000010 /* Hash Filter Unicast Address */ -#define HM 0x00000020 /* Hash Filter Multicast Address */ -#define PAM 0x00000040 /* Pass-All-Multicast Mode Enable */ -#define PR 0x00000080 /* Promiscuous Mode Enable */ -#define IFE 0x00000100 /* Inverse Filtering Enable */ -#define DBF 0x00000200 /* Disable Broadcast Frame Reception */ -#define PBF 0x00000400 /* Pass Bad Frames Enable */ -#define PSF 0x00000800 /* Pass Short Frames Enable */ -#define RAF 0x00001000 /* Receive-All Mode */ -#define TE 0x00010000 /* Transmitter Enable */ -#define DTXPAD 0x00020000 /* Disable Automatic TX Padding */ -#define DTXCRC 0x00040000 /* Disable Automatic TX CRC Generation */ -#define DC 0x00080000 /* Deferral Check */ -#define BOLMT 0x00300000 /* Back-Off Limit */ -#define BOLMT_10 0x00000000 /* 10-bit range */ -#define BOLMT_8 0x00100000 /* 8-bit range */ -#define BOLMT_4 0x00200000 /* 4-bit range */ -#define BOLMT_1 0x00300000 /* 1-bit range */ -#define DRTY 0x00400000 /* Disable TX Retry On Collision */ -#define LCTRE 0x00800000 /* Enable TX Retry On Late Collision */ -#define RMII 0x01000000 /* RMII/MII* Mode */ -#define RMII_10 0x02000000 /* Speed Select for RMII Port (10MBit/100MBit*) */ -#define FDMODE 0x04000000 /* Duplex Mode Enable (Full/Half*) */ -#define LB 0x08000000 /* Internal Loopback Enable */ -#define DRO 0x10000000 /* Disable Receive Own Frames (Half-Duplex Mode) */ - -/* EMAC_STAADD Masks */ - -#define STABUSY 0x00000001 /* Initiate Station Mgt Reg Access / STA Busy Stat */ -#define STAOP 0x00000002 /* Station Management Operation Code (Write/Read*) */ -#define STADISPRE 0x00000004 /* Disable Preamble Generation */ -#define STAIE 0x00000008 /* Station Mgt. Transfer Done Interrupt Enable */ -#define REGAD 0x000007C0 /* STA Register Address */ -#define PHYAD 0x0000F800 /* PHY Device Address */ - -#define SET_REGAD(x) (((x)&0x1F)<< 6 ) /* Set STA Register Address */ -#define SET_PHYAD(x) (((x)&0x1F)<< 11 ) /* Set PHY Device Address */ - -/* EMAC_STADAT Mask */ - -#define STADATA 0x0000FFFF /* Station Management Data */ - -/* EMAC_FLC Masks */ - -#define FLCBUSY 0x00000001 /* Send Flow Ctrl Frame / Flow Ctrl Busy Status */ -#define FLCE 0x00000002 /* Flow Control Enable */ -#define PCF 0x00000004 /* Pass Control Frames */ -#define BKPRSEN 0x00000008 /* Enable Backpressure */ -#define FLCPAUSE 0xFFFF0000 /* Pause Time */ - -#define SET_FLCPAUSE(x) (((x)&0xFFFF)<< 16) /* Set Pause Time */ - -/* EMAC_WKUP_CTL Masks */ - -#define CAPWKFRM 0x00000001 /* Capture Wake-Up Frames */ -#define MPKE 0x00000002 /* Magic Packet Enable */ -#define RWKE 0x00000004 /* Remote Wake-Up Frame Enable */ -#define GUWKE 0x00000008 /* Global Unicast Wake Enable */ -#define MPKS 0x00000020 /* Magic Packet Received Status */ -#define RWKS 0x00000F00 /* Wake-Up Frame Received Status, Filters 3:0 */ - -/* EMAC_WKUP_FFCMD Masks */ - -#define WF0_E 0x00000001 /* Enable Wake-Up Filter 0 */ -#define WF0_T 0x00000008 /* Wake-Up Filter 0 Addr Type (Multicast/Unicast*) */ -#define WF1_E 0x00000100 /* Enable Wake-Up Filter 1 */ -#define WF1_T 0x00000800 /* Wake-Up Filter 1 Addr Type (Multicast/Unicast*) */ -#define WF2_E 0x00010000 /* Enable Wake-Up Filter 2 */ -#define WF2_T 0x00080000 /* Wake-Up Filter 2 Addr Type (Multicast/Unicast*) */ -#define WF3_E 0x01000000 /* Enable Wake-Up Filter 3 */ -#define WF3_T 0x08000000 /* Wake-Up Filter 3 Addr Type (Multicast/Unicast*) */ - -/* EMAC_WKUP_FFOFF Masks */ - -#define WF0_OFF 0x000000FF /* Wake-Up Filter 0 Pattern Offset */ -#define WF1_OFF 0x0000FF00 /* Wake-Up Filter 1 Pattern Offset */ -#define WF2_OFF 0x00FF0000 /* Wake-Up Filter 2 Pattern Offset */ -#define WF3_OFF 0xFF000000 /* Wake-Up Filter 3 Pattern Offset */ - -#define SET_WF0_OFF(x) (((x)&0xFF)<< 0 ) /* Set Wake-Up Filter 0 Byte Offset */ -#define SET_WF1_OFF(x) (((x)&0xFF)<< 8 ) /* Set Wake-Up Filter 1 Byte Offset */ -#define SET_WF2_OFF(x) (((x)&0xFF)<< 16 ) /* Set Wake-Up Filter 2 Byte Offset */ -#define SET_WF3_OFF(x) (((x)&0xFF)<< 24 ) /* Set Wake-Up Filter 3 Byte Offset */ -/* Set ALL Offsets */ -#define SET_WF_OFFS(x0,x1,x2,x3) (SET_WF0_OFF((x0))|SET_WF1_OFF((x1))|SET_WF2_OFF((x2))|SET_WF3_OFF((x3))) - -/* EMAC_WKUP_FFCRC0 Masks */ - -#define WF0_CRC 0x0000FFFF /* Wake-Up Filter 0 Pattern CRC */ -#define WF1_CRC 0xFFFF0000 /* Wake-Up Filter 1 Pattern CRC */ - -#define SET_WF0_CRC(x) (((x)&0xFFFF)<< 0 ) /* Set Wake-Up Filter 0 Target CRC */ -#define SET_WF1_CRC(x) (((x)&0xFFFF)<< 16 ) /* Set Wake-Up Filter 1 Target CRC */ - -/* EMAC_WKUP_FFCRC1 Masks */ - -#define WF2_CRC 0x0000FFFF /* Wake-Up Filter 2 Pattern CRC */ -#define WF3_CRC 0xFFFF0000 /* Wake-Up Filter 3 Pattern CRC */ - -#define SET_WF2_CRC(x) (((x)&0xFFFF)<< 0 ) /* Set Wake-Up Filter 2 Target CRC */ -#define SET_WF3_CRC(x) (((x)&0xFFFF)<< 16 ) /* Set Wake-Up Filter 3 Target CRC */ - -/* EMAC_SYSCTL Masks */ - -#define PHYIE 0x00000001 /* PHY_INT Interrupt Enable */ -#define RXDWA 0x00000002 /* Receive Frame DMA Word Alignment (Odd/Even*) */ -#define RXCKS 0x00000004 /* Enable RX Frame TCP/UDP Checksum Computation */ -#define TXDWA 0x00000010 /* Transmit Frame DMA Word Alignment (Odd/Even*) */ -#define MDCDIV 0x00003F00 /* SCLK:MDC Clock Divisor [MDC=SCLK/(2*(N+1))] */ - -#define SET_MDCDIV(x) (((x)&0x3F)<< 8) /* Set MDC Clock Divisor */ - -/* EMAC_SYSTAT Masks */ - -#define PHYINT 0x00000001 /* PHY_INT Interrupt Status */ -#define MMCINT 0x00000002 /* MMC Counter Interrupt Status */ -#define RXFSINT 0x00000004 /* RX Frame-Status Interrupt Status */ -#define TXFSINT 0x00000008 /* TX Frame-Status Interrupt Status */ -#define WAKEDET 0x00000010 /* Wake-Up Detected Status */ -#define RXDMAERR 0x00000020 /* RX DMA Direction Error Status */ -#define TXDMAERR 0x00000040 /* TX DMA Direction Error Status */ -#define STMDONE 0x00000080 /* Station Mgt. Transfer Done Interrupt Status */ - -/* EMAC_RX_STAT, EMAC_RX_STKY, and EMAC_RX_IRQE Masks */ - -#define RX_FRLEN 0x000007FF /* Frame Length In Bytes */ -#define RX_COMP 0x00001000 /* RX Frame Complete */ -#define RX_OK 0x00002000 /* RX Frame Received With No Errors */ -#define RX_LONG 0x00004000 /* RX Frame Too Long Error */ -#define RX_ALIGN 0x00008000 /* RX Frame Alignment Error */ -#define RX_CRC 0x00010000 /* RX Frame CRC Error */ -#define RX_LEN 0x00020000 /* RX Frame Length Error */ -#define RX_FRAG 0x00040000 /* RX Frame Fragment Error */ -#define RX_ADDR 0x00080000 /* RX Frame Address Filter Failed Error */ -#define RX_DMAO 0x00100000 /* RX Frame DMA Overrun Error */ -#define RX_PHY 0x00200000 /* RX Frame PHY Error */ -#define RX_LATE 0x00400000 /* RX Frame Late Collision Error */ -#define RX_RANGE 0x00800000 /* RX Frame Length Field Out of Range Error */ -#define RX_MULTI 0x01000000 /* RX Multicast Frame Indicator */ -#define RX_BROAD 0x02000000 /* RX Broadcast Frame Indicator */ -#define RX_CTL 0x04000000 /* RX Control Frame Indicator */ -#define RX_UCTL 0x08000000 /* Unsupported RX Control Frame Indicator */ -#define RX_TYPE 0x10000000 /* RX Typed Frame Indicator */ -#define RX_VLAN1 0x20000000 /* RX VLAN1 Frame Indicator */ -#define RX_VLAN2 0x40000000 /* RX VLAN2 Frame Indicator */ -#define RX_ACCEPT 0x80000000 /* RX Frame Accepted Indicator */ - -/* EMAC_TX_STAT, EMAC_TX_STKY, and EMAC_TX_IRQE Masks */ - -#define TX_COMP 0x00000001 /* TX Frame Complete */ -#define TX_OK 0x00000002 /* TX Frame Sent With No Errors */ -#define TX_ECOLL 0x00000004 /* TX Frame Excessive Collision Error */ -#define TX_LATE 0x00000008 /* TX Frame Late Collision Error */ -#define TX_DMAU 0x00000010 /* TX Frame DMA Underrun Error (STAT) */ -#define TX_MACE 0x00000010 /* Internal MAC Error Detected (STKY and IRQE) */ -#define TX_EDEFER 0x00000020 /* TX Frame Excessive Deferral Error */ -#define TX_BROAD 0x00000040 /* TX Broadcast Frame Indicator */ -#define TX_MULTI 0x00000080 /* TX Multicast Frame Indicator */ -#define TX_CCNT 0x00000F00 /* TX Frame Collision Count */ -#define TX_DEFER 0x00001000 /* TX Frame Deferred Indicator */ -#define TX_CRS 0x00002000 /* TX Frame Carrier Sense Not Asserted Error */ -#define TX_LOSS 0x00004000 /* TX Frame Carrier Lost During TX Error */ -#define TX_RETRY 0x00008000 /* TX Frame Successful After Retry */ -#define TX_FRLEN 0x07FF0000 /* TX Frame Length (Bytes) */ - -/* EMAC_MMC_CTL Masks */ -#define RSTC 0x00000001 /* Reset All Counters */ -#define CROLL 0x00000002 /* Counter Roll-Over Enable */ -#define CCOR 0x00000004 /* Counter Clear-On-Read Mode Enable */ -#define MMCE 0x00000008 /* Enable MMC Counter Operation */ - -/* EMAC_MMC_RIRQS and EMAC_MMC_RIRQE Masks */ -#define RX_OK_CNT 0x00000001 /* RX Frames Received With No Errors */ -#define RX_FCS_CNT 0x00000002 /* RX Frames W/Frame Check Sequence Errors */ -#define RX_ALIGN_CNT 0x00000004 /* RX Frames With Alignment Errors */ -#define RX_OCTET_CNT 0x00000008 /* RX Octets Received OK */ -#define RX_LOST_CNT 0x00000010 /* RX Frames Lost Due To Internal MAC RX Error */ -#define RX_UNI_CNT 0x00000020 /* Unicast RX Frames Received OK */ -#define RX_MULTI_CNT 0x00000040 /* Multicast RX Frames Received OK */ -#define RX_BROAD_CNT 0x00000080 /* Broadcast RX Frames Received OK */ -#define RX_IRL_CNT 0x00000100 /* RX Frames With In-Range Length Errors */ -#define RX_ORL_CNT 0x00000200 /* RX Frames With Out-Of-Range Length Errors */ -#define RX_LONG_CNT 0x00000400 /* RX Frames With Frame Too Long Errors */ -#define RX_MACCTL_CNT 0x00000800 /* MAC Control RX Frames Received */ -#define RX_OPCODE_CTL 0x00001000 /* Unsupported Op-Code RX Frames Received */ -#define RX_PAUSE_CNT 0x00002000 /* PAUSEMAC Control RX Frames Received */ -#define RX_ALLF_CNT 0x00004000 /* All RX Frames Received */ -#define RX_ALLO_CNT 0x00008000 /* All RX Octets Received */ -#define RX_TYPED_CNT 0x00010000 /* Typed RX Frames Received */ -#define RX_SHORT_CNT 0x00020000 /* RX Frame Fragments (< 64 Bytes) Received */ -#define RX_EQ64_CNT 0x00040000 /* 64-Byte RX Frames Received */ -#define RX_LT128_CNT 0x00080000 /* 65-127-Byte RX Frames Received */ -#define RX_LT256_CNT 0x00100000 /* 128-255-Byte RX Frames Received */ -#define RX_LT512_CNT 0x00200000 /* 256-511-Byte RX Frames Received */ -#define RX_LT1024_CNT 0x00400000 /* 512-1023-Byte RX Frames Received */ -#define RX_GE1024_CNT 0x00800000 /* 1024-Max-Byte RX Frames Received */ - -/* EMAC_MMC_TIRQS and EMAC_MMC_TIRQE Masks */ - -#define TX_OK_CNT 0x00000001 /* TX Frames Sent OK */ -#define TX_SCOLL_CNT 0x00000002 /* TX Frames With Single Collisions */ -#define TX_MCOLL_CNT 0x00000004 /* TX Frames With Multiple Collisions */ -#define TX_OCTET_CNT 0x00000008 /* TX Octets Sent OK */ -#define TX_DEFER_CNT 0x00000010 /* TX Frames With Deferred Transmission */ -#define TX_LATE_CNT 0x00000020 /* TX Frames With Late Collisions */ -#define TX_ABORTC_CNT 0x00000040 /* TX Frames Aborted Due To Excess Collisions */ -#define TX_LOST_CNT 0x00000080 /* TX Frames Lost Due To Internal MAC TX Error */ -#define TX_CRS_CNT 0x00000100 /* TX Frames With Carrier Sense Errors */ -#define TX_UNI_CNT 0x00000200 /* Unicast TX Frames Sent */ -#define TX_MULTI_CNT 0x00000400 /* Multicast TX Frames Sent */ -#define TX_BROAD_CNT 0x00000800 /* Broadcast TX Frames Sent */ -#define TX_EXDEF_CTL 0x00001000 /* TX Frames With Excessive Deferral */ -#define TX_MACCTL_CNT 0x00002000 /* MAC Control TX Frames Sent */ -#define TX_ALLF_CNT 0x00004000 /* All TX Frames Sent */ -#define TX_ALLO_CNT 0x00008000 /* All TX Octets Sent */ -#define TX_EQ64_CNT 0x00010000 /* 64-Byte TX Frames Sent */ -#define TX_LT128_CNT 0x00020000 /* 65-127-Byte TX Frames Sent */ -#define TX_LT256_CNT 0x00040000 /* 128-255-Byte TX Frames Sent */ -#define TX_LT512_CNT 0x00080000 /* 256-511-Byte TX Frames Sent */ -#define TX_LT1024_CNT 0x00100000 /* 512-1023-Byte TX Frames Sent */ -#define TX_GE1024_CNT 0x00200000 /* 1024-Max-Byte TX Frames Sent */ -#define TX_ABORT_CNT 0x00400000 /* TX Frames Aborted */ - -/* SDH Registers */ - -#define SDH_PWR_CTL 0xFFC03900 /* SDH Power Control */ -#define SDH_CLK_CTL 0xFFC03904 /* SDH Clock Control */ -#define SDH_ARGUMENT 0xFFC03908 /* SDH Argument */ -#define SDH_COMMAND 0xFFC0390C /* SDH Command */ -#define SDH_RESP_CMD 0xFFC03910 /* SDH Response Command */ -#define SDH_RESPONSE0 0xFFC03914 /* SDH Response0 */ -#define SDH_RESPONSE1 0xFFC03918 /* SDH Response1 */ -#define SDH_RESPONSE2 0xFFC0391C /* SDH Response2 */ -#define SDH_RESPONSE3 0xFFC03920 /* SDH Response3 */ -#define SDH_DATA_TIMER 0xFFC03924 /* SDH Data Timer */ -#define SDH_DATA_LGTH 0xFFC03928 /* SDH Data Length */ -#define SDH_DATA_CTL 0xFFC0392C /* SDH Data Control */ -#define SDH_DATA_CNT 0xFFC03930 /* SDH Data Counter */ -#define SDH_STATUS 0xFFC03934 /* SDH Status */ -#define SDH_STATUS_CLR 0xFFC03938 /* SDH Status Clear */ -#define SDH_MASK0 0xFFC0393C /* SDH Interrupt0 Mask */ -#define SDH_MASK1 0xFFC03940 /* SDH Interrupt1 Mask */ -#define SDH_FIFO_CNT 0xFFC03948 /* SDH FIFO Counter */ -#define SDH_FIFO 0xFFC03980 /* SDH Data FIFO */ -#define SDH_E_STATUS 0xFFC039C0 /* SDH Exception Status */ -#define SDH_E_MASK 0xFFC039C4 /* SDH Exception Mask */ -#define SDH_CFG 0xFFC039C8 /* SDH Configuration */ -#define SDH_RD_WAIT_EN 0xFFC039CC /* SDH Read Wait Enable */ -#define SDH_PID0 0xFFC039D0 /* SDH Peripheral Identification0 */ -#define SDH_PID1 0xFFC039D4 /* SDH Peripheral Identification1 */ -#define SDH_PID2 0xFFC039D8 /* SDH Peripheral Identification2 */ -#define SDH_PID3 0xFFC039DC /* SDH Peripheral Identification3 */ -#define SDH_PID4 0xFFC039E0 /* SDH Peripheral Identification4 */ -#define SDH_PID5 0xFFC039E4 /* SDH Peripheral Identification5 */ -#define SDH_PID6 0xFFC039E8 /* SDH Peripheral Identification6 */ -#define SDH_PID7 0xFFC039EC /* SDH Peripheral Identification7 */ - -/* Removable Storage Interface Registers */ - -#define RSI_PWR_CONTROL 0xFFC03800 /* RSI Power Control Register */ -#define RSI_CLK_CONTROL 0xFFC03804 /* RSI Clock Control Register */ -#define RSI_ARGUMENT 0xFFC03808 /* RSI Argument Register */ -#define RSI_COMMAND 0xFFC0380C /* RSI Command Register */ -#define RSI_RESP_CMD 0xFFC03810 /* RSI Response Command Register */ -#define RSI_RESPONSE0 0xFFC03814 /* RSI Response Register */ -#define RSI_RESPONSE1 0xFFC03818 /* RSI Response Register */ -#define RSI_RESPONSE2 0xFFC0381C /* RSI Response Register */ -#define RSI_RESPONSE3 0xFFC03820 /* RSI Response Register */ -#define RSI_DATA_TIMER 0xFFC03824 /* RSI Data Timer Register */ -#define RSI_DATA_LGTH 0xFFC03828 /* RSI Data Length Register */ -#define RSI_DATA_CONTROL 0xFFC0382C /* RSI Data Control Register */ -#define RSI_DATA_CNT 0xFFC03830 /* RSI Data Counter Register */ -#define RSI_STATUS 0xFFC03834 /* RSI Status Register */ -#define RSI_STATUSCL 0xFFC03838 /* RSI Status Clear Register */ -#define RSI_MASK0 0xFFC0383C /* RSI Interrupt 0 Mask Register */ -#define RSI_MASK1 0xFFC03840 /* RSI Interrupt 1 Mask Register */ -#define RSI_FIFO_CNT 0xFFC03848 /* RSI FIFO Counter Register */ -#define RSI_CEATA_CONTROL 0xFFC0384C /* RSI CEATA Register */ -#define RSI_FIFO 0xFFC03880 /* RSI Data FIFO Register */ -#define RSI_ESTAT 0xFFC038C0 /* RSI Exception Status Register */ -#define RSI_EMASK 0xFFC038C4 /* RSI Exception Mask Register */ -#define RSI_CONFIG 0xFFC038C8 /* RSI Configuration Register */ -#define RSI_RD_WAIT_EN 0xFFC038CC /* RSI Read Wait Enable Register */ -#define RSI_PID0 0xFFC03FE0 /* RSI Peripheral ID Register 0 */ -#define RSI_PID1 0xFFC03FE4 /* RSI Peripheral ID Register 1 */ -#define RSI_PID2 0xFFC03FE8 /* RSI Peripheral ID Register 2 */ -#define RSI_PID3 0xFFC03FEC /* RSI Peripheral ID Register 3 */ -#define RSI_PID4 0xFFC03FF0 /* RSI Peripheral ID Register 4 */ -#define RSI_PID5 0xFFC03FF4 /* RSI Peripheral ID Register 5 */ -#define RSI_PID6 0xFFC03FF8 /* RSI Peripheral ID Register 6 */ -#define RSI_PID7 0xFFC03FFC /* RSI Peripheral ID Register 7 */ +/* BF518 is BF516 + IEEE-1588 */ +#include "defBF516.h" /* PTP TSYNC Registers */ @@ -489,141 +36,6 @@ #define EMAC_PTP_PPS_STARTHI 0xFFC030F4 /* PPS Start Time High */ #define EMAC_PTP_PPS_PERIOD 0xFFC030F8 /* PPS Count Register */ -/* ********************************************************** */ -/* SINGLE BIT MACRO PAIRS (bit mask and negated one) */ -/* and MULTI BIT READ MACROS */ -/* ********************************************************** */ - -/* Bit masks for SDH_COMMAND */ - -#define CMD_IDX 0x3f /* Command Index */ -#define CMD_RSP 0x40 /* Response */ -#define CMD_L_RSP 0x80 /* Long Response */ -#define CMD_INT_E 0x100 /* Command Interrupt */ -#define CMD_PEND_E 0x200 /* Command Pending */ -#define CMD_E 0x400 /* Command Enable */ - -/* Bit masks for SDH_PWR_CTL */ - -#define PWR_ON 0x3 /* Power On */ -#if 0 -#define TBD 0x3c /* TBD */ -#endif -#define SD_CMD_OD 0x40 /* Open Drain Output */ -#define ROD_CTL 0x80 /* Rod Control */ - -/* Bit masks for SDH_CLK_CTL */ - -#define CLKDIV 0xff /* MC_CLK Divisor */ -#define CLK_E 0x100 /* MC_CLK Bus Clock Enable */ -#define PWR_SV_E 0x200 /* Power Save Enable */ -#define CLKDIV_BYPASS 0x400 /* Bypass Divisor */ -#define WIDE_BUS 0x800 /* Wide Bus Mode Enable */ - -/* Bit masks for SDH_RESP_CMD */ - -#define RESP_CMD 0x3f /* Response Command */ - -/* Bit masks for SDH_DATA_CTL */ - -#define DTX_E 0x1 /* Data Transfer Enable */ -#define DTX_DIR 0x2 /* Data Transfer Direction */ -#define DTX_MODE 0x4 /* Data Transfer Mode */ -#define DTX_DMA_E 0x8 /* Data Transfer DMA Enable */ -#define DTX_BLK_LGTH 0xf0 /* Data Transfer Block Length */ - -/* Bit masks for SDH_STATUS */ - -#define CMD_CRC_FAIL 0x1 /* CMD CRC Fail */ -#define DAT_CRC_FAIL 0x2 /* Data CRC Fail */ -#define CMD_TIME_OUT 0x4 /* CMD Time Out */ -#define DAT_TIME_OUT 0x8 /* Data Time Out */ -#define TX_UNDERRUN 0x10 /* Transmit Underrun */ -#define RX_OVERRUN 0x20 /* Receive Overrun */ -#define CMD_RESP_END 0x40 /* CMD Response End */ -#define CMD_SENT 0x80 /* CMD Sent */ -#define DAT_END 0x100 /* Data End */ -#define START_BIT_ERR 0x200 /* Start Bit Error */ -#define DAT_BLK_END 0x400 /* Data Block End */ -#define CMD_ACT 0x800 /* CMD Active */ -#define TX_ACT 0x1000 /* Transmit Active */ -#define RX_ACT 0x2000 /* Receive Active */ -#define TX_FIFO_STAT 0x4000 /* Transmit FIFO Status */ -#define RX_FIFO_STAT 0x8000 /* Receive FIFO Status */ -#define TX_FIFO_FULL 0x10000 /* Transmit FIFO Full */ -#define RX_FIFO_FULL 0x20000 /* Receive FIFO Full */ -#define TX_FIFO_ZERO 0x40000 /* Transmit FIFO Empty */ -#define RX_DAT_ZERO 0x80000 /* Receive FIFO Empty */ -#define TX_DAT_RDY 0x100000 /* Transmit Data Available */ -#define RX_FIFO_RDY 0x200000 /* Receive Data Available */ - -/* Bit masks for SDH_STATUS_CLR */ - -#define CMD_CRC_FAIL_STAT 0x1 /* CMD CRC Fail Status */ -#define DAT_CRC_FAIL_STAT 0x2 /* Data CRC Fail Status */ -#define CMD_TIMEOUT_STAT 0x4 /* CMD Time Out Status */ -#define DAT_TIMEOUT_STAT 0x8 /* Data Time Out status */ -#define TX_UNDERRUN_STAT 0x10 /* Transmit Underrun Status */ -#define RX_OVERRUN_STAT 0x20 /* Receive Overrun Status */ -#define CMD_RESP_END_STAT 0x40 /* CMD Response End Status */ -#define CMD_SENT_STAT 0x80 /* CMD Sent Status */ -#define DAT_END_STAT 0x100 /* Data End Status */ -#define START_BIT_ERR_STAT 0x200 /* Start Bit Error Status */ -#define DAT_BLK_END_STAT 0x400 /* Data Block End Status */ - -/* Bit masks for SDH_MASK0 */ - -#define CMD_CRC_FAIL_MASK 0x1 /* CMD CRC Fail Mask */ -#define DAT_CRC_FAIL_MASK 0x2 /* Data CRC Fail Mask */ -#define CMD_TIMEOUT_MASK 0x4 /* CMD Time Out Mask */ -#define DAT_TIMEOUT_MASK 0x8 /* Data Time Out Mask */ -#define TX_UNDERRUN_MASK 0x10 /* Transmit Underrun Mask */ -#define RX_OVERRUN_MASK 0x20 /* Receive Overrun Mask */ -#define CMD_RESP_END_MASK 0x40 /* CMD Response End Mask */ -#define CMD_SENT_MASK 0x80 /* CMD Sent Mask */ -#define DAT_END_MASK 0x100 /* Data End Mask */ -#define START_BIT_ERR_MASK 0x200 /* Start Bit Error Mask */ -#define DAT_BLK_END_MASK 0x400 /* Data Block End Mask */ -#define CMD_ACT_MASK 0x800 /* CMD Active Mask */ -#define TX_ACT_MASK 0x1000 /* Transmit Active Mask */ -#define RX_ACT_MASK 0x2000 /* Receive Active Mask */ -#define TX_FIFO_STAT_MASK 0x4000 /* Transmit FIFO Status Mask */ -#define RX_FIFO_STAT_MASK 0x8000 /* Receive FIFO Status Mask */ -#define TX_FIFO_FULL_MASK 0x10000 /* Transmit FIFO Full Mask */ -#define RX_FIFO_FULL_MASK 0x20000 /* Receive FIFO Full Mask */ -#define TX_FIFO_ZERO_MASK 0x40000 /* Transmit FIFO Empty Mask */ -#define RX_DAT_ZERO_MASK 0x80000 /* Receive FIFO Empty Mask */ -#define TX_DAT_RDY_MASK 0x100000 /* Transmit Data Available Mask */ -#define RX_FIFO_RDY_MASK 0x200000 /* Receive Data Available Mask */ - -/* Bit masks for SDH_FIFO_CNT */ - -#define FIFO_COUNT 0x7fff /* FIFO Count */ - -/* Bit masks for SDH_E_STATUS */ - -#define SDIO_INT_DET 0x2 /* SDIO Int Detected */ -#define SD_CARD_DET 0x10 /* SD Card Detect */ - -/* Bit masks for SDH_E_MASK */ - -#define SDIO_MSK 0x2 /* Mask SDIO Int Detected */ -#define SCD_MSK 0x40 /* Mask Card Detect */ - -/* Bit masks for SDH_CFG */ - -#define CLKS_EN 0x1 /* Clocks Enable */ -#define SD4E 0x4 /* SDIO 4-Bit Enable */ -#define MWE 0x8 /* Moving Window Enable */ -#define SD_RST 0x10 /* SDMMC Reset */ -#define PUP_SDDAT 0x20 /* Pull-up SD_DAT */ -#define PUP_SDDAT3 0x40 /* Pull-up SD_DAT3 */ -#define PD_SDDAT3 0x80 /* Pull-down SD_DAT3 */ - -/* Bit masks for SDH_RD_WAIT_EN */ - -#define RWR 0x1 /* Read Wait Request */ - /* Bit masks for EMAC_PTP_CTL */ #define PTP_EN 0x1 /* Enable the PTP_TSYNC module */ -- cgit v0.10.2 From 57af8edf3f0346aa0f942f245acbfe122bb75707 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 16 Oct 2009 12:35:20 +0000 Subject: Blackfin: bf537-stamp/bf548-ezkit: update ADXL34x resources Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index d5a4c82..fc76ddb 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -698,7 +698,7 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = { #if defined(CONFIG_INPUT_ADXL34X) || defined(CONFIG_INPUT_ADXL34X_MODULE) #include -#include +#include static const struct adxl34x_platform_data adxl34x_info = { .x_axis_offset = 0, .y_axis_offset = 0, @@ -722,9 +722,7 @@ static const struct adxl34x_platform_data adxl34x_info = { .ev_code_y = ABS_Y, /* EV_REL */ .ev_code_z = ABS_Z, /* EV_REL */ - .ev_code_tap_x = BTN_TOUCH, /* EV_KEY */ - .ev_code_tap_y = BTN_TOUCH, /* EV_KEY */ - .ev_code_tap_z = BTN_TOUCH, /* EV_KEY */ + .ev_code_tap = {BTN_TOUCH, BTN_TOUCH, BTN_TOUCH}, /* EV_KEY x,y,z */ /* .ev_code_ff = KEY_F,*/ /* EV_KEY */ /* .ev_code_act_inactivity = KEY_A,*/ /* EV_KEY */ @@ -795,6 +793,13 @@ static struct bfin5xx_spi_chip data_flash_chip_info = { }; #endif +#if defined(CONFIG_INPUT_ADXL34X_SPI) || defined(CONFIG_INPUT_ADXL34X_SPI_MODULE) +static struct bfin5xx_spi_chip spi_adxl34x_chip_info = { + .enable_dma = 0, /* use dma transfer with this chip*/ + .bits_per_word = 8, +}; +#endif + static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_MTD_M25P80) \ || defined(CONFIG_MTD_M25P80_MODULE) @@ -933,6 +938,18 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_0, }, #endif +#if defined(CONFIG_INPUT_ADXL34X_SPI) || defined(CONFIG_INPUT_ADXL34X_SPI_MODULE) + { + .modalias = "adxl34x", + .platform_data = &adxl34x_info, + .irq = IRQ_PF6, + .max_speed_hz = 5000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 2, + .controller_data = &spi_adxl34x_chip_info, + .mode = SPI_MODE_3, + }, +#endif }; #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 0d65cfa..93595cf 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -186,7 +186,7 @@ static struct platform_device bfin_rotary_device = { #endif #if defined(CONFIG_INPUT_ADXL34X) || defined(CONFIG_INPUT_ADXL34X_MODULE) -#include +#include static const struct adxl34x_platform_data adxl34x_info = { .x_axis_offset = 0, .y_axis_offset = 0, @@ -210,9 +210,7 @@ static const struct adxl34x_platform_data adxl34x_info = { .ev_code_y = ABS_Y, /* EV_REL */ .ev_code_z = ABS_Z, /* EV_REL */ - .ev_code_tap_x = BTN_TOUCH, /* EV_KEY */ - .ev_code_tap_y = BTN_TOUCH, /* EV_KEY */ - .ev_code_tap_z = BTN_TOUCH, /* EV_KEY */ + .ev_code_tap = {BTN_TOUCH, BTN_TOUCH, BTN_TOUCH}, /* EV_KEY x,y,z */ /* .ev_code_ff = KEY_F,*/ /* EV_KEY */ /* .ev_code_act_inactivity = KEY_A,*/ /* EV_KEY */ -- cgit v0.10.2 From 5db4036b46ee0d0334a1ac34c1e2375746ba5522 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 29 Oct 2009 13:48:10 +0000 Subject: Blackfin: bf537-stamp: add ADXL346 orientation sensing support The ADXL34x driver was updated to include orientation sensing, so have the bf537-stamp use it by default. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 93595cf..fa44ea2 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -216,6 +216,11 @@ static const struct adxl34x_platform_data adxl34x_info = { /* .ev_code_act_inactivity = KEY_A,*/ /* EV_KEY */ .power_mode = ADXL_AUTO_SLEEP | ADXL_LINK, .fifo_mode = ADXL_FIFO_STREAM, + .orientation_enable = ADXL_EN_ORIENTATION_3D, + .deadzone_angle = ADXL_DEADZONE_ANGLE_10p8, + .divisor_length = ADXL_LP_FILTER_DIVISOR_16, + /* EV_KEY {+Z, +Y, +X, -X, -Y, -Z} */ + .ev_codes_orient_3d = {BTN_Z, BTN_Y, BTN_X, BTN_A, BTN_B, BTN_C}, }; #endif -- cgit v0.10.2 From 1d23dc89f29b8ceea87bb6656172c13e4c9549de Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 5 Oct 2009 13:33:11 +0000 Subject: Blackfin: bf537-stamp: update ADP5520 resources Matches feedback for driver changes. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index fc76ddb..03fd835 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1286,22 +1286,22 @@ static struct adp5588_kpad_platform_data adp5588_kpad_data = { * ADP5520/5501 Backlight Data */ -static struct adp5520_backlight_platfrom_data adp5520_backlight_data = { - .fade_in = FADE_T_1200ms, - .fade_out = FADE_T_1200ms, - .fade_led_law = BL_LAW_LINEAR, - .en_ambl_sens = 1, - .abml_filt = BL_AMBL_FILT_640ms, - .l1_daylight_max = BL_CUR_mA(15), - .l1_daylight_dim = BL_CUR_mA(0), - .l2_office_max = BL_CUR_mA(7), - .l2_office_dim = BL_CUR_mA(0), - .l3_dark_max = BL_CUR_mA(3), - .l3_dark_dim = BL_CUR_mA(0), - .l2_trip = L2_COMP_CURR_uA(700), - .l2_hyst = L2_COMP_CURR_uA(50), - .l3_trip = L3_COMP_CURR_uA(80), - .l3_hyst = L3_COMP_CURR_uA(20), +static struct adp5520_backlight_platform_data adp5520_backlight_data = { + .fade_in = ADP5520_FADE_T_1200ms, + .fade_out = ADP5520_FADE_T_1200ms, + .fade_led_law = ADP5520_BL_LAW_LINEAR, + .en_ambl_sens = 1, + .abml_filt = ADP5520_BL_AMBL_FILT_640ms, + .l1_daylight_max = ADP5520_BL_CUR_mA(15), + .l1_daylight_dim = ADP5520_BL_CUR_mA(0), + .l2_office_max = ADP5520_BL_CUR_mA(7), + .l2_office_dim = ADP5520_BL_CUR_mA(0), + .l3_dark_max = ADP5520_BL_CUR_mA(3), + .l3_dark_dim = ADP5520_BL_CUR_mA(0), + .l2_trip = ADP5520_L2_COMP_CURR_uA(700), + .l2_hyst = ADP5520_L2_COMP_CURR_uA(50), + .l3_trip = ADP5520_L3_COMP_CURR_uA(80), + .l3_hyst = ADP5520_L3_COMP_CURR_uA(20), }; /* @@ -1314,7 +1314,7 @@ static struct led_info adp5520_leds[] = { { .name = "adp5520-led1", .default_trigger = "none", - .flags = FLAG_ID_ADP5520_LED1_ADP5501_LED0 | LED_OFFT_600ms, + .flags = FLAG_ID_ADP5520_LED1_ADP5501_LED0 | ADP5520_LED_OFFT_600ms, }, #ifdef ADP5520_EN_ALL_LEDS { @@ -1330,22 +1330,22 @@ static struct led_info adp5520_leds[] = { #endif }; -static struct adp5520_leds_platfrom_data adp5520_leds_data = { +static struct adp5520_leds_platform_data adp5520_leds_data = { .num_leds = ARRAY_SIZE(adp5520_leds), .leds = adp5520_leds, - .fade_in = FADE_T_600ms, - .fade_out = FADE_T_600ms, - .led_on_time = LED_ONT_600ms, + .fade_in = ADP5520_FADE_T_600ms, + .fade_out = ADP5520_FADE_T_600ms, + .led_on_time = ADP5520_LED_ONT_600ms, }; /* * ADP5520 GPIO Data */ -static struct adp5520_gpio_platfrom_data adp5520_gpio_data = { +static struct adp5520_gpio_platform_data adp5520_gpio_data = { .gpio_start = 50, - .gpio_en_mask = GPIO_C1 | GPIO_C2 | GPIO_R2, - .gpio_pullup_mask = GPIO_C1 | GPIO_C2 | GPIO_R2, + .gpio_en_mask = ADP5520_GPIO_C1 | ADP5520_GPIO_C2 | ADP5520_GPIO_R2, + .gpio_pullup_mask = ADP5520_GPIO_C1 | ADP5520_GPIO_C2 | ADP5520_GPIO_R2, }; /* @@ -1354,27 +1354,27 @@ static struct adp5520_gpio_platfrom_data adp5520_gpio_data = { #include static const unsigned short adp5520_keymap[ADP5520_KEYMAPSIZE] = { - [KEY(0, 0)] = KEY_GRAVE, - [KEY(0, 1)] = KEY_1, - [KEY(0, 2)] = KEY_2, - [KEY(0, 3)] = KEY_3, - [KEY(1, 0)] = KEY_4, - [KEY(1, 1)] = KEY_5, - [KEY(1, 2)] = KEY_6, - [KEY(1, 3)] = KEY_7, - [KEY(2, 0)] = KEY_8, - [KEY(2, 1)] = KEY_9, - [KEY(2, 2)] = KEY_0, - [KEY(2, 3)] = KEY_MINUS, - [KEY(3, 0)] = KEY_EQUAL, - [KEY(3, 1)] = KEY_BACKSLASH, - [KEY(3, 2)] = KEY_BACKSPACE, - [KEY(3, 3)] = KEY_ENTER, -}; - -static struct adp5520_keys_platfrom_data adp5520_keys_data = { - .rows_en_mask = ROW_R3 | ROW_R2 | ROW_R1 | ROW_R0, - .cols_en_mask = COL_C3 | COL_C2 | COL_C1 | COL_C0, + [ADP5520_KEY(0, 0)] = KEY_GRAVE, + [ADP5520_KEY(0, 1)] = KEY_1, + [ADP5520_KEY(0, 2)] = KEY_2, + [ADP5520_KEY(0, 3)] = KEY_3, + [ADP5520_KEY(1, 0)] = KEY_4, + [ADP5520_KEY(1, 1)] = KEY_5, + [ADP5520_KEY(1, 2)] = KEY_6, + [ADP5520_KEY(1, 3)] = KEY_7, + [ADP5520_KEY(2, 0)] = KEY_8, + [ADP5520_KEY(2, 1)] = KEY_9, + [ADP5520_KEY(2, 2)] = KEY_0, + [ADP5520_KEY(2, 3)] = KEY_MINUS, + [ADP5520_KEY(3, 0)] = KEY_EQUAL, + [ADP5520_KEY(3, 1)] = KEY_BACKSLASH, + [ADP5520_KEY(3, 2)] = KEY_BACKSPACE, + [ADP5520_KEY(3, 3)] = KEY_ENTER, +}; + +static struct adp5520_keys_platform_data adp5520_keys_data = { + .rows_en_mask = ADP5520_ROW_R3 | ADP5520_ROW_R2 | ADP5520_ROW_R1 | ADP5520_ROW_R0, + .cols_en_mask = ADP5520_COL_C3 | ADP5520_COL_C2 | ADP5520_COL_C1 | ADP5520_COL_C0, .keymap = adp5520_keymap, .keymapsize = ARRAY_SIZE(adp5520_keymap), .repeat = 0, @@ -1384,39 +1384,18 @@ static struct adp5520_keys_platfrom_data adp5520_keys_data = { * ADP5520/5501 Multifuction Device Init Data */ -static struct adp5520_subdev_info adp5520_subdevs[] = { - { - .name = "adp5520-backlight", - .id = ID_ADP5520, - .platform_data = &adp5520_backlight_data, - }, - { - .name = "adp5520-led", - .id = ID_ADP5520, - .platform_data = &adp5520_leds_data, - }, - { - .name = "adp5520-gpio", - .id = ID_ADP5520, - .platform_data = &adp5520_gpio_data, - }, - { - .name = "adp5520-keys", - .id = ID_ADP5520, - .platform_data = &adp5520_keys_data, - }, -}; - static struct adp5520_platform_data adp5520_pdev_data = { - .num_subdevs = ARRAY_SIZE(adp5520_subdevs), - .subdevs = adp5520_subdevs, + .backlight = &adp5520_backlight_data, + .leds = &adp5520_leds_data, + .gpio = &adp5520_gpio_data, + .keys = &adp5520_keys_data, }; #endif #if defined(CONFIG_GPIO_ADP5588) || defined(CONFIG_GPIO_ADP5588_MODULE) #include -static struct adp5588_gpio_platfrom_data adp5588_gpio_data = { +static struct adp5588_gpio_platform_data adp5588_gpio_data = { .gpio_start = 50, .pullup_dis_mask = 0, }; -- cgit v0.10.2 From 5b7c57751e6dcf3a3063b8e94977972d4cb646c6 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 12 Oct 2009 15:56:58 +0000 Subject: Blackfin: bf537-stamp: kill AD714x board-specific Kconfigs Include the AD714x SPI/I2C resources based on what is possible. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 03fd835..f911d2f 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -515,7 +515,7 @@ static struct bfin5xx_spi_chip ad1938_spi_chip_info = { }; #endif -#if defined(CONFIG_INPUT_EVAL_AD7147EBZ) +#if defined(CONFIG_INPUT_AD714X_SPI) || defined(CONFIG_INPUT_AD714X_SPI_MODULE) #include #include static struct bfin5xx_spi_chip ad7147_spi_chip_info = { @@ -523,7 +523,7 @@ static struct bfin5xx_spi_chip ad7147_spi_chip_info = { .bits_per_word = 16, }; -static struct ad714x_slider_plat slider_plat[] = { +static struct ad714x_slider_plat ad7147_spi_slider_plat[] = { { .start_stage = 0, .end_stage = 7, @@ -531,7 +531,7 @@ static struct ad714x_slider_plat slider_plat[] = { }, }; -static struct ad714x_button_plat button_plat[] = { +static struct ad714x_button_plat ad7147_spi_button_plat[] = { { .keycode = BTN_FORWARD, .l_mask = 0, @@ -558,11 +558,11 @@ static struct ad714x_button_plat button_plat[] = { .h_mask = 0x400, }, }; -static struct ad714x_platform_data ad7147_platfrom_data = { +static struct ad714x_platform_data ad7147_spi_platform_data = { .slider_num = 1, .button_num = 5, - .slider = slider_plat, - .button = button_plat, + .slider = ad7147_spi_slider_plat, + .button = ad7147_spi_button_plat, .stage_cfg_reg = { {0xFBFF, 0x1FFF, 0, 0x2626, 1600, 1600, 1600, 1600}, {0xEFFF, 0x1FFF, 0, 0x2626, 1650, 1650, 1650, 1650}, @@ -581,10 +581,10 @@ static struct ad714x_platform_data ad7147_platfrom_data = { }; #endif -#if defined(CONFIG_INPUT_EVAL_AD7142EB) +#if defined(CONFIG_INPUT_AD714X_I2C) || defined(CONFIG_INPUT_AD714X_I2C_MODULE) #include #include -static struct ad714x_button_plat button_plat[] = { +static struct ad714x_button_plat ad7142_i2c_button_plat[] = { { .keycode = BTN_1, .l_mask = 0, @@ -606,9 +606,9 @@ static struct ad714x_button_plat button_plat[] = { .h_mask = 0x8, }, }; -static struct ad714x_platform_data ad7142_platfrom_data = { +static struct ad714x_platform_data ad7142_i2c_platform_data = { .button_num = 4, - .button = button_plat, + .button = ad7142_i2c_button_plat, .stage_cfg_reg = { /* fixme: figure out right setting for all comoponent according * to hardware feature of EVAL-AD7142EB board */ @@ -861,7 +861,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_INPUT_EVAL_AD7147EBZ) +#if defined(CONFIG_INPUT_AD714X_SPI) || defined(CONFIG_INPUT_AD714X_SPI_MODULE) { .modalias = "ad714x_captouch", .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ @@ -869,7 +869,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .bus_num = 0, .chip_select = 5, .mode = SPI_MODE_3, - .platform_data = &ad7147_platfrom_data, + .platform_data = &ad7147_spi_platform_data, .controller_data = &ad7147_spi_chip_info, }, #endif @@ -1402,11 +1402,11 @@ static struct adp5588_gpio_platform_data adp5588_gpio_data = { #endif static struct i2c_board_info __initdata bfin_i2c_board_info[] = { -#if defined(CONFIG_INPUT_EVAL_AD7142EB) +#if defined(CONFIG_INPUT_AD714X_I2C) || defined(CONFIG_INPUT_AD714X_I2C_MODULE) { I2C_BOARD_INFO("ad7142_captouch", 0x2C), .irq = IRQ_PG5, - .platform_data = (void *)&ad7142_platfrom_data, + .platform_data = (void *)&ad7142_i2c_platform_data, }, #endif #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) -- cgit v0.10.2 From 78756c62309c0bccf3705dbf448f3a31542e973d Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 13 Oct 2009 15:28:33 +0000 Subject: Blackfin: bf537-stamp: add ADP8870 resources Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index f911d2f..d2fb96a 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include #include @@ -77,7 +79,6 @@ static struct platform_device bfin_isp1760_device = { #endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -#include #include static struct gpio_keys_button bfin_gpio_keys_table[] = { @@ -516,7 +517,6 @@ static struct bfin5xx_spi_chip ad1938_spi_chip_info = { #endif #if defined(CONFIG_INPUT_AD714X_SPI) || defined(CONFIG_INPUT_AD714X_SPI_MODULE) -#include #include static struct bfin5xx_spi_chip ad7147_spi_chip_info = { .enable_dma = 0, @@ -582,7 +582,6 @@ static struct ad714x_platform_data ad7147_spi_platform_data = { #endif #if defined(CONFIG_INPUT_AD714X_I2C) || defined(CONFIG_INPUT_AD714X_I2C_MODULE) -#include #include static struct ad714x_button_plat ad7142_i2c_button_plat[] = { { @@ -697,7 +696,6 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = { #endif #if defined(CONFIG_INPUT_ADXL34X) || defined(CONFIG_INPUT_ADXL34X_MODULE) -#include #include static const struct adxl34x_platform_data adxl34x_info = { .x_axis_offset = 0, @@ -1193,7 +1191,6 @@ static struct platform_device i2c_bfin_twi_device = { #endif #if defined(CONFIG_KEYBOARD_ADP5588) || defined(CONFIG_KEYBOARD_ADP5588_MODULE) -#include #include static const unsigned short adp5588_keymap[ADP5588_KEYMAPSIZE] = { [0] = KEY_GRAVE, @@ -1308,8 +1305,6 @@ static struct adp5520_backlight_platform_data adp5520_backlight_data = { * ADP5520/5501 LEDs Data */ -#include - static struct led_info adp5520_leds[] = { { .name = "adp5520-led1", @@ -1352,7 +1347,6 @@ static struct adp5520_gpio_platform_data adp5520_gpio_data = { * ADP5520 Keypad Data */ -#include static const unsigned short adp5520_keymap[ADP5520_KEYMAPSIZE] = { [ADP5520_KEY(0, 0)] = KEY_GRAVE, [ADP5520_KEY(0, 1)] = KEY_1, @@ -1401,6 +1395,58 @@ static struct adp5588_gpio_platform_data adp5588_gpio_data = { }; #endif +#if defined(CONFIG_BACKLIGHT_ADP8870) || defined(CONFIG_BACKLIGHT_ADP8870_MODULE) +#include +static struct led_info adp8870_leds[] = { + { + .name = "adp8870-led7", + .default_trigger = "none", + .flags = ADP8870_LED_D7 | ADP8870_LED_OFFT_600ms, + }, +}; + + +static struct adp8870_backlight_platform_data adp8870_pdata = { + .bl_led_assign = ADP8870_BL_D1 | ADP8870_BL_D2 | ADP8870_BL_D3 | + ADP8870_BL_D4 | ADP8870_BL_D5 | ADP8870_BL_D6, /* 1 = Backlight 0 = Individual LED */ + .pwm_assign = 0, /* 1 = Enables PWM mode */ + + .bl_fade_in = ADP8870_FADE_T_1200ms, /* Backlight Fade-In Timer */ + .bl_fade_out = ADP8870_FADE_T_1200ms, /* Backlight Fade-Out Timer */ + .bl_fade_law = ADP8870_FADE_LAW_CUBIC1, /* fade-on/fade-off transfer characteristic */ + + .en_ambl_sens = 1, /* 1 = enable ambient light sensor */ + .abml_filt = ADP8870_BL_AMBL_FILT_320ms, /* Light sensor filter time */ + + .l1_daylight_max = ADP8870_BL_CUR_mA(20), /* use BL_CUR_mA(I) 0 <= I <= 30 mA */ + .l1_daylight_dim = ADP8870_BL_CUR_mA(0), /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */ + .l2_bright_max = ADP8870_BL_CUR_mA(14), /* use BL_CUR_mA(I) 0 <= I <= 30 mA */ + .l2_bright_dim = ADP8870_BL_CUR_mA(0), /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */ + .l3_office_max = ADP8870_BL_CUR_mA(6), /* use BL_CUR_mA(I) 0 <= I <= 30 mA */ + .l3_office_dim = ADP8870_BL_CUR_mA(0), /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */ + .l4_indoor_max = ADP8870_BL_CUR_mA(3), /* use BL_CUR_mA(I) 0 <= I <= 30 mA */ + .l4_indor_dim = ADP8870_BL_CUR_mA(0), /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */ + .l5_dark_max = ADP8870_BL_CUR_mA(2), /* use BL_CUR_mA(I) 0 <= I <= 30 mA */ + .l5_dark_dim = ADP8870_BL_CUR_mA(0), /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */ + + .l2_trip = ADP8870_L2_COMP_CURR_uA(710), /* use L2_COMP_CURR_uA(I) 0 <= I <= 1106 uA */ + .l2_hyst = ADP8870_L2_COMP_CURR_uA(73), /* use L2_COMP_CURR_uA(I) 0 <= I <= 1106 uA */ + .l3_trip = ADP8870_L3_COMP_CURR_uA(389), /* use L3_COMP_CURR_uA(I) 0 <= I <= 551 uA */ + .l3_hyst = ADP8870_L3_COMP_CURR_uA(54), /* use L3_COMP_CURR_uA(I) 0 <= I <= 551 uA */ + .l4_trip = ADP8870_L4_COMP_CURR_uA(167), /* use L4_COMP_CURR_uA(I) 0 <= I <= 275 uA */ + .l4_hyst = ADP8870_L4_COMP_CURR_uA(16), /* use L4_COMP_CURR_uA(I) 0 <= I <= 275 uA */ + .l5_trip = ADP8870_L5_COMP_CURR_uA(43), /* use L5_COMP_CURR_uA(I) 0 <= I <= 138 uA */ + .l5_hyst = ADP8870_L5_COMP_CURR_uA(11), /* use L6_COMP_CURR_uA(I) 0 <= I <= 138 uA */ + + .leds = adp8870_leds, + .num_leds = ARRAY_SIZE(adp8870_leds), + .led_fade_law = ADP8870_FADE_LAW_SQUARE, /* fade-on/fade-off transfer characteristic */ + .led_fade_in = ADP8870_FADE_T_600ms, + .led_fade_out = ADP8870_FADE_T_600ms, + .led_on_time = ADP8870_LED_ONT_200ms, +}; +#endif + static struct i2c_board_info __initdata bfin_i2c_board_info[] = { #if defined(CONFIG_INPUT_AD714X_I2C) || defined(CONFIG_INPUT_AD714X_I2C_MODULE) { @@ -1464,6 +1510,12 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { I2C_BOARD_INFO("bf537-lq035-ad5280", 0x2C), }, #endif +#if defined(CONFIG_BACKLIGHT_ADP8870) || defined(CONFIG_BACKLIGHT_ADP8870_MODULE) + { + I2C_BOARD_INFO("adp8870", 0x2B), + .platform_data = (void *)&adp8870_pdata, + }, +#endif }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) -- cgit v0.10.2 From d53127ffd6e19feb5f045da917207f9e6e2ed331 Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Thu, 15 Oct 2009 02:33:04 +0000 Subject: Blackfin: bf537-stamp: add adau1371 i2c address Signed-off-by: Cliff Cai Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index d2fb96a..18903e9 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1516,6 +1516,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { .platform_data = (void *)&adp8870_pdata, }, #endif +#if defined(CONFIG_SND_SOC_ADAU1371) || defined(CONFIG_SND_SOC_ADAU1371_MODULE) + { + I2C_BOARD_INFO("adau1371", 0x1A), + }, +#endif }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) -- cgit v0.10.2 From 04267638e07f4430f902d7a304845634443caf1a Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Wed, 28 Oct 2009 06:50:36 +0000 Subject: Blackfin: bf537-stamp: add adau1761 i2c address Signed-off-by: Cliff Cai Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 18903e9..2ba6f36 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1521,6 +1521,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { I2C_BOARD_INFO("adau1371", 0x1A), }, #endif +#if defined(CONFIG_SND_SOC_ADAU1761) || defined(CONFIG_SND_SOC_ADAU1761_MODULE) + { + I2C_BOARD_INFO("adau1761", 0x38), + }, +#endif }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) -- cgit v0.10.2 From 1f13f2fdca71408ad211936b85e673b72e91911a Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 17 Nov 2009 10:18:27 +0000 Subject: Blackfin: bf537-stamp: add AD5258 i2c address Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 2ba6f36..187e6fd 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1526,6 +1526,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { I2C_BOARD_INFO("adau1761", 0x38), }, #endif +#if defined(CONFIG_AD525X_DPOT) || defined(CONFIG_AD525X_DPOT_MODULE) + { + I2C_BOARD_INFO("ad5258", 0x18), + }, +#endif }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) -- cgit v0.10.2 From 706a01b1c6d50b0940ca31d2dc21ba54f095f5af Mon Sep 17 00:00:00 2001 From: Barry Song Date: Mon, 2 Nov 2009 07:29:07 +0000 Subject: Blackfin: bf537-stamp: add CAN resources Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 187e6fd..70349d3 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -302,6 +302,44 @@ static struct platform_device isp1362_hcd_device = { }; #endif +#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) +unsigned short bfin_can_peripherals[] = { + P_CAN0_RX, P_CAN0_TX, 0 +}; + +static struct resource bfin_can_resources[] = { + { + .start = 0xFFC02A00, + .end = 0xFFC02FFF, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_CAN_RX, + .end = IRQ_CAN_RX, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_CAN_TX, + .end = IRQ_CAN_TX, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_CAN_ERROR, + .end = IRQ_CAN_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_can_device = { + .name = "bfin_can", + .num_resources = ARRAY_SIZE(bfin_can_resources), + .resource = bfin_can_resources, + .dev = { + .platform_data = &bfin_can_peripherals, /* Passed to driver */ + }, +}; +#endif + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) static struct platform_device bfin_mii_bus = { .name = "bfin_mii_bus", @@ -1675,6 +1713,10 @@ static struct platform_device *stamp_devices[] __initdata = { &ax88180_device, #endif +#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) + &bfin_can_device, +#endif + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) &bfin_mii_bus, &bfin_mac_device, diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c index 14af5c2..c296bb1 100644 --- a/arch/blackfin/mach-bf538/boards/ezkit.c +++ b/arch/blackfin/mach-bf538/boards/ezkit.c @@ -151,6 +151,44 @@ static struct platform_device bfin_sir2_device = { #endif #endif +#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) +unsigned short bfin_can_peripherals[] = { + P_CAN0_RX, P_CAN0_TX, 0 +}; + +static struct resource bfin_can_resources[] = { + { + .start = 0xFFC02A00, + .end = 0xFFC02FFF, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_CAN_RX, + .end = IRQ_CAN_RX, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_CAN_TX, + .end = IRQ_CAN_TX, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_CAN_ERROR, + .end = IRQ_CAN_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_can_device = { + .name = "bfin_can", + .num_resources = ARRAY_SIZE(bfin_can_resources), + .resource = bfin_can_resources, + .dev = { + .platform_data = &bfin_can_peripherals, /* Passed to driver */ + }, +}; +#endif + /* * USB-LAN EzExtender board * Driver needs to know address, irq and flag pin. @@ -610,6 +648,10 @@ static struct platform_device *cm_bf538_devices[] __initdata = { #endif #endif +#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) + &bfin_can_device, +#endif + #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) &smc91x_device, #endif diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index fa44ea2..60193f7 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -464,6 +464,44 @@ static struct platform_device musb_device = { }; #endif +#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) +unsigned short bfin_can_peripherals[] = { + P_CAN0_RX, P_CAN0_TX, 0 +}; + +static struct resource bfin_can_resources[] = { + { + .start = 0xFFC02A00, + .end = 0xFFC02FFF, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_CAN0_RX, + .end = IRQ_CAN0_RX, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_CAN0_TX, + .end = IRQ_CAN0_TX, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_CAN0_ERROR, + .end = IRQ_CAN0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_can_device = { + .name = "bfin_can", + .num_resources = ARRAY_SIZE(bfin_can_resources), + .resource = bfin_can_resources, + .dev = { + .platform_data = &bfin_can_peripherals, /* Passed to driver */ + }, +}; +#endif + #if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE) static struct resource bfin_atapi_resources[] = { { @@ -956,6 +994,10 @@ static struct platform_device *ezkit_devices[] __initdata = { &bfin_isp1760_device, #endif +#if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) + &bfin_can_device, +#endif + #if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE) &bfin_atapi_device, #endif -- cgit v0.10.2 From efaf7cd9557712a72b5856af19d701783b654a63 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 12 Nov 2009 16:54:08 +0000 Subject: Blackfin: bf537-stamp: add ADF702x network driver resources Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 70349d3..c080c77 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -796,6 +796,47 @@ static struct bfin5xx_spi_chip enc28j60_spi_chip_info = { }; #endif +#if defined(CONFIG_ADF702X) || defined(CONFIG_ADF702X_MODULE) +static struct bfin5xx_spi_chip adf7021_spi_chip_info = { + .bits_per_word = 16, + .cs_gpio = GPIO_PF10, +}; + +#include +#define TXREG 0x0160A470 +static const u32 adf7021_regs[] = { + 0x09608FA0, + 0x00575011, + 0x00A7F092, + 0x2B141563, + 0x81F29E94, + 0x00003155, + 0x050A4F66, + 0x00000007, + 0x00000008, + 0x000231E9, + 0x3296354A, + 0x891A2B3B, + 0x00000D9C, + 0x0000000D, + 0x0000000E, + 0x0000000F, +}; + +static struct adf702x_platform_data adf7021_platform_data = { + .regs_base = (void *)SPORT1_TCR1, + .dma_ch_rx = CH_SPORT1_RX, + .dma_ch_tx = CH_SPORT1_TX, + .irq_sport_err = IRQ_SPORT1_ERROR, + .gpio_int_rfs = GPIO_PF8, + .pin_req = {P_SPORT1_DTPRI, P_SPORT1_RFS, P_SPORT1_DRPRI, + P_SPORT1_RSCLK, P_SPORT1_TSCLK, 0}, + .adf702x_model = MODEL_ADF7021, + .adf702x_regs = adf7021_regs, + .tx_reg = TXREG, +}; +#endif + #if defined(CONFIG_MTD_DATAFLASH) \ || defined(CONFIG_MTD_DATAFLASH_MODULE) @@ -986,6 +1027,18 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif +#if defined(CONFIG_ADF702X) || defined(CONFIG_ADF702X_MODULE) + { + .modalias = "adf702x", + .max_speed_hz = 16000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 0, /* GPIO controlled SSEL */ + .controller_data = &adf7021_spi_chip_info, + .platform_data = &adf7021_platform_data, + .mode = SPI_MODE_0, + }, +#endif + }; #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) -- cgit v0.10.2 From caf0ea858217025546425d75671a14d9f12ce9c9 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 15 Nov 2009 07:39:59 +0000 Subject: Blackfin: drop unused ax88180 resources The ax88180 driver was never merged, so drop the corresponding resources. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index c080c77..ac9b52e 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -197,28 +197,6 @@ static struct platform_device dm9000_device = { }; #endif -#if defined(CONFIG_AX88180) || defined(CONFIG_AX88180_MODULE) -static struct resource ax88180_resources[] = { - [0] = { - .start = 0x20300000, - .end = 0x20300000 + 0x8000, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_PF7, - .end = IRQ_PF7, - .flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL), - }, -}; - -static struct platform_device ax88180_device = { - .name = "ax88180", - .id = -1, - .num_resources = ARRAY_SIZE(ax88180_resources), - .resource = ax88180_resources, -}; -#endif - #if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) static struct resource sl811_hcd_resources[] = { { @@ -1762,10 +1740,6 @@ static struct platform_device *stamp_devices[] __initdata = { &dm9000_device, #endif -#if defined(CONFIG_AX88180) || defined(CONFIG_AX88180_MODULE) - &ax88180_device, -#endif - #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) &bfin_can_device, #endif diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c index 6c5b508..ffd3e6a 100644 --- a/arch/blackfin/mach-bf561/boards/ezkit.c +++ b/arch/blackfin/mach-bf561/boards/ezkit.c @@ -159,28 +159,6 @@ static struct platform_device smc91x_device = { }; #endif -#if defined(CONFIG_AX88180) || defined(CONFIG_AX88180_MODULE) -static struct resource ax88180_resources[] = { - [0] = { - .start = 0x2c000000, - .end = 0x2c000000 + 0x8000, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_PF10, - .end = IRQ_PF10, - .flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL), - }, -}; - -static struct platform_device ax88180_device = { - .name = "ax88180", - .id = -1, - .num_resources = ARRAY_SIZE(ax88180_resources), - .resource = ax88180_resources, -}; -#endif - #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) static struct resource bfin_uart_resources[] = { { @@ -421,10 +399,6 @@ static struct platform_device *ezkit_devices[] __initdata = { &smc91x_device, #endif -#if defined(CONFIG_AX88180) || defined(CONFIG_AX88180_MODULE) - &ax88180_device, -#endif - #if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) &net2272_bfin_device, #endif -- cgit v0.10.2 From 99e452e5d3f0066307a28e3a6f06b4b51f0e1594 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 3 Dec 2009 23:37:07 +0000 Subject: Blackfin: ip0x: pull in asm/portmux.h for P_xxx defines Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf533/boards/ip0x.c b/arch/blackfin/mach-bf533/boards/ip0x.c index 48cfbf8..8ec42ba 100644 --- a/arch/blackfin/mach-bf533/boards/ip0x.c +++ b/arch/blackfin/mach-bf533/boards/ip0x.c @@ -20,6 +20,7 @@ #endif #include #include +#include /* * Name the Board for the /proc/cpuinfo -- cgit v0.10.2 From c768a943fd8f41f5f7ed33c91d50818b301f5635 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 4 Dec 2009 03:32:11 +0000 Subject: Blackfin: convert cyc2ns() to clocksource_cyc2ns() The former no longer exists. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index eef5283..17c38c5 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c @@ -64,7 +64,8 @@ static struct clocksource bfin_cs_cycles = { static inline unsigned long long bfin_cs_cycles_sched_clock(void) { - return cyc2ns(&bfin_cs_cycles, bfin_read_cycles(&bfin_cs_cycles)); + return clocksource_cyc2ns(bfin_read_cycles(&bfin_cs_cycles), + bfin_cs_cycles.mult, bfin_cs_cycles.shift); } static int __init bfin_cs_cycles_init(void) @@ -111,7 +112,8 @@ static struct clocksource bfin_cs_gptimer0 = { static inline unsigned long long bfin_cs_gptimer0_sched_clock(void) { - return cyc2ns(&bfin_cs_gptimer0, bfin_read_TIMER0_COUNTER()); + return clocksource_cyc2ns(bfin_read_TIMER0_COUNTER(), + bfin_cs_gptimer0.mult, bfin_cs_gptimer0.shift); } static int __init bfin_cs_gptimer0_init(void) -- cgit v0.10.2 From 397b761cc42e2c56f8de07de680486892448b628 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sat, 5 Dec 2009 03:27:29 +0300 Subject: Blackfin: convert kgdbtest to proc_fops The read_proc and write_proc interfaces are going to be removed in the common kernel code. Signed-off-by: Alexey Dobriyan Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/kgdb_test.c b/arch/blackfin/kernel/kgdb_test.c index 59fc42d..6fc4e5f 100644 --- a/arch/blackfin/kernel/kgdb_test.c +++ b/arch/blackfin/kernel/kgdb_test.c @@ -18,7 +18,7 @@ #include static char cmdline[256]; -static unsigned long len; +static size_t len; #ifndef CONFIG_SMP static int num1 __attribute__((l1_data)); @@ -59,7 +59,8 @@ int kgdb_test(char *name, int len, int count, int z) return count; } -static int test_proc_output(char *buf) +static ssize_t kgdb_test_proc_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) { kgdb_test("hello world!", 12, 0x55, 0x10); #ifndef CONFIG_SMP @@ -72,25 +73,8 @@ static int test_proc_output(char *buf) return 0; } -static int test_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len; - - len = test_proc_output(page); - if (len <= off+count) - *eof = 1; - *start = page + off; - len -= off; - if (len > count) - len = count; - if (len < 0) - len = 0; - return len; -} - -static int test_write_proc(struct file *file, const char *buffer, - unsigned long count, void *data) +static ssize_t kgdb_test_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *pos) { if (count >= 256) len = 255; @@ -103,18 +87,19 @@ static int test_write_proc(struct file *file, const char *buffer, return len; } +static const struct file_operations kgdb_test_proc_fops = { + .owner = THIS_MODULE, + .read = kgdb_test_proc_read, + .write = kgdb_test_proc_write, +}; + static int __init kgdbtest_init(void) { struct proc_dir_entry *entry; - entry = create_proc_entry("kgdbtest", 0, NULL); + entry = proc_create("kgdbtest", 0, NULL, &kgdb_test_proc_fops); if (entry == NULL) return -ENOMEM; - - entry->read_proc = test_read_proc; - entry->write_proc = test_write_proc; - entry->data = NULL; - return 0; } -- cgit v0.10.2 From 88f7c2fb0fa96887c7be8cdb00afb1a6f9d7894e Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 7 Dec 2009 10:20:20 +0000 Subject: Blackfin: kgdb_test: clean up code a bit - document simple global symbols - convert printk to pr_* - clean up spurious whitespace - use min_t() Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/kgdb_test.c b/arch/blackfin/kernel/kgdb_test.c index 6fc4e5f..9a4b075 100644 --- a/arch/blackfin/kernel/kgdb_test.c +++ b/arch/blackfin/kernel/kgdb_test.c @@ -17,6 +17,7 @@ #include +/* Symbols are here for kgdb test to poke directly */ static char cmdline[256]; static size_t len; @@ -27,11 +28,10 @@ void kgdb_l1_test(void) __attribute__((l1_text)); void kgdb_l1_test(void) { - printk(KERN_ALERT "L1(before change) : data variable addr = 0x%p, data value is %d\n", &num1, num1); - printk(KERN_ALERT "L1 : code function addr = 0x%p\n", kgdb_l1_test); - num1 = num1 + 10 ; - printk(KERN_ALERT "L1(after change) : data variable addr = 0x%p, data value is %d\n", &num1, num1); - return ; + pr_alert("L1(before change) : data variable addr = 0x%p, data value is %d\n", &num1, num1); + pr_alert("L1 : code function addr = 0x%p\n", kgdb_l1_test); + num1 = num1 + 10; + pr_alert("L1(after change) : data variable addr = 0x%p, data value is %d\n", &num1, num1); } #endif @@ -42,11 +42,10 @@ void kgdb_l2_test(void) __attribute__((l2)); void kgdb_l2_test(void) { - printk(KERN_ALERT "L2(before change) : data variable addr = 0x%p, data value is %d\n", &num2, num2); - printk(KERN_ALERT "L2 : code function addr = 0x%p\n", kgdb_l2_test); - num2 = num2 + 20 ; - printk(KERN_ALERT "L2(after change) : data variable addr = 0x%p, data value is %d\n", &num2, num2); - return ; + pr_alert("L2(before change) : data variable addr = 0x%p, data value is %d\n", &num2, num2); + pr_alert("L2 : code function addr = 0x%p\n", kgdb_l2_test); + num2 = num2 + 20; + pr_alert("L2(after change) : data variable addr = 0x%p, data value is %d\n", &num2, num2); } #endif @@ -54,13 +53,14 @@ void kgdb_l2_test(void) int kgdb_test(char *name, int len, int count, int z) { - printk(KERN_ALERT "kgdb name(%d): %s, %d, %d\n", len, name, count, z); + pr_alert("kgdb name(%d): %s, %d, %d\n", len, name, count, z); count = z; return count; } -static ssize_t kgdb_test_proc_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) +static ssize_t +kgdb_test_proc_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) { kgdb_test("hello world!", 12, 0x55, 0x10); #ifndef CONFIG_SMP @@ -73,14 +73,11 @@ static ssize_t kgdb_test_proc_read(struct file *file, char __user *buf, return 0; } -static ssize_t kgdb_test_proc_write(struct file *file, - const char __user *buffer, size_t count, loff_t *pos) +static ssize_t +kgdb_test_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - if (count >= 256) - len = 255; - else - len = count; - + len = min_t(size_t, 255, count); memcpy(cmdline, buffer, count); cmdline[len] = 0; @@ -88,9 +85,9 @@ static ssize_t kgdb_test_proc_write(struct file *file, } static const struct file_operations kgdb_test_proc_fops = { - .owner = THIS_MODULE, - .read = kgdb_test_proc_read, - .write = kgdb_test_proc_write, + .owner = THIS_MODULE, + .read = kgdb_test_proc_read, + .write = kgdb_test_proc_write, }; static int __init kgdbtest_init(void) @@ -100,6 +97,7 @@ static int __init kgdbtest_init(void) entry = proc_create("kgdbtest", 0, NULL, &kgdb_test_proc_fops); if (entry == NULL) return -ENOMEM; + return 0; } -- cgit v0.10.2 From d1be2e485bfb5e3ee3ef5d2131f0151f9a3c4387 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Tue, 8 Dec 2009 09:55:37 +0000 Subject: Blackfin: add support for TIF_NOTIFY_RESUME Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h index afb3a86..a40d936 100644 --- a/arch/blackfin/include/asm/thread_info.h +++ b/arch/blackfin/include/asm/thread_info.h @@ -103,11 +103,13 @@ static inline struct thread_info *current_thread_info(void) #define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ #define TIF_FREEZE 6 /* is freezing for suspend */ #define TIF_IRQ_SYNC 7 /* sync pipeline stage */ +#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */ /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1< #include #include +#include #include #include @@ -332,3 +333,20 @@ asmlinkage void do_signal(struct pt_regs *regs) sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } } + +/* + * notification of userspace execution resumption + */ +asmlinkage void do_notify_resume(struct pt_regs *regs) +{ + if (test_thread_flag(TIF_SIGPENDING) || test_thread_flag(TIF_RESTORE_SIGMASK)) + do_signal(regs); + + if (test_thread_flag(TIF_NOTIFY_RESUME)) { + clear_thread_flag(TIF_NOTIFY_RESUME); + tracehook_notify_resume(regs); + if (current->replacement_session_keyring) + key_replace_session_keyring(); + } +} + diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index f3f8bb4..b0ed0b4 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -713,6 +713,8 @@ ENTRY(_system_call) cc = BITTST(r7, TIF_RESTORE_SIGMASK); if cc jump .Lsyscall_do_signals; cc = BITTST(r7, TIF_SIGPENDING); + if cc jump .Lsyscall_do_signals; + cc = BITTST(r7, TIF_NOTIFY_RESUME); if !cc jump .Lsyscall_really_exit; .Lsyscall_do_signals: /* Reenable interrupts. */ @@ -721,7 +723,7 @@ ENTRY(_system_call) r0 = sp; SP += -12; - call _do_signal; + call _do_notify_resume; SP += 12; .Lsyscall_really_exit: -- cgit v0.10.2 From 0a68b5341de1d80cf0ec8e6c9a851e4bfd99787c Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 12 Dec 2009 14:22:22 +0000 Subject: Blackfin: MPU: add missing __init markings Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c index b52c1f8..8d42b9e 100644 --- a/arch/blackfin/kernel/cplb-mpu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c @@ -92,6 +92,6 @@ void __init generate_cplb_tables_cpu(unsigned int cpu) icplb_tbl[cpu][i_i++].data = 0; } -void generate_cplb_tables_all(void) +void __init generate_cplb_tables_all(void) { } -- cgit v0.10.2 From a797a0e242b94548af8b41e6454349b515b66eca Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 12 Dec 2009 14:27:40 +0000 Subject: Blackfin: NOMPU: skip DMA ICPLB hole when it is redundant Normally there is no user-reserved memory after the DMA region which means there is no user-reserved ICPLB coverage. So the DMA hole can be covered by the large hole that is always added to cover up to the async bank. We only need an explicit DMA whole when we also add an explicit mapping for the user-reserved memory. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index c9b0a4d..282a791 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c @@ -147,12 +147,13 @@ void __init generate_cplb_tables_all(void) /* Normal RAM, including MTD FS. */ icplb_bounds[i_i].eaddr = uncached_end; icplb_bounds[i_i++].data = SDRAM_IGENERIC; - /* DMA uncached region. */ - if (DMA_UNCACHED_REGION) { - icplb_bounds[i_i].eaddr = _ramend; - icplb_bounds[i_i++].data = 0; - } if (_ramend != physical_mem_end) { + /* DMA uncached region. */ + if (DMA_UNCACHED_REGION) { + /* Normally this hole is caught by the async below. */ + icplb_bounds[i_i].eaddr = _ramend; + icplb_bounds[i_i++].data = 0; + } /* Reserved memory. */ icplb_bounds[i_i].eaddr = physical_mem_end; icplb_bounds[i_i++].data = (reserved_mem_icache_on ? -- cgit v0.10.2 From 8a833110f10f091a4aa09c9b81845726c2766473 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 14 Dec 2009 19:56:54 +0000 Subject: Blackfin: drop duplicate sched_clock The Blackfin sched_clock() func is pretty much a duplicate of the common version, so just punt it. Reported-by: David Miller Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c index bd3b53d..13c1ee3 100644 --- a/arch/blackfin/kernel/time.c +++ b/arch/blackfin/kernel/time.c @@ -184,11 +184,3 @@ void __init time_init(void) time_sched_init(timer_interrupt); } - -/* - * Scheduler clock - returns current time in nanosec units. - */ -unsigned long long sched_clock(void) -{ - return (unsigned long long)jiffies *(NSEC_PER_SEC / HZ); -} -- cgit v0.10.2 From 8bf2805918e9ee3ccdc18590fec0416a01d635c9 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 14 Dec 2009 01:53:41 +0000 Subject: x25: Update maintainer. On Monday 14 December 2009, andrew hendry wrote: > Thanks, I didn't know X.25 was actively maintained. I get bounces. > Is the the maintainers out of date? From looking at the posts on the x.25 mailing list and the changes that went into the kernel during the last three years in that area, I think it is safe to say that you are now the maintainer ;-). The last mail on this topic from Henner Eisen was around 2001. > AX.25 NETWORK LAYER > M: Ralf Baechle > > X.25 NETWORK LAYER > M: Henner Eisen How about this change? Signed-off-by: Andrew Hendry Signed-off-by: David S. Miller diff --git a/MAINTAINERS b/MAINTAINERS index 93a0743..256139e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5959,9 +5959,9 @@ F: sound/soc/codecs/wm8350.c F: sound/soc/codecs/wm8400.c X.25 NETWORK LAYER -M: Henner Eisen +M: Andrew Hendry L: linux-x25@vger.kernel.org -S: Maintained +S: Odd Fixes F: Documentation/networking/x25* F: include/net/x25* F: net/x25/ -- cgit v0.10.2 From 1abff64d49ae24a77ae1e191fa58b725c5991c7e Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 12 Nov 2009 19:26:14 +1100 Subject: sparc64: don't export static inline pci_ functions Exporting an inline function breaks the new assembler-based alphabetical sorted symbol list. Signed-off-by: Stephen Rothwell Signed-off-by: Rusty Russell diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index b85374f..539e83f 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -1064,7 +1064,6 @@ int pci64_dma_supported(struct pci_dev *pdev, u64 device_mask) return (device_mask & dma_addr_mask) == dma_addr_mask; } -EXPORT_SYMBOL(pci_dma_supported); void pci_resource_to_user(const struct pci_dev *pdev, int bar, const struct resource *rp, resource_size_t *start, diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c index 0f26066..372ad59 100644 --- a/arch/sparc/kernel/sparc_ksyms_64.c +++ b/arch/sparc/kernel/sparc_ksyms_64.c @@ -38,17 +38,5 @@ EXPORT_SYMBOL(sun4v_niagara_setperf); EXPORT_SYMBOL(sun4v_niagara2_getperf); EXPORT_SYMBOL(sun4v_niagara2_setperf); -#ifdef CONFIG_PCI -/* inline functions in asm/pci_64.h */ -EXPORT_SYMBOL(pci_alloc_consistent); -EXPORT_SYMBOL(pci_free_consistent); -EXPORT_SYMBOL(pci_map_single); -EXPORT_SYMBOL(pci_unmap_single); -EXPORT_SYMBOL(pci_map_sg); -EXPORT_SYMBOL(pci_unmap_sg); -EXPORT_SYMBOL(pci_dma_sync_single_for_cpu); -EXPORT_SYMBOL(pci_dma_sync_sg_for_cpu); -#endif - /* Exporting a symbol from /init/main.c */ EXPORT_SYMBOL(saved_command_line); -- cgit v0.10.2 From e6428047725d72d63c1d9c4ba852e635e3ffe52a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 15 Dec 2009 16:28:13 -0600 Subject: x86: don't export inline function For CONFIG_PARAVIRT, load_gs_index is an inline function (it's #defined to native_load_gs_index otherwise). Exporting an inline function breaks the new assembler-based alphabetical sorted symbol list: Today's linux-next build (x86_64 allmodconfig) failed like this: .tmp_exports-asm.o: In function `__ksymtab_load_gs_index': (__ksymtab_sorted+0x5b40): undefined reference to `load_gs_index' Signed-off-by: Rusty Russell To: x86@kernel.org Cc: alan-jenkins@tuffmail.co.uk diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index a102976..084c1ad 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c @@ -56,4 +56,6 @@ EXPORT_SYMBOL(__memcpy); EXPORT_SYMBOL(empty_zero_page); EXPORT_SYMBOL(init_level4_pgt); -EXPORT_SYMBOL(load_gs_index); +#ifndef CONFIG_PARAVIRT +EXPORT_SYMBOL(native_load_gs_index); +#endif -- cgit v0.10.2 From e3f28c1333acfe9e4109b836bc15caf794e94d09 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Sat, 7 Nov 2009 21:03:52 +0000 Subject: ARM: use unified discard definition in linker script Commit 023bf6f "linker script: unify usage of discard definition" changed the linker scripts for all architectures except for ARM. I can find no discussion about this ommision, so here are the changes for ARM. These changes are exactly parallel to the ia64 case. "ia64 is notable because it first throws away some ia64 specific subsections and then include the rest of the sections into the final image, so those sections must be discarded before the inclusion." Not boot-tested. In build testing, the modified linker script generated an identical vmlinux file. [I would like to be able to rely on this unified discard definition. I want to sort the kernel symbol tables to allow faster symbol resolution during module loading. The simplest way appears to be to generate sorted versions from vmlinux.o, link them in to vmlinux, _and discard the original unsorted tables_. This work is driven by my x86 netbook, but it is implemented at a generic level. It is possible it will benefit some ARM systems also.] Signed-off-by: Alan Jenkins Acked-by: Russell King Acked-by-without-testing: Tejun Heo Signed-off-by: Rusty Russell diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 71151bd..4957e13e 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -65,11 +65,11 @@ SECTIONS __init_end = .; #endif - /DISCARD/ : { /* Exit code and data */ - EXIT_TEXT - EXIT_DATA - *(.exitcall.exit) - *(.discard) + /* + * unwind exit sections must be discarded before the rest of the + * unwind sections get included. + */ + /DISCARD/ : { *(.ARM.exidx.exit.text) *(.ARM.extab.exit.text) #ifndef CONFIG_HOTPLUG_CPU @@ -238,6 +238,9 @@ SECTIONS STABS_DEBUG .comment 0 : { *(.comment) } + + /* Default discards */ + DISCARDS } /* -- cgit v0.10.2 From 3e7b19efe621bcf8bfef896c9c4cc5c99c52c3ec Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Sat, 7 Nov 2009 21:03:53 +0000 Subject: ARM: unexport symbols used to implement floating point emulation The Kconfigs for in-tree floating point emulation do not allow building as modules. That leaves the Acorn FPEmulator module. I found two public releases of this as a binary module for 2.1 and 2.2 kernels, optimized for ARMV4.[1] If there is a resurgence of interest in this, the symbols can always be re-exported. This allows the EXPORT_SYMBOL_ALIAS() hack to be removed. The ulterior motive here is that EXPORT_SYMBOL_ALIAS() makes it harder to sort the resulting kernel symbol tables. Sorted symbol tables will allow faster symbol resolution during module loading. Note that fp_send_sigs() and fp_printk() are simply aliases for existing exports and add no obvious value. Similarly fp_enter could easily be renamed to kern_fp_enter at the point of definition. Therefore removing EXPORT_SYMBOL_ALIAS will not serve as a material obstacle to re-adding the exports should they be desired in future. Build tested only. [1] http://ftp.arm.linux.org.uk/pub/linux/arm/fpemulator/ Signed-off-by: Alan Jenkins CC: Russell King Signed-off-by: Rusty Russell diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 0e62770..8214bfe 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -48,27 +48,7 @@ extern void __aeabi_uidivmod(void); extern void __aeabi_ulcmp(void); extern void fpundefinstr(void); -extern void fp_enter(void); -/* - * This has a special calling convention; it doesn't - * modify any of the usual registers, except for LR. - */ -#define EXPORT_CRC_ALIAS(sym) __CRC_SYMBOL(sym, "") - -#define EXPORT_SYMBOL_ALIAS(sym,orig) \ - EXPORT_CRC_ALIAS(sym) \ - static const struct kernel_symbol __ksymtab_##sym \ - __used __attribute__((section("__ksymtab"))) = \ - { (unsigned long)&orig, #sym }; - -/* - * floating point math emulator support. - * These symbols will never change their calling convention... - */ -EXPORT_SYMBOL_ALIAS(kern_fp_enter,fp_enter); -EXPORT_SYMBOL_ALIAS(fp_printk,printk); -EXPORT_SYMBOL_ALIAS(fp_send_sig,send_sig); EXPORT_SYMBOL(__backtrace); -- cgit v0.10.2 From 9e1b9b80721661bd63b3662453767b22cd614fe7 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Sat, 7 Nov 2009 21:03:54 +0000 Subject: module: make MODULE_SYMBOL_PREFIX into a CONFIG option The next commit will require the use of MODULE_SYMBOL_PREFIX in .tmp_exports-asm.S. Currently it is mixed in with C structure definitions in "asm/module.h". Move the definition of this arch option into Kconfig, so it can be easily accessed by any code. This also lets modpost.c use the same definition. Previously modpost relied on a hardcoded list of architectures in mk_elfconfig.c. A build test for blackfin, one of the two MODULE_SYMBOL_PREFIX archs, showed the generated code was unchanged. vmlinux was identical save for build ids, and an apparently randomized suffix on a single "__key" symbol in the kallsyms data). Signed-off-by: Alan Jenkins Acked-by: Mike Frysinger (blackfin) CC: Sam Ravnborg Signed-off-by: Rusty Russell diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index ae6a60f..2180433 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -5,6 +5,10 @@ mainmenu "Blackfin Kernel Configuration" +config SYMBOL_PREFIX + string + default "_" + config MMU def_bool n diff --git a/arch/blackfin/include/asm/module.h b/arch/blackfin/include/asm/module.h index 9c1cfff..4282b16 100644 --- a/arch/blackfin/include/asm/module.h +++ b/arch/blackfin/include/asm/module.h @@ -7,8 +7,6 @@ #ifndef _ASM_BFIN_MODULE_H #define _ASM_BFIN_MODULE_H -#define MODULE_SYMBOL_PREFIX "_" - #define Elf_Shdr Elf32_Shdr #define Elf_Sym Elf32_Sym #define Elf_Ehdr Elf32_Ehdr diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index 10e1253..f39707c 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S @@ -4,8 +4,6 @@ * Licensed under the GPL-2 or later */ -#define VMLINUX_SYMBOL(_sym_) _##_sym_ - #include #include #include diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 9420648..53cc669 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -10,6 +10,10 @@ config H8300 default y select HAVE_IDE +config SYMBOL_PREFIX + string + default "_" + config MMU bool default n diff --git a/arch/h8300/include/asm/module.h b/arch/h8300/include/asm/module.h index de23231..8e46724 100644 --- a/arch/h8300/include/asm/module.h +++ b/arch/h8300/include/asm/module.h @@ -8,6 +8,4 @@ struct mod_arch_specific { }; #define Elf_Sym Elf32_Sym #define Elf_Ehdr Elf32_Ehdr -#define MODULE_SYMBOL_PREFIX "_" - #endif /* _ASM_H8/300_MODULE_H */ diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S index b9e24907..03d356d 100644 --- a/arch/h8300/kernel/vmlinux.lds.S +++ b/arch/h8300/kernel/vmlinux.lds.S @@ -1,4 +1,3 @@ -#define VMLINUX_SYMBOL(_sym_) _##_sym_ #include #include diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index b6e818f..67e6520 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -52,8 +52,12 @@ #define LOAD_OFFSET 0 #endif -#ifndef VMLINUX_SYMBOL -#define VMLINUX_SYMBOL(_sym_) _sym_ +#ifndef SYMBOL_PREFIX +#define VMLINUX_SYMBOL(sym) sym +#else +#define PASTE2(x,y) x##y +#define PASTE(x,y) PASTE2(x,y) +#define VMLINUX_SYMBOL(sym) PASTE(SYMBOL_PREFIX, sym) #endif /* Align . to a 8 byte boundary equals to maximum function alignment. */ diff --git a/include/linux/module.h b/include/linux/module.h index 482efc8..6cb1a3c 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -25,8 +25,10 @@ /* Not Yet Implemented */ #define MODULE_SUPPORTED_DEVICE(name) -/* some toolchains uses a `_' prefix for all user symbols */ -#ifndef MODULE_SYMBOL_PREFIX +/* Some toolchains use a `_' prefix for all user symbols. */ +#ifdef CONFIG_SYMBOL_PREFIX +#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX +#else #define MODULE_SYMBOL_PREFIX "" #endif diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index ffdafb2..224d85e 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -127,6 +127,11 @@ _c_flags += $(if $(patsubst n%,, \ $(CFLAGS_GCOV)) endif +ifdef CONFIG_SYMBOL_PREFIX +_cpp_flags += -DSYMBOL_PREFIX=$(patsubst "%",%,$(CONFIG_SYMBOL_PREFIX)) +endif + + # If building the kernel in a separate objtree expand all occurrences # of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/'). diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile index 11d69c3..ff954f8 100644 --- a/scripts/mod/Makefile +++ b/scripts/mod/Makefile @@ -8,7 +8,7 @@ modpost-objs := modpost.o file2alias.o sumversion.o $(obj)/modpost.o $(obj)/file2alias.o $(obj)/sumversion.o: $(obj)/elfconfig.h quiet_cmd_elfconfig = MKELF $@ - cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@ + cmd_elfconfig = $(obj)/mk_elfconfig < $< > $@ $(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE $(call if_changed,elfconfig) diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c index 6a96d47..639bca7 100644 --- a/scripts/mod/mk_elfconfig.c +++ b/scripts/mod/mk_elfconfig.c @@ -9,9 +9,6 @@ main(int argc, char **argv) unsigned char ei[EI_NIDENT]; union { short s; char c[2]; } endian_test; - if (argc != 2) { - fprintf(stderr, "Error: no arch\n"); - } if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) { fprintf(stderr, "Error: input truncated\n"); return 1; @@ -55,12 +52,6 @@ main(int argc, char **argv) else exit(1); - if ((strcmp(argv[1], "h8300") == 0) - || (strcmp(argv[1], "blackfin") == 0)) - printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); - else - printf("#define MODULE_SYMBOL_PREFIX \"\"\n"); - return 0; } diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 801a16a..fb0f9b7 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -15,8 +15,17 @@ #include #include #include "modpost.h" +#include "../../include/linux/autoconf.h" #include "../../include/linux/license.h" +/* Some toolchains use a `_' prefix for all user symbols. */ +#ifdef CONFIG_SYMBOL_PREFIX +#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX +#else +#define MODULE_SYMBOL_PREFIX "" +#endif + + /* Are we using CONFIG_MODVERSIONS? */ int modversions = 0; /* Warn about undefined symbols? (do so if we have vmlinux) */ -- cgit v0.10.2 From a8773769d1a1e08d0ca15f890515401ab3860637 Mon Sep 17 00:00:00 2001 From: Wenji Huang Date: Mon, 16 Nov 2009 13:49:55 +0800 Subject: Kbuild: clear marker out of modpost Remove the unnecessary functions and variables. Signed-off-by: Wenji Huang Signed-off-by: Michal Marek Signed-off-by: Rusty Russell diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index fb0f9b7..c16c0a0 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -460,8 +460,6 @@ static int parse_elf(struct elf_info *info, const char *filename) info->export_unused_gpl_sec = i; else if (strcmp(secname, "__ksymtab_gpl_future") == 0) info->export_gpl_future_sec = i; - else if (strcmp(secname, "__markers_strings") == 0) - info->markers_strings_sec = i; if (sechdrs[i].sh_type != SHT_SYMTAB) continue; @@ -1518,62 +1516,6 @@ static void check_sec_ref(struct module *mod, const char *modname, } } -static void get_markers(struct elf_info *info, struct module *mod) -{ - const Elf_Shdr *sh = &info->sechdrs[info->markers_strings_sec]; - const char *strings = (const char *) info->hdr + sh->sh_offset; - const Elf_Sym *sym, *first_sym, *last_sym; - size_t n; - - if (!info->markers_strings_sec) - return; - - /* - * First count the strings. We look for all the symbols defined - * in the __markers_strings section named __mstrtab_*. For - * these local names, the compiler puts a random .NNN suffix on, - * so the names don't correspond exactly. - */ - first_sym = last_sym = NULL; - n = 0; - for (sym = info->symtab_start; sym < info->symtab_stop; sym++) - if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT && - sym->st_shndx == info->markers_strings_sec && - !strncmp(info->strtab + sym->st_name, - "__mstrtab_", sizeof "__mstrtab_" - 1)) { - if (first_sym == NULL) - first_sym = sym; - last_sym = sym; - ++n; - } - - if (n == 0) - return; - - /* - * Now collect each name and format into a line for the output. - * Lines look like: - * marker_name vmlinux marker %s format %d - * The format string after the second \t can use whitespace. - */ - mod->markers = NOFAIL(malloc(sizeof mod->markers[0] * n)); - mod->nmarkers = n; - - n = 0; - for (sym = first_sym; sym <= last_sym; sym++) - if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT && - sym->st_shndx == info->markers_strings_sec && - !strncmp(info->strtab + sym->st_name, - "__mstrtab_", sizeof "__mstrtab_" - 1)) { - const char *name = strings + sym->st_value; - const char *fmt = strchr(name, '\0') + 1; - char *line = NULL; - asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt); - NOFAIL(line); - mod->markers[n++] = line; - } -} - static void read_symbols(char *modname) { const char *symname; @@ -1629,8 +1571,6 @@ static void read_symbols(char *modname) get_src_version(modname, mod->srcversion, sizeof(mod->srcversion)-1); - get_markers(&info, mod); - parse_elf_finish(&info); /* Our trick to get versioning for module struct etc. - it's @@ -1985,96 +1925,6 @@ static void write_dump(const char *fname) write_if_changed(&buf, fname); } -static void add_marker(struct module *mod, const char *name, const char *fmt) -{ - char *line = NULL; - asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt); - NOFAIL(line); - - mod->markers = NOFAIL(realloc(mod->markers, ((mod->nmarkers + 1) * - sizeof mod->markers[0]))); - mod->markers[mod->nmarkers++] = line; -} - -static void read_markers(const char *fname) -{ - unsigned long size, pos = 0; - void *file = grab_file(fname, &size); - char *line; - - if (!file) /* No old markers, silently ignore */ - return; - - while ((line = get_next_line(&pos, file, size))) { - char *marker, *modname, *fmt; - struct module *mod; - - marker = line; - modname = strchr(marker, '\t'); - if (!modname) - goto fail; - *modname++ = '\0'; - fmt = strchr(modname, '\t'); - if (!fmt) - goto fail; - *fmt++ = '\0'; - if (*marker == '\0' || *modname == '\0') - goto fail; - - mod = find_module(modname); - if (!mod) { - mod = new_module(modname); - mod->skip = 1; - } - if (is_vmlinux(modname)) { - have_vmlinux = 1; - mod->skip = 0; - } - - if (!mod->skip) - add_marker(mod, marker, fmt); - } - release_file(file, size); - return; -fail: - fatal("parse error in markers list file\n"); -} - -static int compare_strings(const void *a, const void *b) -{ - return strcmp(*(const char **) a, *(const char **) b); -} - -static void write_markers(const char *fname) -{ - struct buffer buf = { }; - struct module *mod; - size_t i; - - for (mod = modules; mod; mod = mod->next) - if ((!external_module || !mod->skip) && mod->markers != NULL) { - /* - * Sort the strings so we can skip duplicates when - * we write them out. - */ - qsort(mod->markers, mod->nmarkers, - sizeof mod->markers[0], &compare_strings); - for (i = 0; i < mod->nmarkers; ++i) { - char *line = mod->markers[i]; - buf_write(&buf, line, strlen(line)); - while (i + 1 < mod->nmarkers && - !strcmp(mod->markers[i], - mod->markers[i + 1])) - free(mod->markers[i++]); - free(mod->markers[i]); - } - free(mod->markers); - mod->markers = NULL; - } - - write_if_changed(&buf, fname); -} - struct ext_sym_list { struct ext_sym_list *next; const char *file; @@ -2086,8 +1936,6 @@ int main(int argc, char **argv) struct buffer buf = { }; char *kernel_read = NULL, *module_read = NULL; char *dump_write = NULL; - char *markers_read = NULL; - char *markers_write = NULL; int opt; int err; struct ext_sym_list *extsym_iter; @@ -2131,12 +1979,6 @@ int main(int argc, char **argv) case 'w': warn_unresolved = 1; break; - case 'M': - markers_write = optarg; - break; - case 'K': - markers_read = optarg; - break; default: exit(1); } @@ -2191,11 +2033,5 @@ int main(int argc, char **argv) "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n", sec_mismatch_count); - if (markers_read) - read_markers(markers_read); - - if (markers_write) - write_markers(markers_write); - return err; } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 09f58e3..be987a4 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -112,8 +112,6 @@ struct module { int has_init; int has_cleanup; struct buffer dev_table_buf; - char **markers; - size_t nmarkers; char srcversion[25]; }; @@ -128,7 +126,6 @@ struct elf_info { Elf_Section export_gpl_sec; Elf_Section export_unused_gpl_sec; Elf_Section export_gpl_future_sec; - Elf_Section markers_strings_sec; const char *strtab; char *modinfo; unsigned int modinfo_len; -- cgit v0.10.2 From d4703aefdbc8f9f347f6dcefcddd791294314eb7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 15 Dec 2009 16:28:32 -0600 Subject: module: handle ppc64 relocating kcrctabs when CONFIG_RELOCATABLE=y powerpc applies relocations to the kcrctab. They're absolute symbols, but it's not completely unreasonable: other archs may too, but the relocation is often 0. http://lists.ozlabs.org/pipermail/linuxppc-dev/2009-November/077972.html Inspired-by: Neil Horman Signed-off-by: Rusty Russell Tested-by: Neil Horman Acked-by: Paul Mackerras diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h index 0845488..0192a4e 100644 --- a/arch/powerpc/include/asm/module.h +++ b/arch/powerpc/include/asm/module.h @@ -87,5 +87,10 @@ struct exception_table_entry; void sort_ex_table(struct exception_table_entry *start, struct exception_table_entry *finish); +#ifdef CONFIG_MODVERSIONS +#define ARCH_RELOCATES_KCRCTAB + +extern const unsigned long reloc_start[]; +#endif #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_MODULE_H */ diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 27735a7..dcd01c8 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -38,6 +38,9 @@ jiffies = jiffies_64 + 4; #endif SECTIONS { + . = 0; + reloc_start = .; + . = KERNELBASE; /* diff --git a/kernel/module.c b/kernel/module.c index 12afc5a..a65dc78 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -880,11 +880,23 @@ static int try_to_force_load(struct module *mod, const char *reason) } #ifdef CONFIG_MODVERSIONS +/* If the arch applies (non-zero) relocations to kernel kcrctab, unapply it. */ +static unsigned long maybe_relocated(unsigned long crc, + const struct module *crc_owner) +{ +#ifdef ARCH_RELOCATES_KCRCTAB + if (crc_owner == NULL) + return crc - (unsigned long)reloc_start; +#endif + return crc; +} + static int check_version(Elf_Shdr *sechdrs, unsigned int versindex, const char *symname, struct module *mod, - const unsigned long *crc) + const unsigned long *crc, + const struct module *crc_owner) { unsigned int i, num_versions; struct modversion_info *versions; @@ -905,10 +917,10 @@ static int check_version(Elf_Shdr *sechdrs, if (strcmp(versions[i].name, symname) != 0) continue; - if (versions[i].crc == *crc) + if (versions[i].crc == maybe_relocated(*crc, crc_owner)) return 1; DEBUGP("Found checksum %lX vs module %lX\n", - *crc, versions[i].crc); + maybe_relocated(*crc, crc_owner), versions[i].crc); goto bad_version; } @@ -931,7 +943,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs, if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL, &crc, true, false)) BUG(); - return check_version(sechdrs, versindex, "module_layout", mod, crc); + return check_version(sechdrs, versindex, "module_layout", mod, crc, + NULL); } /* First part is kernel version, which we ignore if module has crcs. */ @@ -949,7 +962,8 @@ static inline int check_version(Elf_Shdr *sechdrs, unsigned int versindex, const char *symname, struct module *mod, - const unsigned long *crc) + const unsigned long *crc, + const struct module *crc_owner) { return 1; } @@ -984,8 +998,8 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs, /* use_module can fail due to OOM, or module initialization or unloading */ if (sym) { - if (!check_version(sechdrs, versindex, name, mod, crc) || - !use_module(mod, owner)) + if (!check_version(sechdrs, versindex, name, mod, crc, owner) + || !use_module(mod, owner)) sym = NULL; } return sym; -- cgit v0.10.2 From 8d99513c1b76cfd0b2dcf061c5136cb1061e6b37 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Sat, 12 Dec 2009 12:02:24 +0100 Subject: modpost: fix segfault with short symbol names memcmp() is wrong here, the symbol name can be shorter than KSYMTAB_PFX or CRC_PFX. Signed-off-by: Michal Marek Signed-off-by: Rusty Russell diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c16c0a0..6c4ffc7 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -522,7 +522,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, break; case SHN_ABS: /* CRC'd symbol */ - if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { + if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { crc = (unsigned int) sym->st_value; sym_update_crc(symname + strlen(CRC_PFX), mod, crc, export); @@ -566,7 +566,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, break; default: /* All exported symbols */ - if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { + if (strncmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { sym_add_exported(symname + strlen(KSYMTAB_PFX), mod, export); } -- cgit v0.10.2 From dae3a5112d258764cad9e48439ca7dd05c2edca1 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 14 Dec 2009 08:33:47 +0000 Subject: sky2: print Optima chip name Off by one in name lookup makes Optima display as (chip 0xbc) Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 89a05d6..9431f64 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -4530,7 +4530,7 @@ static const char *sky2_name(u8 chipid, char *buf, int sz) "Optima", /* 0xbc */ }; - if (chipid >= CHIP_ID_YUKON_XL && chipid < CHIP_ID_YUKON_OPT) + if (chipid >= CHIP_ID_YUKON_XL && chipid <= CHIP_ID_YUKON_OPT) strncpy(buf, name[chipid - CHIP_ID_YUKON_XL], sz); else snprintf(buf, sz, "(chip %#x)", chipid); -- cgit v0.10.2 From 166a0fd4c788ec7f10ca8194ec6d526afa12db75 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 14 Dec 2009 08:50:12 +0000 Subject: sky2: leave PCI config space writeable Since power management is done by PCI subsystem as well as driver, don't toggle the bit that disables PCI register writes. Signed-off-by: Stephen Hemminger Acked-by: Rafael J. Wysocki Signed-off-by: David S. Miller diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 9431f64..1c01b96 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -644,7 +644,6 @@ static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port) { u32 reg1; - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); reg1 &= ~phy_power[port]; @@ -652,7 +651,6 @@ static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port) reg1 |= coma_mode[port]; sky2_pci_write32(hw, PCI_DEV_REG1, reg1); - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); sky2_pci_read32(hw, PCI_DEV_REG1); if (hw->chip_id == CHIP_ID_YUKON_FE) @@ -709,11 +707,9 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port) gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_PDOWN); } - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); reg1 |= phy_power[port]; /* set PHY to PowerDown/COMA Mode */ sky2_pci_write32(hw, PCI_DEV_REG1, reg1); - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } /* Force a renegotiation */ @@ -2152,9 +2148,7 @@ static void sky2_qlink_intr(struct sky2_hw *hw) /* reset PHY Link Detect */ phy = sky2_pci_read16(hw, PSM_CONFIG_REG4); - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); sky2_pci_write16(hw, PSM_CONFIG_REG4, phy | 1); - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); sky2_link_up(sky2); } @@ -2645,7 +2639,6 @@ static void sky2_hw_intr(struct sky2_hw *hw) if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) { u16 pci_err; - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); pci_err = sky2_pci_read16(hw, PCI_STATUS); if (net_ratelimit()) dev_err(&pdev->dev, "PCI hardware error (0x%x)\n", @@ -2653,14 +2646,12 @@ static void sky2_hw_intr(struct sky2_hw *hw) sky2_pci_write16(hw, PCI_STATUS, pci_err | PCI_STATUS_ERROR_BITS); - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } if (status & Y2_IS_PCI_EXP) { /* PCI-Express uncorrectable Error occurred */ u32 err; - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS); sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS, 0xfffffffful); @@ -2668,7 +2659,6 @@ static void sky2_hw_intr(struct sky2_hw *hw) dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err); sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS); - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } if (status & Y2_HWE_L1_MASK) @@ -3047,7 +3037,6 @@ static void sky2_reset(struct sky2_hw *hw) } sky2_power_on(hw); - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); for (i = 0; i < hw->ports; i++) { sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); @@ -3084,7 +3073,6 @@ static void sky2_reset(struct sky2_hw *hw) reg <<= PSM_CONFIG_REG4_TIMER_PHY_LINK_DETECT_BASE; /* reset PHY Link Detect */ - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); sky2_pci_write16(hw, PSM_CONFIG_REG4, reg | PSM_CONFIG_REG4_RST_PHY_LINK_DETECT); sky2_pci_write16(hw, PSM_CONFIG_REG4, reg); @@ -3102,7 +3090,6 @@ static void sky2_reset(struct sky2_hw *hw) /* restore the PCIe Link Control register */ sky2_pci_write16(hw, cap + PCI_EXP_LNKCTL, reg); } - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); /* re-enable PEX PM in PEX PHY debug reg. 8 (clear bit 12) */ sky2_write32(hw, Y2_PEX_PHY_DATA, PEX_DB_ACCESS | (0x08UL << 16)); -- cgit v0.10.2 From e36c54582c6f14adc9e10473e2aec2cc4f0acc03 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 14 Dec 2009 15:58:33 -0500 Subject: tracing: Fix return of trace_dump_stack() The trace_dump_stack() returned a value for a void function. Also, added the missing stub for trace_dump_stack() when tracing is not configured. Reported-by: Ingo Molnar LKML-Reference: <20091214162713.GA31060@elte.hu> Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 5ad4199..f1dc752 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -527,6 +527,7 @@ trace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); static inline void tracing_start(void) { } static inline void tracing_stop(void) { } static inline void ftrace_off_permanent(void) { } +static inline void trace_dump_stack(void) { } static inline int trace_printk(const char *fmt, ...) { diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index bd7b969..ee61915 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1158,7 +1158,7 @@ void trace_dump_stack(void) unsigned long flags; if (tracing_disabled || tracing_selftest_running) - return 0; + return; local_save_flags(flags); -- cgit v0.10.2 From f823e441ab4dfaeaf17832fa1931e0dc0fde304d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 14 Dec 2009 15:06:01 -0200 Subject: perf session: Event statistics also are per session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260810361-22828-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 1f1341f..fa833f5 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -487,7 +487,7 @@ static int __cmd_annotate(void) dsos__fprintf(stdout); perf_session__collapse_resort(session); - perf_session__output_resort(session, event__total[0]); + perf_session__output_resort(session, session->event_total[0]); perf_session__find_annotations(session); out_delete: perf_session__delete(session); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 142c475..d12ea4a 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -619,8 +619,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) return -1; } - event__stats.total += data.period; - + session->events_stats.total += data.period; return 0; } @@ -731,8 +730,8 @@ static int __cmd_report(void) dsos__fprintf(stdout); perf_session__collapse_resort(session); - perf_session__output_resort(session, event__stats.total); - perf_session__fprintf_hist_entries(session, event__stats.total, stdout); + perf_session__output_resort(session, session->events_stats.total); + perf_session__fprintf_hist_entries(session, session->events_stats.total, stdout); if (show_threads) perf_read_values_destroy(&show_threads_values); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 9ee976d..07da665 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -96,8 +96,8 @@ static int process_sample_event(event_t *event, struct perf_session *session) data.raw_size, data.time, thread->comm); } - event__stats.total += data.period; + session->events_stats.total += data.period; return 0; } diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 222efb1..375fb6d 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -187,8 +187,6 @@ void event__synthesize_threads(int (*process)(event_t *event, closedir(proc); } -struct events_stats event__stats; - int event__process_comm(event_t *self, struct perf_session *session) { struct thread *thread = perf_session__findnew(session, self->comm.pid); @@ -203,10 +201,10 @@ int event__process_comm(event_t *self, struct perf_session *session) return 0; } -int event__process_lost(event_t *self, struct perf_session *session __used) +int event__process_lost(event_t *self, struct perf_session *session) { dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost); - event__stats.lost += self->lost.lost; + session->events_stats.lost += self->lost.lost; return 0; } diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 035ecf3..a92e0b0 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -168,11 +168,6 @@ void event__synthesize_threads(int (*process)(event_t *event, struct perf_session *session), struct perf_session *session); -extern char *event__cwd; -extern int event__cwdlen; -extern struct events_stats event__stats; -extern unsigned long event__total[PERF_RECORD_MAX]; - int event__process_comm(event_t *self, struct perf_session *session); int event__process_lost(event_t *self, struct perf_session *session); int event__process_mmap(event_t *self, struct perf_session *session); diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 4e8a21c..bdfc4b8 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -5,6 +5,7 @@ #include "header.h" #include "thread.h" #include +#include "../../../include/linux/perf_event.h" struct ip_callchain; struct thread; @@ -18,6 +19,8 @@ struct perf_session { struct map_groups kmaps; struct rb_root threads; struct thread *last_match; + struct events_stats events_stats; + unsigned long event_total[PERF_RECORD_MAX]; struct rb_root hists; u64 sample_type; int fd; -- cgit v0.10.2 From c8829c7a31c7e0156b230fa8d5a14be9881d7677 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 14 Dec 2009 20:09:29 -0200 Subject: perf util: Remove setup_sorting dups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And it is also needed by 'perf diff'. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260828571-3613-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index fa833f5..2e2855a 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -521,21 +521,6 @@ static const struct option options[] = { OPT_END() }; -static void setup_sorting(void) -{ - char *tmp, *tok, *str = strdup(sort_order); - - for (tok = strtok_r(str, ", ", &tmp); - tok; tok = strtok_r(NULL, ", ", &tmp)) { - if (sort_dimension__add(tok) < 0) { - error("Unknown --sort key: `%s'", tok); - usage_with_options(annotate_usage, options); - } - } - - free(str); -} - int cmd_annotate(int argc, const char **argv, const char *prefix __used) { if (symbol__init(&symbol_conf) < 0) @@ -543,7 +528,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used) argc = parse_options(argc, argv, options, annotate_usage, 0); - setup_sorting(); + setup_sorting(annotate_usage, options); if (argc) { /* diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index d12ea4a..beff7c0 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -843,21 +843,6 @@ static const struct option options[] = { OPT_END() }; -static void setup_sorting(void) -{ - char *tmp, *tok, *str = strdup(sort_order); - - for (tok = strtok_r(str, ", ", &tmp); - tok; tok = strtok_r(NULL, ", ", &tmp)) { - if (sort_dimension__add(tok) < 0) { - error("Unknown --sort key: `%s'", tok); - usage_with_options(report_usage, options); - } - } - - free(str); -} - static void setup_list(struct strlist **list, const char *list_str, struct sort_entry *se, const char *list_name, FILE *fp) @@ -884,7 +869,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) argc = parse_options(argc, argv, options, report_usage, 0); - setup_sorting(); + setup_sorting(report_usage, options); if (parent_pattern != default_parent_pattern) { sort_dimension__add("parent"); diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index b490354..cff1c31 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -288,3 +288,18 @@ int sort_dimension__add(const char *tok) return -ESRCH; } + +void setup_sorting(const char * const usagestr[], const struct option *opts) +{ + char *tmp, *tok, *str = strdup(sort_order); + + for (tok = strtok_r(str, ", ", &tmp); + tok; tok = strtok_r(NULL, ", ", &tmp)) { + if (sort_dimension__add(tok) < 0) { + error("Unknown --sort key: `%s'", tok); + usage_with_options(usagestr, opts); + } + } + + free(str); +} diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 333e664..cb6151c 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -81,6 +81,8 @@ struct sort_entry { extern struct sort_entry sort_thread; extern struct list_head hist_entry__sort_list; +void setup_sorting(const char * const usagestr[], const struct option *opts); + extern int repsep_fprintf(FILE *fp, const char *fmt, ...); extern size_t sort__thread_print(FILE *, struct hist_entry *, unsigned int); extern size_t sort__comm_print(FILE *, struct hist_entry *, unsigned int); -- cgit v0.10.2 From b38d34645cc52136b6c99623fef7ded26742e573 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 14 Dec 2009 20:09:30 -0200 Subject: perf record: Rename perf.data to perf.data.old if --force/-f is used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suggested-by: Steven Rostedt Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1260828571-3613-2-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index a66a58d..66979a5 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -421,10 +421,19 @@ static int __cmd_record(int argc, const char **argv) signal(SIGINT, sig_handler); if (!stat(output_name, &st) && st.st_size) { - if (!force && !append_file) { - fprintf(stderr, "Error, output file %s exists, use -A to append or -f to overwrite.\n", - output_name); - exit(-1); + if (!force) { + if (!append_file) { + pr_err("Error, output file %s exists, use -A " + "to append or -f to overwrite.\n", + output_name); + exit(-1); + } + } else { + char oldname[PATH_MAX]; + snprintf(oldname, sizeof(oldname), "%s.old", + output_name); + unlink(oldname); + rename(output_name, oldname); } } else { append_file = 0; -- cgit v0.10.2 From 86a9eee047ba09a714c3b8e27c9df2bbf715393a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 14 Dec 2009 20:09:31 -0200 Subject: perf diff: Introduce tool to show performance difference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I guess it is enough to show some examples: [root@doppio linux-2.6-tip]# rm -f perf.data* [root@doppio linux-2.6-tip]# ls -la perf.data* ls: cannot access perf.data*: No such file or directory [root@doppio linux-2.6-tip]# perf record -f find / > /dev/null [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.062 MB perf.data (~2699 samples) ] [root@doppio linux-2.6-tip]# ls -la perf.data* -rw------- 1 root root 74440 2009-12-14 20:03 perf.data [root@doppio linux-2.6-tip]# perf record -f find / > /dev/null [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.062 MB perf.data (~2692 samples) ] [root@doppio linux-2.6-tip]# ls -la perf.data* -rw------- 1 root root 74280 2009-12-14 20:03 perf.data -rw------- 1 root root 74440 2009-12-14 20:03 perf.data.old [root@doppio linux-2.6-tip]# perf diff | head -5 1 -34994580 /lib64/libc-2.10.1.so _IO_vfprintf_internal 2 -15307806 [kernel.kallsyms] __kmalloc 3 +1 +3665941 /lib64/libc-2.10.1.so __GI_memmove 4 +4 +23508995 /lib64/libc-2.10.1.so _int_malloc 5 +7 +38538813 [kernel.kallsyms] __d_lookup [root@doppio linux-2.6-tip]# perf diff -p | head -5 1 +1.00% /lib64/libc-2.10.1.so _IO_vfprintf_internal 2 [kernel.kallsyms] __kmalloc 3 +1 /lib64/libc-2.10.1.so __GI_memmove 4 +4 /lib64/libc-2.10.1.so _int_malloc 5 +7 -1.00% [kernel.kallsyms] __d_lookup [root@doppio linux-2.6-tip]# perf diff -v | head -5 1 361449551 326454971 -34994580 /lib64/libc-2.10.1.so _IO_vfprintf_internal 2 151009241 135701435 -15307806 [kernel.kallsyms] __kmalloc 3 +1 101805328 105471269 +3665941 /lib64/libc-2.10.1.so __GI_memmove 4 +4 78041440 101550435 +23508995 /lib64/libc-2.10.1.so _int_malloc 5 +7 59536172 98074985 +38538813 [kernel.kallsyms] __d_lookup [root@doppio linux-2.6-tip]# perf diff -vp | head -5 1 9.00% 8.00% +1.00% /lib64/libc-2.10.1.so _IO_vfprintf_internal 2 3.00% 3.00% [kernel.kallsyms] __kmalloc 3 +1 2.00% 2.00% /lib64/libc-2.10.1.so __GI_memmove 4 +4 2.00% 2.00% /lib64/libc-2.10.1.so _int_malloc 5 +7 1.00% 2.00% -1.00% [kernel.kallsyms] __d_lookup [root@doppio linux-2.6-tip]# This should be enough for diffs where the system is non volatile, i.e. when one doesn't updates binaries. For volatile environments, stay tuned for the next perf tool feature: a buildid cache populated by 'perf record', managed by 'perf buildid-cache' a-la ccache, and used by all the report tools. Signed-off-by: Arnaldo Carvalho de Melo Cc: "Paul E. McKenney" Cc: Stephen Hemminger Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Paul E. McKenney LKML-Reference: <1260828571-3613-3-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt new file mode 100644 index 0000000..bd1ee55 --- /dev/null +++ b/tools/perf/Documentation/perf-diff.txt @@ -0,0 +1,31 @@ +perf-diff(1) +============== + +NAME +---- +perf-diff - Read perf.data (created by perf record) and display the profile + +SYNOPSIS +-------- +[verse] +'perf diff' [oldfile] [newfile] + +DESCRIPTION +----------- +This command displays the performance difference among two perf.data files +captured via perf record. + +If no parameters are passed it will assume perf.data.old and perf.data. + +OPTIONS +------- +-p:: +--percentage:: + Show percentages instead of raw counters +-v:: +--verbose:: + Be verbose, for instance, show the raw counters in addition to the + diff. +SEE ALSO +-------- +linkperf:perf-record[1] diff --git a/tools/perf/Makefile b/tools/perf/Makefile index a4cb792..87a424e 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -427,6 +427,7 @@ BUILTIN_OBJS += bench/sched-messaging.o BUILTIN_OBJS += bench/sched-pipe.o BUILTIN_OBJS += bench/mem-memcpy.o +BUILTIN_OBJS += builtin-diff.o BUILTIN_OBJS += builtin-help.o BUILTIN_OBJS += builtin-sched.o BUILTIN_OBJS += builtin-buildid-list.o diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c new file mode 100644 index 0000000..0d52801 --- /dev/null +++ b/tools/perf/builtin-diff.c @@ -0,0 +1,288 @@ +/* + * builtin-diff.c + * + * Builtin diff command: Analyze two perf.data input files, look up and read + * DSOs and symbol information, sort them and produce a diff. + */ +#include "builtin.h" + +#include "util/debug.h" +#include "util/event.h" +#include "util/hist.h" +#include "util/session.h" +#include "util/sort.h" +#include "util/symbol.h" +#include "util/util.h" + +#include + +static char const *input_old = "perf.data.old", + *input_new = "perf.data"; +static int force; +static bool show_percent; + +struct symbol_conf symbol_conf; + +static int perf_session__add_hist_entry(struct perf_session *self, + struct addr_location *al, u64 count) +{ + bool hit; + struct hist_entry *he = __perf_session__add_hist_entry(self, al, NULL, + count, &hit); + if (he == NULL) + return -ENOMEM; + + if (hit) + he->count += count; + + return 0; +} + +static int diff__process_sample_event(event_t *event, struct perf_session *session) +{ + struct addr_location al; + struct sample_data data = { .period = 1, }; + + dump_printf("(IP, %d): %d: %p\n", event->header.misc, + event->ip.pid, (void *)(long)event->ip.ip); + + if (event__preprocess_sample(event, session, &al, NULL) < 0) { + pr_warning("problem processing %d event, skipping it.\n", + event->header.type); + return -1; + } + + event__parse_sample(event, session->sample_type, &data); + + if (al.sym && perf_session__add_hist_entry(session, &al, data.period)) { + pr_warning("problem incrementing symbol count, skipping event\n"); + return -1; + } + + session->events_stats.total += data.period; + return 0; +} + +static struct perf_event_ops event_ops = { + .process_sample_event = diff__process_sample_event, + .process_mmap_event = event__process_mmap, + .process_comm_event = event__process_comm, + .process_exit_event = event__process_task, + .process_fork_event = event__process_task, + .process_lost_event = event__process_lost, +}; + +static void perf_session__insert_hist_entry_by_name(struct rb_root *root, + struct hist_entry *he) +{ + struct rb_node **p = &root->rb_node; + struct rb_node *parent = NULL; + struct hist_entry *iter; + + while (*p != NULL) { + int cmp; + parent = *p; + iter = rb_entry(parent, struct hist_entry, rb_node); + + cmp = strcmp(he->map->dso->name, iter->map->dso->name); + if (cmp > 0) + p = &(*p)->rb_left; + else if (cmp < 0) + p = &(*p)->rb_right; + else { + cmp = strcmp(he->sym->name, iter->sym->name); + if (cmp > 0) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + } + + rb_link_node(&he->rb_node, parent, p); + rb_insert_color(&he->rb_node, root); +} + +static void perf_session__resort_by_name(struct perf_session *self) +{ + unsigned long position = 1; + struct rb_root tmp = RB_ROOT; + struct rb_node *next = rb_first(&self->hists); + + while (next != NULL) { + struct hist_entry *n = rb_entry(next, struct hist_entry, rb_node); + + next = rb_next(&n->rb_node); + rb_erase(&n->rb_node, &self->hists); + n->position = position++; + perf_session__insert_hist_entry_by_name(&tmp, n); + } + + self->hists = tmp; +} + +static struct hist_entry * +perf_session__find_hist_entry_by_name(struct perf_session *self, + struct hist_entry *he) +{ + struct rb_node *n = self->hists.rb_node; + + while (n) { + struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node); + int cmp = strcmp(he->map->dso->name, iter->map->dso->name); + + if (cmp > 0) + n = n->rb_left; + else if (cmp < 0) + n = n->rb_right; + else { + cmp = strcmp(he->sym->name, iter->sym->name); + if (cmp > 0) + n = n->rb_left; + else if (cmp < 0) + n = n->rb_right; + else + return iter; + } + } + + return NULL; +} + +static void perf_session__match_hists(struct perf_session *old_session, + struct perf_session *new_session) +{ + struct rb_node *nd; + + perf_session__resort_by_name(old_session); + + for (nd = rb_first(&new_session->hists); nd; nd = rb_next(nd)) { + struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node); + pos->pair = perf_session__find_hist_entry_by_name(old_session, pos); + } +} + +static size_t hist_entry__fprintf_matched(struct hist_entry *self, + unsigned long pos, + struct perf_session *session, + struct perf_session *pair_session, + FILE *fp) +{ + u64 old_count = 0; + char displacement[16]; + size_t printed; + + if (self->pair != NULL) { + long pdiff = (long)self->pair->position - (long)pos; + old_count = self->pair->count; + if (pdiff == 0) + goto blank; + snprintf(displacement, sizeof(displacement), "%+4ld", pdiff); + } else { +blank: memset(displacement, ' ', sizeof(displacement)); + } + + printed = fprintf(fp, "%4lu %5.5s ", pos, displacement); + + if (show_percent) { + double old_percent = (old_count * 100) / pair_session->events_stats.total, + new_percent = (self->count * 100) / session->events_stats.total; + double diff = old_percent - new_percent; + + if (verbose) + printed += fprintf(fp, " %3.2f%% %3.2f%%", old_percent, new_percent); + + if ((u64)diff != 0) + printed += fprintf(fp, " %+4.2F%%", diff); + else + printed += fprintf(fp, " "); + } else { + if (verbose) + printed += fprintf(fp, " %9Lu %9Lu", old_count, self->count); + printed += fprintf(fp, " %+9Ld", (s64)self->count - (s64)old_count); + } + + return printed + fprintf(fp, " %25.25s %s\n", + self->map->dso->name, self->sym->name); +} + +static size_t perf_session__fprintf_matched_hists(struct perf_session *self, + struct perf_session *pair, + FILE *fp) +{ + struct rb_node *nd; + size_t printed = 0; + unsigned long pos = 1; + + for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) { + struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); + printed += hist_entry__fprintf_matched(he, pos++, self, pair, fp); + } + + return printed; +} + +static int __cmd_diff(void) +{ + int ret, i; + struct perf_session *session[2]; + + session[0] = perf_session__new(input_old, O_RDONLY, force, &symbol_conf); + session[1] = perf_session__new(input_new, O_RDONLY, force, &symbol_conf); + if (session[0] == NULL || session[1] == NULL) + return -ENOMEM; + + for (i = 0; i < 2; ++i) { + ret = perf_session__process_events(session[i], &event_ops); + if (ret) + goto out_delete; + perf_session__output_resort(session[i], session[i]->events_stats.total); + } + + perf_session__match_hists(session[0], session[1]); + perf_session__fprintf_matched_hists(session[1], session[0], stdout); +out_delete: + for (i = 0; i < 2; ++i) + perf_session__delete(session[i]); + return ret; +} + +static const char *const diff_usage[] = { + "perf diff [] [old_file] [new_file]", +}; + +static const struct option options[] = { + OPT_BOOLEAN('v', "verbose", &verbose, + "be more verbose (show symbol address, etc)"), + OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, + "dump raw trace in ASCII"), + OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), + OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, + "load module symbols - WARNING: use only with -k and LIVE kernel"), + OPT_BOOLEAN('p', "percentages", &show_percent, + "Don't shorten the pathnames taking into account the cwd"), + OPT_BOOLEAN('P', "full-paths", &event_ops.full_paths, + "Don't shorten the pathnames taking into account the cwd"), + OPT_END() +}; + +int cmd_diff(int argc, const char **argv, const char *prefix __used) +{ + if (symbol__init(&symbol_conf) < 0) + return -1; + + setup_sorting(diff_usage, options); + + argc = parse_options(argc, argv, options, diff_usage, 0); + if (argc) { + if (argc > 2) + usage_with_options(diff_usage, options); + if (argc == 2) { + input_old = argv[0]; + input_new = argv[1]; + } else + input_new = argv[0]; + } + + setup_pager(); + return __cmd_diff(); +} diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h index a3d8bf6..18035b1 100644 --- a/tools/perf/builtin.h +++ b/tools/perf/builtin.h @@ -17,6 +17,7 @@ extern int check_pager_config(const char *cmd); extern int cmd_annotate(int argc, const char **argv, const char *prefix); extern int cmd_bench(int argc, const char **argv, const char *prefix); extern int cmd_buildid_list(int argc, const char **argv, const char *prefix); +extern int cmd_diff(int argc, const char **argv, const char *prefix); extern int cmd_help(int argc, const char **argv, const char *prefix); extern int cmd_sched(int argc, const char **argv, const char *prefix); extern int cmd_list(int argc, const char **argv, const char *prefix); diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt index 02b09ea..71dc7c3 100644 --- a/tools/perf/command-list.txt +++ b/tools/perf/command-list.txt @@ -5,6 +5,7 @@ perf-annotate mainporcelain common perf-bench mainporcelain common perf-buildid-list mainporcelain common +perf-diff mainporcelain common perf-list mainporcelain common perf-sched mainporcelain common perf-record mainporcelain common diff --git a/tools/perf/perf.c b/tools/perf/perf.c index cf64049..873e55f 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -286,6 +286,7 @@ static void handle_internal_command(int argc, const char **argv) const char *cmd = argv[0]; static struct cmd_struct commands[] = { { "buildid-list", cmd_buildid_list, 0 }, + { "diff", cmd_diff, 0 }, { "help", cmd_help, 0 }, { "list", cmd_list, 0 }, { "record", cmd_record, 0 }, diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index cb6151c..925f083 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -49,9 +49,13 @@ struct hist_entry { struct symbol *sym; u64 ip; char level; - struct symbol *parent; + struct symbol *parent; struct callchain_node callchain; - struct rb_root sorted_chain; + union { + unsigned long position; + struct hist_entry *pair; + struct rb_root sorted_chain; + }; }; enum sort_type { -- cgit v0.10.2 From c249a4ce796b30b742bb4854bf3039ced12ef8e5 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Tue, 15 Dec 2009 03:15:22 +0100 Subject: perf tools: Make symbol_conf static perf top, report and annotate all define their own symbol_conf, it should be static. Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras LKML-Reference: <1260843322-6602-1-git-send-regression-fweisbec@gmail.com> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index beff7c0..40389c0 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -52,7 +52,7 @@ static int exclude_other = 1; static char callchain_default_opt[] = "fractal,0.5"; -struct symbol_conf symbol_conf; +static struct symbol_conf symbol_conf; static size_t diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 3b212bb..296e809 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -80,7 +80,7 @@ static int dump_symtab = 0; static bool hide_kernel_symbols = false; static bool hide_user_symbols = false; static struct winsize winsize; -struct symbol_conf symbol_conf; +static struct symbol_conf symbol_conf; /* * Source -- cgit v0.10.2 From b9f8fcd55bbdb037e5332dbdb7b494f0b70861ac Mon Sep 17 00:00:00 2001 From: David Miller Date: Sun, 13 Dec 2009 18:25:02 -0800 Subject: sched: Fix cpu_clock() in NMIs, on !CONFIG_HAVE_UNSTABLE_SCHED_CLOCK Relax stable-sched-clock architectures to not save/disable/restore hardirqs in cpu_clock(). The background is that I was trying to resolve a sparc64 perf issue when I discovered this problem. On sparc64 I implement pseudo NMIs by simply running the kernel at IRQ level 14 when local_irq_disable() is called, this allows performance counter events to still come in at IRQ level 15. This doesn't work if any code in an NMI handler does local_irq_save() or local_irq_disable() since the "disable" will kick us back to cpu IRQ level 14 thus letting NMIs back in and we recurse. The only path which that does that in the perf event IRQ handling path is the code supporting frequency based events. It uses cpu_clock(). cpu_clock() simply invokes sched_clock() with IRQs disabled. And that's a fundamental bug all on it's own, particularly for the HAVE_UNSTABLE_SCHED_CLOCK case. NMIs can thus get into the sched_clock() code interrupting the local IRQ disable code sections of it. Furthermore, for the not-HAVE_UNSTABLE_SCHED_CLOCK case, the IRQ disabling done by cpu_clock() is just pure overhead and completely unnecessary. So the core problem is that sched_clock() is not NMI safe, but we are invoking it from NMI contexts in the perf events code (via cpu_clock()). A less important issue is the overhead of IRQ disabling when it isn't necessary in cpu_clock(). CONFIG_HAVE_UNSTABLE_SCHED_CLOCK architectures are not affected by this patch. Signed-off-by: David S. Miller Acked-by: Peter Zijlstra Cc: Mike Galbraith LKML-Reference: <20091213.182502.215092085.davem@davemloft.net> Signed-off-by: Ingo Molnar diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index 479ce56..5b49613 100644 --- a/kernel/sched_clock.c +++ b/kernel/sched_clock.c @@ -236,6 +236,18 @@ void sched_clock_idle_wakeup_event(u64 delta_ns) } EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event); +unsigned long long cpu_clock(int cpu) +{ + unsigned long long clock; + unsigned long flags; + + local_irq_save(flags); + clock = sched_clock_cpu(cpu); + local_irq_restore(flags); + + return clock; +} + #else /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */ void sched_clock_init(void) @@ -251,17 +263,12 @@ u64 sched_clock_cpu(int cpu) return sched_clock(); } -#endif /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */ unsigned long long cpu_clock(int cpu) { - unsigned long long clock; - unsigned long flags; + return sched_clock_cpu(cpu); +} - local_irq_save(flags); - clock = sched_clock_cpu(cpu); - local_irq_restore(flags); +#endif /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */ - return clock; -} EXPORT_SYMBOL_GPL(cpu_clock); -- cgit v0.10.2 From f74890277a196949e4004fe2955e1d4fb3930f98 Mon Sep 17 00:00:00 2001 From: Steve Soule Date: Mon, 14 Dec 2009 11:06:03 -0700 Subject: ALSA: ac97_codec - increase timeout for analog sections to 5 second I have a Soundblaster 16PCI. For many years, alsa has had a bug where not all of the card's controls are detected (many alsa versions, many kernel versions). In particular, Master Playback Volume is usually not detected, and so I get no sound or extremely faint sound. The problem has always been inconsistent: sometimes all of the controls are detected correctly, and sometimes a partial set is detected. It works correctly about 10% of the time. Finally, I got around to tracking down the problem. When the driver fails, it prints the kernel message "AC'97 0 analog subsections not ready". This message is generated from the function snd_ac97_mixer() in ac97_codec.c. The message indicates that the card failed to come back after reset within the time limit. The time limit is 120 milliseconds. I tried increasing the time limit to 1 second, and found that this made the driver work about 70% of the time. I tried increasing it to 5 seconds, and it now seems to work 100% of the time. I expect that this change would be completely harmless for existing cards that work, and would only introduce additional delay for cards that do not work. ALSA bug#4032. Signed-off-by: Steve Soule Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 20cb60a..c119206 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -2122,7 +2122,7 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, } /* nothing should be in powerdown mode */ snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0); - end_time = jiffies + msecs_to_jiffies(120); + end_time = jiffies + msecs_to_jiffies(5000); do { if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f) goto __ready_ok; -- cgit v0.10.2 From 5540a44e3ec5b738e9cf09d0c3a6f95328468701 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 15 Dec 2009 04:07:32 -0500 Subject: Blackfin: define __NR_recvmmsg Commit a2e2725541f added recvmmsg to a bunch of arches (including the Blackfin entry.S), but didn't actually add the new __NR_ define for it. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h index 779be02..22886cb 100644 --- a/arch/blackfin/include/asm/unistd.h +++ b/arch/blackfin/include/asm/unistd.h @@ -388,8 +388,9 @@ #define __NR_pwritev 367 #define __NR_rt_tgsigqueueinfo 368 #define __NR_perf_event_open 369 +#define __NR_recvmmsg 370 -#define __NR_syscall 370 +#define __NR_syscall 371 #define NR_syscalls __NR_syscall /* Old optional stuff no one actually uses */ -- cgit v0.10.2 From 66ae291978177d5c012015f12b8fbc76dc7d0965 Mon Sep 17 00:00:00 2001 From: Gui Jianfeng Date: Tue, 15 Dec 2009 10:08:45 +0100 Subject: cfq: set workload as expired if it doesn't have any slice left When a group is resumed, if it doesn't have workload slice left, we should set workload_expires as expired. Otherwise, we might start from where we left in previous group by error. Thanks the idea from Corrado. Signed-off-by: Gui Jianfeng Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index f3f6239..e2f8046 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -2113,7 +2113,9 @@ static void cfq_choose_cfqg(struct cfq_data *cfqd) cfqd->workload_expires = jiffies + cfqg->saved_workload_slice; cfqd->serving_type = cfqg->saved_workload; cfqd->serving_prio = cfqg->saved_serving_prio; - } + } else + cfqd->workload_expires = jiffies - 1; + choose_service_tree(cfqd, cfqg); } -- cgit v0.10.2 From 586bc5cce88be993dad584c3936c49f945368551 Mon Sep 17 00:00:00 2001 From: Tom Zanussi Date: Tue, 15 Dec 2009 02:53:35 -0600 Subject: perf trace/scripting: Add support for script args One oversight of the original scripting_ops patch was a lack of support for passing args to handler scripts. This adds argc/argv to the start_script() scripting_op, and changes the rw-by-file script to take 'comm' arg rather than the 'perf' value currently hard-coded. It also takes the opportunity to do some related minor cleanup. Signed-off-by: Tom Zanussi Cc: fweisbec@gmail.com Cc: rostedt@goodmis.org LKML-Reference: <1260867220-15699-2-git-send-email-tzanussi@gmail.com> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 07da665..88b0353 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -12,7 +12,9 @@ static char const *script_name; static char const *generate_script_lang; -static int default_start_script(const char *script __attribute((unused))) +static int default_start_script(const char *script __unused, + int argc __unused, + const char **argv __unused) { return 0; } @@ -22,7 +24,7 @@ static int default_stop_script(void) return 0; } -static int default_generate_script(const char *outfile __attribute ((unused))) +static int default_generate_script(const char *outfile __unused) { return 0; } @@ -302,15 +304,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) setup_scripting(); - argc = parse_options(argc, argv, options, annotate_usage, 0); - if (argc) { - /* - * Special case: if there's an argument left then assume tha - * it's a symbol filter: - */ - if (argc > 1) - usage_with_options(annotate_usage, options); - } + argc = parse_options(argc, argv, options, annotate_usage, + PARSE_OPT_STOP_AT_NON_OPTION); setup_pager(); @@ -350,7 +345,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) } if (script_name) { - err = scripting_ops->start_script(script_name); + err = scripting_ops->start_script(script_name, argc, argv); if (err) goto out; } diff --git a/tools/perf/scripts/perl/bin/rw-by-file-report b/tools/perf/scripts/perl/bin/rw-by-file-report index f5dcf9c..1c05675 100644 --- a/tools/perf/scripts/perl/bin/rw-by-file-report +++ b/tools/perf/scripts/perl/bin/rw-by-file-report @@ -1,5 +1,5 @@ #!/bin/bash -perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl +perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl $1 diff --git a/tools/perf/scripts/perl/rw-by-file.pl b/tools/perf/scripts/perl/rw-by-file.pl index 61f9156..2a39097 100644 --- a/tools/perf/scripts/perl/rw-by-file.pl +++ b/tools/perf/scripts/perl/rw-by-file.pl @@ -18,8 +18,9 @@ use lib "./Perf-Trace-Util/lib"; use Perf::Trace::Core; use Perf::Trace::Util; -# change this to the comm of the program you're interested in -my $for_comm = "perf"; +my $usage = "perf trace -s rw-by-file.pl \n"; + +my $for_comm = shift or die $usage; my %reads; my %writes; diff --git a/tools/perf/util/trace-event-perl.c b/tools/perf/util/trace-event-perl.c index a5ffe60..6f10e76 100644 --- a/tools/perf/util/trace-event-perl.c +++ b/tools/perf/util/trace-event-perl.c @@ -267,7 +267,7 @@ int common_lock_depth(struct scripting_context *context) } static void perl_process_event(int cpu, void *data, - int size __attribute((unused)), + int size __unused, unsigned long long nsecs, char *comm) { struct format_field *field; @@ -359,28 +359,42 @@ static void run_start_sub(void) /* * Start trace script */ -static int perl_start_script(const char *script) +static int perl_start_script(const char *script, int argc, const char **argv) { - const char *command_line[2] = { "", NULL }; + const char **command_line; + int i, err = 0; + command_line = malloc((argc + 2) * sizeof(const char *)); + command_line[0] = ""; command_line[1] = script; + for (i = 2; i < argc + 2; i++) + command_line[i] = argv[i - 2]; my_perl = perl_alloc(); perl_construct(my_perl); - if (perl_parse(my_perl, xs_init, 2, (char **)command_line, - (char **)NULL)) - return -1; + if (perl_parse(my_perl, xs_init, argc + 2, (char **)command_line, + (char **)NULL)) { + err = -1; + goto error; + } perl_run(my_perl); - if (SvTRUE(ERRSV)) - return -1; + if (SvTRUE(ERRSV)) { + err = -1; + goto error; + } run_start_sub(); + free(command_line); fprintf(stderr, "perf trace started with Perl script %s\n\n", script); - return 0; +error: + perl_free(my_perl); + free(command_line); + + return err; } /* @@ -579,7 +593,9 @@ static void print_unsupported_msg(void) "\n etc.\n"); } -static int perl_start_script_unsupported(const char *script __unused) +static int perl_start_script_unsupported(const char *script __unused, + int argc __unused, + const char **argv __unused) { print_unsupported_msg(); diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 81698d5..6ad4056 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -270,7 +270,7 @@ enum trace_flag_type { struct scripting_ops { const char *name; - int (*start_script) (const char *); + int (*start_script) (const char *script, int argc, const char **argv); int (*stop_script) (void); void (*process_event) (int cpu, void *data, int size, unsigned long long nsecs, char *comm); -- cgit v0.10.2 From a3a7cb7bb1d7bd989982314cf6f90ec392890006 Mon Sep 17 00:00:00 2001 From: Tom Zanussi Date: Tue, 15 Dec 2009 02:53:36 -0600 Subject: perf trace/scripting: Don't install unneeded files README and Makefile.PL don't need to be installed for Perl run-time support. Signed-off-by: Tom Zanussi Cc: fweisbec@gmail.com Cc: rostedt@goodmis.org LKML-Reference: <1260867220-15699-3-git-send-email-tzanussi@gmail.com> Signed-off-by: Ingo Molnar diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 87a424e..7814dbb 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -996,8 +996,6 @@ install: all $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace' $(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl' $(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin' - $(INSTALL) scripts/perl/Perf-Trace-Util/Makefile.PL -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util' - $(INSTALL) scripts/perl/Perf-Trace-Util/README -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util' ifdef BUILT_INS $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' $(INSTALL) $(BUILT_INS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' -- cgit v0.10.2 From 8f11d85a0e7e9025acea7493e6864089c8b52f42 Mon Sep 17 00:00:00 2001 From: Tom Zanussi Date: Tue, 15 Dec 2009 02:53:37 -0600 Subject: perf trace/scripting: Check return val of perl_run() The return value from perl_run() is currently ignored, but it should be checked and used to exit perf if there are problems loading the script. Signed-off-by: Tom Zanussi Cc: fweisbec@gmail.com Cc: rostedt@goodmis.org LKML-Reference: <1260867220-15699-4-git-send-email-tzanussi@gmail.com> Signed-off-by: Ingo Molnar diff --git a/tools/perf/util/trace-event-perl.c b/tools/perf/util/trace-event-perl.c index 6f10e76..6d6d76b 100644 --- a/tools/perf/util/trace-event-perl.c +++ b/tools/perf/util/trace-event-perl.c @@ -379,7 +379,11 @@ static int perl_start_script(const char *script, int argc, const char **argv) goto error; } - perl_run(my_perl); + if (perl_run(my_perl)) { + err = -1; + goto error; + } + if (SvTRUE(ERRSV)) { err = -1; goto error; -- cgit v0.10.2 From 4b9c0c596ea826ef784eb83f663c5351ed01ba6d Mon Sep 17 00:00:00 2001 From: Tom Zanussi Date: Tue, 15 Dec 2009 02:53:38 -0600 Subject: perf trace/scripting: List available scripts Lists the available perf trace scripts, one per line e.g.: root@tropicana:~# perf trace -l List of available trace scripts: workqueue-stats workqueue stats (ins/exe/create/destroy) wakeup-latency system-wide min/max/avg wakeup latency rw-by-file r/w activity for a program, by file check-perf-trace useless but exhaustive test script rw-by-pid system-wide r/w activity To be consistent with the other listing options in perf, the current latency trace option was changed to '-L', and '-l' is now used to access the script listing as: To create the list, it searches each scripts/*/bin directory for files ending with "-report" and reads information found in certain comment lines contained in those shell scripts: - if the comment line starts with "description:", the rest of the line is used as a 'half-line' description. To keep each line in the list to a single line, the description should be limited to 40 characters (the rest of the line contains the script name and args) - if the comment line starts with "args:", the rest of the line names the args the script supports. Required args should be surrounded by <> brackets, optional args by [] brackets. The current scripts in scripts/perl/bin have also been updated with description: and args: comments. Signed-off-by: Tom Zanussi Cc: fweisbec@gmail.com Cc: rostedt@goodmis.org LKML-Reference: <1260867220-15699-5-git-send-email-tzanussi@gmail.com> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 88b0353..7674153 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -274,6 +274,201 @@ static int parse_scriptname(const struct option *opt __used, return 0; } +#define for_each_lang(scripts_dir, lang_dirent, lang_next) \ + while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) && \ + lang_next) \ + if (lang_dirent.d_type == DT_DIR && \ + (strcmp(lang_dirent.d_name, ".")) && \ + (strcmp(lang_dirent.d_name, ".."))) + +#define for_each_script(lang_dir, script_dirent, script_next) \ + while (!readdir_r(lang_dir, &script_dirent, &script_next) && \ + script_next) \ + if (script_dirent.d_type != DT_DIR) + + +#define RECORD_SUFFIX "-record" +#define REPORT_SUFFIX "-report" + +struct script_desc { + struct list_head node; + char *name; + char *half_liner; + char *args; +}; + +LIST_HEAD(script_descs); + +static struct script_desc *script_desc__new(const char *name) +{ + struct script_desc *s = zalloc(sizeof(*s)); + + if (s != NULL) + s->name = strdup(name); + + return s; +} + +static void script_desc__delete(struct script_desc *s) +{ + free(s->name); + free(s); +} + +static void script_desc__add(struct script_desc *s) +{ + list_add_tail(&s->node, &script_descs); +} + +static struct script_desc *script_desc__find(const char *name) +{ + struct script_desc *s; + + list_for_each_entry(s, &script_descs, node) + if (strcasecmp(s->name, name) == 0) + return s; + return NULL; +} + +static struct script_desc *script_desc__findnew(const char *name) +{ + struct script_desc *s = script_desc__find(name); + + if (s) + return s; + + s = script_desc__new(name); + if (!s) + goto out_delete_desc; + + script_desc__add(s); + + return s; + +out_delete_desc: + script_desc__delete(s); + + return NULL; +} + +static char *ends_with(char *str, const char *suffix) +{ + size_t suffix_len = strlen(suffix); + char *p = str; + + if (strlen(str) > suffix_len) { + p = str + strlen(str) - suffix_len; + if (!strncmp(p, suffix, suffix_len)) + return p; + } + + return NULL; +} + +static char *ltrim(char *str) +{ + int len = strlen(str); + + while (len && isspace(*str)) { + len--; + str++; + } + + return str; +} + +static int read_script_info(struct script_desc *desc, const char *filename) +{ + char line[BUFSIZ], *p; + FILE *fp; + + fp = fopen(filename, "r"); + if (!fp) + return -1; + + while (fgets(line, sizeof(line), fp)) { + p = ltrim(line); + if (strlen(p) == 0) + continue; + if (*p != '#') + continue; + p++; + if (strlen(p) && *p == '!') + continue; + + p = ltrim(p); + if (strlen(p) && p[strlen(p) - 1] == '\n') + p[strlen(p) - 1] = '\0'; + + if (!strncmp(p, "description:", strlen("description:"))) { + p += strlen("description:"); + desc->half_liner = strdup(ltrim(p)); + continue; + } + + if (!strncmp(p, "args:", strlen("args:"))) { + p += strlen("args:"); + desc->args = strdup(ltrim(p)); + continue; + } + } + + fclose(fp); + + return 0; +} + +static int list_available_scripts(const struct option *opt __used, + const char *s __used, int unset __used) +{ + struct dirent *script_next, *lang_next, script_dirent, lang_dirent; + char scripts_path[MAXPATHLEN]; + DIR *scripts_dir, *lang_dir; + char script_path[MAXPATHLEN]; + char lang_path[MAXPATHLEN]; + struct script_desc *desc; + char first_half[BUFSIZ]; + char *script_root; + char *str; + + snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); + + scripts_dir = opendir(scripts_path); + if (!scripts_dir) + return -1; + + for_each_lang(scripts_dir, lang_dirent, lang_next) { + snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, + lang_dirent.d_name); + lang_dir = opendir(lang_path); + if (!lang_dir) + continue; + + for_each_script(lang_dir, script_dirent, script_next) { + script_root = strdup(script_dirent.d_name); + str = ends_with(script_root, REPORT_SUFFIX); + if (str) { + *str = '\0'; + desc = script_desc__findnew(script_root); + snprintf(script_path, MAXPATHLEN, "%s/%s", + lang_path, script_dirent.d_name); + read_script_info(desc, script_path); + } + free(script_root); + } + } + + fprintf(stdout, "List of available trace scripts:\n"); + list_for_each_entry(desc, &script_descs, node) { + sprintf(first_half, "%s %s", desc->name, + desc->args ? desc->args : ""); + fprintf(stdout, " %-36s %s\n", first_half, + desc->half_liner ? desc->half_liner : ""); + } + + exit(0); +} + static const char * const annotate_usage[] = { "perf trace [] ", NULL @@ -284,8 +479,10 @@ static const struct option options[] = { "dump raw trace in ASCII"), OPT_BOOLEAN('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"), - OPT_BOOLEAN('l', "latency", &latency_format, + OPT_BOOLEAN('L', "Latency", &latency_format, "show latency attributes (irqs/preemption disabled, etc)"), + OPT_CALLBACK_NOOPT('l', "list", NULL, NULL, "list available scripts", + list_available_scripts), OPT_CALLBACK('s', "script", NULL, "name", "script file name (lang:script name, script name, or *)", parse_scriptname), diff --git a/tools/perf/scripts/perl/bin/check-perf-trace-report b/tools/perf/scripts/perl/bin/check-perf-trace-report index 89948b0..7fc4a03 100644 --- a/tools/perf/scripts/perl/bin/check-perf-trace-report +++ b/tools/perf/scripts/perl/bin/check-perf-trace-report @@ -1,4 +1,5 @@ #!/bin/bash +# description: useless but exhaustive test script perf trace -s ~/libexec/perf-core/scripts/perl/check-perf-trace.pl diff --git a/tools/perf/scripts/perl/bin/rw-by-file-report b/tools/perf/scripts/perl/bin/rw-by-file-report index 1c05675..eddb9cc 100644 --- a/tools/perf/scripts/perl/bin/rw-by-file-report +++ b/tools/perf/scripts/perl/bin/rw-by-file-report @@ -1,4 +1,6 @@ #!/bin/bash +# description: r/w activity for a program, by file +# args: perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl $1 diff --git a/tools/perf/scripts/perl/bin/rw-by-pid-report b/tools/perf/scripts/perl/bin/rw-by-pid-report index cea16f7..7f44c25 100644 --- a/tools/perf/scripts/perl/bin/rw-by-pid-report +++ b/tools/perf/scripts/perl/bin/rw-by-pid-report @@ -1,4 +1,5 @@ #!/bin/bash +# description: system-wide r/w activity perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-pid.pl diff --git a/tools/perf/scripts/perl/bin/wakeup-latency-report b/tools/perf/scripts/perl/bin/wakeup-latency-report index 85769dc..fce3adc 100644 --- a/tools/perf/scripts/perl/bin/wakeup-latency-report +++ b/tools/perf/scripts/perl/bin/wakeup-latency-report @@ -1,4 +1,5 @@ #!/bin/bash +# description: system-wide min/max/avg wakeup latency perf trace -s ~/libexec/perf-core/scripts/perl/wakeup-latency.pl diff --git a/tools/perf/scripts/perl/bin/workqueue-stats-report b/tools/perf/scripts/perl/bin/workqueue-stats-report index aa68435..71cfbd1 100644 --- a/tools/perf/scripts/perl/bin/workqueue-stats-report +++ b/tools/perf/scripts/perl/bin/workqueue-stats-report @@ -1,4 +1,5 @@ #!/bin/bash +# description: workqueue stats (ins/exe/create/destroy) perf trace -s ~/libexec/perf-core/scripts/perl/workqueue-stats.pl -- cgit v0.10.2 From 3875294f5c0d7b9ef96ffc373d8a956ebd7c0c7f Mon Sep 17 00:00:00 2001 From: Tom Zanussi Date: Tue, 15 Dec 2009 02:53:39 -0600 Subject: perf trace/scripting: Add 'record' and 'report' options Allow scripts to be recorded/executed by simply specifying the script root name (the script name minus extension) along with 'record' or 'report' to 'perf trace'. The script names shown by 'perf trace -l' can be directly used to run the command-line contained within the corresponding '-record' and '-report' versions of scripts in the scripts/*/bin directories. For example, to record the trace data needed to run the wakeup-latency.pl script, the user can easily find the name of the corresponding script from the script list and invoke it using 'perf trace record', without having to remember the details of how to do the same thing using the lower-level perf trace command-line options: root@tropicana:~# perf trace -l List of available trace scripts: workqueue-stats workqueue stats (ins/exe/create/destroy) wakeup-latency system-wide min/max/avg wakeup latency rw-by-file r/w activity for a program, by file check-perf-trace useless but exhaustive test script rw-by-pid system-wide r/w activity root@tropicana:~# perf trace record wakeup-latency ^C[ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.296 MB perf.data (~12931 samples) ] To run the wakeup-latency.pl script using the captured data, change 'record' to 'report' in the command-line: root@tropicana:~# perf trace report wakeup-latency wakeup_latency stats: total_wakeups: 65 avg_wakeup_latency (ns): 22417 min_wakeup_latency (ns): 3470 max_wakeup_latency (ns): 223311 perf trace Perl script stopped If the script takes options, thay can be simply added to the end of the 'report' invocation: root@tropicana:~# perf trace record rw-by-file ^C[ perf record: Woken up 2 times to write data ] [ perf record: Captured and wrote 0.782 MB perf.data (~34171 samples) ] root@tropicana:~# perf trace report rw-by-file perf file read counts for perf: fd # reads bytes_requested ------ ---------- ----------- 122 1934 1980416 120 1 32 file write counts for perf: fd # writes bytes_written ------ ---------- ----------- 3 4006 280568 perf trace Perl script stopped Signed-off-by: Tom Zanussi Cc: fweisbec@gmail.com Cc: rostedt@goodmis.org LKML-Reference: <1260867220-15699-6-git-send-email-tzanussi@gmail.com> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 7674153..7e744f7 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -469,6 +469,49 @@ static int list_available_scripts(const struct option *opt __used, exit(0); } +static char *get_script_path(const char *script_root, const char *suffix) +{ + struct dirent *script_next, *lang_next, script_dirent, lang_dirent; + char scripts_path[MAXPATHLEN]; + char script_path[MAXPATHLEN]; + DIR *scripts_dir, *lang_dir; + char lang_path[MAXPATHLEN]; + char *str, *__script_root; + char *path = NULL; + + snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); + + scripts_dir = opendir(scripts_path); + if (!scripts_dir) + return NULL; + + for_each_lang(scripts_dir, lang_dirent, lang_next) { + snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, + lang_dirent.d_name); + lang_dir = opendir(lang_path); + if (!lang_dir) + continue; + + for_each_script(lang_dir, script_dirent, script_next) { + __script_root = strdup(script_dirent.d_name); + str = ends_with(__script_root, suffix); + if (str) { + *str = '\0'; + if (strcmp(__script_root, script_root)) + continue; + snprintf(script_path, MAXPATHLEN, "%s/%s", + lang_path, script_dirent.d_name); + path = strdup(script_path); + free(__script_root); + break; + } + free(__script_root); + } + } + + return path; +} + static const char * const annotate_usage[] = { "perf trace [] ", NULL @@ -494,8 +537,47 @@ static const struct option options[] = { int cmd_trace(int argc, const char **argv, const char *prefix __used) { - int err; struct perf_session *session; + const char *suffix = NULL; + const char **__argv; + char *script_path; + int i, err; + + if (argc >= 2 && strncmp(argv[1], "rec", strlen("rec")) == 0) { + if (argc < 3) { + fprintf(stderr, + "Please specify a record script\n"); + return -1; + } + suffix = RECORD_SUFFIX; + } + + if (argc >= 2 && strncmp(argv[1], "rep", strlen("rep")) == 0) { + if (argc < 3) { + fprintf(stderr, + "Please specify a report script\n"); + return -1; + } + suffix = REPORT_SUFFIX; + } + + if (suffix) { + script_path = get_script_path(argv[2], suffix); + if (!script_path) { + fprintf(stderr, "script not found\n"); + return -1; + } + + __argv = malloc((argc + 1) * sizeof(const char *)); + __argv[0] = "/bin/sh"; + __argv[1] = script_path; + for (i = 3; i < argc; i++) + __argv[i - 1] = argv[i]; + __argv[argc - 1] = NULL; + + execvp("/bin/sh", (char **)__argv); + exit(-1); + } symbol__init(0); -- cgit v0.10.2 From a6005123ce22770dbd91bc3cb637ce0807ab959b Mon Sep 17 00:00:00 2001 From: Tom Zanussi Date: Tue, 15 Dec 2009 02:53:40 -0600 Subject: perf trace/scripting: Update Documentation Update the perf-trace page with new and missing options and remove some unused ones. Signed-off-by: Tom Zanussi Cc: fweisbec@gmail.com Cc: rostedt@goodmis.org LKML-Reference: <1260867220-15699-7-git-send-email-tzanussi@gmail.com> Signed-off-by: Ingo Molnar diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index 07065ef..60e5900 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt @@ -8,18 +8,43 @@ perf-trace - Read perf.data (created by perf record) and display trace output SYNOPSIS -------- [verse] -'perf trace' [-i | --input=file] symbol_name +'perf trace' {record