<commit_before>/*
 *  Copyright (C) 1998-2000 <NAME>, Maintainer
 *  Copyright (C) 1998-2000 <NAME>, Maintainer
 *  Copyright (C) 1999-2000 CJ, <EMAIL>, Maintainer
 *
 *  Copyright (C) 1998-2000 <NAME> (<EMAIL>)
 *  May be copied or modified under the terms of the GNU General Public License
 *  Copyright (C) 2002 <NAME>
 *  ALi (now ULi M5228) support by <NAME> <<EMAIL>>
 *  Copyright (C) 2007 MontaVista Software, Inc. <<EMAIL>>
 *  Copyright (C) 2007-2010 <NAME>
 *
 *  (U)DMA capable version of ali 1533/1543(C), 1535(D)
 *
 **********************************************************************
 *  9/7/99 --Parts from the above author are included and need to be
 *  converted into standard interface, once I finish the thought.
 *
 *  Recent changes
 *	Don't use LBA48 mode on ALi <= 0xC4
 *	Don't poke 0x79 with a non ALi northbridge
 *	Don't flip undefined bits on newer chipsets (fix Fujitsu laptop hang)
 *	Allow UDMA6 on revisions > 0xC4
 *
 *  Documentation
 *	Chipset documentation available under NDA only
 *
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/dmi.h>

#include <asm/io.h>

#define DRV_NAME "alim15x3"

/*
 *	ALi devices are not plug in. Otherwise these static values would
 *	need to go. They ought to go away anyway
 */
 
static u8 m5229_revision;
static u8 chip_is_1543c_e;
static struct pci_dev *isa_dev;

static void ali_fifo_control(ide_hwif_t *hwif, ide_drive_t *drive, int on)
{
	struct pci_dev *pdev = to_pci_dev(hwif->dev);
	int pio_fifo = 0x54 + hwif->channel;
	u8 fifo;
	int shift = 4 * (drive->dn & 1);

	pci_read_config_byte(pdev, pio_fifo, &fifo);
	fifo &= ~(0x0F << shift);
	fifo |= (on << shift);
	pci_write_config_byte(pdev, pio_fifo, fifo);
}

/**
 *	ali_set_pio_mode	-	set host controller for PIO mode
 *	@hwif: port
 *	@drive: drive
 *
 *	Program the controller for the given PIO mode.
 */

static void ali_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
	struct pci_dev *dev = to_pci_dev(hwif->dev);
	ide_drive_t *pair = ide_get_pair_dev(drive);
	int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
	unsigned long T =  1000000 / bus_speed; /* PCI clock based */
	int port = hwif->channel ? 0x5c : 0x58;
	u8 unit = drive->dn & 1;
	struct ide_timing t;

	ide_timing_compute(drive, drive->pio_mode, &t, T, 1);
	if (pair) {
		struct ide_timing p;

		ide_timing_compute(pair, pair->pio_mode, &p, T, 1);
		ide_timing_merge(&p, &t, &t,
			IDE_TIMING_SETUP | IDE_TIMING_8BIT);
		if (pair->dma_mode) {
			ide_timing_compute(pair, pair->dma_mode, &p, T, 1);
			ide_timing_merge(&p, &t, &t,
				IDE_TIMING_SETUP | IDE_TIMING_8BIT);
		}
	}

	t.setup = clamp_val(t.setup, 1, 8) & 7;
	t.act8b = clamp_val(t.act8b, 1, 8) & 7;
	t.rec8b = clamp_val(t.rec8b, 1, 16) & 15;
	t.active = clamp_val(t.active, 1, 8) & 7;
	t.recover = clamp_val(t.recover, 1, 16) & 15;

	/* 
	 * PIO mode => ATA FIFO on, ATAPI FIFO off
	 */
	ali_fifo_control(hwif, drive, (drive->media == ide_disk) ? 0x05 : 0x00);

	pci_write_config_byte(dev, port, t.setup);
	pci_write_config_byte(dev, port + 1, (t.act8b << 4) | t.rec8b);
	pci_write_config_byte(dev, port + unit + 2,
			      (t.active << 4) | t.recover);
}

/**
 *	ali_udma_filter		-	compute UDMA mask
 *	@drive: IDE device
 *
 *	Return available UDMA modes.
 *
 *	The actual rules for the ALi are:
 *		No UDMA on revisions <= 0x20
 *		Disk only for revisions < 0xC2
 *		Not WDC drives on M1543C-E (?)
 */

static u8 ali_udma_filter(ide_drive_t *drive)
{
	if (m5229_revision > 0x20 && m5229_revision < 0xC2) {
		if (drive->media != ide_disk)
			return 0;
		if (chip_is_1543c_e &&
		    strstr((char *)&drive->id[ATA_ID_PROD], "WDC "))
			return 0;
	}

	return drive->hwif->ultra_mask;
}

/**
 *	ali_set_dma_mode	-	set host controller for DMA mode
 *	@hwif: port
 *	@drive: drive
 *
 *	Configure the hardware for the desired IDE transfer mode.
 */

static void ali_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	const u8 speed		= drive->dma_mode;
	u8 speed1		= speed;
	u8 unit			= drive->dn & 1;
	u8 tmpbyte		= 0x00;
	int m5229_udma		= (hwif->channel) ? 0x57 : 0x56;

	if (speed == XFER_UDMA_6)
		speed1 = 0x47;

	if (speed < XFER_UDMA_0) {
		u8 ultra_enable	= (unit) ? 0x7f : 0xf7;
		/*
		 * clear "ultra enable" bit
		 */
		pci_read_config_byte(dev, m5229_udma, &tmpbyte);
		tmpbyte &= ultra_enable;
		pci_write_config_byte(dev, m5229_udma, tmpbyte);

		/*
		 * FIXME: Oh, my... DMA timings are never set.
		 */
	} else {
		pci_read_config_byte(dev, m5229_udma, &tmpbyte);
		tmpbyte &= (0x0f << ((1-unit) << 2));
		/*
		 * enable ultra dma and set timing
		 */
		tmpbyte |= ((0x08 | ((4-speed1)&0x07)) << (unit << 2));<commit_msg>alim15x3: fix handling of DMA timings<commit_after>/*
 *  Copyright (C) 1998-2000 <NAME>, Maintainer
 *  Copyright (C) 1998-2000 <NAME>, Maintainer
 *  Copyright (C) 1999-2000 CJ, <EMAIL>, Maintainer
 *
 *  Copyright (C) 1998-2000 <NAME> (<EMAIL>)
 *  May be copied or modified under the terms of the GNU General Public License
 *  Copyright (C) 2002 <NAME>
 *  ALi (now ULi M5228) support by Clear Zhang <<EMAIL>>
 *  Copyright (C) 2007 MontaVista Software, Inc. <<EMAIL>>
 *  Copyright (C) 2007-2010 <NAME>
 *
 *  (U)DMA capable version of ali 1533/1543(C), 1535(D)
 *
 **********************************************************************
 *  9/7/99 --Parts from the above author are included and need to be
 *  converted into standard interface, once I finish the thought.
 *
 *  Recent changes
 *	Don't use LBA48 mode on ALi <= 0xC4
 *	Don't poke 0x79 with a non ALi northbridge
 *	Don't flip undefined bits on newer chipsets (fix Fujitsu laptop hang)
 *	Allow UDMA6 on revisions > 0xC4
 *
 *  Documentation
 *	Chipset documentation available under NDA only
 *
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/dmi.h>

#include <asm/io.h>

#define DRV_NAME "alim15x3"

/*
 *	ALi devices are not plug in. Otherwise these static values would
 *	need to go. They ought to go away anyway
 */
 
static u8 m5229_revision;
static u8 chip_is_1543c_e;
static struct pci_dev *isa_dev;

static void ali_fifo_control(ide_hwif_t *hwif, ide_drive_t *drive, int on)
{
	struct pci_dev *pdev = to_pci_dev(hwif->dev);
	int pio_fifo = 0x54 + hwif->channel;
	u8 fifo;
	int shift = 4 * (drive->dn & 1);

	pci_read_config_byte(pdev, pio_fifo, &fifo);
	fifo &= ~(0x0F << shift);
	fifo |= (on << shift);
	pci_write_config_byte(pdev, pio_fifo, fifo);
}

static void ali_program_timings(ide_hwif_t *hwif, ide_drive_t *drive,
				struct ide_timing *t)
{
	struct pci_dev *dev = to_pci_dev(hwif->dev);
	int port = hwif->channel ? 0x5c : 0x58;
	u8 unit = drive->dn & 1;

	t->setup = clamp_val(t->setup, 1, 8) & 7;
	t->act8b = clamp_val(t->act8b, 1, 8) & 7;
	t->rec8b = clamp_val(t->rec8b, 1, 16) & 15;
	t->active = clamp_val(t->active, 1, 8) & 7;
	t->recover = clamp_val(t->recover, 1, 16) & 15;

	pci_write_config_byte(dev, port, t->setup);
	pci_write_config_byte(dev, port + 1, (t->act8b << 4) | t->rec8b);
	pci_write_config_byte(dev, port + unit + 2,
			      (t->active << 4) | t->recover);
}

/**
 *	ali_set_pio_mode	-	set host controller for PIO mode
 *	@hwif: port
 *	@drive: drive
 *
 *	Program the controller for the given PIO mode.
 */

static void ali_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
	ide_drive_t *pair = ide_get_pair_dev(drive);
	int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
	unsigned long T =  1000000 / bus_speed; /* PCI clock based */
	struct ide_timing t;

	ide_timing_compute(drive, drive->pio_mode, &t, T, 1);
	if (pair) {
		struct ide_timing p;

		ide_timing_compute(pair, pair->pio_mode, &p, T, 1);
		ide_timing_merge(&p, &t, &t,
			IDE_TIMING_SETUP | IDE_TIMING_8BIT);
		if (pair->dma_mode) {
			ide_timing_compute(pair, pair->dma_mode, &p, T, 1);
			ide_timing_merge(&p, &t, &t,
				IDE_TIMING_SETUP | IDE_TIMING_8BIT);
		}
	}

	/* 
	 * PIO mode => ATA FIFO on, ATAPI FIFO off
	 */
	ali_fifo_control(hwif, drive, (drive->media == ide_disk) ? 0x05 : 0x00);

	ali_program_timings(hwif, drive, &t);
}

/**
 *	ali_udma_filter		-	compute UDMA mask
 *	@drive: IDE device
 *
 *	Return available UDMA modes.
 *
 *	The actual rules for the ALi are:
 *		No UDMA on revisions <= 0x20
 *		Disk only for revisions < 0xC2
 *		Not WDC drives on M1543C-E (?)
 */

static u8 ali_udma_filter(ide_drive_t *drive)
{
	if (m5229_revision > 0x20 && m5229_revision < 0xC2) {
		if (drive->media != ide_disk)
			return 0;
		if (chip_is_1543c_e &&
		    strstr((char *)&drive->id[ATA_ID_PROD], "WDC "))
			return 0;
	}

	return drive->hwif->ultra_mask;
}

/**
 *	ali_set_dma_mode	-	set host controller for DMA mode
 *	@hwif: port
 *	@drive: drive
 *
 *	Configure the hardware for the desired IDE transfer mode.
 */

static void ali_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	ide_drive_t *pair	= ide_get_pair_dev(drive);
	int bus_speed		= ide_pci_clk ? ide_pci_clk : 33;
	unsigned long T		=  1000000 / bus_speed; /* PCI clock based */
	const u8 speed		= drive->dma_mode;
	u8 speed1		= speed;
	u8 unit			= drive->dn & 1;
	u8 tmpbyte		= 0x00;
	int m5229_udma		= (hwif->channel) ? 0x57 : 0x56;
	struct ide_timing t;

	if (speed == XFER_UDMA_6)
		speed1 = 0x47;

	if (speed < XFER_UDMA_0) {
		u8 ultra_enable	= (unit) ? 0x7f : 0xf7;
		/*
		 * clear "ultra enable" bit
		 */
		pci_read_config_byte(dev, m5229_udma, &tmpbyte);
		tmpbyte &= ultra_enable;
		pci_write_config_byte(dev, m5229_udma, tmpbyte);

		ide_timing_compute(drive, drive->dma_mode, &t, T, 1);
		if (pair) {
			struct ide_timing p;

			ide_timing_compute(pair, pair->pio_mode, &p, T, 1);
			ide_timing_merge(&p, &t, &t,
				IDE_TIMING_SETUP | IDE_TIMING_8BIT);
			if (pair->dma_mode) {
				ide_timing_compute(pair, pair->dma_mode,
						&p, T, 1);
				ide_timing_merge(&p, &t, &t,
					IDE_TIMING_SETUP | IDE_TIMING_8BIT);
			}
		}
		ali_program_timings(hwif, drive, &t);
	} else {
		pci_read_config_byte(dev, m5229_udma, &tmpbyte);
		tmpbyte &= (0x0f << ((1-unit) << 2));
		/*
		 * enable ultra dma and set timing
		 */
		tmpbyte |= ((0x08 | ((4-speed1)&0x07)) << (unit << 2));
{'fraction_non_alphanumeric': 0.14984917777561546, 'fraction_numerical': 0.048165807142162106, 'mean_word_length': 3.776022304832714, 'pattern_counts': {'":': 0, '<': 84, '<?xml version=': 0, '>': 105, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3476906', 'n_tokens_mistral': 4715, 'n_tokens_neox': 4214, 'n_words': 1087}