Message ID | 20181018122951eucas1p2be43dc17df8d2c754e771785b3ad7457~es8dn4Tg90035600356eucas1p2H@eucas1p2.samsung.com |
---|---|
State | Not Applicable |
Delegated to: | David Miller |
Headers | show |
Series | ata: add Buddha PATA controller driver | expand |
Hi!
On 10/18/18 2:29 PM, Bartlomiej Zolnierkiewicz wrote:
> John, please test if possible..
Yes, will test ASAP. @Michael: Can you build an updated kernel from your
tree for elgar and copy it over. I'll make sure to test it and also
hook up an IDE drive for testing.
Adrian
> +static int __init pata_buddha_init_one(void) > +{ > + struct zorro_dev *z = NULL; > + > + while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { I'm not really an m68k expert, but shouldn't this implement a struct zorro_driver instead? (or maybe two of them as xsurf seems sufficiently different).
On 10/18/2018 02:41 PM, Christoph Hellwig wrote: >> +static int __init pata_buddha_init_one(void) >> +{ >> + struct zorro_dev *z = NULL; >> + >> + while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { > > I'm not really an m68k expert, but shouldn't this implement a > struct zorro_driver instead? (or maybe two of them as xsurf > seems sufficiently different). I didn't want to introduce too many changes over old IDE's driver in the initial version of the libata driver as I can't test them myself. Once the new driver is verified to work I plan to convert it into proper Zorro_driver. Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics
Hi Bartlomiej, Christoph, On Thu, Oct 18, 2018 at 3:12 PM Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> wrote: > On 10/18/2018 02:41 PM, Christoph Hellwig wrote: > >> +static int __init pata_buddha_init_one(void) > >> +{ > >> + struct zorro_dev *z = NULL; > >> + > >> + while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { > > > > I'm not really an m68k expert, but shouldn't this implement a > > struct zorro_driver instead? (or maybe two of them as xsurf > > seems sufficiently different). > > I didn't want to introduce too many changes over old IDE's > driver in the initial version of the libata driver as > I can't test them myself. Once the new driver is verified > to work I plan to convert it into proper Zorro_driver. Unfortunately that conversion cannot happen right now, as zorro8390.c already binds against the X-Surf zorro device. I think the proper solution would be to start using MFD for multi-function Zorro devices, cfr. the work I started years ago, but never completed https://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git/log/?h=zorro-mfd Then the Buddha MFD driver can instantiate 2 Buddha IDE cells, the Catweasel MFD driver can instantiate 3 Buddha IDE cells and a Catweasel floppy cell, and the X-Surf MFD driver can instantiate 2 Buddha IDE cells and a zorro8390 cell. Gr{oetje,eeting}s, Geert
Hi Adrian, module built and loaded fine (no need to build a new kernel for this). Can't unload the module however (-EBUSY). You'll have to reboot elgar to reload the module, I'm afraid. Cheers, Michael On 19/10/18 01:32, John Paul Adrian Glaubitz wrote: > Hi! > > On 10/18/18 2:29 PM, Bartlomiej Zolnierkiewicz wrote: >> John, please test if possible.. > Yes, will test ASAP. @Michael: Can you build an updated kernel from your > tree for elgar and copy it over. I'll make sure to test it and also > hook up an IDE drive for testing. > > Adrian >
Hi Bartlomiej, On 19/10/18 01:29, Bartlomiej Zolnierkiewicz wrote: > Add Buddha PATA controller driver. It enables libata support for > the Buddha, Catweasel and X-Surf expansion boards on the Zorro > expansion bus. > > Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> > Cc: Michael Schmitz <schmitzmic@gmail.com> > Cc: Geert Uytterhoeven <geert@linux-m68k.org> > Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> > --- > John, please test if possible.. > > drivers/ata/Kconfig | 12 ++ > drivers/ata/Makefile | 1 > drivers/ata/pata_buddha.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 270 insertions(+) > > Index: b/drivers/ata/Kconfig > =================================================================== > --- a/drivers/ata/Kconfig 2018-10-18 14:18:02.766452406 +0200 > +++ b/drivers/ata/Kconfig 2018-10-18 14:18:02.766452406 +0200 > @@ -965,6 +965,18 @@ config PATA_GAYLE > > If unsure, say N. > > +config PATA_BUDDHA > + tristate "Buddha/Catweasel/X-Surf PATA support" > + depends on ZORRO > + help > + This option enables support for the IDE interfaces > + on the Buddha, Catweasel and X-Surf expansion boards > + on the Zorro expansion bus. It supports up to two > + interfaces on the Buddha, three on the Catweasel and > + two on the X-Surf. > + > + If unsure, say N. > + > config PATA_ISAPNP > tristate "ISA Plug and Play PATA support" > depends on ISAPNP > Index: b/drivers/ata/Makefile > =================================================================== > --- a/drivers/ata/Makefile 2018-10-18 14:18:02.766452406 +0200 > +++ b/drivers/ata/Makefile 2018-10-18 14:18:02.766452406 +0200 > @@ -98,6 +98,7 @@ obj-$(CONFIG_PATA_WINBOND) += pata_sl82c > obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o > obj-$(CONFIG_PATA_FALCON) += pata_falcon.o > obj-$(CONFIG_PATA_GAYLE) += pata_gayle.o > +obj-$(CONFIG_PATA_BUDDHA) += pata_buddha.o > obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o > obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o > obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o > Index: b/drivers/ata/pata_buddha.c > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ b/drivers/ata/pata_buddha.c 2018-10-18 14:23:41.054460925 +0200 > @@ -0,0 +1,257 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +/* > + * Buddha, Catweasel and X-Surf PATA controller driver > + * > + * Copyright (c) 2018 Samsung Electronics Co., Ltd. > + * http://www.samsung.com > + * > + * Based on buddha.c: > + * > + * Copyright (C) 1997, 2001 by Geert Uytterhoeven and others > + */ > + > +#include <linux/ata.h> > +#include <linux/blkdev.h> > +#include <linux/delay.h> > +#include <linux/interrupt.h> > +#include <linux/kernel.h> > +#include <linux/libata.h> > +#include <linux/mm.h> > +#include <linux/module.h> > +#include <linux/zorro.h> > +#include <scsi/scsi_cmnd.h> > +#include <scsi/scsi_host.h> > + > +#include <asm/amigahw.h> > +#include <asm/amigaints.h> > +#include <asm/ide.h> > +#include <asm/setup.h> > + > +#define DRV_NAME "pata_buddha" > +#define DRV_VERSION "0.1.0" > + > +#define BUDDHA_BASE1 0x800 > +#define BUDDHA_BASE2 0xa00 > +#define BUDDHA_BASE3 0xc00 > +#define XSURF_BASE1 0xb000 /* 2.5" interface */ > +#define XSURF_BASE2 0xd000 /* 3.5" interface */ > +#define BUDDHA_CONTROL 0x11a > +#define BUDDHA_IRQ 0xf00 > +#define XSURF_IRQ 0x7e > +#define BUDDHA_IRQ_MR 0xfc0 /* master interrupt enable */ > + > +enum { > + BOARD_BUDDHA = 0, > + BOARD_CATWEASEL, > + BOARD_XSURF > +}; > + > +static unsigned int buddha_bases[3] __initdata = { > + BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3 > +}; > + > +static unsigned int xsurf_bases[2] __initdata = { > + XSURF_BASE1, XSURF_BASE2 > +}; > + > +static struct scsi_host_template pata_buddha_sht = { > + ATA_PIO_SHT(DRV_NAME), > +}; > + > +/* FIXME: is this needed? */ > +static unsigned int pata_buddha_data_xfer(struct ata_queued_cmd *qc, > + unsigned char *buf, > + unsigned int buflen, int rw) > +{ > + struct ata_device *dev = qc->dev; > + struct ata_port *ap = dev->link->ap; > + void __iomem *data_addr = ap->ioaddr.data_addr; > + unsigned int words = buflen >> 1; > + > + /* Transfer multiple of 2 bytes */ > + if (rw == READ) > + raw_insw((u16 *)data_addr, (u16 *)buf, words); > + else > + raw_outsw((u16 *)data_addr, (u16 *)buf, words); > + > + /* Transfer trailing byte, if any. */ > + if (unlikely(buflen & 0x01)) { > + unsigned char pad[2] = { }; > + > + /* Point buf to the tail of buffer */ > + buf += buflen - 1; > + > + if (rw == READ) { > + raw_insw((u16 *)data_addr, (u16 *)pad, 1); > + *buf = pad[0]; > + } else { > + pad[0] = *buf; > + raw_outsw((u16 *)data_addr, (u16 *)pad, 1); > + } > + words++; > + } > + > + return words << 1; > +} > + > +/* > + * Provide our own set_mode() as we don't want to change anything that has > + * already been configured.. > + */ > +static int pata_buddha_set_mode(struct ata_link *link, > + struct ata_device **unused) > +{ > + struct ata_device *dev; > + > + ata_for_each_dev(dev, link, ENABLED) { > + /* We don't really care */ > + dev->pio_mode = dev->xfer_mode = XFER_PIO_0; > + dev->xfer_shift = ATA_SHIFT_PIO; > + dev->flags |= ATA_DFLAG_PIO; > + ata_dev_info(dev, "configured for PIO\n"); > + } > + return 0; > +} > + > +static bool pata_buddha_irq_check(struct ata_port *ap) > +{ > + u8 ch; > + > + ch = z_readb((unsigned long)ap->private_data); > + > + return !!(ch & 0x80); > +} > + > +static void pata_xsurf_irq_clear(struct ata_port *ap) > +{ > + z_writeb(0, (unsigned long)ap->private_data); > +} > + > +static struct ata_port_operations pata_buddha_ops = { > + .inherits = &ata_sff_port_ops, > + .sff_data_xfer = pata_buddha_data_xfer, > + .sff_irq_check = pata_buddha_irq_check, > + .cable_detect = ata_cable_unknown, > + .set_mode = pata_buddha_set_mode, > +}; > + > +static struct ata_port_operations pata_xsurf_ops = { > + .inherits = &ata_sff_port_ops, > + .sff_data_xfer = pata_buddha_data_xfer, > + .sff_irq_check = pata_buddha_irq_check, > + .sff_irq_clear = pata_xsurf_irq_clear, > + .cable_detect = ata_cable_unknown, > + .set_mode = pata_buddha_set_mode, > +}; > + > +static int __init pata_buddha_init_one(void) That's a misnomer - it'll pick up _all_ devices matching the search criteria below: > +{ > + struct zorro_dev *z = NULL; > + > + while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { All Zorro devices ... > + static const char *board_name[] > + = { "Buddha", "Catweasel", "X-Surf" }; > + struct ata_host *host; > + void __iomem *buddha_board; > + unsigned long board; > + unsigned int type, nr_ports = 2; > + int i; > + > + if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) { > + type = BOARD_BUDDHA; > + } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL) { > + type = BOARD_CATWEASEL; > + nr_ports++; > + } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF) { > + type = BOARD_XSURF; matching these three board IDs. > + } else > + continue; > + > + dev_info(&z->dev, "%s IDE controller\n", board_name[type]); > + > + board = z->resource.start; > + > + if (type != BOARD_XSURF) { > + if (!devm_request_mem_region(&z->dev, > + board + BUDDHA_BASE1, > + 0x800, DRV_NAME)) > + continue; > + } else { > + if (!devm_request_mem_region(&z->dev, > + board + XSURF_BASE1, > + 0x1000, DRV_NAME)) > + continue; > + if (!devm_request_mem_region(&z->dev, > + board + XSURF_BASE2, > + 0x1000, DRV_NAME)) > + continue; > + } > + > + /* allocate host */ > + host = ata_host_alloc(&z->dev, nr_ports); > + if (!host) > + continue; > + > + buddha_board = ZTWO_VADDR(board); > + > + /* enable the board IRQ on Buddha/Catweasel */ > + if (type != BOARD_XSURF) > + z_writeb(0, buddha_board + BUDDHA_IRQ_MR); > + > + for (i = 0; i < nr_ports; i++) { > + struct ata_port *ap = host->ports[i]; > + void __iomem *base, *irqport; > + unsigned long ctl = 0; > + > + if (type != BOARD_XSURF) { > + ap->ops = &pata_buddha_ops; > + base = buddha_board + buddha_bases[i]; > + ctl = BUDDHA_CONTROL; > + irqport = buddha_board + BUDDHA_IRQ + i * 0x40; > + } else { > + ap->ops = &pata_xsurf_ops; > + base = buddha_board + xsurf_bases[i]; > + /* X-Surf has no CS1* (Control/AltStat) */ > + irqport = buddha_board + XSURF_IRQ; > + } > + > + ap->pio_mask = ATA_PIO4; > + ap->flags |= ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY; > + > + ap->ioaddr.data_addr = base; > + ap->ioaddr.error_addr = base + 2 + 1 * 4; > + ap->ioaddr.feature_addr = base + 2 + 1 * 4; > + ap->ioaddr.nsect_addr = base + 2 + 2 * 4; > + ap->ioaddr.lbal_addr = base + 2 + 3 * 4; > + ap->ioaddr.lbam_addr = base + 2 + 4 * 4; > + ap->ioaddr.lbah_addr = base + 2 + 5 * 4; > + ap->ioaddr.device_addr = base + 2 + 6 * 4; > + ap->ioaddr.status_addr = base + 2 + 7 * 4; > + ap->ioaddr.command_addr = base + 2 + 7 * 4; > + > + if (ctl) { > + ap->ioaddr.altstatus_addr = base + ctl; > + ap->ioaddr.ctl_addr = base + ctl; > + } > + > + ap->private_data = (void *)irqport; > + > + ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", board, > + ctl ? board + buddha_bases[i] + ctl : 0); > + } > + > + ata_host_activate(host, IRQ_AMIGA_PORTS, ata_sff_interrupt, > + IRQF_SHARED, &pata_buddha_sht); > + > + } > + > + return 0; > +} > + > +module_init(pata_buddha_init_one); > + > +MODULE_AUTHOR("Bartlomiej Zolnierkiewicz"); > +MODULE_DESCRIPTION("low-level driver for Buddha/Catweasel/X-Surf PATA"); > +MODULE_LICENSE("GPL v2"); > +MODULE_VERSION(DRV_VERSION); No module_exit(). Untested (stolen from pata_legacy.c): commit 66a85e7f93a0144b2542b6c9944f5fb726b04662 Author: Michael Schmitz <schmitzmic@gmail.com> Date: Fri Oct 19 12:31:57 2018 +1300 ata: pata_buddha - add module_exit() Note ata hosts as we probe, and use those in forgotten module_exit() later. Signed-off-by: Michael Schmitz <schmitzmic@gmail.com> diff --git a/drivers/ata/pata_buddha.c b/drivers/ata/pata_buddha.c index 11a8044..39582c0 100644 --- a/drivers/ata/pata_buddha.c +++ b/drivers/ata/pata_buddha.c @@ -59,6 +59,10 @@ enum { ATA_PIO_SHT(DRV_NAME), }; +#define NR_HOST 6 +static struct ata_host *buddha_host[NR_HOST]; +static int nr_buddha_host; + /* FIXME: is this needed? */ static unsigned int pata_buddha_data_xfer(struct ata_queued_cmd *qc, unsigned char *buf, @@ -244,6 +248,7 @@ static int __init pata_buddha_init_one(void) ata_host_activate(host, IRQ_AMIGA_PORTS, ata_sff_interrupt, IRQF_SHARED, &pata_buddha_sht); + buddha_host[nr_buddha_host++] = host; } return 0; @@ -251,6 +256,16 @@ static int __init pata_buddha_init_one(void) module_init(pata_buddha_init_one); +static __exit void pata_buddha_exit_one(void) +{ + int i; + + for (i = 0; i < nr_buddha_host; i++) + ata_host_detach(buddha_host[i]); +} + +module_exit(pata_buddha_exit_one); + Cheers, Michael
Hi! Sorry for the delay! On 10/18/18 2:29 PM, Bartlomiej Zolnierkiewicz wrote: > John, please test if possible.. Driver loads and detects hard drive connected to it: [ 256.110000] zorro zorro3: Buddha IDE controller [ 256.430000] scsi host2: pata_buddha [ 256.580000] scsi host3: pata_buddha [ 256.590000] ata2: PATA max PIO4 cmd 0xeb0000 ctl 0xeb091a irq 2 [ 256.600000] ata3: PATA max PIO4 cmd 0xeb0000 ctl 0xeb0b1a irq 2 [ 256.790000] ata2.00: ATA-6: ST380011A, 8.01, max UDMA/100 [ 256.810000] ata2.00: 156301488 sectors, multi 16: LBA48 [ 256.820000] ata2.00: configured for PIO [ 256.870000] scsi 2:0:0:0: Direct-Access ATA ST380011A 8.01 PQ: 0 ANSI: 5 [ 257.080000] sd 2:0:0:0: [sdc] 156301488 512-byte logical blocks: (80.0 GB/74.5 GiB) [ 257.170000] sd 2:0:0:0: [sdc] Write Protect is off [ 257.190000] sd 2:0:0:0: [sdc] Mode Sense: 00 3a 00 00 [ 257.330000] sd 2:0:0:0: [sdc] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA [ 257.960000] sd 2:0:0:0: [sdc] Attached SCSI disk I was then able to create an MS-DOS partition table on the disk and create an ext2 filesystem. I copied some files onto the partition which worked without any problems. Tested-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> Michael wants to make some changes to the driver though, I think. He has access to the Amiga 4000, in any case, so he can also test them. Adrian
Hi! On 10/25/18 9:38 PM, John Paul Adrian Glaubitz wrote: > Tested-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> > > Michael wants to make some changes to the driver though, I think. He has access > to the Amiga 4000, in any case, so he can also test them. @Michael: Can you post an updated version of the driver, rebased for 4.19 and with your patch? Adrian
Hi Adrian, my fix is evidently incomplete - I just crashed elgar trying to remove the pata_buddha module, sorry. Must've done something silly. So no, can't post a patch to add module_exit just yet. Cheers, Michael Am 31.10.2018 um 23:06 schrieb John Paul Adrian Glaubitz: > Hi! > > On 10/25/18 9:38 PM, John Paul Adrian Glaubitz wrote: >> Tested-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> >> >> Michael wants to make some changes to the driver though, I think. He has access >> to the Amiga 4000, in any case, so he can also test them. > > @Michael: Can you post an updated version of the driver, rebased for 4.19 > and with your patch? > > Adrian >
Good morning!
On 11/1/18 5:53 AM, Michael Schmitz wrote:
> my fix is evidently incomplete - I just crashed elgar trying to remove the pata_buddha module, sorry. Must've done something silly.
I'll reboot him in about 2-3 hours when I'm in the office.
Adrian
Index: b/drivers/ata/Kconfig =================================================================== --- a/drivers/ata/Kconfig 2018-10-18 14:18:02.766452406 +0200 +++ b/drivers/ata/Kconfig 2018-10-18 14:18:02.766452406 +0200 @@ -965,6 +965,18 @@ config PATA_GAYLE If unsure, say N. +config PATA_BUDDHA + tristate "Buddha/Catweasel/X-Surf PATA support" + depends on ZORRO + help + This option enables support for the IDE interfaces + on the Buddha, Catweasel and X-Surf expansion boards + on the Zorro expansion bus. It supports up to two + interfaces on the Buddha, three on the Catweasel and + two on the X-Surf. + + If unsure, say N. + config PATA_ISAPNP tristate "ISA Plug and Play PATA support" depends on ISAPNP Index: b/drivers/ata/Makefile =================================================================== --- a/drivers/ata/Makefile 2018-10-18 14:18:02.766452406 +0200 +++ b/drivers/ata/Makefile 2018-10-18 14:18:02.766452406 +0200 @@ -98,6 +98,7 @@ obj-$(CONFIG_PATA_WINBOND) += pata_sl82c obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o obj-$(CONFIG_PATA_FALCON) += pata_falcon.o obj-$(CONFIG_PATA_GAYLE) += pata_gayle.o +obj-$(CONFIG_PATA_BUDDHA) += pata_buddha.o obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o Index: b/drivers/ata/pata_buddha.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ b/drivers/ata/pata_buddha.c 2018-10-18 14:23:41.054460925 +0200 @@ -0,0 +1,257 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Buddha, Catweasel and X-Surf PATA controller driver + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Based on buddha.c: + * + * Copyright (C) 1997, 2001 by Geert Uytterhoeven and others + */ + +#include <linux/ata.h> +#include <linux/blkdev.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/libata.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/zorro.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_host.h> + +#include <asm/amigahw.h> +#include <asm/amigaints.h> +#include <asm/ide.h> +#include <asm/setup.h> + +#define DRV_NAME "pata_buddha" +#define DRV_VERSION "0.1.0" + +#define BUDDHA_BASE1 0x800 +#define BUDDHA_BASE2 0xa00 +#define BUDDHA_BASE3 0xc00 +#define XSURF_BASE1 0xb000 /* 2.5" interface */ +#define XSURF_BASE2 0xd000 /* 3.5" interface */ +#define BUDDHA_CONTROL 0x11a +#define BUDDHA_IRQ 0xf00 +#define XSURF_IRQ 0x7e +#define BUDDHA_IRQ_MR 0xfc0 /* master interrupt enable */ + +enum { + BOARD_BUDDHA = 0, + BOARD_CATWEASEL, + BOARD_XSURF +}; + +static unsigned int buddha_bases[3] __initdata = { + BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3 +}; + +static unsigned int xsurf_bases[2] __initdata = { + XSURF_BASE1, XSURF_BASE2 +}; + +static struct scsi_host_template pata_buddha_sht = { + ATA_PIO_SHT(DRV_NAME), +}; + +/* FIXME: is this needed? */ +static unsigned int pata_buddha_data_xfer(struct ata_queued_cmd *qc, + unsigned char *buf, + unsigned int buflen, int rw) +{ + struct ata_device *dev = qc->dev; + struct ata_port *ap = dev->link->ap; + void __iomem *data_addr = ap->ioaddr.data_addr; + unsigned int words = buflen >> 1; + + /* Transfer multiple of 2 bytes */ + if (rw == READ) + raw_insw((u16 *)data_addr, (u16 *)buf, words); + else + raw_outsw((u16 *)data_addr, (u16 *)buf, words); + + /* Transfer trailing byte, if any. */ + if (unlikely(buflen & 0x01)) { + unsigned char pad[2] = { }; + + /* Point buf to the tail of buffer */ + buf += buflen - 1; + + if (rw == READ) { + raw_insw((u16 *)data_addr, (u16 *)pad, 1); + *buf = pad[0]; + } else { + pad[0] = *buf; + raw_outsw((u16 *)data_addr, (u16 *)pad, 1); + } + words++; + } + + return words << 1; +} + +/* + * Provide our own set_mode() as we don't want to change anything that has + * already been configured.. + */ +static int pata_buddha_set_mode(struct ata_link *link, + struct ata_device **unused) +{ + struct ata_device *dev; + + ata_for_each_dev(dev, link, ENABLED) { + /* We don't really care */ + dev->pio_mode = dev->xfer_mode = XFER_PIO_0; + dev->xfer_shift = ATA_SHIFT_PIO; + dev->flags |= ATA_DFLAG_PIO; + ata_dev_info(dev, "configured for PIO\n"); + } + return 0; +} + +static bool pata_buddha_irq_check(struct ata_port *ap) +{ + u8 ch; + + ch = z_readb((unsigned long)ap->private_data); + + return !!(ch & 0x80); +} + +static void pata_xsurf_irq_clear(struct ata_port *ap) +{ + z_writeb(0, (unsigned long)ap->private_data); +} + +static struct ata_port_operations pata_buddha_ops = { + .inherits = &ata_sff_port_ops, + .sff_data_xfer = pata_buddha_data_xfer, + .sff_irq_check = pata_buddha_irq_check, + .cable_detect = ata_cable_unknown, + .set_mode = pata_buddha_set_mode, +}; + +static struct ata_port_operations pata_xsurf_ops = { + .inherits = &ata_sff_port_ops, + .sff_data_xfer = pata_buddha_data_xfer, + .sff_irq_check = pata_buddha_irq_check, + .sff_irq_clear = pata_xsurf_irq_clear, + .cable_detect = ata_cable_unknown, + .set_mode = pata_buddha_set_mode, +}; + +static int __init pata_buddha_init_one(void) +{ + struct zorro_dev *z = NULL; + + while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { + static const char *board_name[] + = { "Buddha", "Catweasel", "X-Surf" }; + struct ata_host *host; + void __iomem *buddha_board; + unsigned long board; + unsigned int type, nr_ports = 2; + int i; + + if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) { + type = BOARD_BUDDHA; + } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL) { + type = BOARD_CATWEASEL; + nr_ports++; + } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF) { + type = BOARD_XSURF; + } else + continue; + + dev_info(&z->dev, "%s IDE controller\n", board_name[type]); + + board = z->resource.start; + + if (type != BOARD_XSURF) { + if (!devm_request_mem_region(&z->dev, + board + BUDDHA_BASE1, + 0x800, DRV_NAME)) + continue; + } else { + if (!devm_request_mem_region(&z->dev, + board + XSURF_BASE1, + 0x1000, DRV_NAME)) + continue; + if (!devm_request_mem_region(&z->dev, + board + XSURF_BASE2, + 0x1000, DRV_NAME)) + continue; + } + + /* allocate host */ + host = ata_host_alloc(&z->dev, nr_ports); + if (!host) + continue; + + buddha_board = ZTWO_VADDR(board); + + /* enable the board IRQ on Buddha/Catweasel */ + if (type != BOARD_XSURF) + z_writeb(0, buddha_board + BUDDHA_IRQ_MR); + + for (i = 0; i < nr_ports; i++) { + struct ata_port *ap = host->ports[i]; + void __iomem *base, *irqport; + unsigned long ctl = 0; + + if (type != BOARD_XSURF) { + ap->ops = &pata_buddha_ops; + base = buddha_board + buddha_bases[i]; + ctl = BUDDHA_CONTROL; + irqport = buddha_board + BUDDHA_IRQ + i * 0x40; + } else { + ap->ops = &pata_xsurf_ops; + base = buddha_board + xsurf_bases[i]; + /* X-Surf has no CS1* (Control/AltStat) */ + irqport = buddha_board + XSURF_IRQ; + } + + ap->pio_mask = ATA_PIO4; + ap->flags |= ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY; + + ap->ioaddr.data_addr = base; + ap->ioaddr.error_addr = base + 2 + 1 * 4; + ap->ioaddr.feature_addr = base + 2 + 1 * 4; + ap->ioaddr.nsect_addr = base + 2 + 2 * 4; + ap->ioaddr.lbal_addr = base + 2 + 3 * 4; + ap->ioaddr.lbam_addr = base + 2 + 4 * 4; + ap->ioaddr.lbah_addr = base + 2 + 5 * 4; + ap->ioaddr.device_addr = base + 2 + 6 * 4; + ap->ioaddr.status_addr = base + 2 + 7 * 4; + ap->ioaddr.command_addr = base + 2 + 7 * 4; + + if (ctl) { + ap->ioaddr.altstatus_addr = base + ctl; + ap->ioaddr.ctl_addr = base + ctl; + } + + ap->private_data = (void *)irqport; + + ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", board, + ctl ? board + buddha_bases[i] + ctl : 0); + } + + ata_host_activate(host, IRQ_AMIGA_PORTS, ata_sff_interrupt, + IRQF_SHARED, &pata_buddha_sht); + + } + + return 0; +} + +module_init(pata_buddha_init_one); + +MODULE_AUTHOR("Bartlomiej Zolnierkiewicz"); +MODULE_DESCRIPTION("low-level driver for Buddha/Catweasel/X-Surf PATA"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION(DRV_VERSION);
Add Buddha PATA controller driver. It enables libata support for the Buddha, Catweasel and X-Surf expansion boards on the Zorro expansion bus. Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> Cc: Michael Schmitz <schmitzmic@gmail.com> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- John, please test if possible.. drivers/ata/Kconfig | 12 ++ drivers/ata/Makefile | 1 drivers/ata/pata_buddha.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 270 insertions(+)