All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Drake <dsd@gentoo.org>
To: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Cc: linux-kernel@vger.kernel.org, linux-ide@vger.kernel.org,
	posting@blx4.net, vsu@altlinux.ru
Subject: Re: [PATCH] via82cxxx IDE: Support multiple controllers
Date: Fri, 09 Sep 2005 23:19:56 +0100	[thread overview]
Message-ID: <43220A8C.7070508@gentoo.org> (raw)
In-Reply-To: <43179CC9.8090608@gentoo.org>

[-- Attachment #1: Type: text/plain, Size: 424 bytes --]

Bart, any word on this? I know you're busy but it would be much appreciated if 
you could comment, even if it is hurling abuse ;)

Thanks.

Daniel Drake wrote:
> Hows this? I don't have any hardware with two VIA controllers, however I 
> have tested this on a pc which has a single vt8233a controller.
> 
> ---
> 
> Support multiple controllers in the via82cxxx IDE driver
> 
> Signed-off-by: Daniel Drake <dsd@gentoo.org>


[-- Attachment #2: via82cxxx-multi.patch --]
[-- Type: text/x-patch, Size: 13513 bytes --]

--- linux/drivers/ide/pci/via82cxxx.c.orig	2005-08-31 01:32:05.000000000 +0100
+++ linux/drivers/ide/pci/via82cxxx.c	2005-09-02 01:16:59.000000000 +0100
@@ -101,11 +101,19 @@ static struct via_isa_bridge {
 	{ NULL }
 };
 
-static struct via_isa_bridge *via_config;
-static unsigned int via_80w;
-static unsigned int via_clock;
 static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
 
+struct via82cxxx_dev
+{
+	struct pci_dev *pci_dev, *isa_dev;
+	struct via_isa_bridge *via_config;
+	unsigned int via_clock;
+	unsigned int via_80w;
+};
+
+#define VIA_MAX_CONTROLLERS 4
+static struct via82cxxx_dev *via_controllers[VIA_MAX_CONTROLLERS];
+
 /*
  * VIA /proc entry.
  */
@@ -116,9 +124,6 @@ static char *via_dma[] = { "MWDMA16", "U
 #include <linux/proc_fs.h>
 
 static u8 via_proc = 0;
-static unsigned long via_base;
-static struct pci_dev *bmide_dev, *isa_dev;
-
 static char *via_control3[] = { "No limit", "64", "128", "192" };
 
 #define via_print(format, arg...) p += sprintf(p, format "\n" , ## arg)
@@ -127,43 +132,42 @@ static char *via_control3[] = { "No limi
 
 
 /**
- *	via_get_info		-	generate via /proc file 
- *	@buffer: buffer for data
- *	@addr: set to start of data to use
- *	@offset: current file offset
- *	@count: size of read
+ *	via_print_controller_info	-	produce /proc info for one controller
+ *	@p: buffer for data
+ *	@hwif: hwif of controller
  *
  *	Fills in buffer with the debugging/configuration information for
- *	the VIA chipset tuning and attached drives
+ *	the VIA chipset tuning and attached drives on the specified
+ *	controller. Returns the end of the buffer that was reached.
  */
- 
-static int via_get_info(char *buffer, char **addr, off_t offset, int count)
+
+static char* via_print_controller_info(char *p, struct via82cxxx_dev *vdev)
 {
+	struct pci_dev *dev = vdev->pci_dev;
 	int speed[4], cycle[4], setup[4], active[4], recover[4], den[4],
 		 uen[4], udma[4], umul[4], active8b[4], recover8b[4];
-	struct pci_dev *dev = bmide_dev;
 	unsigned int v, u, i;
-	int len;
 	u16 c, w;
 	u8 t, x;
-	char *p = buffer;
+	unsigned long via_base;
 
 	via_print("----------VIA BusMastering IDE Configuration"
 		"----------------");
 
 	via_print("Driver Version:                     3.38");
 	via_print("South Bridge:                       VIA %s",
-		via_config->name);
+		vdev->via_config->name);
 
-	pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t);
+	pci_read_config_byte(vdev->isa_dev, PCI_REVISION_ID, &t);
 	pci_read_config_byte(dev, PCI_REVISION_ID, &x);
 	via_print("Revision:                           ISA %#x IDE %#x", t, x);
 	via_print("Highest DMA rate:                   %s",
-		via_dma[via_config->flags & VIA_UDMA]);
+		via_dma[vdev->via_config->flags & VIA_UDMA]);
 
+	via_base = pci_resource_start(dev, 4);
 	via_print("BM-DMA base:                        %#lx", via_base);
 	via_print("PCI clock:                          %d.%dMHz",
-		via_clock / 1000, via_clock / 100 % 10);
+		vdev->via_clock / 1000, vdev->via_clock / 100 % 10);
 
 	pci_read_config_byte(dev, VIA_MISC_1, &t);
 	via_print("Master Read  Cycle IRDY:            %dws",
@@ -199,7 +203,7 @@ static int via_get_info(char *buffer, ch
 		(c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no");
 
 	via_print("Cable Type:            %10s%20s",
-		(via_80w & 1) ? "80w" : "40w", (via_80w & 2) ? "80w" : "40w");
+		(vdev->via_80w & 1) ? "80w" : "40w", (vdev->via_80w & 2) ? "80w" : "40w");
 
 	via_print("-------------------drive0----drive1"
 		"----drive2----drive3-----");
@@ -208,7 +212,7 @@ static int via_get_info(char *buffer, ch
 	pci_read_config_dword(dev, VIA_DRIVE_TIMING, &v);
 	pci_read_config_word(dev, VIA_8BIT_TIMING, &w);
 
-	if (via_config->flags & VIA_UDMA)
+	if (vdev->via_config->flags & VIA_UDMA)
 		pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
 	else u = 0;
 
@@ -224,32 +228,32 @@ static int via_get_info(char *buffer, ch
 		uen[i]       = ((u >> ((3 - i) << 3)) & 0x20);
 		den[i]       = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2));
 
-		speed[i] = 2 * via_clock / (active[i] + recover[i]);
-		cycle[i] = 1000000 * (active[i] + recover[i]) / via_clock;
+		speed[i] = 2 * vdev->via_clock / (active[i] + recover[i]);
+		cycle[i] = 1000000 * (active[i] + recover[i]) / vdev->via_clock;
 
 		if (!uen[i] || !den[i])
 			continue;
 
-		switch (via_config->flags & VIA_UDMA) {
+		switch (vdev->via_config->flags & VIA_UDMA) {
 
 			case VIA_UDMA_33:
-				speed[i] = 2 * via_clock / udma[i];
-				cycle[i] = 1000000 * udma[i] / via_clock;
+				speed[i] = 2 * vdev->via_clock / udma[i];
+				cycle[i] = 1000000 * udma[i] / vdev->via_clock;
 				break;
 
 			case VIA_UDMA_66:
-				speed[i] = 4 * via_clock / (udma[i] * umul[i]);
-				cycle[i] = 500000 * (udma[i] * umul[i]) / via_clock;
+				speed[i] = 4 * vdev->via_clock / (udma[i] * umul[i]);
+				cycle[i] = 500000 * (udma[i] * umul[i]) / vdev->via_clock;
 				break;
 
 			case VIA_UDMA_100:
-				speed[i] = 6 * via_clock / udma[i];
-				cycle[i] = 333333 * udma[i] / via_clock;
+				speed[i] = 6 * vdev->via_clock / udma[i];
+				cycle[i] = 333333 * udma[i] / vdev->via_clock;
 				break;
 
 			case VIA_UDMA_133:
-				speed[i] = 8 * via_clock / udma[i];
-				cycle[i] = 250000 * udma[i] / via_clock;
+				speed[i] = 8 * vdev->via_clock / udma[i];
+				cycle[i] = 250000 * udma[i] / vdev->via_clock;
 				break;
 		}
 	}
@@ -258,20 +262,46 @@ static int via_get_info(char *buffer, ch
 		den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO");
 
 	via_print_drive("Address Setup: ", "%8dns",
-		1000000 * setup[i] / via_clock);
+		1000000 * setup[i] / vdev->via_clock);
 	via_print_drive("Cmd Active:    ", "%8dns",
-		1000000 * active8b[i] / via_clock);
+		1000000 * active8b[i] / vdev->via_clock);
 	via_print_drive("Cmd Recovery:  ", "%8dns",
-		1000000 * recover8b[i] / via_clock);
+		1000000 * recover8b[i] / vdev->via_clock);
 	via_print_drive("Data Active:   ", "%8dns",
-		1000000 * active[i] / via_clock);
+		1000000 * active[i] / vdev->via_clock);
 	via_print_drive("Data Recovery: ", "%8dns",
-		1000000 * recover[i] / via_clock);
+		1000000 * recover[i] / vdev->via_clock);
 	via_print_drive("Cycle Time:    ", "%8dns",
 		cycle[i]);
 	via_print_drive("Transfer Rate: ", "%4d.%dMB/s",
 		speed[i] / 1000, speed[i] / 100 % 10);
 
+	return p;
+}
+
+/**
+ *	via_get_info		-	generate via /proc file 
+ *	@buffer: buffer for data
+ *	@addr: set to start of data to use
+ *	@offset: current file offset
+ *	@count: size of read
+ *
+ *	Fills in buffer with the debugging/configuration information for
+ *	the VIA chipset tuning and attached drives of all controllers
+ */
+ 
+static int via_get_info(char *buffer, char **addr, off_t offset, int count)
+{
+	unsigned int i;
+	int len;
+	char *p = buffer;
+
+	for (i = 0; i < VIA_MAX_CONTROLLERS; i++)
+		if (via_controllers[i] != NULL) {
+			via_print("====== CONTROLLER %d ======\n", i+1);
+			p = via_print_controller_info(p, via_controllers[i]);
+		}
+
 	/* hoping it is less than 4K... */
 	len = (p - buffer) - offset;
 	*addr = buffer + offset;
@@ -283,18 +313,20 @@ static int via_get_info(char *buffer, ch
 
 /**
  *	via_set_speed			-	write timing registers
- *	@dev: PCI device
+ *	@hwif: hwif of device
  *	@dn: device
  *	@timing: IDE timing data to use
  *
  *	via_set_speed writes timing values to the chipset registers
  */
 
-static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
+static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
 {
+	struct pci_dev *dev = hwif->pci_dev;
+	struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif);
 	u8 t;
 
-	if (~via_config->flags & VIA_BAD_AST) {
+	if (~vdev->via_config->flags & VIA_BAD_AST) {
 		pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
 		t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
 		pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t);
@@ -306,7 +338,7 @@ static void via_set_speed(struct pci_dev
 	pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn),
 		((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
 
-	switch (via_config->flags & VIA_UDMA) {
+	switch (vdev->via_config->flags & VIA_UDMA) {
 		case VIA_UDMA_33:  t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
 		case VIA_UDMA_66:  t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break;
 		case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
@@ -330,15 +362,16 @@ static void via_set_speed(struct pci_dev
 static int via_set_drive(ide_drive_t *drive, u8 speed)
 {
 	ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
+	struct via82cxxx_dev *vdev = ide_get_hwifdata(drive->hwif);
 	struct ide_timing t, p;
 	unsigned int T, UT;
 
 	if (speed != XFER_PIO_SLOW)
 		ide_config_drive_speed(drive, speed);
 
-	T = 1000000000 / via_clock;
+	T = 1000000000 / vdev->via_clock;
 
-	switch (via_config->flags & VIA_UDMA) {
+	switch (vdev->via_config->flags & VIA_UDMA) {
 		case VIA_UDMA_33:   UT = T;   break;
 		case VIA_UDMA_66:   UT = T/2; break;
 		case VIA_UDMA_100:  UT = T/3; break;
@@ -353,7 +386,7 @@ static int via_set_drive(ide_drive_t *dr
 		ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
 	}
 
-	via_set_speed(HWIF(drive)->pci_dev, drive->dn, &t);
+	via_set_speed(HWIF(drive), drive->dn, &t);
 
 	if (!drive->init_speed)
 		drive->init_speed = speed;
@@ -391,20 +424,22 @@ static void via82cxxx_tune_drive(ide_dri
  
 static int via82cxxx_ide_dma_check (ide_drive_t *drive)
 {
-	u16 w80 = HWIF(drive)->udma_four;
+	ide_hwif_t *hwif = HWIF(drive);
+	struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif);
+	u16 w80 = hwif->udma_four;
 
 	u16 speed = ide_find_best_mode(drive,
 		XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
-		(via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
-		(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
-		(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
-		(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
+		(vdev->via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
+		(w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
+		(w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
+		(w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
 
 	via_set_drive(drive, speed);
 
 	if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
-		return HWIF(drive)->ide_dma_on(drive);
-	return HWIF(drive)->ide_dma_off_quietly(drive);
+		return hwif->ide_dma_on(drive);
+	return hwif->ide_dma_off_quietly(drive);
 }
 
 /**
@@ -418,9 +453,11 @@ static int via82cxxx_ide_dma_check (ide_
 
 static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name)
 {
+	struct via82cxxx_dev *vdev;
+	struct via_isa_bridge *via_config;
 	struct pci_dev *isa = NULL;
 	u8 t, v;
-	unsigned int u;
+	unsigned int via_80w = 0, via_clock, u;
 	int i;
 
 	/*
@@ -444,6 +481,28 @@ static unsigned int __devinit init_chips
 	}
 
 	/*
+	 * Allocate and index a via82cxxx_dev for this controller
+	 */
+
+	for (i = 0; i <= VIA_MAX_CONTROLLERS; i++)
+		if (via_controllers[i] == NULL)
+			break;
+
+	if (i == VIA_MAX_CONTROLLERS) {
+		printk(KERN_WARNING "VP_IDE: Controller limit reached.\n");
+		return -ENODEV;
+	}
+
+	vdev = kmalloc(sizeof(struct via82cxxx_dev), GFP_KERNEL);
+	if (vdev == NULL) {
+		printk(KERN_ERR "VP_IDE: out of memory :(\n");
+		return -ENODEV;
+	}
+
+	memset(vdev, 0, sizeof(struct via82cxxx_dev));
+	via_controllers[i] = vdev;
+
+	/*
 	 * Check 80-wire cable presence and setup Clk66.
 	 */
 
@@ -562,14 +621,20 @@ static unsigned int __devinit init_chips
 		pci_name(dev));
 
 	/*
+	 * Populate our via82cxxx_dev
+	 */
+	vdev->pci_dev = dev;
+	vdev->isa_dev = isa;
+	vdev->via_config = via_config;
+	vdev->via_clock = via_clock;
+	vdev->via_80w = via_80w;
+
+	/*
 	 * Setup /proc/ide/via entry.
 	 */
 
 #if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
 	if (!via_proc) {
-		via_base = pci_resource_start(dev, 4);
-		bmide_dev = dev;
-		isa_dev = isa;
 		ide_pci_create_host_proc("via", via_get_info);
 		via_proc = 1;
 	}
@@ -580,6 +645,19 @@ static unsigned int __devinit init_chips
 static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
 {
 	int i;
+	struct via82cxxx_dev *vdev;
+
+	/*
+	 * Find the via82cxxx_dev we created at init_chipset time
+	 */
+
+	for (i = 0; i < VIA_MAX_CONTROLLERS; i++)
+		if (via_controllers[i] != NULL
+			&& via_controllers[i]->pci_dev == hwif->pci_dev)
+			break;
+
+	vdev = via_controllers[i];
+	ide_set_hwifdata(hwif, vdev);
 
 	hwif->autodma = 0;
 
@@ -595,7 +673,7 @@ static void __devinit init_hwif_via82cxx
 
 	for (i = 0; i < 2; i++) {
 		hwif->drives[i].io_32bit = 1;
-		hwif->drives[i].unmask = (via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
+		hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
 		hwif->drives[i].autotune = 1;
 		hwif->drives[i].dn = hwif->channel * 2 + i;
 	}
@@ -609,7 +687,7 @@ static void __devinit init_hwif_via82cxx
 	hwif->swdma_mask = 0x07;
 
 	if (!hwif->udma_four)
-		hwif->udma_four = (via_80w >> hwif->channel) & 1;
+		hwif->udma_four = (vdev->via_80w >> hwif->channel) & 1;
 	hwif->ide_dma_check = &via82cxxx_ide_dma_check;
 	if (!noautodma)
 		hwif->autodma = 1;
@@ -658,6 +736,7 @@ static struct pci_driver driver = {
 
 static int via_ide_init(void)
 {
+	memset(via_controllers, 0, sizeof(via_controllers));
 	return ide_pci_register_driver(&driver);
 }
 

  reply	other threads:[~2005-09-09 22:19 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-08-30 14:27 [PATCH] Add VIA VT6410 support Daniel Drake
2005-08-30 15:12 ` Bartlomiej Zolnierkiewicz
2005-09-02  0:28   ` [PATCH] via82cxxx IDE: Support multiple controllers Daniel Drake
2005-09-09 22:19     ` Daniel Drake [this message]
2005-09-27 13:20     ` Bartlomiej Zolnierkiewicz
2005-09-28 22:18       ` [PATCH] via82cxxx IDE: Remove /proc/via entry Daniel Drake
2005-09-28 22:37         ` Al Viro
2005-09-28 23:00           ` [PATCH] via82cxxx IDE: Remove /proc/ide/via entry Daniel Drake
2005-09-29  7:26             ` Bartlomiej Zolnierkiewicz
2005-09-28 22:48         ` [PATCH] via82cxxx IDE: Remove /proc/via entry Grzegorz Kulewski
2005-09-29  7:27           ` Bartlomiej Zolnierkiewicz
2005-10-09 15:18             ` Grzegorz Kulewski
2005-10-13 22:52               ` Daniel Drake
2005-11-18 20:39                 ` Bartlomiej Zolnierkiewicz
2005-09-28 22:22       ` [PATCH] via82cxxx IDE: Support multiple controllers (v2) Daniel Drake
2005-11-04 10:52         ` Daniel Drake
2005-11-18 20:41           ` Bartlomiej Zolnierkiewicz
2005-10-12 15:38       ` [PATCH] via82cxxx IDE: Support multiple controllers Daniel Drake
2005-10-12 15:49         ` Jeff Garzik
2005-10-12 15:57         ` Daniel Drake
2005-10-12 17:52           ` Alan Cox
2005-10-13 11:45             ` Alan Cox
2005-10-13 14:41               ` Mark Lord
2005-10-13 15:29                 ` Alan Cox

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=43220A8C.7070508@gentoo.org \
    --to=dsd@gentoo.org \
    --cc=bzolnier@gmail.com \
    --cc=linux-ide@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=posting@blx4.net \
    --cc=vsu@altlinux.ru \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.