drop a lot of dead code, including an old winbond southbridge from our removed
ppc port, some ambiguous use of CONFIG_IDE and an unused ide driver (we dropped the filesystems already to be used with it) (somewhat trivial) Signed-off-by: Stefan Reinauer <stepan@coresystems.de> Acked-by: Stefan Reinauer <stepan@coresystems.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4828 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
		
				
					committed by
					
						 Stefan Reinauer
						Stefan Reinauer
					
				
			
			
				
	
			
			
			
						parent
						
							707fad0508
						
					
				
				
					commit
					5e1a8d10ba
				
			| @@ -717,31 +717,6 @@ define CONFIG_IOAPIC | |||||||
| 	comment "IOAPIC support" | 	comment "IOAPIC support" | ||||||
| end | end | ||||||
|  |  | ||||||
| ############################################### |  | ||||||
| # IDE specific options |  | ||||||
| ############################################### |  | ||||||
|  |  | ||||||
| define CONFIG_IDE |  | ||||||
| 	default 0 |  | ||||||
| 	export always |  | ||||||
| 	comment "Define to include IDE support" |  | ||||||
| end |  | ||||||
| define CONFIG_IDE_BOOT_DRIVE |  | ||||||
| 	default 0 |  | ||||||
| 	export always |  | ||||||
| 	comment "Disk number of boot drive" |  | ||||||
| end |  | ||||||
| define CONFIG_IDE_SWAB |  | ||||||
| 	default none |  | ||||||
| 	export used |  | ||||||
| 	comment "Swap bytes when reading from IDE device" |  | ||||||
| end |  | ||||||
| define CONFIG_IDE_OFFSET |  | ||||||
| 	default 0 |  | ||||||
| 	export always |  | ||||||
| 	comment "Sector at which to start searching for boot image" |  | ||||||
| end |  | ||||||
|  |  | ||||||
| ############################################### | ############################################### | ||||||
| # Options for memory mapped I/O | # Options for memory mapped I/O | ||||||
| ############################################### | ############################################### | ||||||
|   | |||||||
| @@ -27,7 +27,6 @@ struct device_operations pci_bridge_ops  = { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| struct pci_driver pci_bridge_pci_driver __pci_driver = { | struct pci_driver pci_bridge_pci_driver __pci_driver = { | ||||||
| 	/* w83c553f */ |  | ||||||
| 	.ops = &pci_bridge_ops, | 	.ops = &pci_bridge_ops, | ||||||
| 	.device = PCI_DEVICE_ID_IBM_405GP, | 	.device = PCI_DEVICE_ID_IBM_405GP, | ||||||
| 	.vendor = PCI_VENDOR_ID_IBM, | 	.vendor = PCI_VENDOR_ID_IBM, | ||||||
|   | |||||||
| @@ -1,211 +0,0 @@ | |||||||
| /* |  | ||||||
|  *   UBL, The Universal Talkware Boot Loader  |  | ||||||
|  *    Copyright (C) 2000 Universal Talkware Inc. |  | ||||||
|  *    Copyright (C) 2002 Eric Biederman |  | ||||||
|  * |  | ||||||
|  *   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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA |  | ||||||
|  *  |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| typedef uint64_t sector_t; |  | ||||||
|  |  | ||||||
| struct controller { |  | ||||||
| 	uint16_t cmd_base; |  | ||||||
| 	uint16_t ctrl_base; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| struct harddisk_info { |  | ||||||
| 	struct controller *ctrl; |  | ||||||
| 	uint16_t heads; |  | ||||||
| 	uint16_t cylinders; |  | ||||||
| 	uint16_t sectors_per_track; |  | ||||||
| 	uint8_t  model_number[41]; |  | ||||||
| 	uint8_t  slave; |  | ||||||
| 	sector_t sectors; |  | ||||||
| 	int  address_mode;	/* am i lba (0x40) or chs (0x00) */ |  | ||||||
| #define ADDRESS_MODE_CHS    0 |  | ||||||
| #define ADDRESS_MODE_LBA    1 |  | ||||||
| #define ADDRESS_MODE_LBA48  2 |  | ||||||
| #define ADDRESS_MODE_PACKET 3 |  | ||||||
| 	uint32_t hw_sector_size; |  | ||||||
| 	unsigned drive_exists : 1; |  | ||||||
| 	unsigned slave_absent : 1; |  | ||||||
| 	unsigned removable : 1; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #define IDE_SECTOR_SIZE 0x200 |  | ||||||
| #define CDROM_SECTOR_SIZE 0x800 |  | ||||||
|  |  | ||||||
| #define IDE_BASE0             (0x1F0u) /* primary controller */ |  | ||||||
| #define IDE_BASE1             (0x170u) /* secondary */ |  | ||||||
| #define IDE_BASE2             (0x0F0u) /* third */ |  | ||||||
| #define IDE_BASE3             (0x070u) /* fourth */ |  | ||||||
|  |  | ||||||
| #define IDE_REG_EXTENDED_OFFSET   (0x204u) |  | ||||||
|  |  | ||||||
| #define IDE_REG_DATA(ctrl)           ((ctrl)->cmd_base + 0u) /* word register */ |  | ||||||
| #define IDE_REG_ERROR(ctrl)          ((ctrl)->cmd_base + 1u) |  | ||||||
| #define IDE_REG_PRECOMP(ctrl)        ((ctrl)->cmd_base + 1u) |  | ||||||
| #define IDE_REG_FEATURE(ctrl)        ((ctrl)->cmd_base + 1u) |  | ||||||
| #define IDE_REG_SECTOR_COUNT(ctrl)   ((ctrl)->cmd_base + 2u) |  | ||||||
| #define IDE_REG_SECTOR_NUMBER(ctrl)  ((ctrl)->cmd_base + 3u) |  | ||||||
| #define IDE_REG_LBA_LOW(ctrl)        ((ctrl)->cmd_base + 3u) |  | ||||||
| #define IDE_REG_CYLINDER_LSB(ctrl)   ((ctrl)->cmd_base + 4u) |  | ||||||
| #define IDE_REG_LBA_MID(ctrl)	     ((ctrl)->cmd_base + 4u) |  | ||||||
| #define IDE_REG_CYLINDER_MSB(ctrl)   ((ctrl)->cmd_base + 5u) |  | ||||||
| #define IDE_REG_LBA_HIGH(ctrl)	     ((ctrl)->cmd_base + 5u) |  | ||||||
| #define IDE_REG_DRIVEHEAD(ctrl)      ((ctrl)->cmd_base + 6u) |  | ||||||
| #define IDE_REG_DEVICE(ctrl)	     ((ctrl)->cmd_base + 6u) |  | ||||||
| #define IDE_REG_STATUS(ctrl)         ((ctrl)->cmd_base + 7u) |  | ||||||
| #define IDE_REG_COMMAND(ctrl)        ((ctrl)->cmd_base + 7u) |  | ||||||
| #define IDE_REG_ALTSTATUS(ctrl)      ((ctrl)->ctrl_base + 2u) |  | ||||||
| #define IDE_REG_DEVICE_CONTROL(ctrl) ((ctrl)->ctrl_base + 2u) |  | ||||||
|  |  | ||||||
| struct ide_pio_command |  | ||||||
| { |  | ||||||
| 	uint8_t feature; |  | ||||||
| 	uint8_t sector_count; |  | ||||||
| 	uint8_t lba_low; |  | ||||||
| 	uint8_t lba_mid; |  | ||||||
| 	uint8_t lba_high; |  | ||||||
| 	uint8_t device; |  | ||||||
| #       define IDE_DH_DEFAULT (0xA0) |  | ||||||
| #       define IDE_DH_HEAD(x) ((x) & 0x0F) |  | ||||||
| #       define IDE_DH_MASTER  (0x00) |  | ||||||
| #       define IDE_DH_SLAVE   (0x10) |  | ||||||
| #       define IDE_DH_LBA     (0x40) |  | ||||||
| #       define IDE_DH_CHS     (0x00) |  | ||||||
| 	uint8_t command; |  | ||||||
| 	uint8_t sector_count2; |  | ||||||
| 	uint8_t lba_low2; |  | ||||||
| 	uint8_t lba_mid2; |  | ||||||
| 	uint8_t lba_high2; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| #define IDE_DEFAULT_COMMAND { 0xFFu, 0x01, 0x00, 0x0000, IDE_DH_DEFAULT } |  | ||||||
|  |  | ||||||
| #define IDE_ERR_ICRC	0x80	/* ATA Ultra DMA bad CRC */ |  | ||||||
| #define IDE_ERR_BBK	0x80	/* ATA bad block */ |  | ||||||
| #define IDE_ERR_UNC	0x40	/* ATA uncorrected error */ |  | ||||||
| #define IDE_ERR_MC	0x20	/* ATA media change */ |  | ||||||
| #define IDE_ERR_IDNF	0x10	/* ATA id not found */ |  | ||||||
| #define IDE_ERR_MCR	0x08	/* ATA media change request */ |  | ||||||
| #define IDE_ERR_ABRT	0x04	/* ATA command aborted */ |  | ||||||
| #define IDE_ERR_NTK0	0x02	/* ATA track 0 not found */ |  | ||||||
| #define IDE_ERR_NDAM	0x01	/* ATA address mark not found */ |  | ||||||
|  |  | ||||||
| #define IDE_STATUS_BSY	0x80	/* busy */ |  | ||||||
| #define IDE_STATUS_RDY	0x40	/* ready */ |  | ||||||
| #define IDE_STATUS_DF	0x20	/* device fault */ |  | ||||||
| #define IDE_STATUS_WFT	0x20	/* write fault (old name) */ |  | ||||||
| #define IDE_STATUS_SKC	0x10	/* seek complete */ |  | ||||||
| #define IDE_STATUS_DRQ	0x08	/* data request */ |  | ||||||
| #define IDE_STATUS_CORR	0x04	/* corrected */ |  | ||||||
| #define IDE_STATUS_IDX	0x02	/* index */ |  | ||||||
| #define IDE_STATUS_ERR	0x01	/* error (ATA) */ |  | ||||||
| #define IDE_STATUS_CHK	0x01	/* check (ATAPI) */ |  | ||||||
|  |  | ||||||
| #define IDE_CTRL_HD15	0x08	/* bit should always be set to one */ |  | ||||||
| #define IDE_CTRL_SRST	0x04	/* soft reset */ |  | ||||||
| #define IDE_CTRL_NIEN	0x02	/* disable interrupts */ |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /* Most mandtory and optional ATA commands (from ATA-3), */ |  | ||||||
|  |  | ||||||
| #define IDE_CMD_CFA_ERASE_SECTORS            0xC0 |  | ||||||
| #define IDE_CMD_CFA_REQUEST_EXT_ERR_CODE     0x03 |  | ||||||
| #define IDE_CMD_CFA_TRANSLATE_SECTOR         0x87 |  | ||||||
| #define IDE_CMD_CFA_WRITE_MULTIPLE_WO_ERASE  0xCD |  | ||||||
| #define IDE_CMD_CFA_WRITE_SECTORS_WO_ERASE   0x38 |  | ||||||
| #define IDE_CMD_CHECK_POWER_MODE1            0xE5 |  | ||||||
| #define IDE_CMD_CHECK_POWER_MODE2            0x98 |  | ||||||
| #define IDE_CMD_DEVICE_RESET                 0x08 |  | ||||||
| #define IDE_CMD_EXECUTE_DEVICE_DIAGNOSTIC    0x90 |  | ||||||
| #define IDE_CMD_FLUSH_CACHE                  0xE7 |  | ||||||
| #define IDE_CMD_FORMAT_TRACK                 0x50 |  | ||||||
| #define IDE_CMD_IDENTIFY_DEVICE              0xEC |  | ||||||
| #define IDE_CMD_IDENTIFY_DEVICE_PACKET       0xA1 |  | ||||||
| #define IDE_CMD_IDENTIFY_PACKET_DEVICE       0xA1 |  | ||||||
| #define IDE_CMD_IDLE1                        0xE3 |  | ||||||
| #define IDE_CMD_IDLE2                        0x97 |  | ||||||
| #define IDE_CMD_IDLE_IMMEDIATE1              0xE1 |  | ||||||
| #define IDE_CMD_IDLE_IMMEDIATE2              0x95 |  | ||||||
| #define IDE_CMD_INITIALIZE_DRIVE_PARAMETERS  0x91 |  | ||||||
| #define IDE_CMD_INITIALIZE_DEVICE_PARAMETERS 0x91 |  | ||||||
| #define IDE_CMD_NOP                          0x00 |  | ||||||
| #define IDE_CMD_PACKET                       0xA0 |  | ||||||
| #define IDE_CMD_READ_BUFFER                  0xE4 |  | ||||||
| #define IDE_CMD_READ_DMA                     0xC8 |  | ||||||
| #define IDE_CMD_READ_DMA_QUEUED              0xC7 |  | ||||||
| #define IDE_CMD_READ_MULTIPLE                0xC4 |  | ||||||
| #define IDE_CMD_READ_SECTORS                 0x20 |  | ||||||
| #define IDE_CMD_READ_SECTORS_EXT             0x24 |  | ||||||
| #define IDE_CMD_READ_VERIFY_SECTORS          0x40 |  | ||||||
| #define IDE_CMD_RECALIBRATE                  0x10 |  | ||||||
| #define IDE_CMD_SEEK                         0x70 |  | ||||||
| #define IDE_CMD_SET_FEATURES                 0xEF |  | ||||||
| #define IDE_CMD_SET_MAX_ADDR_EXT             0x24 |  | ||||||
| #define IDE_CMD_SET_MULTIPLE_MODE            0xC6 |  | ||||||
| #define IDE_CMD_SLEEP1                       0xE6 |  | ||||||
| #define IDE_CMD_SLEEP2                       0x99 |  | ||||||
| #define IDE_CMD_STANDBY1                     0xE2 |  | ||||||
| #define IDE_CMD_STANDBY2                     0x96 |  | ||||||
| #define IDE_CMD_STANDBY_IMMEDIATE1           0xE0 |  | ||||||
| #define IDE_CMD_STANDBY_IMMEDIATE2           0x94 |  | ||||||
| #define IDE_CMD_WRITE_BUFFER                 0xE8 |  | ||||||
| #define IDE_CMD_WRITE_DMA                    0xCA |  | ||||||
| #define IDE_CMD_WRITE_DMA_QUEUED             0xCC |  | ||||||
| #define IDE_CMD_WRITE_MULTIPLE               0xC5 |  | ||||||
| #define IDE_CMD_WRITE_SECTORS                0x30 |  | ||||||
| #define IDE_CMD_WRITE_VERIFY                 0x3C |  | ||||||
|  |  | ||||||
| /* IDE_CMD_SET_FEATURE sub commands */ |  | ||||||
| #define IDE_FEATURE_CFA_ENABLE_8BIT_PIO                     0x01 |  | ||||||
| #define IDE_FEATURE_ENABLE_WRITE_CACHE                      0x02 |  | ||||||
| #define IDE_FEATURE_SET_TRANSFER_MODE                       0x03 |  | ||||||
| #define IDE_FEATURE_ENABLE_POWER_MANAGEMENT                 0x05 |  | ||||||
| #define IDE_FEATURE_ENABLE_POWERUP_IN_STANDBY               0x06 |  | ||||||
| #define IDE_FEATURE_STANDBY_SPINUP_DRIVE                    0x07 |  | ||||||
| #define IDE_FEATURE_CFA_ENABLE_POWER_MODE1                  0x0A |  | ||||||
| #define IDE_FEATURE_DISABLE_MEDIA_STATUS_NOTIFICATION       0x31 |  | ||||||
| #define IDE_FEATURE_ENABLE_AUTOMATIC_ACOUSTIC_MANAGEMENT    0x42 |  | ||||||
| #define IDE_FEATURE_SET_MAXIMUM_HOST_INTERFACE_SECTOR_TIMES 0x43 |  | ||||||
| #define IDE_FEATURE_DISABLE_READ_LOOKAHEAD                  0x55 |  | ||||||
| #define IDE_FEATURE_ENABLE_RELEASE_INTERRUPT                0x5D |  | ||||||
| #define IDE_FEATURE_ENABLE_SERVICE_INTERRUPT                0x5E |  | ||||||
| #define IDE_FEATURE_DISABLE_REVERTING_TO_POWERON_DEFAULTS   0x66 |  | ||||||
| #define IDE_FEATURE_CFA_DISABLE_8BIT_PIO                    0x81 |  | ||||||
| #define IDE_FEATURE_DISABLE_WRITE_CACHE                     0x82 |  | ||||||
| #define IDE_FEATURE_DISABLE_POWER_MANAGEMENT                0x85 |  | ||||||
| #define IDE_FEATURE_DISABLE_POWERUP_IN_STANDBY              0x86 |  | ||||||
| #define IDE_FEATURE_CFA_DISABLE_POWER_MODE1                 0x8A |  | ||||||
| #define IDE_FEATURE_ENABLE_MEDIA_STATUS_NOTIFICATION        0x95 |  | ||||||
| #define IDE_FEATURE_ENABLE_READ_LOOKAHEAD                   0xAA |  | ||||||
| #define IDE_FEATURE_DISABLE_AUTOMATIC_ACOUSTIC_MANAGEMENT   0xC2 |  | ||||||
| #define IDE_FEATURE_ENABLE_REVERTING_TO_POWERON_DEFAULTS    0xCC |  | ||||||
| #define IDE_FEATURE_DISABLE_SERVICE_INTERRUPT               0xDE |  | ||||||
|  |  | ||||||
| #define IDE_MAX_CONTROLLERS 2 |  | ||||||
| #define IDE_MAX_DRIVES (IDE_MAX_CONTROLLERS*2) |  | ||||||
| #define SECTOR_SIZE 512 |  | ||||||
| #define SECTOR_SHIFT 9 |  | ||||||
|  |  | ||||||
| /* Maximum block_size that may be set. */ |  | ||||||
| #define DISK_BUFFER_SIZE (18 * SECTOR_SIZE) |  | ||||||
|  |  | ||||||
| extern int ide_probe(int drive); |  | ||||||
| extern int ide_read(int drive, sector_t sector, void *buffer); |  | ||||||
| @@ -38,7 +38,6 @@ uses CONFIG_TTYS0_BAUD | |||||||
| uses CONFIG_TTYS0_BASE | uses CONFIG_TTYS0_BASE | ||||||
| uses CONFIG_TTYS0_LCS | uses CONFIG_TTYS0_LCS | ||||||
| uses CONFIG_UDELAY_TSC | uses CONFIG_UDELAY_TSC | ||||||
| uses CONFIG_IDE |  | ||||||
|  |  | ||||||
| ## CONFIG_ROM_SIZE is the size of boot ROM that this board will use. | ## CONFIG_ROM_SIZE is the size of boot ROM that this board will use. | ||||||
| default CONFIG_ROM_SIZE  = 512*1024 | default CONFIG_ROM_SIZE  = 512*1024 | ||||||
| @@ -73,9 +72,6 @@ default CONFIG_IRQ_SLOT_COUNT = 11 | |||||||
| ## | ## | ||||||
| default CONFIG_HAVE_OPTION_TABLE = 0 | default CONFIG_HAVE_OPTION_TABLE = 0 | ||||||
|  |  | ||||||
| ## IDE Support |  | ||||||
| default CONFIG_IDE = 1 |  | ||||||
|  |  | ||||||
| ### | ### | ||||||
| ### coreboot layout values | ### coreboot layout values | ||||||
| ### | ### | ||||||
|   | |||||||
| @@ -44,7 +44,6 @@ uses CONFIG_CONSOLE_VGA | |||||||
| uses CONFIG_PCI_ROM_RUN | uses CONFIG_PCI_ROM_RUN | ||||||
| uses CONFIG_DEBUG | uses CONFIG_DEBUG | ||||||
| #uses CONFIG_CPU_OPT | #uses CONFIG_CPU_OPT | ||||||
| uses CONFIG_IDE |  | ||||||
|  |  | ||||||
| ## These are defined in target Config.lb, don't add here | ## These are defined in target Config.lb, don't add here | ||||||
| uses CONFIG_USE_FALLBACK_IMAGE | uses CONFIG_USE_FALLBACK_IMAGE | ||||||
| @@ -228,9 +227,6 @@ default  CONFIG_MAXIMUM_CONSOLE_LOGLEVEL=8 | |||||||
| ## Select power on after power fail setting | ## Select power on after power fail setting | ||||||
| default CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON" | default CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON" | ||||||
|  |  | ||||||
| ## Things we may not have |  | ||||||
| default CONFIG_IDE=1 |  | ||||||
|  |  | ||||||
| default CONFIG_DEBUG=1 | default CONFIG_DEBUG=1 | ||||||
| # default CONFIG_CPU_OPT="-g" | # default CONFIG_CPU_OPT="-g" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
| uses CONFIG_IDE |  | ||||||
| uses CONFIG_UDELAY_IO | uses CONFIG_UDELAY_IO | ||||||
| uses CONFIG_USE_INIT | uses CONFIG_USE_INIT | ||||||
| uses CONFIG_ARCH_X86 | uses CONFIG_ARCH_X86 | ||||||
| @@ -12,10 +11,6 @@ if CONFIG_UDELAY_IO | |||||||
| 	object udelay_io.o | 	object udelay_io.o | ||||||
| end | end | ||||||
|  |  | ||||||
| if CONFIG_IDE |  | ||||||
| 	dir ide |  | ||||||
| end |  | ||||||
|  |  | ||||||
| dir vga | dir vga | ||||||
|  |  | ||||||
| object keyboard.o | object keyboard.o | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
| object ide.o |  | ||||||
| @@ -1,959 +0,0 @@ | |||||||
| /* Derived from Etherboot 5.1 */ |  | ||||||
|  |  | ||||||
| #include <stdlib.h> |  | ||||||
| #include <string.h> |  | ||||||
| #include <console/console.h> |  | ||||||
| #include <arch/io.h> |  | ||||||
| #include <pc80/ide.h> |  | ||||||
| #include <device/device.h> |  | ||||||
| #include <device/pci.h> |  | ||||||
| #include <delay.h> |  | ||||||
| #include <arch/byteorder.h> |  | ||||||
|  |  | ||||||
| #define BSY_SET_DURING_SPINUP 1 |  | ||||||
|  |  | ||||||
| static unsigned short ide_base[] = { |  | ||||||
| 	IDE_BASE0, |  | ||||||
| 	IDE_BASE1,  |  | ||||||
| 	IDE_BASE2,  |  | ||||||
| 	IDE_BASE3,  |  | ||||||
| 	0 |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static struct controller controllers[IDE_MAX_CONTROLLERS]; |  | ||||||
| static struct harddisk_info harddisk_info[IDE_MAX_DRIVES]; |  | ||||||
|  |  | ||||||
| static unsigned char ide_buffer[IDE_SECTOR_SIZE]; |  | ||||||
|  |  | ||||||
| static int await_ide(int (*done)(struct controller *ctrl),  |  | ||||||
| 	struct controller *ctrl, unsigned long timeout) |  | ||||||
| { |  | ||||||
| 	int result; |  | ||||||
| 	timeout *= 100; /* timeout was ms; finer granularity => reacts faster */ |  | ||||||
| 	for(;;) { |  | ||||||
| 		result = done(ctrl); |  | ||||||
| 		if (result) { |  | ||||||
| 			return 0; |  | ||||||
| 		} |  | ||||||
| 		//poll_interruptions(); |  | ||||||
|                 if (timeout-- <= 0) { |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		udelay(10); /* Added to avoid spinning GRW */ |  | ||||||
| 	} |  | ||||||
| 	printk_info("IDE time out\n"); |  | ||||||
| 	return -1; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* The maximum time any IDE command can last 31 seconds, |  | ||||||
|  * So if any IDE commands takes this long we know we have problems. |  | ||||||
|  */ |  | ||||||
| #define IDE_TIMEOUT (32*1000) |  | ||||||
|  |  | ||||||
| static int not_bsy(struct controller *ctrl) |  | ||||||
| { |  | ||||||
| 	return !(inb(IDE_REG_STATUS(ctrl)) & IDE_STATUS_BSY); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* IDE drives assert BSY bit within 400 nsec when SRST is set. |  | ||||||
|  * Use 2 msec since our tick is 1 msec */ |  | ||||||
| #define IDE_RESET_PULSE 2 |  | ||||||
|  |  | ||||||
| static int bsy(struct controller *ctrl) |  | ||||||
| { |  | ||||||
| 	return inb(IDE_REG_STATUS(ctrl)) & IDE_STATUS_BSY; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #if  !BSY_SET_DURING_SPINUP |  | ||||||
| static int timeout(struct controller *ctrl) |  | ||||||
| { |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| static void print_status(struct controller *ctrl) |  | ||||||
| { |  | ||||||
| 	printk_debug("IDE: status=%#x, err=%#x\n", |  | ||||||
| 			inb(IDE_REG_STATUS(ctrl)), inb(IDE_REG_ERROR(ctrl))); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int ide_software_reset(struct controller *ctrl) |  | ||||||
| { |  | ||||||
| 	/* Wait a little bit in case this is immediately after |  | ||||||
| 	 * hardware reset. |  | ||||||
| 	 */ |  | ||||||
| 	mdelay(2); |  | ||||||
| 	/* A software reset should not be delivered while the bsy bit |  | ||||||
| 	 * is set.  If the bsy bit does not clear in a reasonable |  | ||||||
| 	 * amount of time give up. |  | ||||||
| 	 */ |  | ||||||
| 	printk_debug("Waiting for ide%d to become ready for reset... ", |  | ||||||
| 			ctrl - controllers); |  | ||||||
| 	if (await_ide(not_bsy, ctrl, IDE_TIMEOUT) < 0) { |  | ||||||
| 		printk_debug("failed\n"); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	printk_debug("ok\n"); |  | ||||||
|  |  | ||||||
| 	/* Disable Interrupts and reset the ide bus */ |  | ||||||
| 	outb(IDE_CTRL_HD15 | IDE_CTRL_SRST | IDE_CTRL_NIEN,  |  | ||||||
| 		IDE_REG_DEVICE_CONTROL(ctrl)); |  | ||||||
| 	/* If BSY bit is not asserted within 400ns, no device there */ |  | ||||||
| 	if (await_ide(bsy, ctrl, IDE_RESET_PULSE) < 0) { |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	outb(IDE_CTRL_HD15 | IDE_CTRL_NIEN, IDE_REG_DEVICE_CONTROL(ctrl)); |  | ||||||
| 	mdelay(2); |  | ||||||
| 	if (await_ide(not_bsy, ctrl, IDE_TIMEOUT) < 0) { |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void pio_set_registers( |  | ||||||
| 	struct controller *ctrl, const struct ide_pio_command *cmd) |  | ||||||
| { |  | ||||||
| 	uint8_t device; |  | ||||||
| 	/* Disable Interrupts */ |  | ||||||
| 	outb(IDE_CTRL_HD15 | IDE_CTRL_NIEN, IDE_REG_DEVICE_CONTROL(ctrl)); |  | ||||||
|  |  | ||||||
| 	/* Possibly switch selected device */ |  | ||||||
| 	device = inb(IDE_REG_DEVICE(ctrl)); |  | ||||||
| 	outb(cmd->device,          IDE_REG_DEVICE(ctrl)); |  | ||||||
| 	if ((device & (1UL << 4)) != (cmd->device & (1UL << 4))) { |  | ||||||
| 		/* Allow time for the selected drive to switch, |  | ||||||
| 		 * The linux ide code suggests 50ms is the right |  | ||||||
| 		 * amount of time to use here. |  | ||||||
| 		 */ |  | ||||||
| 		mdelay(50);  |  | ||||||
| 	} |  | ||||||
| 	outb(cmd->feature,         IDE_REG_FEATURE(ctrl)); |  | ||||||
| 	if (cmd->command == IDE_CMD_READ_SECTORS_EXT) { |  | ||||||
| 		outb(cmd->sector_count2,   IDE_REG_SECTOR_COUNT(ctrl)); |  | ||||||
| 		outb(cmd->lba_low2,        IDE_REG_LBA_LOW(ctrl)); |  | ||||||
| 		outb(cmd->lba_mid2,        IDE_REG_LBA_MID(ctrl)); |  | ||||||
| 		outb(cmd->lba_high2,       IDE_REG_LBA_HIGH(ctrl)); |  | ||||||
| 	} |  | ||||||
| 	outb(cmd->sector_count,    IDE_REG_SECTOR_COUNT(ctrl)); |  | ||||||
| 	outb(cmd->lba_low,         IDE_REG_LBA_LOW(ctrl)); |  | ||||||
| 	outb(cmd->lba_mid,         IDE_REG_LBA_MID(ctrl)); |  | ||||||
| 	outb(cmd->lba_high,        IDE_REG_LBA_HIGH(ctrl)); |  | ||||||
| 	outb(cmd->command,         IDE_REG_COMMAND(ctrl)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| static int pio_non_data(struct controller *ctrl, const struct ide_pio_command *cmd) |  | ||||||
| { |  | ||||||
| 	/* Wait until the busy bit is clear */ |  | ||||||
| 	if (await_ide(not_bsy, ctrl, IDE_TIMEOUT) < 0) { |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	pio_set_registers(ctrl, cmd); |  | ||||||
| 	udelay(1); |  | ||||||
| 	if (await_ide(not_bsy, ctrl, IDE_TIMEOUT) < 0) { |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	/* FIXME is there more error checking I could do here? */ |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int pio_data_in(struct controller *ctrl,  |  | ||||||
| 	const struct ide_pio_command *cmd, |  | ||||||
| 	void *buffer, size_t bytes) |  | ||||||
| { |  | ||||||
| 	unsigned int status; |  | ||||||
|  |  | ||||||
| 	/* FIXME handle commands with multiple blocks */ |  | ||||||
| 	/* Wait until the busy bit is clear */ |  | ||||||
| 	if (await_ide(not_bsy, ctrl, IDE_TIMEOUT) < 0) { |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* How do I tell if INTRQ is asserted? */ |  | ||||||
| 	pio_set_registers(ctrl, cmd); |  | ||||||
| 	udelay(1); |  | ||||||
| 	if (await_ide(not_bsy, ctrl, IDE_TIMEOUT) < 0) { |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	status = inb(IDE_REG_STATUS(ctrl)); |  | ||||||
| 	if (!(status & IDE_STATUS_DRQ)) { |  | ||||||
| 		print_status(ctrl); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	insw(IDE_REG_DATA(ctrl), buffer, bytes/2); |  | ||||||
| 	status = inb(IDE_REG_STATUS(ctrl)); |  | ||||||
| 	if (status & IDE_STATUS_DRQ) { |  | ||||||
| 		print_status(ctrl); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #ifdef __BIG_ENDIAN |  | ||||||
| static int pio_data_in_sw(struct controller *ctrl,  |  | ||||||
| 	const struct ide_pio_command *cmd, |  | ||||||
| 	void *buffer, size_t bytes) |  | ||||||
| { |  | ||||||
| 	unsigned int status; |  | ||||||
|  |  | ||||||
| 	/* FIXME handle commands with multiple blocks */ |  | ||||||
| 	/* Wait until the busy bit is clear */ |  | ||||||
| 	if (await_ide(not_bsy, ctrl, IDE_TIMEOUT) < 0) { |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* How do I tell if INTRQ is asserted? */ |  | ||||||
| 	pio_set_registers(ctrl, cmd); |  | ||||||
| 	udelay(1); |  | ||||||
| 	if (await_ide(not_bsy, ctrl, IDE_TIMEOUT) < 0) { |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	status = inb(IDE_REG_STATUS(ctrl)); |  | ||||||
| 	if (!(status & IDE_STATUS_DRQ)) { |  | ||||||
| 		print_status(ctrl); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	insw_ns(IDE_REG_DATA(ctrl), buffer, bytes/2); |  | ||||||
| 	status = inb(IDE_REG_STATUS(ctrl)); |  | ||||||
| 	if (status & IDE_STATUS_DRQ) { |  | ||||||
| 		print_status(ctrl); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| #endif /* __BIG_ENDIAN */ |  | ||||||
|  |  | ||||||
| static int pio_packet(struct harddisk_info *info, int in, |  | ||||||
| 	const void *packet, int packet_len, |  | ||||||
| 	void *buffer, int buffer_len) |  | ||||||
| { |  | ||||||
| 	unsigned int status; |  | ||||||
| 	struct ide_pio_command cmd; |  | ||||||
|  |  | ||||||
| 	memset(&cmd, 0, sizeof(cmd)); |  | ||||||
|  |  | ||||||
| 	/* Wait until the busy bit is clear */ |  | ||||||
| 	if (await_ide(not_bsy, info->ctrl, IDE_TIMEOUT) < 0) { |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* Issue a PACKET command */ |  | ||||||
| 	cmd.lba_mid = (uint8_t) buffer_len; |  | ||||||
| 	cmd.lba_high = (uint8_t) (buffer_len >> 8); |  | ||||||
| 	cmd.device = IDE_DH_DEFAULT | info->slave; |  | ||||||
| 	cmd.command = IDE_CMD_PACKET; |  | ||||||
| 	pio_set_registers(info->ctrl, &cmd); |  | ||||||
| 	udelay(1); |  | ||||||
| 	if (await_ide(not_bsy, info->ctrl, IDE_TIMEOUT) < 0) { |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	status = inb(IDE_REG_STATUS(info->ctrl)); |  | ||||||
| 	if (!(status & IDE_STATUS_DRQ)) { |  | ||||||
| 		printk_debug("no drq after PACKET\n"); |  | ||||||
| 		print_status(info->ctrl); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* Send the packet */ |  | ||||||
| #ifdef __BIG_ENDIAN |  | ||||||
| 	outsw_ns(IDE_REG_DATA(info->ctrl), packet, packet_len/2); |  | ||||||
| #else /* __BIG_ENDIAN */ |  | ||||||
| 	outsw(IDE_REG_DATA(info->ctrl), packet, packet_len/2); |  | ||||||
| #endif /* __BIG_ENDIAN */ |  | ||||||
|  |  | ||||||
| 	if (await_ide(not_bsy, info->ctrl, IDE_TIMEOUT) < 0) { |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	status = inb(IDE_REG_STATUS(info->ctrl)); |  | ||||||
| 	if (buffer_len == 0) { |  | ||||||
| 		if (status & IDE_STATUS_DRQ) { |  | ||||||
| 			printk_debug("drq after non-data command\n"); |  | ||||||
| 			print_status(info->ctrl); |  | ||||||
| 			return -1; |  | ||||||
| 		} |  | ||||||
| 		return 0; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (!(status & IDE_STATUS_DRQ)) { |  | ||||||
| 		printk_debug("no drq after sending packet\n"); |  | ||||||
| 		print_status(info->ctrl); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| #ifdef __BIG_ENDIAN |  | ||||||
| 	insw_ns(IDE_REG_DATA(info->ctrl), buffer, buffer_len/2); |  | ||||||
| #else /* __BIG_ENDIAN */ |  | ||||||
| 	insw(IDE_REG_DATA(info->ctrl), buffer, buffer_len/2); |  | ||||||
| #endif /* __BIG_ENDIAN */ |  | ||||||
|  |  | ||||||
| 	status = inb(IDE_REG_STATUS(info->ctrl)); |  | ||||||
| 	if (status & IDE_STATUS_DRQ) { |  | ||||||
| 		printk_debug("drq after insw\n"); |  | ||||||
| 		print_status(info->ctrl); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static inline int ide_read_sector_chs( |  | ||||||
| 	struct harddisk_info *info, void *buffer, unsigned long sector) |  | ||||||
| { |  | ||||||
| 	struct ide_pio_command cmd; |  | ||||||
| 	unsigned int track; |  | ||||||
| 	unsigned int offset; |  | ||||||
| 	unsigned int cylinder; |  | ||||||
| 		 |  | ||||||
| 	memset(&cmd, 0, sizeof(cmd)); |  | ||||||
| 	cmd.sector_count = 1; |  | ||||||
|  |  | ||||||
| 	//printk_debug("ide_read_sector_chs: sector= %ld.\n",sector); |  | ||||||
|  |  | ||||||
| 	track = sector / info->sectors_per_track; |  | ||||||
| 	/* Sector number */ |  | ||||||
| 	offset = 1 + (sector % info->sectors_per_track); |  | ||||||
| 	cylinder = track / info->heads; |  | ||||||
| 	cmd.lba_low = offset; |  | ||||||
| 	cmd.lba_mid = cylinder & 0xff; |  | ||||||
| 	cmd.lba_high = (cylinder >> 8) & 0xff; |  | ||||||
| 	cmd.device = IDE_DH_DEFAULT | |  | ||||||
| 		IDE_DH_HEAD(track % info->heads) | |  | ||||||
| 		info->slave | |  | ||||||
| 		IDE_DH_CHS; |  | ||||||
| 	cmd.command = IDE_CMD_READ_SECTORS; |  | ||||||
| #ifdef __BIG_ENDIAN |  | ||||||
| 	return pio_data_in_sw(info->ctrl, &cmd, buffer, IDE_SECTOR_SIZE); |  | ||||||
| #else /* __BIG_ENDIAN */ |  | ||||||
| 	return pio_data_in(info->ctrl, &cmd, buffer, IDE_SECTOR_SIZE); |  | ||||||
| #endif /* __BIG_ENDIAN */ |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static inline int ide_read_sector_lba( |  | ||||||
| 	struct harddisk_info *info, void *buffer, unsigned long sector) |  | ||||||
| { |  | ||||||
| 	struct ide_pio_command cmd; |  | ||||||
| 	memset(&cmd, 0, sizeof(cmd)); |  | ||||||
|  |  | ||||||
| 	cmd.sector_count = 1; |  | ||||||
| 	cmd.lba_low = sector & 0xff; |  | ||||||
| 	cmd.lba_mid = (sector >> 8) & 0xff; |  | ||||||
| 	cmd.lba_high = (sector >> 16) & 0xff; |  | ||||||
| 	cmd.device = IDE_DH_DEFAULT | |  | ||||||
| 		((sector >> 24) & 0x0f) | |  | ||||||
| 		info->slave |  |  | ||||||
| 		IDE_DH_LBA; |  | ||||||
| 	cmd.command = IDE_CMD_READ_SECTORS; |  | ||||||
| 	//printk_debug("%s: sector= %ld, device command= 0x%x.\n",__func__,(unsigned long) sector, cmd.device); |  | ||||||
| #ifdef __BIG_ENDIAN |  | ||||||
| 	return pio_data_in_sw(info->ctrl, &cmd, buffer, IDE_SECTOR_SIZE); |  | ||||||
| #else /* __BIG_ENDIAN */ |  | ||||||
| 	return pio_data_in(info->ctrl, &cmd, buffer, IDE_SECTOR_SIZE); |  | ||||||
| #endif /* __BIG_ENDIAN */ |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static inline int ide_read_sector_lba48( |  | ||||||
| 	struct harddisk_info *info, void *buffer, sector_t sector) |  | ||||||
| { |  | ||||||
| 	struct ide_pio_command cmd; |  | ||||||
| 	memset(&cmd, 0, sizeof(cmd)); |  | ||||||
| 	//printk_debug("ide_read_sector_lba48: sector= %ld.\n",(unsigned long) sector); |  | ||||||
|  |  | ||||||
| 	cmd.sector_count = 1; |  | ||||||
| 	cmd.lba_low = sector & 0xff; |  | ||||||
| 	cmd.lba_mid = (sector >> 8) & 0xff; |  | ||||||
| 	cmd.lba_high = (sector >> 16) & 0xff; |  | ||||||
| 	cmd.lba_low2 = (sector >> 24) & 0xff; |  | ||||||
| 	cmd.lba_mid2 = (sector >> 32) & 0xff; |  | ||||||
| 	cmd.lba_high2 = (sector >> 40) & 0xff; |  | ||||||
| 	cmd.device =  info->slave | IDE_DH_LBA; |  | ||||||
| 	cmd.command = IDE_CMD_READ_SECTORS_EXT; |  | ||||||
| #ifdef __BIG_ENDIAN |  | ||||||
| 	return pio_data_in_sw(info->ctrl, &cmd, buffer, IDE_SECTOR_SIZE); |  | ||||||
| #else /* __BIG_ENDIAN */ |  | ||||||
| 	return pio_data_in(info->ctrl, &cmd, buffer, IDE_SECTOR_SIZE); |  | ||||||
| #endif /* __BIG_ENDIAN */ |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static inline int ide_read_sector_packet( |  | ||||||
| 	struct harddisk_info *info, void *buffer, sector_t sector) |  | ||||||
| { |  | ||||||
| 	char packet[12]; |  | ||||||
| 	static uint8_t cdbuffer[CDROM_SECTOR_SIZE]; |  | ||||||
| 	static struct harddisk_info *last_disk = 0; |  | ||||||
| 	static sector_t last_sector = (sector_t) -1; |  | ||||||
| 	uint8_t *buf; |  | ||||||
| 	uint32_t hw_sector; |  | ||||||
|  |  | ||||||
| 	//printk_debug("sector=%Ld\n", sector); |  | ||||||
|  |  | ||||||
| 	if (info->hw_sector_size == CDROM_SECTOR_SIZE) { |  | ||||||
| 		buf = cdbuffer; |  | ||||||
| 		hw_sector = sector >> 2; |  | ||||||
| 	} else { |  | ||||||
| 		buf = buffer; |  | ||||||
| 		hw_sector = sector; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (buf==buffer || info != last_disk || hw_sector != last_sector) { |  | ||||||
| 		//printk_debug("hw_sector=%u\n", hw_sector); |  | ||||||
| 		memset(packet, 0, sizeof packet); |  | ||||||
| 		packet[0] = 0x28; /* READ */ |  | ||||||
| 		packet[2] = hw_sector >> 24; |  | ||||||
| 		packet[3] = hw_sector >> 16; |  | ||||||
| 		packet[4] = hw_sector >> 8; |  | ||||||
| 		packet[5] = hw_sector >> 0; |  | ||||||
| 		packet[7] = 0; |  | ||||||
| 		packet[8] = 1; /* length */ |  | ||||||
|  |  | ||||||
| 		if (pio_packet(info, 1, packet, sizeof packet, |  | ||||||
| 					buf, info->hw_sector_size) != 0) { |  | ||||||
| 			printk_debug("read error\n"); |  | ||||||
| 			return -1; |  | ||||||
| 		} |  | ||||||
| 		last_disk = info; |  | ||||||
| 		last_sector = hw_sector; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (buf != buffer) |  | ||||||
| 		memcpy(buffer, &cdbuffer[(sector & 3) << 9], IDE_SECTOR_SIZE); |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int ide_read(int drive, sector_t sector, void *buffer) |  | ||||||
| { |  | ||||||
| 	struct harddisk_info *info = &harddisk_info[drive]; |  | ||||||
| 	int result; |  | ||||||
|  |  | ||||||
| 	//printk_debug("drive=%d, sector=%ld\n",drive,(unsigned long) sector); |  | ||||||
| 	/* Report the buffer is empty */ |  | ||||||
| 	if (sector > info->sectors) { |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	if (info->address_mode == ADDRESS_MODE_CHS) { |  | ||||||
| 		result = ide_read_sector_chs(info, buffer, sector); |  | ||||||
| 	} |  | ||||||
| 	else if (info->address_mode == ADDRESS_MODE_LBA) { |  | ||||||
| 		result = ide_read_sector_lba(info, buffer, sector); |  | ||||||
| 	} |  | ||||||
| 	else if (info->address_mode == ADDRESS_MODE_LBA48) { |  | ||||||
| 		result = ide_read_sector_lba48(info, buffer, sector); |  | ||||||
| 	} |  | ||||||
| 	else if (info->address_mode == ADDRESS_MODE_PACKET) { |  | ||||||
| 		result = ide_read_sector_packet(info, buffer, sector); |  | ||||||
| 	} |  | ||||||
| 	else { |  | ||||||
| 		result = -1; |  | ||||||
| 	} |  | ||||||
| 	return result; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int init_drive(struct harddisk_info *info, struct controller *ctrl, |  | ||||||
| 		int slave, int drive, unsigned char *buffer, int ident_command) |  | ||||||
| { |  | ||||||
| 	uint16_t* drive_info; |  | ||||||
| 	struct ide_pio_command cmd; |  | ||||||
| 	int i; |  | ||||||
|  |  | ||||||
| 	info->ctrl = ctrl; |  | ||||||
| 	info->heads = 0u; |  | ||||||
| 	info->cylinders = 0u; |  | ||||||
| 	info->sectors_per_track = 0u; |  | ||||||
| 	info->address_mode = IDE_DH_CHS; |  | ||||||
| 	info->sectors = 0ul; |  | ||||||
| 	info->drive_exists = 0; |  | ||||||
| 	info->slave_absent = 0; |  | ||||||
| 	info->removable = 0; |  | ||||||
| 	info->hw_sector_size = IDE_SECTOR_SIZE; |  | ||||||
| 	info->slave = slave?IDE_DH_SLAVE: IDE_DH_MASTER; |  | ||||||
|  |  | ||||||
| 	printk_debug("Testing for hd%c\n", 'a'+drive); |  | ||||||
|  |  | ||||||
| 	/* Select the drive that we are testing */ |  | ||||||
| 	outb(IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS | info->slave,  |  | ||||||
| 		IDE_REG_DEVICE(ctrl)); |  | ||||||
| 	mdelay(50); |  | ||||||
|  |  | ||||||
| 	/* Test to see if the drive registers exist, |  | ||||||
| 	 * In many cases this quickly rules out a missing drive. |  | ||||||
| 	 */ |  | ||||||
| 	for(i = 0; i < 4; i++) { |  | ||||||
| 		outb(0xaa + i, (ctrl->cmd_base) + 2 + i); |  | ||||||
| 	} |  | ||||||
| 	for(i = 0; i < 4; i++) { |  | ||||||
| 		if (inb((ctrl->cmd_base) + 2 + i) != 0xaa + i) { |  | ||||||
| 			return 1; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	for(i = 0; i < 4; i++) { |  | ||||||
| 		outb(0x55 + i, (ctrl->cmd_base) + 2 + i); |  | ||||||
| 	} |  | ||||||
| 	for(i = 0; i < 4; i++) { |  | ||||||
| 		if (inb((ctrl->cmd_base) + 2 + i) != 0x55 + i) { |  | ||||||
| 			return 1; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	printk_debug("Probing for hd%c\n", 'a'+drive); |  | ||||||
| 	 |  | ||||||
| 	memset(&cmd, 0, sizeof(cmd)); |  | ||||||
| 	cmd.device = IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS | info->slave; |  | ||||||
| 	cmd.command = ident_command; |  | ||||||
|  |  | ||||||
| 	if (pio_data_in(ctrl, &cmd, buffer, IDE_SECTOR_SIZE) < 0) { |  | ||||||
| 		/* Well, if that command didn't work, we probably don't have drive. */ |  | ||||||
| 		return 1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* Now suck the data out */ |  | ||||||
| 	drive_info = (uint16_t *)buffer; |  | ||||||
| 	if (drive_info[2] == 0x37C8) { |  | ||||||
| 		/* If the response is incomplete spin up the drive... */ |  | ||||||
| 		memset(&cmd, 0, sizeof(cmd)); |  | ||||||
| 		cmd.device = IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS | |  | ||||||
| 			info->slave; |  | ||||||
| 		cmd.feature = IDE_FEATURE_STANDBY_SPINUP_DRIVE; |  | ||||||
| 		if (pio_non_data(ctrl, &cmd) < 0) { |  | ||||||
| 			/* If the command doesn't work give up on the drive */ |  | ||||||
| 			return 1; |  | ||||||
| 		} |  | ||||||
| 		 |  | ||||||
| 	} |  | ||||||
| 	if ((drive_info[2] == 0x37C8) || (drive_info[2] == 0x8C73)) { |  | ||||||
| 		/* The response is incomplete retry the drive info command */ |  | ||||||
| 		memset(&cmd, 0, sizeof(cmd)); |  | ||||||
| 		cmd.device = IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS | |  | ||||||
| 			info->slave; |  | ||||||
| 		cmd.command = ident_command; |  | ||||||
| 		if (pio_data_in(ctrl, &cmd, buffer, IDE_SECTOR_SIZE) < 0) { |  | ||||||
| 			/* If the command didn't work give up on the drive. */ |  | ||||||
| 			return 1; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if ((drive_info[2] != 0x37C8) && |  | ||||||
| 		(drive_info[2] != 0x738C) && |  | ||||||
| 		(drive_info[2] != 0x8C73) && |  | ||||||
| 		(drive_info[2] != 0xC837) && |  | ||||||
| 		(drive_info[2] != 0x0000)) { |  | ||||||
| 		printk_info("Invalid IDE Configuration: %hx\n", drive_info[2]); |  | ||||||
| 		return 1; |  | ||||||
| 	} |  | ||||||
| 	for(i = 27; i < 47; i++) { |  | ||||||
| 		info->model_number[((i-27)<< 1)] = (drive_info[i] >> 8) & 0xff; |  | ||||||
| 		info->model_number[((i-27)<< 1)+1] = drive_info[i] & 0xff; |  | ||||||
| 	} |  | ||||||
| 	info->model_number[40] = '\0'; |  | ||||||
| 	info->drive_exists = 1; |  | ||||||
|  |  | ||||||
| 	/* See if LBA is supported */ |  | ||||||
| 	if (ident_command == IDE_CMD_IDENTIFY_PACKET_DEVICE) { |  | ||||||
| 		info->address_mode = ADDRESS_MODE_PACKET; |  | ||||||
| 		info->removable = 1; /* XXX */ |  | ||||||
| 	} else if (drive_info[49] & (1 << 9)) { |  | ||||||
| 		info->address_mode = ADDRESS_MODE_LBA; |  | ||||||
| 		info->sectors = (drive_info[61] << 16) | (drive_info[60]); |  | ||||||
| 		printk_debug("LBA mode, sectors=%Ld\n", info->sectors); |  | ||||||
| 		/* Enable LBA48 mode if it is present */ |  | ||||||
| 		if (drive_info[83] & (1 <<10)) { |  | ||||||
| 			/* Should LBA48 depend on LBA? */ |  | ||||||
| 			info->address_mode = ADDRESS_MODE_LBA48; |  | ||||||
| 			info->sectors =  |  | ||||||
| 				(((sector_t)drive_info[103]) << 48) | |  | ||||||
| 				(((sector_t)drive_info[102]) << 32) | |  | ||||||
| 				(((sector_t)drive_info[101]) << 16) | |  | ||||||
| 				(((sector_t)drive_info[100]) <<  0); |  | ||||||
| 			printk_debug("LBA48 mode, sectors=%Ld\n", info->sectors); |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		info->address_mode = ADDRESS_MODE_CHS; |  | ||||||
| 		info->heads = drive_info[3]; |  | ||||||
| 		info->cylinders = drive_info[1]; |  | ||||||
| 		info->sectors_per_track = drive_info[6]; |  | ||||||
| 		info->sectors =  |  | ||||||
| 			info->sectors_per_track * |  | ||||||
| 			info->heads * |  | ||||||
| 			info->cylinders; |  | ||||||
| 		printk_debug("CHS mode, sectors_per_track=[%d], heads=[%d], cylinders=[%d]\n", |  | ||||||
| 			info->sectors_per_track, |  | ||||||
| 			info->heads, |  | ||||||
| 			info->cylinders); |  | ||||||
| 		printk_debug("sectors=%Ld\n", info->sectors); |  | ||||||
| 	} |  | ||||||
| 	/* See if we have a slave */ |  | ||||||
| 	if (!info->slave && (((drive_info[93] >> 14) & 3) == 1)) { |  | ||||||
| 		info->slave_absent = !(drive_info[93] & (1 << 5)); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* See if we need to put the device in CFA power mode 1 */ |  | ||||||
| 	if ((drive_info[160] & ((1 << 15) | (1 << 13)| (1 << 12))) == |  | ||||||
| 		((1 << 15) | (1 << 13)| (1 << 12))) { |  | ||||||
| 		memset(&cmd, 0, sizeof(cmd)); |  | ||||||
| 		cmd.device = IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS | info->slave; |  | ||||||
| 		cmd.feature = IDE_FEATURE_CFA_ENABLE_POWER_MODE1; |  | ||||||
| 		if (pio_non_data(ctrl, &cmd) < 0) { |  | ||||||
| 			/* If I need to power up the drive, and I can't |  | ||||||
| 			 * give up. |  | ||||||
| 			 */ |  | ||||||
| 			printk_info("Cannot power up CFA device\n"); |  | ||||||
| 			return 1; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* Some extra steps for older drives.. */ |  | ||||||
| 	if (info->address_mode != ADDRESS_MODE_PACKET) { |  | ||||||
| 		/* Initialize drive parameters |  | ||||||
| 		 * This is an obsolete command (disappeared as of ATA-6) |  | ||||||
| 		 * but old drives need it before accessing media. */ |  | ||||||
| 		memset(&cmd, 0, sizeof(cmd)); |  | ||||||
| 		cmd.device = IDE_DH_DEFAULT | IDE_DH_HEAD(drive_info[3] - 1) |  | ||||||
| 		    | info->slave; |  | ||||||
| 		cmd.sector_count = drive_info[6]; |  | ||||||
| 		cmd.command = IDE_CMD_INITIALIZE_DRIVE_PARAMETERS; |  | ||||||
| 		printk_debug("Init device params... "); |  | ||||||
| 		if (pio_non_data(ctrl, &cmd) < 0) |  | ||||||
| 			printk_debug("failed (ok for newer drives)\n"); |  | ||||||
| 		else |  | ||||||
| 			printk_debug("ok\n"); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	printk_info("hd%c: %s", |  | ||||||
| 		'a'+drive, |  | ||||||
| 		(info->address_mode==ADDRESS_MODE_CHS) ? "CHS" : |  | ||||||
| 		(info->address_mode==ADDRESS_MODE_LBA) ? "LBA" : |  | ||||||
| 		(info->address_mode==ADDRESS_MODE_LBA48) ? "LBA48" : |  | ||||||
| 		(info->address_mode==ADDRESS_MODE_PACKET) ? "ATAPI" : "???"); |  | ||||||
|  |  | ||||||
| 	if (info->sectors > (10LL*1000*1000*1000/512)) |  | ||||||
| 		printk_info(" %uGB", (unsigned) (info->sectors / (1000*1000*1000/512))); |  | ||||||
| 	else if (info->sectors > (10*1000*1000/512)) |  | ||||||
| 		printk_info(" %uMB", (unsigned) (info->sectors / (1000*1000/512))); |  | ||||||
| 	else if (info->sectors > 0) |  | ||||||
| 		printk_info(" %uKB", (unsigned) (info->sectors / 2)); |  | ||||||
| 	printk_info(": %s\n", info->model_number); |  | ||||||
|  |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* Experimental floating bus detection |  | ||||||
|  * As Eric mentions, we get stuck when the bus has no drive |  | ||||||
|  * and floating high. To avoid this, try some heuristics. |  | ||||||
|  * This is based on a paper on Phoenix website. --ts1 */ |  | ||||||
| static int ide_bus_floating(struct controller *ctrl) |  | ||||||
| { |  | ||||||
| 	unsigned long timeout; |  | ||||||
| 	unsigned char status; |  | ||||||
|  |  | ||||||
| 	/* Test 1: if status reads 0xff, probably no device is present |  | ||||||
| 	 * on the bus. Repeat this for 20msec. */ |  | ||||||
| 	timeout = 20; |  | ||||||
| 	status = 0; |  | ||||||
| 	do { |  | ||||||
| 		/* Take logical OR to avoid chattering */ |  | ||||||
| 		status |= inb(IDE_REG_STATUS(ctrl)); |  | ||||||
| 		/* If it makes 0xff, it's possible to be floating,  |  | ||||||
| 		 * do test2 to ensure. */ |  | ||||||
| 		if (status == 0xff) |  | ||||||
| 			goto test2; |  | ||||||
| 		/* If BSY bit is not set, it's harmless to continue probing. */ |  | ||||||
| 		if ((status & IDE_STATUS_BSY) == 0) |  | ||||||
| 			return 0; |  | ||||||
| 		udelay(1000); |  | ||||||
| 	} while (timeout > 0); |  | ||||||
| 	/* Timed out. Logical ORed status didn't make 0xFF. |  | ||||||
| 	 * We have something there. */ |  | ||||||
| 	return 0; |  | ||||||
|  |  | ||||||
| test2: |  | ||||||
| 	/* Test 2: write something to registers, then read back and  |  | ||||||
| 	 * compare. Note that ATA spec inhibits this while BSY is set, |  | ||||||
| 	 * but for many drives this works. This is a confirmation step anyway. |  | ||||||
| 	 */ |  | ||||||
| 	outb(0xaa, ctrl->cmd_base + 2); |  | ||||||
| 	outb(0x55, ctrl->cmd_base + 3); |  | ||||||
| 	outb(0xff, ctrl->cmd_base + 4); |  | ||||||
| 	if (inb(ctrl->cmd_base+2) == 0xaa |  | ||||||
| 			&& inb(ctrl->cmd_base+3) == 0x55 |  | ||||||
| 			&& inb(ctrl->cmd_base+4) == 0xff) { |  | ||||||
| 		/* We have some registers there.  |  | ||||||
| 		 * Though this does not mean it is not a NIC or something... */ |  | ||||||
| 		return 0; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* Status port is 0xFF, and other registers are not there. |  | ||||||
| 	 * Most certainly this bus is floating. */ |  | ||||||
| 	printk_info("Detected floating bus\n"); |  | ||||||
| 	return 1; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int init_controller(struct controller *ctrl, int drive, unsigned char *buffer)  |  | ||||||
| { |  | ||||||
| 	struct harddisk_info *info; |  | ||||||
|  |  | ||||||
| 	/* Put the drives ide channel in a know state and wait |  | ||||||
| 	 * for the drives to spinup.   |  | ||||||
| 	 * |  | ||||||
| 	 * In practice IDE disks tend not to respond to commands until |  | ||||||
| 	 * they have spun up.  This makes IDE hard to deal with |  | ||||||
| 	 * immediately after power up, as the delays can be quite |  | ||||||
| 	 * long, so we must be very careful here. |  | ||||||
| 	 * |  | ||||||
| 	 * There are two pathological cases that must be dealt with: |  | ||||||
| 	 * |  | ||||||
| 	 * - The BSY bit not being set while the IDE drives spin up. |  | ||||||
| 	 *   In this cases only a hard coded delay will work.  As |  | ||||||
| 	 *   I have not reproduced it, and this is out of spec for |  | ||||||
| 	 *   IDE drives the work around can be enabled by setting |  | ||||||
| 	 *   BSY_SET_DURING_SPINUP to 0. |  | ||||||
| 	 * |  | ||||||
| 	 * - The BSY bit floats high when no drives are plugged in. |  | ||||||
| 	 *   This case will not be detected except by timing out but |  | ||||||
| 	 *   we avoid the problems by only probing devices we are |  | ||||||
| 	 *   supposed to boot from.  If we don't do the probe we |  | ||||||
| 	 *   will not experience the problem. |  | ||||||
| 	 * |  | ||||||
| 	 * So speed wise I am only slow if the BSY bit is not set |  | ||||||
| 	 * or not reported by the IDE controller during spinup, which |  | ||||||
| 	 * is quite rare. |  | ||||||
| 	 *  |  | ||||||
| 	 */ |  | ||||||
| #if !BSY_SET_DURING_SPINUP |  | ||||||
| 	if (await_ide(timeout, ctrl, IDE_TIMEOUT) < 0) { |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| #endif |  | ||||||
| 	/* ts1: Try some heuristics to avoid waiting for floating bus */ |  | ||||||
| 	if (ide_bus_floating(ctrl)) |  | ||||||
| 		return -1; |  | ||||||
|  |  | ||||||
| 	if (ide_software_reset(ctrl) < 0) { |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* Note: I have just done a software reset.  It may be |  | ||||||
| 	 * reasonable to just read the boot time signatures  |  | ||||||
| 	 * off of the drives to see if they are present. |  | ||||||
| 	 * |  | ||||||
| 	 * For now I will go with just sending commands to the drives |  | ||||||
| 	 * and assuming filtering out missing drives by detecting registers |  | ||||||
| 	 * that won't set and commands that fail to execute properly. |  | ||||||
| 	 */ |  | ||||||
|  |  | ||||||
| 	/* Now initialize the individual drives */ |  | ||||||
| 	info = &harddisk_info[drive]; |  | ||||||
| 	init_drive(info, ctrl, 0, drive, buffer, IDE_CMD_IDENTIFY_DEVICE); |  | ||||||
| 	if (!info->drive_exists) |  | ||||||
| 		init_drive(info, ctrl, 0, drive, buffer, |  | ||||||
| 				IDE_CMD_IDENTIFY_PACKET_DEVICE); |  | ||||||
| #ifdef CHECK_FOR_SLAVES |  | ||||||
| 	if (info->drive_exists && !info->slave_absent) { |  | ||||||
| 		drive++; |  | ||||||
| 		info++; |  | ||||||
| 		init_drive(info, ctrl, 1, drive, buffer, |  | ||||||
| 				IDE_CMD_IDENTIFY_DEVICE); |  | ||||||
| 		if (!info->drive_exists) |  | ||||||
| 			init_drive(info, ctrl, 1, drive, buffer, |  | ||||||
| 					IDE_CMD_IDENTIFY_PACKET_DEVICE); |  | ||||||
| 	} |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| atapi_request_sense(struct harddisk_info *info, uint8_t *asc, uint8_t *ascq) |  | ||||||
| { |  | ||||||
| 	uint8_t packet[12]; |  | ||||||
| 	uint8_t buf[18]; |  | ||||||
|  |  | ||||||
| 	memset(packet, 0, sizeof packet); |  | ||||||
| 	packet[0] = 0x03; /* REQUEST SENSE */ |  | ||||||
| 	packet[4] = sizeof buf; |  | ||||||
| 	if (pio_packet(info, 1, packet, sizeof packet, buf, sizeof buf) != 0) |  | ||||||
| 		return -1; |  | ||||||
|  |  | ||||||
| 	if (asc) |  | ||||||
| 		*asc = buf[12]; |  | ||||||
| 	if (ascq) |  | ||||||
| 		*ascq = buf[13]; |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int atapi_detect_medium(struct harddisk_info *info) |  | ||||||
| { |  | ||||||
| 	uint8_t packet[12]; |  | ||||||
| 	uint8_t buf[8]; |  | ||||||
| 	uint32_t block_len, sectors; |  | ||||||
| 	unsigned long timeout; |  | ||||||
| 	uint8_t asc, ascq; |  | ||||||
| 	int in_progress; |  | ||||||
|  |  | ||||||
| 	memset(packet, 0, sizeof packet); |  | ||||||
| 	packet[0] = 0x25; /* READ CAPACITY */ |  | ||||||
|  |  | ||||||
| 	/* Retry READ CAPACITY for 5 seconds unless MEDIUM NOT PRESENT |  | ||||||
| 	 * is reported by the drive. If the drive reports "IN PROGRESS", |  | ||||||
| 	 * 30 seconds is added. */ |  | ||||||
| 	timeout =  5000; |  | ||||||
| 	in_progress = 0; |  | ||||||
| 	while (timeout > 0) { |  | ||||||
| 		if (pio_packet(info, 1, packet, sizeof packet, buf, sizeof buf) |  | ||||||
| 				== 0) |  | ||||||
| 			goto ok; |  | ||||||
|  |  | ||||||
| 		if (atapi_request_sense(info, &asc, &ascq) == 0) { |  | ||||||
| 			if (asc == 0x3a) { /* MEDIUM NOT PRESENT */ |  | ||||||
| 				printk_debug("Device reports MEDIUM NOT PRESENT\n"); |  | ||||||
| 				return -1; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if (asc == 0x04 && ascq == 0x01 && !in_progress) { |  | ||||||
| 					/* IN PROGRESS OF BECOMING READY */ |  | ||||||
| 				printk_info("Waiting for drive to detect " |  | ||||||
| 						"the medium... "); |  | ||||||
| 				/* Allow 30 seconds more */ |  | ||||||
| 				timeout =  30000; |  | ||||||
| 				in_progress = 1; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		udelay(1000); |  | ||||||
| 	} |  | ||||||
| 	printk_debug("read capacity failed\n"); |  | ||||||
| 	return -1; |  | ||||||
| ok: |  | ||||||
|  |  | ||||||
| 	block_len = (uint32_t) buf[4] << 24 |  | ||||||
| 		| (uint32_t) buf[5] << 16 |  | ||||||
| 		| (uint32_t) buf[6] << 8 |  | ||||||
| 		| (uint32_t) buf[7] << 0; |  | ||||||
| 	if (block_len != IDE_SECTOR_SIZE && block_len != CDROM_SECTOR_SIZE) { |  | ||||||
| 		printk_info("Unsupported sector size %u\n", block_len); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	info->hw_sector_size = block_len; |  | ||||||
|  |  | ||||||
| 	sectors = (uint32_t) buf[0] << 24 |  | ||||||
| 		| (uint32_t) buf[1] << 16 |  | ||||||
| 		| (uint32_t) buf[2] << 8 |  | ||||||
| 		| (uint32_t) buf[3] << 0; |  | ||||||
|  |  | ||||||
| 	if (info->hw_sector_size == CDROM_SECTOR_SIZE) |  | ||||||
| 		sectors <<= 2; /* # of sectors in 512-byte "soft" sector */ |  | ||||||
| 	if (sectors != info->sectors) |  | ||||||
| 		printk_info("%uMB medium detected\n", sectors>>(20-9)); |  | ||||||
| 	info->sectors = sectors; |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int detect_medium(struct harddisk_info *info) |  | ||||||
| { |  | ||||||
| 	if (info->address_mode == ADDRESS_MODE_PACKET) { |  | ||||||
| 		if (atapi_detect_medium(info) != 0) |  | ||||||
| 			return -1; |  | ||||||
| 	} else { |  | ||||||
| 		printk_debug("not implemented for non-ATAPI device\n"); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int find_ide_controller_compat(struct controller *ctrl, int index) |  | ||||||
| { |  | ||||||
| 	if (index >= IDE_MAX_CONTROLLERS) |  | ||||||
| 		return -1; |  | ||||||
| 	ctrl->cmd_base  = ide_base[index]; |  | ||||||
| 	ctrl->ctrl_base = ide_base[index] + IDE_REG_EXTENDED_OFFSET; |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int find_ide_controller(struct controller *ctrl, int ctrl_index) |  | ||||||
| { |  | ||||||
| 	int pci_index; |  | ||||||
| 	struct device *dev = 0; |  | ||||||
| 	unsigned int mask; |  | ||||||
| 	unsigned int prog_if; |  | ||||||
|  |  | ||||||
| 	/* A PCI IDE controller has two channels (pri, sec) */ |  | ||||||
| 	pci_index = ctrl_index >> 1; |  | ||||||
|  |  | ||||||
| 	for (;;) { |  | ||||||
| 		/* Find a IDE storage class device */ |  | ||||||
| 		dev = dev_find_class(0x010100, dev); |  | ||||||
| 		if (!dev) { |  | ||||||
| 			printk_debug("PCI IDE #%d not found\n", pci_index); |  | ||||||
| 			return -1; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (pci_index-- == 0) |  | ||||||
| 			break; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	prog_if = dev->class & 0xff; |  | ||||||
| 	printk_debug("found PCI IDE controller %04x:%04x prog_if=%#x\n", |  | ||||||
| 			dev->vendor, dev->device, prog_if); |  | ||||||
|  |  | ||||||
| 	/* See how this controller is configured */ |  | ||||||
| 	mask = (ctrl_index & 1) ? 4 : 1; |  | ||||||
| 	printk_debug("%s channel: ", (ctrl_index & 1) ? "secondary" : "primary"); |  | ||||||
| 	if (prog_if & mask) { |  | ||||||
| 		printk_debug("native PCI mode\n"); |  | ||||||
| 		if ((ctrl_index & 1) == 0) { |  | ||||||
| 			/* Primary channel */ |  | ||||||
| 			ctrl->cmd_base = pci_read_config32(dev, PCI_BASE_ADDRESS_0); |  | ||||||
| 			ctrl->ctrl_base = pci_read_config32(dev, PCI_BASE_ADDRESS_1); |  | ||||||
| 		} else { |  | ||||||
| 			/* Secondary channel */ |  | ||||||
| 			ctrl->cmd_base = pci_read_config32(dev, PCI_BASE_ADDRESS_2); |  | ||||||
| 			ctrl->ctrl_base = pci_read_config32(dev, PCI_BASE_ADDRESS_3); |  | ||||||
| 		} |  | ||||||
| 		ctrl->cmd_base &= ~3; |  | ||||||
| 		ctrl->ctrl_base &= ~3; |  | ||||||
| 	} else { |  | ||||||
| 		printk_debug("compatibility mode\n"); |  | ||||||
| 		if (find_ide_controller_compat(ctrl, ctrl_index) != 0) |  | ||||||
| 			return -1; |  | ||||||
| 	} |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int ide_probe(int drive) |  | ||||||
| { |  | ||||||
| 	struct controller *ctrl; |  | ||||||
| 	int ctrl_index; |  | ||||||
| 	struct harddisk_info *info; |  | ||||||
|  |  | ||||||
| 	if (drive >= IDE_MAX_DRIVES) { |  | ||||||
| 		printk_info("Unsupported drive number\n"); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* A controller has two drives (master, slave) */ |  | ||||||
| 	ctrl_index = drive >> 1; |  | ||||||
|  |  | ||||||
| 	ctrl = &controllers[ctrl_index]; |  | ||||||
| 	if (ctrl->cmd_base == 0) { |  | ||||||
| 		if (find_ide_controller(ctrl, ctrl_index) != 0) { |  | ||||||
| 			printk_info("IDE channel %d not found\n", ctrl_index); |  | ||||||
| 			return -1; |  | ||||||
| 		} |  | ||||||
| 		if (init_controller(ctrl, drive & ~1, ide_buffer) != 0) { |  | ||||||
| 			printk_info("No drive detected on IDE channel %d\n", |  | ||||||
| 					ctrl_index); |  | ||||||
| 			return -1; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	info = &harddisk_info[drive]; |  | ||||||
| 	if (!info->drive_exists) { |  | ||||||
| 		printk_info("Drive %d does not exist\n", drive); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (info->removable) { |  | ||||||
| 		if (detect_medium(info) != 0) { |  | ||||||
| 			printk_info("Media detection failed\n"); |  | ||||||
| 			return -1; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* vim:set sts=8 sw=8: */ |  | ||||||
| @@ -1,16 +1,8 @@ | |||||||
| uses CONFIG_IDE |  | ||||||
|  |  | ||||||
| config chip.h | config chip.h | ||||||
| driver i82801ca.o | driver i82801ca.o | ||||||
|  |  | ||||||
| driver i82801ca_usb.o | driver i82801ca_usb.o | ||||||
|  |  | ||||||
| driver i82801ca_lpc.o | driver i82801ca_lpc.o | ||||||
|  |  | ||||||
| if CONFIG_IDE |  | ||||||
| driver i82801ca_ide.o | driver i82801ca_ide.o | ||||||
| end |  | ||||||
|  |  | ||||||
| driver i82801ca_ac97.o | driver i82801ca_ac97.o | ||||||
| #driver i82801ca_nic.o | #driver i82801ca_nic.o | ||||||
| driver i82801ca_pci.o | driver i82801ca_pci.o | ||||||
|   | |||||||
| @@ -1,9 +1,7 @@ | |||||||
| driver-y += i82801ca.o | driver-y += i82801ca.o | ||||||
| driver-y += i82801ca_usb.o | driver-y += i82801ca_usb.o | ||||||
| driver-y += i82801ca_lpc.o | driver-y += i82801ca_lpc.o | ||||||
|  | driver-y += i82801ca_ide.o | ||||||
| driver-$(CONFIG_IDE) += i82801ca_ide.o |  | ||||||
|  |  | ||||||
| driver-y += i82801ca_ac97.o | driver-y += i82801ca_ac97.o | ||||||
| #driver-y += i82801ca_nic.o | #driver-y += i82801ca_nic.o | ||||||
| driver-y += i82801ca_pci.o | driver-y += i82801ca_pci.o | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ | |||||||
| #include <pc80/mc146818rtc.h> | #include <pc80/mc146818rtc.h> | ||||||
| #include <pc80/keyboard.h> | #include <pc80/keyboard.h> | ||||||
|  |  | ||||||
| #include "vt8231.h" |  | ||||||
| #include "chip.h" | #include "chip.h" | ||||||
|  |  | ||||||
| /* Base 8231 controller */ | /* Base 8231 controller */ | ||||||
|   | |||||||
| @@ -1,195 +0,0 @@ | |||||||
| /* |  | ||||||
|  * (C) Copyright 2000 |  | ||||||
|  * Rob Taylor, Flying Pig Systems. robt@flyingpig.com. |  | ||||||
|  * |  | ||||||
|  * See file CREDITS for list of people who contributed to this |  | ||||||
|  * project. |  | ||||||
|  * |  | ||||||
|  * 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., 51 Franklin St, Fifth Floor, Boston, |  | ||||||
|  * MA 02110-1301 USA |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
|  /* winbond access routines and defines*/ |  | ||||||
|  |  | ||||||
| /* from the winbond data sheet - |  | ||||||
|  The W83C553F SIO controller with PCI arbiter is a multi-function PCI device. |  | ||||||
|  Function 0 is the ISA bridge, and Function 1 is the bus master IDE controller. |  | ||||||
| */ |  | ||||||
|  |  | ||||||
| /*ISA bridge configuration space*/ |  | ||||||
|  |  | ||||||
| #define W83C553F_VID		0x10AD |  | ||||||
| #define W83C553F_DID		0x0565 |  | ||||||
| #define W83C553F_IDE		0x0105 |  | ||||||
|  |  | ||||||
| /* Function 0 registers */ |  | ||||||
| #define W83C553F_PCICONTR	0x40  /*pci control reg*/ |  | ||||||
| #define W83C553F_SGBAR		0x41  /*scatter/gather base address reg*/ |  | ||||||
| #define W83C553F_LBCR		0x42  /*Line Buffer Control reg*/ |  | ||||||
| #define W83C553F_IDEIRCR	0x43  /*IDE Interrupt Routing Control  Reg*/ |  | ||||||
| #define W83C553F_PCIIRCR	0x44  /*PCI Interrupt Routing Control Reg*/ |  | ||||||
| #define W83C553F_BTBAR		0x46  /*BIOS Timer Base Address Register*/ |  | ||||||
| #define W83C553F_IPADCR		0x48  /*ISA to PCI Address Decoder Control Register*/ |  | ||||||
| #define W83C553F_IRADCR		0x49  /*ISA ROM Address Decoder Control Register*/ |  | ||||||
| #define W83C553F_IPMHSAR	0x4a  /*ISA to PCI Memory Hole STart Address Register*/ |  | ||||||
| #define W83C553F_IPMHSR		0x4b  /*ISA to PCI Memory Hols Size Register*/ |  | ||||||
| #define W83C553F_CDR			0x4c  /*Clock Divisor Register*/ |  | ||||||
| #define W83C553F_CSCR		0x4d  /*Chip Select Control Register*/ |  | ||||||
| #define W83C553F_ATSCR		0x4e  /*AT System Control register*/ |  | ||||||
| #define W83C553F_ATBCR		0x4f  /*AT Bus ControL Register*/ |  | ||||||
| #define W83C553F_IRQBEE0R	0x60  /*IRQ Break Event Enable 0 Register*/ |  | ||||||
| #define W83C553F_IRQBEE1R	0x61  /*IRQ Break Event Enable 1 Register*/ |  | ||||||
| #define W83C553F_ABEER		0x62  /*Additional Break Event Enable Register*/ |  | ||||||
| #define W83C553F_DMABEER	0x63  /*DMA Break Event Enable Register*/ |  | ||||||
|  |  | ||||||
| /* Function 1 registers */ |  | ||||||
| #define W83C553F_PIR		0x09  /*Programming Interface Register*/ |  | ||||||
| #define W83C553F_IDECSR		0x40  /*IDE Control/Status Register*/ |  | ||||||
|  |  | ||||||
| /* register bit definitions */ |  | ||||||
| #define W83C553F_IPADCR_MBE512		0x1 |  | ||||||
| #define W83C553F_IPADCR_MBE640		0x2 |  | ||||||
| #define W83C553F_IPADCR_IPATOM4		0x10 |  | ||||||
| #define W83C553F_IPADCR_IPATOM5		0x20 |  | ||||||
| #define W83C553F_IPADCR_IPATOM6		0x40 |  | ||||||
| #define W83C553F_IPADCR_IPATOM7		0x80 |  | ||||||
|  |  | ||||||
| #define W83C553F_CSCR_UBIOSCSE		0x10 |  | ||||||
| #define W83C553F_CSCR_BIOSWP		0x20 |  | ||||||
|  |  | ||||||
| #define W83C553F_IDECSR_P0EN		0x01 |  | ||||||
| #define W83C553F_IDECSR_P0F16		0x02 |  | ||||||
| #define W83C553F_IDECSR_P1EN		0x10 |  | ||||||
| #define W83C553F_IDECSR_P1F16		0x20 |  | ||||||
| #define W83C553F_IDECSR_LEGIRQ		0x800 |  | ||||||
|  |  | ||||||
| #define W83C553F_ATSCR_ISARE		0x40 |  | ||||||
| #define W83C553F_ATSCR_FERRE		0x10 |  | ||||||
| #define W83C553F_ATSCR_P92E		0x04 |  | ||||||
| #define W83C553F_ATSCR_KRCEE		0x02 |  | ||||||
| #define W83C553F_ATSCR_KGA20EE		0x01 |  | ||||||
|  |  | ||||||
| #define W83C553F_PIR_BM			0x80 |  | ||||||
| #define W83C553F_PIR_P1PROG		0x08 |  | ||||||
| #define W83C553F_PIR_P1NL		0x04 |  | ||||||
| #define W83C553F_PIR_P0PROG		0x02 |  | ||||||
| #define W83C553F_PIR_P0NL		0x01 |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Interrupt controller |  | ||||||
|  */ |  | ||||||
| #define W83C553F_PIC1_ICW1	CONFIG_ISA_IO + 0x20 |  | ||||||
| #define W83C553F_PIC1_ICW2	CONFIG_ISA_IO + 0x21 |  | ||||||
| #define W83C553F_PIC1_ICW3	CONFIG_ISA_IO + 0x21 |  | ||||||
| #define W83C553F_PIC1_ICW4	CONFIG_ISA_IO + 0x21 |  | ||||||
| #define W83C553F_PIC1_OCW1	CONFIG_ISA_IO + 0x21 |  | ||||||
| #define W83C553F_PIC1_OCW2	CONFIG_ISA_IO + 0x20 |  | ||||||
| #define W83C553F_PIC1_OCW3	CONFIG_ISA_IO + 0x20 |  | ||||||
| #define W83C553F_PIC1_ELC	CONFIG_ISA_IO + 0x4D0 |  | ||||||
| #define W83C553F_PIC2_ICW1	CONFIG_ISA_IO + 0xA0 |  | ||||||
| #define W83C553F_PIC2_ICW2	CONFIG_ISA_IO + 0xA1 |  | ||||||
| #define W83C553F_PIC2_ICW3	CONFIG_ISA_IO + 0xA1 |  | ||||||
| #define W83C553F_PIC2_ICW4	CONFIG_ISA_IO + 0xA1 |  | ||||||
| #define W83C553F_PIC2_OCW1	CONFIG_ISA_IO + 0xA1 |  | ||||||
| #define W83C553F_PIC2_OCW2	CONFIG_ISA_IO + 0xA0 |  | ||||||
| #define W83C553F_PIC2_OCW3	CONFIG_ISA_IO + 0xA0 |  | ||||||
| #define W83C553F_PIC2_ELC	CONFIG_ISA_IO + 0x4D1 |  | ||||||
|  |  | ||||||
| #define W83C553F_TMR1_CMOD	CONFIG_ISA_IO + 0x43 |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * DMA controller |  | ||||||
|  */ |  | ||||||
| #define W83C553F_DMA1	CONFIG_ISA_IO + 0x000	/* channel 0 - 3 */ |  | ||||||
| #define W83C553F_DMA2	CONFIG_ISA_IO + 0x0C0	/* channel 4 - 7 */ |  | ||||||
|  |  | ||||||
| /* command/status register bit definitions */ |  | ||||||
|  |  | ||||||
| #define W83C553F_CS_COM_DACKAL	(1<<7)	/* DACK# assert level */ |  | ||||||
| #define W83C553F_CS_COM_DREQSAL	(1<<6)	/* DREQ sense assert level */ |  | ||||||
| #define W83C553F_CS_COM_GAP	(1<<4)	/* group arbitration priority */ |  | ||||||
| #define W83C553F_CS_COM_CGE	(1<<2)	/* channel group enable */ |  | ||||||
|  |  | ||||||
| #define W83C553F_CS_STAT_CH0REQ	(1<<4)	/* channel 0 (4) DREQ status */ |  | ||||||
| #define W83C553F_CS_STAT_CH1REQ	(1<<5)	/* channel 1 (5) DREQ status */ |  | ||||||
| #define W83C553F_CS_STAT_CH2REQ	(1<<6)	/* channel 2 (6) DREQ status */ |  | ||||||
| #define W83C553F_CS_STAT_CH3REQ	(1<<7)	/* channel 3 (7) DREQ status */ |  | ||||||
|  |  | ||||||
| #define W83C553F_CS_STAT_CH0TC	(1<<0)	/* channel 0 (4) TC status */ |  | ||||||
| #define W83C553F_CS_STAT_CH1TC	(1<<1)	/* channel 1 (5) TC status */ |  | ||||||
| #define W83C553F_CS_STAT_CH2TC	(1<<2)	/* channel 2 (6) TC status */ |  | ||||||
| #define W83C553F_CS_STAT_CH3TC	(1<<3)	/* channel 3 (7) TC status */ |  | ||||||
|  |  | ||||||
| /* mode register bit definitions */ |  | ||||||
|  |  | ||||||
| #define W83C553F_MODE_TM_DEMAND	(0<<6)	/* transfer mode - demand */ |  | ||||||
| #define W83C553F_MODE_TM_SINGLE	(1<<6)	/* transfer mode - single */ |  | ||||||
| #define W83C553F_MODE_TM_BLOCK	(2<<6)	/* transfer mode - block */ |  | ||||||
| #define W83C553F_MODE_TM_CASCADE	(3<<6)	/* transfer mode - cascade */ |  | ||||||
| #define W83C553F_MODE_ADDRDEC	(1<<5)	/* address increment/decrement select */ |  | ||||||
| #define W83C553F_MODE_AUTOINIT	(1<<4)	/* autoinitialize enable */ |  | ||||||
| #define W83C553F_MODE_TT_VERIFY	(0<<2)	/* transfer type - verify */ |  | ||||||
| #define W83C553F_MODE_TT_WRITE	(1<<2)	/* transfer type - write */ |  | ||||||
| #define W83C553F_MODE_TT_READ	(2<<2)	/* transfer type - read */ |  | ||||||
| #define W83C553F_MODE_TT_ILLEGAL	(3<<2)	/* transfer type - illegal */ |  | ||||||
| #define W83C553F_MODE_CH0SEL	(0<<0)	/* channel 0 (4) select */ |  | ||||||
| #define W83C553F_MODE_CH1SEL	(1<<0)	/* channel 1 (5) select */ |  | ||||||
| #define W83C553F_MODE_CH2SEL	(2<<0)	/* channel 2 (6) select */ |  | ||||||
| #define W83C553F_MODE_CH3SEL	(3<<0)	/* channel 3 (7) select */ |  | ||||||
|  |  | ||||||
| /* request register bit definitions */ |  | ||||||
|  |  | ||||||
| #define W83C553F_REQ_CHSERREQ	(1<<2)	/* channel service request */ |  | ||||||
| #define W83C553F_REQ_CH0SEL	(0<<0)	/* channel 0 (4) select */ |  | ||||||
| #define W83C553F_REQ_CH1SEL	(1<<0)	/* channel 1 (5) select */ |  | ||||||
| #define W83C553F_REQ_CH2SEL	(2<<0)	/* channel 2 (6) select */ |  | ||||||
| #define W83C553F_REQ_CH3SEL	(3<<0)	/* channel 3 (7) select */ |  | ||||||
|  |  | ||||||
| /* write single mask bit register bit definitions */ |  | ||||||
|  |  | ||||||
| #define W83C553F_WSMB_CHMASKSEL	(1<<2)	/* channel mask select */ |  | ||||||
| #define W83C553F_WSMB_CH0SEL	(0<<0)	/* channel 0 (4) select */ |  | ||||||
| #define W83C553F_WSMB_CH1SEL	(1<<0)	/* channel 1 (5) select */ |  | ||||||
| #define W83C553F_WSMB_CH2SEL	(2<<0)	/* channel 2 (6) select */ |  | ||||||
| #define W83C553F_WSMB_CH3SEL	(3<<0)	/* channel 3 (7) select */ |  | ||||||
|  |  | ||||||
| /* read/write all mask bits register bit definitions */ |  | ||||||
|  |  | ||||||
| #define W83C553F_RWAMB_CH0MASK	(1<<0)	/* channel 0 (4) mask */ |  | ||||||
| #define W83C553F_RWAMB_CH1MASK	(1<<1)	/* channel 1 (5) mask */ |  | ||||||
| #define W83C553F_RWAMB_CH2MASK	(1<<2)	/* channel 2 (6) mask */ |  | ||||||
| #define W83C553F_RWAMB_CH3MASK	(1<<3)	/* channel 3 (7) mask */ |  | ||||||
|  |  | ||||||
| /* typedefs */ |  | ||||||
|  |  | ||||||
| #define W83C553F_DMA1_CS		0x8 |  | ||||||
| #define W83C553F_DMA1_WR		0x9 |  | ||||||
| #define W83C553F_DMA1_WSMB		0xA |  | ||||||
| #define W83C553F_DMA1_WM		0xB |  | ||||||
| #define W83C553F_DMA1_CBP		0xC |  | ||||||
| #define W83C553F_DMA1_MC		0xD |  | ||||||
| #define W83C553F_DMA1_CM		0xE |  | ||||||
| #define W83C553F_DMA1_RWAMB		0xF |  | ||||||
|  |  | ||||||
| #define W83C553F_DMA2_CS		0xD0 |  | ||||||
| #define W83C553F_DMA2_WR		0xD2 |  | ||||||
| #define W83C553F_DMA2_WSMB		0xD4 |  | ||||||
| #define W83C553F_DMA2_WM		0xD6 |  | ||||||
| #define W83C553F_DMA2_CBP		0xD8 |  | ||||||
| #define W83C553F_DMA2_MC		0xDA |  | ||||||
| #define W83C553F_DMA2_CM		0xDC |  | ||||||
| #define W83C553F_DMA2_RWAMB		0xDE |  | ||||||
|  |  | ||||||
| void initialise_w83c553f(void); |  | ||||||
| @@ -3,7 +3,6 @@ | |||||||
| #include <device/pci.h> | #include <device/pci.h> | ||||||
| #include <device/pci_ops.h> | #include <device/pci_ops.h> | ||||||
| #include <device/pci_ids.h> | #include <device/pci_ids.h> | ||||||
| #include "vt8231.h" |  | ||||||
|  |  | ||||||
| static void acpi_init(struct device *dev) | static void acpi_init(struct device *dev) | ||||||
| { | { | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ | |||||||
| #include <device/pci.h> | #include <device/pci.h> | ||||||
| #include <device/pci_ops.h> | #include <device/pci_ops.h> | ||||||
| #include <device/pci_ids.h> | #include <device/pci_ids.h> | ||||||
| #include "vt8231.h" |  | ||||||
| #include "chip.h" | #include "chip.h" | ||||||
|  |  | ||||||
| static void ide_init(struct device *dev) | static void ide_init(struct device *dev) | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ | |||||||
|  |  | ||||||
| #include <pc80/mc146818rtc.h> | #include <pc80/mc146818rtc.h> | ||||||
|  |  | ||||||
| #include "vt8231.h" |  | ||||||
| #include "chip.h" | #include "chip.h" | ||||||
|  |  | ||||||
| /* PIRQ init | /* PIRQ init | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ | |||||||
| #include <device/pci.h> | #include <device/pci.h> | ||||||
| #include <device/pci_ops.h> | #include <device/pci_ops.h> | ||||||
| #include <device/pci_ids.h> | #include <device/pci_ids.h> | ||||||
| #include "vt8231.h" |  | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Enable the ethernet device and turn off stepping (because it is integrated  |  * Enable the ethernet device and turn off stepping (because it is integrated  | ||||||
|   | |||||||
| @@ -5,7 +5,6 @@ | |||||||
| #include <device/pci_ids.h> | #include <device/pci_ids.h> | ||||||
| #include <pc80/keyboard.h> | #include <pc80/keyboard.h> | ||||||
| #include <pc80/i8259.h> | #include <pc80/i8259.h> | ||||||
| #include "vt8235.h" |  | ||||||
| #include "chip.h" | #include "chip.h" | ||||||
|  |  | ||||||
| /* | /* | ||||||
|   | |||||||
| @@ -1,195 +0,0 @@ | |||||||
| /* |  | ||||||
|  * (C) Copyright 2000 |  | ||||||
|  * Rob Taylor, Flying Pig Systems. robt@flyingpig.com. |  | ||||||
|  * |  | ||||||
|  * See file CREDITS for list of people who contributed to this |  | ||||||
|  * project. |  | ||||||
|  * |  | ||||||
|  * 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., 51 Franklin St, Fifth Floor, Boston, |  | ||||||
|  * MA 02110-1301 USA |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
|  /* winbond access routines and defines*/ |  | ||||||
|  |  | ||||||
| /* from the winbond data sheet - |  | ||||||
|  The W83C553F SIO controller with PCI arbiter is a multi-function PCI device. |  | ||||||
|  Function 0 is the ISA bridge, and Function 1 is the bus master IDE controller. |  | ||||||
| */ |  | ||||||
|  |  | ||||||
| /*ISA bridge configuration space*/ |  | ||||||
|  |  | ||||||
| #define W83C553F_VID		0x10AD |  | ||||||
| #define W83C553F_DID		0x0565 |  | ||||||
| #define W83C553F_IDE		0x0105 |  | ||||||
|  |  | ||||||
| /* Function 0 registers */ |  | ||||||
| #define W83C553F_PCICONTR	0x40  /*pci control reg*/ |  | ||||||
| #define W83C553F_SGBAR		0x41  /*scatter/gather base address reg*/ |  | ||||||
| #define W83C553F_LBCR		0x42  /*Line Buffer Control reg*/ |  | ||||||
| #define W83C553F_IDEIRCR	0x43  /*IDE Interrupt Routing Control  Reg*/ |  | ||||||
| #define W83C553F_PCIIRCR	0x44  /*PCI Interrupt Routing Control Reg*/ |  | ||||||
| #define W83C553F_BTBAR		0x46  /*BIOS Timer Base Address Register*/ |  | ||||||
| #define W83C553F_IPADCR		0x48  /*ISA to PCI Address Decoder Control Register*/ |  | ||||||
| #define W83C553F_IRADCR		0x49  /*ISA ROM Address Decoder Control Register*/ |  | ||||||
| #define W83C553F_IPMHSAR	0x4a  /*ISA to PCI Memory Hole STart Address Register*/ |  | ||||||
| #define W83C553F_IPMHSR		0x4b  /*ISA to PCI Memory Hols Size Register*/ |  | ||||||
| #define W83C553F_CDR			0x4c  /*Clock Divisor Register*/ |  | ||||||
| #define W83C553F_CSCR		0x4d  /*Chip Select Control Register*/ |  | ||||||
| #define W83C553F_ATSCR		0x4e  /*AT System Control register*/ |  | ||||||
| #define W83C553F_ATBCR		0x4f  /*AT Bus ControL Register*/ |  | ||||||
| #define W83C553F_IRQBEE0R	0x60  /*IRQ Break Event Enable 0 Register*/ |  | ||||||
| #define W83C553F_IRQBEE1R	0x61  /*IRQ Break Event Enable 1 Register*/ |  | ||||||
| #define W83C553F_ABEER		0x62  /*Additional Break Event Enable Register*/ |  | ||||||
| #define W83C553F_DMABEER	0x63  /*DMA Break Event Enable Register*/ |  | ||||||
|  |  | ||||||
| /* Function 1 registers */ |  | ||||||
| #define W83C553F_PIR		0x09  /*Programming Interface Register*/ |  | ||||||
| #define W83C553F_IDECSR		0x40  /*IDE Control/Status Register*/ |  | ||||||
|  |  | ||||||
| /* register bit definitions */ |  | ||||||
| #define W83C553F_IPADCR_MBE512		0x1 |  | ||||||
| #define W83C553F_IPADCR_MBE640		0x2 |  | ||||||
| #define W83C553F_IPADCR_IPATOM4		0x10 |  | ||||||
| #define W83C553F_IPADCR_IPATOM5		0x20 |  | ||||||
| #define W83C553F_IPADCR_IPATOM6		0x40 |  | ||||||
| #define W83C553F_IPADCR_IPATOM7		0x80 |  | ||||||
|  |  | ||||||
| #define W83C553F_CSCR_UBIOSCSE		0x10 |  | ||||||
| #define W83C553F_CSCR_BIOSWP		0x20 |  | ||||||
|  |  | ||||||
| #define W83C553F_IDECSR_P0EN		0x01 |  | ||||||
| #define W83C553F_IDECSR_P0F16		0x02 |  | ||||||
| #define W83C553F_IDECSR_P1EN		0x10 |  | ||||||
| #define W83C553F_IDECSR_P1F16		0x20 |  | ||||||
| #define W83C553F_IDECSR_LEGIRQ		0x800 |  | ||||||
|  |  | ||||||
| #define W83C553F_ATSCR_ISARE		0x40 |  | ||||||
| #define W83C553F_ATSCR_FERRE		0x10 |  | ||||||
| #define W83C553F_ATSCR_P92E		0x04 |  | ||||||
| #define W83C553F_ATSCR_KRCEE		0x02 |  | ||||||
| #define W83C553F_ATSCR_KGA20EE		0x01 |  | ||||||
|  |  | ||||||
| #define W83C553F_PIR_BM			0x80 |  | ||||||
| #define W83C553F_PIR_P1PROG		0x08 |  | ||||||
| #define W83C553F_PIR_P1NL		0x04 |  | ||||||
| #define W83C553F_PIR_P0PROG		0x02 |  | ||||||
| #define W83C553F_PIR_P0NL		0x01 |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Interrupt controller |  | ||||||
|  */ |  | ||||||
| #define W83C553F_PIC1_ICW1	CONFIG_ISA_IO + 0x20 |  | ||||||
| #define W83C553F_PIC1_ICW2	CONFIG_ISA_IO + 0x21 |  | ||||||
| #define W83C553F_PIC1_ICW3	CONFIG_ISA_IO + 0x21 |  | ||||||
| #define W83C553F_PIC1_ICW4	CONFIG_ISA_IO + 0x21 |  | ||||||
| #define W83C553F_PIC1_OCW1	CONFIG_ISA_IO + 0x21 |  | ||||||
| #define W83C553F_PIC1_OCW2	CONFIG_ISA_IO + 0x20 |  | ||||||
| #define W83C553F_PIC1_OCW3	CONFIG_ISA_IO + 0x20 |  | ||||||
| #define W83C553F_PIC1_ELC	CONFIG_ISA_IO + 0x4D0 |  | ||||||
| #define W83C553F_PIC2_ICW1	CONFIG_ISA_IO + 0xA0 |  | ||||||
| #define W83C553F_PIC2_ICW2	CONFIG_ISA_IO + 0xA1 |  | ||||||
| #define W83C553F_PIC2_ICW3	CONFIG_ISA_IO + 0xA1 |  | ||||||
| #define W83C553F_PIC2_ICW4	CONFIG_ISA_IO + 0xA1 |  | ||||||
| #define W83C553F_PIC2_OCW1	CONFIG_ISA_IO + 0xA1 |  | ||||||
| #define W83C553F_PIC2_OCW2	CONFIG_ISA_IO + 0xA0 |  | ||||||
| #define W83C553F_PIC2_OCW3	CONFIG_ISA_IO + 0xA0 |  | ||||||
| #define W83C553F_PIC2_ELC	CONFIG_ISA_IO + 0x4D1 |  | ||||||
|  |  | ||||||
| #define W83C553F_TMR1_CMOD	CONFIG_ISA_IO + 0x43 |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * DMA controller |  | ||||||
|  */ |  | ||||||
| #define W83C553F_DMA1	CONFIG_ISA_IO + 0x000	/* channel 0 - 3 */ |  | ||||||
| #define W83C553F_DMA2	CONFIG_ISA_IO + 0x0C0	/* channel 4 - 7 */ |  | ||||||
|  |  | ||||||
| /* command/status register bit definitions */ |  | ||||||
|  |  | ||||||
| #define W83C553F_CS_COM_DACKAL	(1<<7)	/* DACK# assert level */ |  | ||||||
| #define W83C553F_CS_COM_DREQSAL	(1<<6)	/* DREQ sense assert level */ |  | ||||||
| #define W83C553F_CS_COM_GAP	(1<<4)	/* group arbitration priority */ |  | ||||||
| #define W83C553F_CS_COM_CGE	(1<<2)	/* channel group enable */ |  | ||||||
|  |  | ||||||
| #define W83C553F_CS_STAT_CH0REQ	(1<<4)	/* channel 0 (4) DREQ status */ |  | ||||||
| #define W83C553F_CS_STAT_CH1REQ	(1<<5)	/* channel 1 (5) DREQ status */ |  | ||||||
| #define W83C553F_CS_STAT_CH2REQ	(1<<6)	/* channel 2 (6) DREQ status */ |  | ||||||
| #define W83C553F_CS_STAT_CH3REQ	(1<<7)	/* channel 3 (7) DREQ status */ |  | ||||||
|  |  | ||||||
| #define W83C553F_CS_STAT_CH0TC	(1<<0)	/* channel 0 (4) TC status */ |  | ||||||
| #define W83C553F_CS_STAT_CH1TC	(1<<1)	/* channel 1 (5) TC status */ |  | ||||||
| #define W83C553F_CS_STAT_CH2TC	(1<<2)	/* channel 2 (6) TC status */ |  | ||||||
| #define W83C553F_CS_STAT_CH3TC	(1<<3)	/* channel 3 (7) TC status */ |  | ||||||
|  |  | ||||||
| /* mode register bit definitions */ |  | ||||||
|  |  | ||||||
| #define W83C553F_MODE_TM_DEMAND	(0<<6)	/* transfer mode - demand */ |  | ||||||
| #define W83C553F_MODE_TM_SINGLE	(1<<6)	/* transfer mode - single */ |  | ||||||
| #define W83C553F_MODE_TM_BLOCK	(2<<6)	/* transfer mode - block */ |  | ||||||
| #define W83C553F_MODE_TM_CASCADE	(3<<6)	/* transfer mode - cascade */ |  | ||||||
| #define W83C553F_MODE_ADDRDEC	(1<<5)	/* address increment/decrement select */ |  | ||||||
| #define W83C553F_MODE_AUTOINIT	(1<<4)	/* autoinitialize enable */ |  | ||||||
| #define W83C553F_MODE_TT_VERIFY	(0<<2)	/* transfer type - verify */ |  | ||||||
| #define W83C553F_MODE_TT_WRITE	(1<<2)	/* transfer type - write */ |  | ||||||
| #define W83C553F_MODE_TT_READ	(2<<2)	/* transfer type - read */ |  | ||||||
| #define W83C553F_MODE_TT_ILLEGAL	(3<<2)	/* transfer type - illegal */ |  | ||||||
| #define W83C553F_MODE_CH0SEL	(0<<0)	/* channel 0 (4) select */ |  | ||||||
| #define W83C553F_MODE_CH1SEL	(1<<0)	/* channel 1 (5) select */ |  | ||||||
| #define W83C553F_MODE_CH2SEL	(2<<0)	/* channel 2 (6) select */ |  | ||||||
| #define W83C553F_MODE_CH3SEL	(3<<0)	/* channel 3 (7) select */ |  | ||||||
|  |  | ||||||
| /* request register bit definitions */ |  | ||||||
|  |  | ||||||
| #define W83C553F_REQ_CHSERREQ	(1<<2)	/* channel service request */ |  | ||||||
| #define W83C553F_REQ_CH0SEL	(0<<0)	/* channel 0 (4) select */ |  | ||||||
| #define W83C553F_REQ_CH1SEL	(1<<0)	/* channel 1 (5) select */ |  | ||||||
| #define W83C553F_REQ_CH2SEL	(2<<0)	/* channel 2 (6) select */ |  | ||||||
| #define W83C553F_REQ_CH3SEL	(3<<0)	/* channel 3 (7) select */ |  | ||||||
|  |  | ||||||
| /* write single mask bit register bit definitions */ |  | ||||||
|  |  | ||||||
| #define W83C553F_WSMB_CHMASKSEL	(1<<2)	/* channel mask select */ |  | ||||||
| #define W83C553F_WSMB_CH0SEL	(0<<0)	/* channel 0 (4) select */ |  | ||||||
| #define W83C553F_WSMB_CH1SEL	(1<<0)	/* channel 1 (5) select */ |  | ||||||
| #define W83C553F_WSMB_CH2SEL	(2<<0)	/* channel 2 (6) select */ |  | ||||||
| #define W83C553F_WSMB_CH3SEL	(3<<0)	/* channel 3 (7) select */ |  | ||||||
|  |  | ||||||
| /* read/write all mask bits register bit definitions */ |  | ||||||
|  |  | ||||||
| #define W83C553F_RWAMB_CH0MASK	(1<<0)	/* channel 0 (4) mask */ |  | ||||||
| #define W83C553F_RWAMB_CH1MASK	(1<<1)	/* channel 1 (5) mask */ |  | ||||||
| #define W83C553F_RWAMB_CH2MASK	(1<<2)	/* channel 2 (6) mask */ |  | ||||||
| #define W83C553F_RWAMB_CH3MASK	(1<<3)	/* channel 3 (7) mask */ |  | ||||||
|  |  | ||||||
| /* typedefs */ |  | ||||||
|  |  | ||||||
| #define W83C553F_DMA1_CS		0x8 |  | ||||||
| #define W83C553F_DMA1_WR		0x9 |  | ||||||
| #define W83C553F_DMA1_WSMB		0xA |  | ||||||
| #define W83C553F_DMA1_WM		0xB |  | ||||||
| #define W83C553F_DMA1_CBP		0xC |  | ||||||
| #define W83C553F_DMA1_MC		0xD |  | ||||||
| #define W83C553F_DMA1_CM		0xE |  | ||||||
| #define W83C553F_DMA1_RWAMB		0xF |  | ||||||
|  |  | ||||||
| #define W83C553F_DMA2_CS		0xD0 |  | ||||||
| #define W83C553F_DMA2_WR		0xD2 |  | ||||||
| #define W83C553F_DMA2_WSMB		0xD4 |  | ||||||
| #define W83C553F_DMA2_WM		0xD6 |  | ||||||
| #define W83C553F_DMA2_CBP		0xD8 |  | ||||||
| #define W83C553F_DMA2_MC		0xDA |  | ||||||
| #define W83C553F_DMA2_CM		0xDC |  | ||||||
| #define W83C553F_DMA2_RWAMB		0xDE |  | ||||||
|  |  | ||||||
| void initialise_w83c553f(void); |  | ||||||
| @@ -3,7 +3,6 @@ | |||||||
| #include <device/pci_ops.h> | #include <device/pci_ops.h> | ||||||
| #include <device/pci_ids.h> | #include <device/pci_ids.h> | ||||||
| #include <console/console.h> | #include <console/console.h> | ||||||
| #include "vt8235.h" |  | ||||||
| #include "chip.h" | #include "chip.h" | ||||||
|  |  | ||||||
| static void ide_init(struct device *dev) | static void ide_init(struct device *dev) | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ | |||||||
|  |  | ||||||
| #include <pc80/mc146818rtc.h> | #include <pc80/mc146818rtc.h> | ||||||
|  |  | ||||||
| #include "vt8235.h" |  | ||||||
| #include "chip.h" | #include "chip.h" | ||||||
|  |  | ||||||
| /* The epia-m is really short on interrupts available, so PCI interupts A & D are ganged togther and so are B & C. | /* The epia-m is really short on interrupts available, so PCI interupts A & D are ganged togther and so are B & C. | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ | |||||||
| #include <device/pci.h> | #include <device/pci.h> | ||||||
| #include <device/pci_ops.h> | #include <device/pci_ops.h> | ||||||
| #include <device/pci_ids.h> | #include <device/pci_ids.h> | ||||||
| #include "vt8235.h" |  | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Enable the ethernet device and turn off stepping (because it is integrated  |  * Enable the ethernet device and turn off stepping (because it is integrated  | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ | |||||||
| #include <device/pci.h> | #include <device/pci.h> | ||||||
| #include <device/pci_ops.h> | #include <device/pci_ops.h> | ||||||
| #include <device/pci_ids.h> | #include <device/pci_ids.h> | ||||||
| #include "vt8235.h" |  | ||||||
|  |  | ||||||
| /* really nothing to do here, both usb 1.1 & 2.0 are normal PCI devices and so get resources allocated | /* really nothing to do here, both usb 1.1 & 2.0 are normal PCI devices and so get resources allocated | ||||||
|    properly. They are part of the southbridge and are enabled in the chip enable function for the southbridge */ |    properly. They are part of the southbridge and are enabled in the chip enable function for the southbridge */ | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
| source src/southbridge/winbond/w83c553/Kconfig |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| subdirs-$(CONFIG_SOUTHBRIDGE_WINBOND_W83C553) += w83c553 |  | ||||||
| @@ -1,4 +0,0 @@ | |||||||
| #config chip.h |  | ||||||
| #object w83c553f.o |  | ||||||
| driver w83c553f.o |  | ||||||
| driver w83c553f_ide.o |  | ||||||
| @@ -1,2 +0,0 @@ | |||||||
| config SOUTHBRIDGE_WINBOND_W83C553 |  | ||||||
| 	bool |  | ||||||
| @@ -1,2 +0,0 @@ | |||||||
| driver-y += w83c553f.o |  | ||||||
| driver-y += w83c553f_ide.o |  | ||||||
| @@ -1,9 +0,0 @@ | |||||||
| #ifndef _SOUTHBRIDGE_WINBOND_W83C553 |  | ||||||
| #define _SOUTHBRIDGE_WINBOND_W83C553 |  | ||||||
|  |  | ||||||
| extern struct chip_operations southbridge_winbond_w83c553_control; |  | ||||||
|  |  | ||||||
| struct southbridge_winbond_w83c553_config { |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| #endif /* _SOUTHBRIDGE_WINBOND_W83C553 */ |  | ||||||
| @@ -1,222 +0,0 @@ | |||||||
| /* |  | ||||||
|  * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> |  | ||||||
|  * Andreas Heppel <aheppel@sysgo.de> |  | ||||||
|  * |  | ||||||
|  * See file CREDITS for list of people who contributed to this |  | ||||||
|  * project. |  | ||||||
|  * |  | ||||||
|  * 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., 51 Franklin St, Fifth Floor, Boston, |  | ||||||
|  * MA 02110-1301 USA |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Initialisation of the PCI-to-ISA bridge and disabling the BIOS |  | ||||||
|  * write protection (for flash) in function 0 of the chip. |  | ||||||
|  * Enabling function 1 (IDE controller of the chip. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #ifndef CONFIG_ISA_IO |  | ||||||
| #define CONFIG_ISA_IO         0xFE000000 |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include <arch/io.h> |  | ||||||
| #include <device/pci.h> |  | ||||||
| #include <device/pci_ids.h> |  | ||||||
| #include <console/console.h> |  | ||||||
| #include "w83c553f.h" |  | ||||||
|  |  | ||||||
| void initialise_pic(void); |  | ||||||
| void initialise_dma(void); |  | ||||||
|  |  | ||||||
| static void  |  | ||||||
| w83c553_init(struct device *dev) |  | ||||||
| { |  | ||||||
| 	printk_info("Configure W83C553F ISA Bridge (Function 0)\n"); |  | ||||||
|  |  | ||||||
| #if 0 |  | ||||||
| 	/* |  | ||||||
| 	 * Set ISA memory space NOT SURE ABOUT THIS??? |  | ||||||
| 	 */ |  | ||||||
| 	reg8 = pci_read_config8(dev, W83C553F_IPADCR); |  | ||||||
| 	/* 16 MB ISA memory space */ |  | ||||||
| 	reg8 |= (W83C553F_IPADCR_IPATOM4 | W83C553F_IPADCR_IPATOM5 | W83C553F_IPADCR_IPATOM6 | W83C553F_IPADCR_IPATOM7); |  | ||||||
| 	reg8 &= ~W83C553F_IPADCR_MBE512; |  | ||||||
| 	pci_write_config8(dev, W83C553F_IPADCR, reg8); |  | ||||||
|  |  | ||||||
| 	/* |  | ||||||
| 	 * Chip select: switch off BIOS write protection |  | ||||||
| 	 */ |  | ||||||
| 	reg8 = pci_read_config8(dev, W83C553F_CSCR); |  | ||||||
| 	reg8 |= W83C553F_CSCR_UBIOSCSE; |  | ||||||
| 	reg8 &= ~W83C553F_CSCR_BIOSWP; |  | ||||||
| 	pci_write_config8(dev, W83C553F_CSCR, reg8); |  | ||||||
|  |  | ||||||
| 	/* |  | ||||||
| 	 * Enable Port 92 |  | ||||||
| 	 */ |  | ||||||
| 	reg8 = W83C553F_ATSCR_P92E | W83C553F_ATSCR_KRCEE; |  | ||||||
| 	pci_write_config8(dev, W83C553F_CSCR, reg8); |  | ||||||
|  |  | ||||||
| 	/* |  | ||||||
| 	 * Route IDE interrupts to IRQ 14 & 15 on 8259. |  | ||||||
| 	 */ |  | ||||||
| 	pci_write_config8(dev, W83C553F_IDEIRCR, 0x90); |  | ||||||
| 	pci_write_config16(dev, W83C553F_PCIIRCR, 0xABEF); |  | ||||||
|  |  | ||||||
| 	/* |  | ||||||
| 	 * Initialise ISA interrupt controller |  | ||||||
| 	 */ |  | ||||||
| 	initialise_pic(); |  | ||||||
|  |  | ||||||
| 	/* |  | ||||||
| 	 * Initialise DMA controller |  | ||||||
| 	 */ |  | ||||||
| 	initialise_dma(); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| 	printk_info("W83C553F configuration complete\n"); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void initialise_pic(void) |  | ||||||
| { |  | ||||||
| 	outb(W83C553F_PIC1_ICW1, 0x11); /* start init sequence, ICW4 needed */ |  | ||||||
| 	outb(W83C553F_PIC1_ICW2, 0x08); /* base address 00001 */ |  | ||||||
| 	outb(W83C553F_PIC1_ICW3, 0x04); /* slave on IRQ2 */ |  | ||||||
| 	outb(W83C553F_PIC1_ICW4, 0x01); /* x86 mode */ |  | ||||||
| 	outb(W83C553F_PIC1_OCW1, 0xfb); /* enable IRQ 2 */ |  | ||||||
| 	outb(W83C553F_PIC1_ELC, 0xf8);	/* all IRQ's edge sensitive */ |  | ||||||
|  |  | ||||||
| 	outb(W83C553F_PIC2_ICW1, 0x11); /* start init sequence, ICW4 needed */ |  | ||||||
| 	outb(W83C553F_PIC2_ICW2, 0x08); /* base address 00001 */ |  | ||||||
| 	outb(W83C553F_PIC2_ICW3, 0x02); /* slave ID 2 */ |  | ||||||
| 	outb(W83C553F_PIC2_ICW4, 0x01); /* x86 mode */ |  | ||||||
| 	outb(W83C553F_PIC2_OCW1, 0xff); /* disable all IRQ's */ |  | ||||||
| 	outb(W83C553F_PIC2_ELC, 0xde);	/* all IRQ's edge sensitive */ |  | ||||||
|  |  | ||||||
| 	outb(W83C553F_TMR1_CMOD, 0x74); |  | ||||||
|  |  | ||||||
| 	outb(W83C553F_PIC2_OCW1, 0x20); |  | ||||||
| 	outb(W83C553F_PIC1_OCW1, 0x20); |  | ||||||
|  |  | ||||||
| 	outb(W83C553F_PIC2_OCW1, 0x2b); |  | ||||||
| 	outb(W83C553F_PIC1_OCW1, 0x2b); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void initialise_dma(void) |  | ||||||
| { |  | ||||||
| 	unsigned int channel; |  | ||||||
| 	unsigned int rvalue1, rvalue2; |  | ||||||
|  |  | ||||||
| 	/* perform a H/W reset of the devices */ |  | ||||||
|  |  | ||||||
| 	outb(W83C553F_DMA1 + W83C553F_DMA1_MC, 0x00); |  | ||||||
| 	outw(W83C553F_DMA2 + W83C553F_DMA2_MC, 0x0000); |  | ||||||
|  |  | ||||||
| 	/* initialise all channels to a sane state */ |  | ||||||
|  |  | ||||||
| 	for (channel = 0; channel < 4; channel++) { |  | ||||||
| 		/* |  | ||||||
| 		 * dependent upon the channel, setup the specifics: |  | ||||||
| 		 * |  | ||||||
| 		 * demand |  | ||||||
| 		 * address-increment |  | ||||||
| 		 * autoinitialize-disable |  | ||||||
| 		 * verify-transfer |  | ||||||
| 		 */ |  | ||||||
|  |  | ||||||
| 		switch (channel) { |  | ||||||
| 		case 0: |  | ||||||
| 			rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH0SEL|W83C553F_MODE_TT_VERIFY); |  | ||||||
| 			rvalue2 = (W83C553F_MODE_TM_CASCADE|W83C553F_MODE_CH0SEL); |  | ||||||
| 			break; |  | ||||||
| 	    	case 1: |  | ||||||
| 			rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH1SEL|W83C553F_MODE_TT_VERIFY); |  | ||||||
| 			rvalue2 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH1SEL|W83C553F_MODE_TT_VERIFY); |  | ||||||
| 			break; |  | ||||||
| 		case 2: |  | ||||||
| 			rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH2SEL|W83C553F_MODE_TT_VERIFY); |  | ||||||
| 			rvalue2 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH2SEL|W83C553F_MODE_TT_VERIFY); |  | ||||||
| 			break; |  | ||||||
| 		case 3: |  | ||||||
| 			rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH3SEL|W83C553F_MODE_TT_VERIFY); |  | ||||||
| 			rvalue2 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH3SEL|W83C553F_MODE_TT_VERIFY); |  | ||||||
| 			break; |  | ||||||
| 		default: |  | ||||||
| 			rvalue1 = 0x00; |  | ||||||
| 			rvalue2 = 0x00; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		/* write to write mode registers */ |  | ||||||
|  |  | ||||||
| 		outb(W83C553F_DMA1 + W83C553F_DMA1_WM, rvalue1 & 0xFF); |  | ||||||
| 		outw(W83C553F_DMA2 + W83C553F_DMA2_WM, rvalue2 & 0x00FF); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/* enable all channels */ |  | ||||||
|  |  | ||||||
| 	outb(W83C553F_DMA1 + W83C553F_DMA1_CM, 0x00); |  | ||||||
| 	outw(W83C553F_DMA2 + W83C553F_DMA2_CM, 0x0000); |  | ||||||
| 	/* |  | ||||||
| 	 * initialize the global DMA configuration |  | ||||||
| 	 * |  | ||||||
| 	 * DACK# active low |  | ||||||
| 	 * DREQ active high |  | ||||||
| 	 * fixed priority |  | ||||||
| 	 * channel group enable |  | ||||||
| 	 */ |  | ||||||
|  |  | ||||||
| 	outb(W83C553F_DMA1 + W83C553F_DMA1_CS, 0x00); |  | ||||||
| 	outw(W83C553F_DMA2 + W83C553F_DMA2_CS, 0x0000); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void w83c553_enable_resources(device_t dev) |  | ||||||
| { |  | ||||||
| 	pci_dev_enable_resources(dev); |  | ||||||
| 	enable_childrens_resources(dev); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void w83c553_read_resources(device_t dev) |  | ||||||
| { |  | ||||||
| 	struct resource* res; |  | ||||||
|  |  | ||||||
| 	pci_dev_read_resources(dev); |  | ||||||
|  |  | ||||||
| 	res = new_resource(dev, 1); |  | ||||||
| 	res->base = 0x0UL; |  | ||||||
| 	res->size = 0x400UL; |  | ||||||
| 	res->limit = 0xffffUL; |  | ||||||
| 	res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; |  | ||||||
|  |  | ||||||
| 	res = new_resource(dev, 3); /* IOAPIC */ |  | ||||||
| 	res->base = 0xfec00000; |  | ||||||
| 	res->size = 0x00001000; |  | ||||||
| 	res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static struct device_operations w83c553_ops  = { |  | ||||||
|         .read_resources   = w83c553_read_resources, |  | ||||||
|         .set_resources    = pci_dev_set_resources, |  | ||||||
|         .enable_resources = w83c553_enable_resources, |  | ||||||
|         .init             = w83c553_init, |  | ||||||
|         .scan_bus         = scan_static_bus, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static const struct pci_driver w83c553f_pci_driver __pci_driver = { |  | ||||||
| 	/* w83c553f */ |  | ||||||
| 	.ops = &w83c553_ops, |  | ||||||
| 	.device = PCI_DEVICE_ID_WINBOND_83C553, |  | ||||||
| 	.vendor = PCI_VENDOR_ID_WINBOND, |  | ||||||
| }; |  | ||||||
| @@ -1,198 +0,0 @@ | |||||||
| /* |  | ||||||
|  * (C) Copyright 2000 |  | ||||||
|  * Rob Taylor, Flying Pig Systems. robt@flyingpig.com. |  | ||||||
|  * |  | ||||||
|  * See file CREDITS for list of people who contributed to this |  | ||||||
|  * project. |  | ||||||
|  * |  | ||||||
|  * 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., 51 Franklin St, Fifth Floor, Boston, |  | ||||||
|  * MA 02110-1301 USA |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #ifndef _W83C553_H |  | ||||||
| #define _W83C553_H |  | ||||||
|  |  | ||||||
|  /* winbond access routines and defines*/ |  | ||||||
|  |  | ||||||
| /* from the winbond data sheet - |  | ||||||
|  The W83C553F SIO controller with PCI arbiter is a multi-function PCI device. |  | ||||||
|  Function 0 is the ISA bridge, and Function 1 is the bus master IDE controller. |  | ||||||
| */ |  | ||||||
|  |  | ||||||
| /*ISA bridge configuration space*/ |  | ||||||
|  |  | ||||||
| #define W83C553F_VID		0x10AD |  | ||||||
| #define W83C553F_DID		0x0565 |  | ||||||
| #define W83C553F_IDE		0x0105 |  | ||||||
|  |  | ||||||
| /* Function 0 registers */ |  | ||||||
| #define W83C553F_PCICONTR	0x40  /*pci control reg*/ |  | ||||||
| #define W83C553F_SGBAR		0x41  /*scatter/gather base address reg*/ |  | ||||||
| #define W83C553F_LBCR		0x42  /*Line Buffer Control reg*/ |  | ||||||
| #define W83C553F_IDEIRCR	0x43  /*IDE Interrupt Routing Control  Reg*/ |  | ||||||
| #define W83C553F_PCIIRCR	0x44  /*PCI Interrupt Routing Control Reg*/ |  | ||||||
| #define W83C553F_BTBAR		0x46  /*BIOS Timer Base Address Register*/ |  | ||||||
| #define W83C553F_IPADCR		0x48  /*ISA to PCI Address Decoder Control Register*/ |  | ||||||
| #define W83C553F_IRADCR		0x49  /*ISA ROM Address Decoder Control Register*/ |  | ||||||
| #define W83C553F_IPMHSAR	0x4a  /*ISA to PCI Memory Hole STart Address Register*/ |  | ||||||
| #define W83C553F_IPMHSR		0x4b  /*ISA to PCI Memory Hols Size Register*/ |  | ||||||
| #define W83C553F_CDR			0x4c  /*Clock Divisor Register*/ |  | ||||||
| #define W83C553F_CSCR		0x4d  /*Chip Select Control Register*/ |  | ||||||
| #define W83C553F_ATSCR		0x4e  /*AT System Control register*/ |  | ||||||
| #define W83C553F_ATBCR		0x4f  /*AT Bus ControL Register*/ |  | ||||||
| #define W83C553F_IRQBEE0R	0x60  /*IRQ Break Event Enable 0 Register*/ |  | ||||||
| #define W83C553F_IRQBEE1R	0x61  /*IRQ Break Event Enable 1 Register*/ |  | ||||||
| #define W83C553F_ABEER		0x62  /*Additional Break Event Enable Register*/ |  | ||||||
| #define W83C553F_DMABEER	0x63  /*DMA Break Event Enable Register*/ |  | ||||||
|  |  | ||||||
| /* Function 1 registers */ |  | ||||||
| #define W83C553F_PIR		0x09  /*Programming Interface Register*/ |  | ||||||
| #define W83C553F_IDECSR		0x40  /*IDE Control/Status Register*/ |  | ||||||
|  |  | ||||||
| /* register bit definitions */ |  | ||||||
| #define W83C553F_IPADCR_MBE512		0x1 |  | ||||||
| #define W83C553F_IPADCR_MBE640		0x2 |  | ||||||
| #define W83C553F_IPADCR_IPATOM4		0x10 |  | ||||||
| #define W83C553F_IPADCR_IPATOM5		0x20 |  | ||||||
| #define W83C553F_IPADCR_IPATOM6		0x40 |  | ||||||
| #define W83C553F_IPADCR_IPATOM7		0x80 |  | ||||||
|  |  | ||||||
| #define W83C553F_CSCR_UBIOSCSE		0x10 |  | ||||||
| #define W83C553F_CSCR_BIOSWP		0x20 |  | ||||||
|  |  | ||||||
| #define W83C553F_IDECSR_P0EN		0x01 |  | ||||||
| #define W83C553F_IDECSR_P0F16		0x02 |  | ||||||
| #define W83C553F_IDECSR_P1EN		0x10 |  | ||||||
| #define W83C553F_IDECSR_P1F16		0x20 |  | ||||||
| #define W83C553F_IDECSR_LEGIRQ		0x800 |  | ||||||
|  |  | ||||||
| #define W83C553F_ATSCR_ISARE		0x40 |  | ||||||
| #define W83C553F_ATSCR_FERRE		0x10 |  | ||||||
| #define W83C553F_ATSCR_P92E		0x04 |  | ||||||
| #define W83C553F_ATSCR_KRCEE		0x02 |  | ||||||
| #define W83C553F_ATSCR_KGA20EE		0x01 |  | ||||||
|  |  | ||||||
| #define W83C553F_PIR_BM			0x80 |  | ||||||
| #define W83C553F_PIR_P1PROG		0x08 |  | ||||||
| #define W83C553F_PIR_P1NL		0x04 |  | ||||||
| #define W83C553F_PIR_P0PROG		0x02 |  | ||||||
| #define W83C553F_PIR_P0NL		0x01 |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Interrupt controller |  | ||||||
|  */ |  | ||||||
| #define W83C553F_PIC1_ICW1	CONFIG_ISA_IO + 0x20 |  | ||||||
| #define W83C553F_PIC1_ICW2	CONFIG_ISA_IO + 0x21 |  | ||||||
| #define W83C553F_PIC1_ICW3	CONFIG_ISA_IO + 0x21 |  | ||||||
| #define W83C553F_PIC1_ICW4	CONFIG_ISA_IO + 0x21 |  | ||||||
| #define W83C553F_PIC1_OCW1	CONFIG_ISA_IO + 0x21 |  | ||||||
| #define W83C553F_PIC1_OCW2	CONFIG_ISA_IO + 0x20 |  | ||||||
| #define W83C553F_PIC1_OCW3	CONFIG_ISA_IO + 0x20 |  | ||||||
| #define W83C553F_PIC1_ELC	CONFIG_ISA_IO + 0x4D0 |  | ||||||
| #define W83C553F_PIC2_ICW1	CONFIG_ISA_IO + 0xA0 |  | ||||||
| #define W83C553F_PIC2_ICW2	CONFIG_ISA_IO + 0xA1 |  | ||||||
| #define W83C553F_PIC2_ICW3	CONFIG_ISA_IO + 0xA1 |  | ||||||
| #define W83C553F_PIC2_ICW4	CONFIG_ISA_IO + 0xA1 |  | ||||||
| #define W83C553F_PIC2_OCW1	CONFIG_ISA_IO + 0xA1 |  | ||||||
| #define W83C553F_PIC2_OCW2	CONFIG_ISA_IO + 0xA0 |  | ||||||
| #define W83C553F_PIC2_OCW3	CONFIG_ISA_IO + 0xA0 |  | ||||||
| #define W83C553F_PIC2_ELC	CONFIG_ISA_IO + 0x4D1 |  | ||||||
|  |  | ||||||
| #define W83C553F_TMR1_CMOD	CONFIG_ISA_IO + 0x43 |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * DMA controller |  | ||||||
|  */ |  | ||||||
| #define W83C553F_DMA1	CONFIG_ISA_IO + 0x000	/* channel 0 - 3 */ |  | ||||||
| #define W83C553F_DMA2	CONFIG_ISA_IO + 0x0C0	/* channel 4 - 7 */ |  | ||||||
|  |  | ||||||
| /* command/status register bit definitions */ |  | ||||||
|  |  | ||||||
| #define W83C553F_CS_COM_DACKAL	(1<<7)	/* DACK# assert level */ |  | ||||||
| #define W83C553F_CS_COM_DREQSAL	(1<<6)	/* DREQ sense assert level */ |  | ||||||
| #define W83C553F_CS_COM_GAP	(1<<4)	/* group arbitration priority */ |  | ||||||
| #define W83C553F_CS_COM_CGE	(1<<2)	/* channel group enable */ |  | ||||||
|  |  | ||||||
| #define W83C553F_CS_STAT_CH0REQ	(1<<4)	/* channel 0 (4) DREQ status */ |  | ||||||
| #define W83C553F_CS_STAT_CH1REQ	(1<<5)	/* channel 1 (5) DREQ status */ |  | ||||||
| #define W83C553F_CS_STAT_CH2REQ	(1<<6)	/* channel 2 (6) DREQ status */ |  | ||||||
| #define W83C553F_CS_STAT_CH3REQ	(1<<7)	/* channel 3 (7) DREQ status */ |  | ||||||
|  |  | ||||||
| #define W83C553F_CS_STAT_CH0TC	(1<<0)	/* channel 0 (4) TC status */ |  | ||||||
| #define W83C553F_CS_STAT_CH1TC	(1<<1)	/* channel 1 (5) TC status */ |  | ||||||
| #define W83C553F_CS_STAT_CH2TC	(1<<2)	/* channel 2 (6) TC status */ |  | ||||||
| #define W83C553F_CS_STAT_CH3TC	(1<<3)	/* channel 3 (7) TC status */ |  | ||||||
|  |  | ||||||
| /* mode register bit definitions */ |  | ||||||
|  |  | ||||||
| #define W83C553F_MODE_TM_DEMAND	(0<<6)	/* transfer mode - demand */ |  | ||||||
| #define W83C553F_MODE_TM_SINGLE	(1<<6)	/* transfer mode - single */ |  | ||||||
| #define W83C553F_MODE_TM_BLOCK	(2<<6)	/* transfer mode - block */ |  | ||||||
| #define W83C553F_MODE_TM_CASCADE	(3<<6)	/* transfer mode - cascade */ |  | ||||||
| #define W83C553F_MODE_ADDRDEC	(1<<5)	/* address increment/decrement select */ |  | ||||||
| #define W83C553F_MODE_AUTOINIT	(1<<4)	/* autoinitialize enable */ |  | ||||||
| #define W83C553F_MODE_TT_VERIFY	(0<<2)	/* transfer type - verify */ |  | ||||||
| #define W83C553F_MODE_TT_WRITE	(1<<2)	/* transfer type - write */ |  | ||||||
| #define W83C553F_MODE_TT_READ	(2<<2)	/* transfer type - read */ |  | ||||||
| #define W83C553F_MODE_TT_ILLEGAL	(3<<2)	/* transfer type - illegal */ |  | ||||||
| #define W83C553F_MODE_CH0SEL	(0<<0)	/* channel 0 (4) select */ |  | ||||||
| #define W83C553F_MODE_CH1SEL	(1<<0)	/* channel 1 (5) select */ |  | ||||||
| #define W83C553F_MODE_CH2SEL	(2<<0)	/* channel 2 (6) select */ |  | ||||||
| #define W83C553F_MODE_CH3SEL	(3<<0)	/* channel 3 (7) select */ |  | ||||||
|  |  | ||||||
| /* request register bit definitions */ |  | ||||||
|  |  | ||||||
| #define W83C553F_REQ_CHSERREQ	(1<<2)	/* channel service request */ |  | ||||||
| #define W83C553F_REQ_CH0SEL	(0<<0)	/* channel 0 (4) select */ |  | ||||||
| #define W83C553F_REQ_CH1SEL	(1<<0)	/* channel 1 (5) select */ |  | ||||||
| #define W83C553F_REQ_CH2SEL	(2<<0)	/* channel 2 (6) select */ |  | ||||||
| #define W83C553F_REQ_CH3SEL	(3<<0)	/* channel 3 (7) select */ |  | ||||||
|  |  | ||||||
| /* write single mask bit register bit definitions */ |  | ||||||
|  |  | ||||||
| #define W83C553F_WSMB_CHMASKSEL	(1<<2)	/* channel mask select */ |  | ||||||
| #define W83C553F_WSMB_CH0SEL	(0<<0)	/* channel 0 (4) select */ |  | ||||||
| #define W83C553F_WSMB_CH1SEL	(1<<0)	/* channel 1 (5) select */ |  | ||||||
| #define W83C553F_WSMB_CH2SEL	(2<<0)	/* channel 2 (6) select */ |  | ||||||
| #define W83C553F_WSMB_CH3SEL	(3<<0)	/* channel 3 (7) select */ |  | ||||||
|  |  | ||||||
| /* read/write all mask bits register bit definitions */ |  | ||||||
|  |  | ||||||
| #define W83C553F_RWAMB_CH0MASK	(1<<0)	/* channel 0 (4) mask */ |  | ||||||
| #define W83C553F_RWAMB_CH1MASK	(1<<1)	/* channel 1 (5) mask */ |  | ||||||
| #define W83C553F_RWAMB_CH2MASK	(1<<2)	/* channel 2 (6) mask */ |  | ||||||
| #define W83C553F_RWAMB_CH3MASK	(1<<3)	/* channel 3 (7) mask */ |  | ||||||
|  |  | ||||||
| /* typedefs */ |  | ||||||
|  |  | ||||||
| #define W83C553F_DMA1_CS		0x8 |  | ||||||
| #define W83C553F_DMA1_WR		0x9 |  | ||||||
| #define W83C553F_DMA1_WSMB		0xA |  | ||||||
| #define W83C553F_DMA1_WM		0xB |  | ||||||
| #define W83C553F_DMA1_CBP		0xC |  | ||||||
| #define W83C553F_DMA1_MC		0xD |  | ||||||
| #define W83C553F_DMA1_CM		0xE |  | ||||||
| #define W83C553F_DMA1_RWAMB		0xF |  | ||||||
|  |  | ||||||
| #define W83C553F_DMA2_CS		0xD0 |  | ||||||
| #define W83C553F_DMA2_WR		0xD2 |  | ||||||
| #define W83C553F_DMA2_WSMB		0xD4 |  | ||||||
| #define W83C553F_DMA2_WM		0xD6 |  | ||||||
| #define W83C553F_DMA2_CBP		0xD8 |  | ||||||
| #define W83C553F_DMA2_MC		0xDA |  | ||||||
| #define W83C553F_DMA2_CM		0xDC |  | ||||||
| #define W83C553F_DMA2_RWAMB		0xDE |  | ||||||
|  |  | ||||||
| #endif /* _W83C553_H */ |  | ||||||
| @@ -1,113 +0,0 @@ | |||||||
| /* |  | ||||||
|  * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> |  | ||||||
|  * Andreas Heppel <aheppel@sysgo.de> |  | ||||||
|  * |  | ||||||
|  * See file CREDITS for list of people who contributed to this |  | ||||||
|  * project. |  | ||||||
|  * |  | ||||||
|  * 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., 51 Franklin St, Fifth Floor, Boston, |  | ||||||
|  * MA 02110-1301 USA |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Enable IDE controller of the W83C553F chip. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #include <console/console.h> |  | ||||||
| #include <device/device.h> |  | ||||||
| #include <device/pci.h> |  | ||||||
| #include <device/pci_ids.h> |  | ||||||
| #include <device/pci_ops.h> |  | ||||||
| #include "w83c553f.h" |  | ||||||
|  |  | ||||||
| #ifndef CONFIG_IDE_MAXBUS |  | ||||||
| #define CONFIG_IDE_MAXBUS	2 |  | ||||||
| #endif |  | ||||||
| #ifndef CONFIG_IDE_MAXDEVICE |  | ||||||
| #define CONFIG_IDE_MAXDEVICE	(CONFIG_IDE_MAXBUS*2) |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| uint32_t ide_base[CONFIG_IDE_MAXBUS];  |  | ||||||
|  |  | ||||||
| static void  |  | ||||||
| w83c553_ide_init(struct device *dev) |  | ||||||
| { |  | ||||||
| 	unsigned char reg8; |  | ||||||
| 	unsigned short reg16; |  | ||||||
| 	unsigned int reg32; |  | ||||||
|  |  | ||||||
| 	printk_info("Configure W83C553F IDE (Function 1)\n"); |  | ||||||
|  |  | ||||||
| 	/* |  | ||||||
| 	 * Enable native mode on IDE ports and set base address. |  | ||||||
| 	 */ |  | ||||||
| 	reg8 = W83C553F_PIR_P1NL | W83C553F_PIR_P0NL; |  | ||||||
| 	pci_write_config8(dev, W83C553F_PIR, reg8); |  | ||||||
| 	pci_write_config32(dev, PCI_BASE_ADDRESS_0, 0xffffffff); |  | ||||||
| 	reg32 = pci_read_config32(dev, PCI_BASE_ADDRESS_0); |  | ||||||
| 	pci_write_config32(dev, PCI_BASE_ADDRESS_0, 0x1f0); |  | ||||||
| 	reg32 = pci_read_config32(dev, PCI_BASE_ADDRESS_0); |  | ||||||
| 	pci_write_config32(dev, PCI_BASE_ADDRESS_1, 0xffffffff); |  | ||||||
| 	reg32 = pci_read_config32(dev, PCI_BASE_ADDRESS_1); |  | ||||||
| 	pci_write_config32(dev, PCI_BASE_ADDRESS_1, 0x3f6); |  | ||||||
| 	reg32 = pci_read_config32(dev, PCI_BASE_ADDRESS_1); |  | ||||||
| 	pci_write_config32(dev, PCI_BASE_ADDRESS_2, 0xffffffff); |  | ||||||
| 	reg32 = pci_read_config32(dev, PCI_BASE_ADDRESS_2); |  | ||||||
| 	pci_write_config32(dev, PCI_BASE_ADDRESS_2, 0x170); |  | ||||||
| 	reg32 = pci_read_config32(dev, PCI_BASE_ADDRESS_2); |  | ||||||
| 	pci_write_config32(dev, PCI_BASE_ADDRESS_3, 0xffffffff); |  | ||||||
| 	reg32 = pci_read_config32(dev, PCI_BASE_ADDRESS_3); |  | ||||||
| 	pci_write_config32(dev, PCI_BASE_ADDRESS_3, 0x376); |  | ||||||
| 	reg32 = pci_read_config32(dev, PCI_BASE_ADDRESS_3); |  | ||||||
|  |  | ||||||
| 	/* |  | ||||||
| 	 * Set read-ahead duration to 0xff |  | ||||||
| 	 * Enable P0 and P1 |  | ||||||
| 	 */ |  | ||||||
| 	reg32 = 0x00ff0000 | W83C553F_IDECSR_P1EN | W83C553F_IDECSR_P0EN; |  | ||||||
| 	pci_write_config32(dev, W83C553F_IDECSR, reg32); |  | ||||||
|  |  | ||||||
| 	ide_base[0] = pci_read_config32(dev, PCI_BASE_ADDRESS_0); |  | ||||||
| 	printk_debug("ide bus offset = 0x%x\n", ide_base[0]); |  | ||||||
| 	ide_base[0] &= ~1; |  | ||||||
| #if CONFIG_IDE_MAXBUS > 1 |  | ||||||
| 	ide_base[1] = pci_read_config32(dev, PCI_BASE_ADDRESS_2); |  | ||||||
| 	ide_base[1] &= ~1; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| 	/* |  | ||||||
| 	 * Enable function 1, IDE -> busmastering and IO space access |  | ||||||
| 	 */ |  | ||||||
| 	reg16 = pci_read_config16(dev, PCI_COMMAND); |  | ||||||
| 	reg16 |= PCI_COMMAND_MASTER | PCI_COMMAND_IO; |  | ||||||
| 	pci_write_config16(dev, PCI_COMMAND, reg16); |  | ||||||
|  |  | ||||||
| 	printk_info("IDE configuration complete\n"); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static struct device_operations w83c553_ide_ops  = { |  | ||||||
|         .read_resources   = pci_dev_read_resources, |  | ||||||
|         .set_resources    = pci_dev_set_resources, |  | ||||||
|         .enable_resources = pci_dev_enable_resources, |  | ||||||
|         .init             = w83c553_ide_init, |  | ||||||
|         .scan_bus         = 0, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static const struct pci_driver w83c553f_ide_pci_driver __pci_driver = { |  | ||||||
| 	/* w83c553f_ide */ |  | ||||||
| 	.ops = &w83c553_ide_ops, |  | ||||||
| 	.device = PCI_DEVICE_ID_WINBOND_82C105, |  | ||||||
| 	.vendor = PCI_VENDOR_ID_WINBOND, |  | ||||||
| }; |  | ||||||
| @@ -43,8 +43,6 @@ sed \ | |||||||
| 	-e "/^CONFIG_ROMBASE / d" \ | 	-e "/^CONFIG_ROMBASE / d" \ | ||||||
| 	-e "/^CONFIG_ROM_IMAGE_SIZE / d" \ | 	-e "/^CONFIG_ROM_IMAGE_SIZE / d" \ | ||||||
| 	-e "/^CONFIG_STACK_SIZE / d" \ | 	-e "/^CONFIG_STACK_SIZE / d" \ | ||||||
| 	-e "/^CONFIG_IDE_BOOT_DRIVE / d" \ |  | ||||||
| 	-e "/^CONFIG_IDE_OFFSET / d" \ |  | ||||||
| 	-e "/^CONFIG_GDB_STUB / d" \ | 	-e "/^CONFIG_GDB_STUB / d" \ | ||||||
| 	$A/old > $A/old.filtered | 	$A/old > $A/old.filtered | ||||||
| sed \ | sed \ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user