Fourth update to the new ATA/ATAPI driver:
Well, better late than newer, but things has been hectic
around here, sorry for the long delay.
DMA support has been added to the ATA disk driver.
This only works on Intel PIIX3/4, Acer Aladdin and Promise controllers.
The promise support works without the BIOS on the board,
and timing modes are set to support up to UDMA speed. This
solves the problems with having more than one promise controller
in the same system.
There is support for "generic" DMA, that might work on other
controllers, but now you have been warned :)
More chipset specific code will come soon, I have to find testers
with the approbiate HW, more on that when I have it ready.
The system now uses its own major numbers, please run MAKEDEV
with the devices you need (ad?, acd?, afd?, ast?).
For now the disk driver will also attach to the old wd major
so one can at least boot without this step, but be warned, this
will eventually go away. The bootblocks will have to be changed
before one can boot directly from an "ad" device though.
Fixed problems:
All known hang problems should be solved
The probe code has been sligthly changed, this should solve
the reports I have lying around (I hope).
Hangs when accessing ata & atapi device on the same channel simultaniously.
A real braino in ata_start caused this, fixed.
As usual USE AT YOUR OWN RISK!!, this is still pre alpha level code.
Especially the DMA support can hose your disk real bad if anything
goes wrong, agaiin you have been warned :)
But please tell me how it works for you!
Enjoy!
-Søren
1999-03-28 18:57:20 +00:00
|
|
|
/*-
|
2017-11-27 14:52:40 +00:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
|
|
|
*
|
2012-01-15 13:23:18 +00:00
|
|
|
* Copyright (c) 1998 - 2008 Søren Schmidt <sos@FreeBSD.org>
|
Fourth update to the new ATA/ATAPI driver:
Well, better late than newer, but things has been hectic
around here, sorry for the long delay.
DMA support has been added to the ATA disk driver.
This only works on Intel PIIX3/4, Acer Aladdin and Promise controllers.
The promise support works without the BIOS on the board,
and timing modes are set to support up to UDMA speed. This
solves the problems with having more than one promise controller
in the same system.
There is support for "generic" DMA, that might work on other
controllers, but now you have been warned :)
More chipset specific code will come soon, I have to find testers
with the approbiate HW, more on that when I have it ready.
The system now uses its own major numbers, please run MAKEDEV
with the devices you need (ad?, acd?, afd?, ast?).
For now the disk driver will also attach to the old wd major
so one can at least boot without this step, but be warned, this
will eventually go away. The bootblocks will have to be changed
before one can boot directly from an "ad" device though.
Fixed problems:
All known hang problems should be solved
The probe code has been sligthly changed, this should solve
the reports I have lying around (I hope).
Hangs when accessing ata & atapi device on the same channel simultaniously.
A real braino in ata_start caused this, fixed.
As usual USE AT YOUR OWN RISK!!, this is still pre alpha level code.
Especially the DMA support can hose your disk real bad if anything
goes wrong, agaiin you have been warned :)
But please tell me how it works for you!
Enjoy!
-Søren
1999-03-28 18:57:20 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer,
|
|
|
|
* without modification, immediately at the beginning of the file.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2003-08-24 17:55:58 +00:00
|
|
|
#include <sys/cdefs.h>
|
|
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
|
Fourth update to the new ATA/ATAPI driver:
Well, better late than newer, but things has been hectic
around here, sorry for the long delay.
DMA support has been added to the ATA disk driver.
This only works on Intel PIIX3/4, Acer Aladdin and Promise controllers.
The promise support works without the BIOS on the board,
and timing modes are set to support up to UDMA speed. This
solves the problems with having more than one promise controller
in the same system.
There is support for "generic" DMA, that might work on other
controllers, but now you have been warned :)
More chipset specific code will come soon, I have to find testers
with the approbiate HW, more on that when I have it ready.
The system now uses its own major numbers, please run MAKEDEV
with the devices you need (ad?, acd?, afd?, ast?).
For now the disk driver will also attach to the old wd major
so one can at least boot without this step, but be warned, this
will eventually go away. The bootblocks will have to be changed
before one can boot directly from an "ad" device though.
Fixed problems:
All known hang problems should be solved
The probe code has been sligthly changed, this should solve
the reports I have lying around (I hope).
Hangs when accessing ata & atapi device on the same channel simultaniously.
A real braino in ata_start caused this, fixed.
As usual USE AT YOUR OWN RISK!!, this is still pre alpha level code.
Especially the DMA support can hose your disk real bad if anything
goes wrong, agaiin you have been warned :)
But please tell me how it works for you!
Enjoy!
-Søren
1999-03-28 18:57:20 +00:00
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
2001-03-15 15:36:25 +00:00
|
|
|
#include <sys/ata.h>
|
2003-02-20 20:02:32 +00:00
|
|
|
#include <sys/kernel.h>
|
2002-04-26 22:48:23 +00:00
|
|
|
#include <sys/endian.h>
|
Fourth update to the new ATA/ATAPI driver:
Well, better late than newer, but things has been hectic
around here, sorry for the long delay.
DMA support has been added to the ATA disk driver.
This only works on Intel PIIX3/4, Acer Aladdin and Promise controllers.
The promise support works without the BIOS on the board,
and timing modes are set to support up to UDMA speed. This
solves the problems with having more than one promise controller
in the same system.
There is support for "generic" DMA, that might work on other
controllers, but now you have been warned :)
More chipset specific code will come soon, I have to find testers
with the approbiate HW, more on that when I have it ready.
The system now uses its own major numbers, please run MAKEDEV
with the devices you need (ad?, acd?, afd?, ast?).
For now the disk driver will also attach to the old wd major
so one can at least boot without this step, but be warned, this
will eventually go away. The bootblocks will have to be changed
before one can boot directly from an "ad" device though.
Fixed problems:
All known hang problems should be solved
The probe code has been sligthly changed, this should solve
the reports I have lying around (I hope).
Hangs when accessing ata & atapi device on the same channel simultaniously.
A real braino in ata_start caused this, fixed.
As usual USE AT YOUR OWN RISK!!, this is still pre alpha level code.
Especially the DMA support can hose your disk real bad if anything
goes wrong, agaiin you have been warned :)
But please tell me how it works for you!
Enjoy!
-Søren
1999-03-28 18:57:20 +00:00
|
|
|
#include <sys/malloc.h>
|
2003-07-01 15:52:06 +00:00
|
|
|
#include <sys/lock.h>
|
2004-01-11 22:08:34 +00:00
|
|
|
#include <sys/sema.h>
|
2003-08-24 09:22:26 +00:00
|
|
|
#include <sys/taskqueue.h>
|
2004-01-14 21:26:35 +00:00
|
|
|
#include <vm/uma.h>
|
1999-04-18 20:48:15 +00:00
|
|
|
#include <sys/bus.h>
|
2000-08-28 21:48:13 +00:00
|
|
|
#include <machine/bus.h>
|
2001-02-06 16:44:25 +00:00
|
|
|
#include <sys/rman.h>
|
2000-09-20 07:00:24 +00:00
|
|
|
#include <dev/ata/ata-all.h>
|
Fourth update to the new ATA/ATAPI driver:
Well, better late than newer, but things has been hectic
around here, sorry for the long delay.
DMA support has been added to the ATA disk driver.
This only works on Intel PIIX3/4, Acer Aladdin and Promise controllers.
The promise support works without the BIOS on the board,
and timing modes are set to support up to UDMA speed. This
solves the problems with having more than one promise controller
in the same system.
There is support for "generic" DMA, that might work on other
controllers, but now you have been warned :)
More chipset specific code will come soon, I have to find testers
with the approbiate HW, more on that when I have it ready.
The system now uses its own major numbers, please run MAKEDEV
with the devices you need (ad?, acd?, afd?, ast?).
For now the disk driver will also attach to the old wd major
so one can at least boot without this step, but be warned, this
will eventually go away. The bootblocks will have to be changed
before one can boot directly from an "ad" device though.
Fixed problems:
All known hang problems should be solved
The probe code has been sligthly changed, this should solve
the reports I have lying around (I hope).
Hangs when accessing ata & atapi device on the same channel simultaniously.
A real braino in ata_start caused this, fixed.
As usual USE AT YOUR OWN RISK!!, this is still pre alpha level code.
Especially the DMA support can hose your disk real bad if anything
goes wrong, agaiin you have been warned :)
But please tell me how it works for you!
Enjoy!
-Søren
1999-03-28 18:57:20 +00:00
|
|
|
|
1999-10-09 19:57:13 +00:00
|
|
|
/* prototypes */
|
2008-04-17 12:29:35 +00:00
|
|
|
static void ata_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error);
|
2008-04-10 13:05:05 +00:00
|
|
|
static void ata_dmaalloc(device_t dev);
|
|
|
|
static void ata_dmafree(device_t dev);
|
|
|
|
static void ata_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error);
|
|
|
|
static int ata_dmaload(struct ata_request *request, void *addr, int *nsegs);
|
|
|
|
static int ata_dmaunload(struct ata_request *request);
|
1999-10-09 19:57:13 +00:00
|
|
|
|
2003-02-20 20:02:32 +00:00
|
|
|
/* local vars */
|
2005-10-31 15:41:29 +00:00
|
|
|
static MALLOC_DEFINE(M_ATADMA, "ata_dma", "ATA driver DMA");
|
2002-04-05 13:13:56 +00:00
|
|
|
|
2003-02-20 20:02:32 +00:00
|
|
|
/* misc defines */
|
This is the much rumoured ATA mkIII update that I've been working on.
o ATA is now fully newbus'd and split into modules.
This means that on a modern system you just load "atapci and ata"
to get the base support, and then one or more of the device
subdrivers "atadisk atapicd atapifd atapist ataraid".
All can be loaded/unloaded anytime, but for obvious reasons you
dont want to unload atadisk when you have mounted filesystems.
o The device identify part of the probe has been rewritten to fix
the problems with odd devices the old had, and to try to remove
so of the long delays some HW could provoke. Also probing is done
without the need for interrupts, making earlier probing possible.
o SATA devices can be hot inserted/removed and devices will be created/
removed in /dev accordingly.
NOTE: only supported on controllers that has this feature:
Promise and Silicon Image for now.
On other controllers the usual atacontrol detach/attach dance is
still needed.
o Support for "atomic" composite ATA requests used for RAID.
o ATA RAID support has been rewritten and and now supports these
metadata formats:
"Adaptec HostRAID"
"Highpoint V2 RocketRAID"
"Highpoint V3 RocketRAID"
"Intel MatrixRAID"
"Integrated Technology Express"
"LSILogic V2 MegaRAID"
"LSILogic V3 MegaRAID"
"Promise FastTrak"
"Silicon Image Medley"
"FreeBSD PseudoRAID"
o Update the ioctl API to match new RAID levels etc.
o Update atacontrol to know about the new RAID levels etc
NOTE: you need to recompile atacontrol with the new sys/ata.h,
make world will take care of that.
NOTE2: that rebuild is done differently from the old system as
the rebuild is now done piggybacked on read requests to the
array, so atacontrol simply starts a background "dd" to rebuild
the array.
o The reinit code has been worked over to be much more robust.
o The timeout code has been overhauled for races.
o Support of new chipsets.
o Lots of fixes for bugs found while doing the modulerization and
reviewing the old code.
Missing or changed features from current ATA:
o atapi-cd no longer has support for ATAPI changers. Todays its
much cheaper and alot faster to copy those CD images to disk
and serve them from there. Besides they dont seem to be made
anymore, maybe for that exact reason.
o ATA RAID can only read metadata from all the above metadata formats,
not write all of them (Promise and Highpoint V2 so far). This means
that arrays can be picked up from the BIOS, but they cannot be
created from FreeBSD. There is more to it than just the missing
write metadata support, those formats are not unique to a given
controller like Promise and Highpoint formats, instead they exist
for several types, and even worse, some controllers can have
different formats and its impossible to tell which one.
The outcome is that we cannot reliably create the metadata of those
formats and be sure the controller BIOS will understand it.
However write support is needed to update/fail/rebuild the arrays
properly so it sits fairly high on the TODO list.
o So far atapicam is not supported with these changes. When/if this
will change is up to the maintainer of atapi-cam so go there for
questions.
HW donated by: Webveveriet AS
HW donated by: Frode Nordahl
HW donated by: Yahoo!
HW donated by: Sentex
Patience by: Vife and my boys (and even the cats)
2005-03-30 12:03:40 +00:00
|
|
|
#define MAXTABSZ PAGE_SIZE
|
2005-04-30 16:22:07 +00:00
|
|
|
#define MAXWSPCSZ PAGE_SIZE*2
|
2002-04-05 13:13:56 +00:00
|
|
|
|
|
|
|
struct ata_dc_cb_args {
|
|
|
|
bus_addr_t maddr;
|
|
|
|
int error;
|
|
|
|
};
|
|
|
|
|
2003-08-25 11:13:04 +00:00
|
|
|
void
|
2005-04-30 16:22:07 +00:00
|
|
|
ata_dmainit(device_t dev)
|
2003-02-20 20:02:32 +00:00
|
|
|
{
|
2005-04-30 16:22:07 +00:00
|
|
|
struct ata_channel *ch = device_get_softc(dev);
|
2008-04-17 12:29:35 +00:00
|
|
|
struct ata_dc_cb_args dcba;
|
2005-04-30 16:22:07 +00:00
|
|
|
|
2010-11-28 18:53:29 +00:00
|
|
|
if (ch->dma.alloc == NULL)
|
|
|
|
ch->dma.alloc = ata_dmaalloc;
|
|
|
|
if (ch->dma.free == NULL)
|
|
|
|
ch->dma.free = ata_dmafree;
|
|
|
|
if (ch->dma.setprd == NULL)
|
|
|
|
ch->dma.setprd = ata_dmasetprd;
|
|
|
|
if (ch->dma.load == NULL)
|
|
|
|
ch->dma.load = ata_dmaload;
|
|
|
|
if (ch->dma.unload == NULL)
|
|
|
|
ch->dma.unload = ata_dmaunload;
|
|
|
|
if (ch->dma.alignment == 0)
|
|
|
|
ch->dma.alignment = 2;
|
|
|
|
if (ch->dma.boundary == 0)
|
|
|
|
ch->dma.boundary = 65536;
|
|
|
|
if (ch->dma.segsize == 0)
|
|
|
|
ch->dma.segsize = 65536;
|
|
|
|
if (ch->dma.max_iosize == 0)
|
Make MAXPHYS tunable. Bump MAXPHYS to 1M.
Replace MAXPHYS by runtime variable maxphys. It is initialized from
MAXPHYS by default, but can be also adjusted with the tunable kern.maxphys.
Make b_pages[] array in struct buf flexible. Size b_pages[] for buffer
cache buffers exactly to atop(maxbcachebuf) (currently it is sized to
atop(MAXPHYS)), and b_pages[] for pbufs is sized to atop(maxphys) + 1.
The +1 for pbufs allow several pbuf consumers, among them vmapbuf(),
to use unaligned buffers still sized to maxphys, esp. when such
buffers come from userspace (*). Overall, we save significant amount
of otherwise wasted memory in b_pages[] for buffer cache buffers,
while bumping MAXPHYS to desired high value.
Eliminate all direct uses of the MAXPHYS constant in kernel and driver
sources, except a place which initialize maxphys. Some random (and
arguably weird) uses of MAXPHYS, e.g. in linuxolator, are converted
straight. Some drivers, which use MAXPHYS to size embeded structures,
get private MAXPHYS-like constant; their convertion is out of scope
for this work.
Changes to cam/, dev/ahci, dev/ata, dev/mpr, dev/mpt, dev/mvs,
dev/siis, where either submitted by, or based on changes by mav.
Suggested by: mav (*)
Reviewed by: imp, mav, imp, mckusick, scottl (intermediate versions)
Tested by: pho
Sponsored by: The FreeBSD Foundation
Differential revision: https://reviews.freebsd.org/D27225
2020-11-28 12:12:51 +00:00
|
|
|
ch->dma.max_iosize = (ATA_DMA_ENTRIES - 1) * PAGE_SIZE;
|
2010-11-28 18:53:29 +00:00
|
|
|
if (ch->dma.max_address == 0)
|
|
|
|
ch->dma.max_address = BUS_SPACE_MAXADDR_32BIT;
|
|
|
|
if (ch->dma.dma_slots == 0)
|
|
|
|
ch->dma.dma_slots = 1;
|
2008-04-17 12:29:35 +00:00
|
|
|
|
|
|
|
if (bus_dma_tag_create(bus_get_dma_tag(dev), ch->dma.alignment, 0,
|
|
|
|
ch->dma.max_address, BUS_SPACE_MAXADDR,
|
|
|
|
NULL, NULL, ch->dma.max_iosize,
|
|
|
|
ATA_DMA_ENTRIES, ch->dma.segsize,
|
|
|
|
0, NULL, NULL, &ch->dma.dmatag))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (bus_dma_tag_create(ch->dma.dmatag, PAGE_SIZE, 64 * 1024,
|
|
|
|
ch->dma.max_address, BUS_SPACE_MAXADDR,
|
|
|
|
NULL, NULL, MAXWSPCSZ, 1, MAXWSPCSZ,
|
|
|
|
0, NULL, NULL, &ch->dma.work_tag))
|
|
|
|
goto error;
|
|
|
|
|
2011-03-06 12:54:00 +00:00
|
|
|
if (bus_dmamem_alloc(ch->dma.work_tag, (void **)&ch->dma.work,
|
|
|
|
BUS_DMA_WAITOK | BUS_DMA_COHERENT,
|
2008-04-17 12:29:35 +00:00
|
|
|
&ch->dma.work_map))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (bus_dmamap_load(ch->dma.work_tag, ch->dma.work_map, ch->dma.work,
|
|
|
|
MAXWSPCSZ, ata_dmasetupc_cb, &dcba, 0) ||
|
|
|
|
dcba.error) {
|
|
|
|
bus_dmamem_free(ch->dma.work_tag, ch->dma.work, ch->dma.work_map);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
ch->dma.work_bus = dcba.maddr;
|
|
|
|
return;
|
|
|
|
|
|
|
|
error:
|
|
|
|
device_printf(dev, "WARNING - DMA initialization failed, disabling DMA\n");
|
|
|
|
ata_dmafini(dev);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ata_dmafini(device_t dev)
|
|
|
|
{
|
|
|
|
struct ata_channel *ch = device_get_softc(dev);
|
|
|
|
|
|
|
|
if (ch->dma.work_bus) {
|
|
|
|
bus_dmamap_unload(ch->dma.work_tag, ch->dma.work_map);
|
|
|
|
bus_dmamem_free(ch->dma.work_tag, ch->dma.work, ch->dma.work_map);
|
|
|
|
ch->dma.work_bus = 0;
|
|
|
|
ch->dma.work = NULL;
|
|
|
|
}
|
|
|
|
if (ch->dma.work_tag) {
|
|
|
|
bus_dma_tag_destroy(ch->dma.work_tag);
|
|
|
|
ch->dma.work_tag = NULL;
|
|
|
|
}
|
|
|
|
if (ch->dma.dmatag) {
|
|
|
|
bus_dma_tag_destroy(ch->dma.dmatag);
|
|
|
|
ch->dma.dmatag = NULL;
|
|
|
|
}
|
2003-02-20 20:02:32 +00:00
|
|
|
}
|
|
|
|
|
2002-04-05 13:13:56 +00:00
|
|
|
static void
|
|
|
|
ata_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
|
|
|
|
{
|
2008-04-10 13:05:05 +00:00
|
|
|
struct ata_dc_cb_args *dcba = (struct ata_dc_cb_args *)xsc;
|
2002-04-05 13:13:56 +00:00
|
|
|
|
2008-04-10 13:05:05 +00:00
|
|
|
if (!(dcba->error = error))
|
|
|
|
dcba->maddr = segs[0].ds_addr;
|
2002-04-05 13:13:56 +00:00
|
|
|
}
|
1999-04-16 21:22:55 +00:00
|
|
|
|
2003-08-25 11:13:04 +00:00
|
|
|
static void
|
2005-04-30 16:22:07 +00:00
|
|
|
ata_dmaalloc(device_t dev)
|
2000-09-19 11:08:39 +00:00
|
|
|
{
|
2005-04-30 16:22:07 +00:00
|
|
|
struct ata_channel *ch = device_get_softc(dev);
|
2008-04-10 13:05:05 +00:00
|
|
|
struct ata_dc_cb_args dcba;
|
2008-04-17 12:29:35 +00:00
|
|
|
int i;
|
2004-04-13 09:44:20 +00:00
|
|
|
|
2008-04-17 12:29:35 +00:00
|
|
|
/* alloc and setup needed dma slots */
|
|
|
|
bzero(ch->dma.slot, sizeof(struct ata_dmaslot) * ATA_DMA_SLOTS);
|
|
|
|
for (i = 0; i < ch->dma.dma_slots; i++) {
|
|
|
|
struct ata_dmaslot *slot = &ch->dma.slot[i];
|
|
|
|
|
|
|
|
if (bus_dma_tag_create(ch->dma.dmatag, PAGE_SIZE, PAGE_SIZE,
|
|
|
|
ch->dma.max_address, BUS_SPACE_MAXADDR,
|
|
|
|
NULL, NULL, PAGE_SIZE, 1, PAGE_SIZE,
|
|
|
|
0, NULL, NULL, &slot->sg_tag)) {
|
|
|
|
device_printf(ch->dev, "FAILURE - create sg_tag\n");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2011-03-06 12:54:00 +00:00
|
|
|
if (bus_dmamem_alloc(slot->sg_tag, (void **)&slot->sg, BUS_DMA_WAITOK,
|
|
|
|
&slot->sg_map)) {
|
2008-04-17 12:29:35 +00:00
|
|
|
device_printf(ch->dev, "FAILURE - alloc sg_map\n");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bus_dmamap_load(slot->sg_tag, slot->sg_map, slot->sg, MAXTABSZ,
|
|
|
|
ata_dmasetupc_cb, &dcba, 0) || dcba.error) {
|
|
|
|
device_printf(ch->dev, "FAILURE - load sg\n");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
slot->sg_bus = dcba.maddr;
|
|
|
|
|
|
|
|
if (bus_dma_tag_create(ch->dma.dmatag,
|
|
|
|
ch->dma.alignment, ch->dma.boundary,
|
|
|
|
ch->dma.max_address, BUS_SPACE_MAXADDR,
|
|
|
|
NULL, NULL, ch->dma.max_iosize,
|
|
|
|
ATA_DMA_ENTRIES, ch->dma.segsize,
|
|
|
|
BUS_DMA_ALLOCNOW, NULL, NULL, &slot->data_tag)) {
|
|
|
|
device_printf(ch->dev, "FAILURE - create data_tag\n");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bus_dmamap_create(slot->data_tag, 0, &slot->data_map)) {
|
|
|
|
device_printf(ch->dev, "FAILURE - create data_map\n");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-08-25 11:13:04 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
error:
|
2005-04-30 16:22:07 +00:00
|
|
|
device_printf(dev, "WARNING - DMA allocation failed, disabling DMA\n");
|
|
|
|
ata_dmafree(dev);
|
2002-04-05 13:13:56 +00:00
|
|
|
}
|
|
|
|
|
2003-02-20 20:02:32 +00:00
|
|
|
static void
|
2005-04-30 16:22:07 +00:00
|
|
|
ata_dmafree(device_t dev)
|
2002-04-05 13:13:56 +00:00
|
|
|
{
|
2005-04-30 16:22:07 +00:00
|
|
|
struct ata_channel *ch = device_get_softc(dev);
|
2008-04-17 12:29:35 +00:00
|
|
|
int i;
|
2005-04-30 16:22:07 +00:00
|
|
|
|
2008-04-17 12:29:35 +00:00
|
|
|
/* free all dma slots */
|
|
|
|
for (i = 0; i < ATA_DMA_SLOTS; i++) {
|
|
|
|
struct ata_dmaslot *slot = &ch->dma.slot[i];
|
|
|
|
|
|
|
|
if (slot->sg_bus) {
|
|
|
|
bus_dmamap_unload(slot->sg_tag, slot->sg_map);
|
|
|
|
slot->sg_bus = 0;
|
|
|
|
}
|
2014-06-10 20:25:45 +00:00
|
|
|
if (slot->sg) {
|
2008-04-17 12:29:35 +00:00
|
|
|
bus_dmamem_free(slot->sg_tag, slot->sg, slot->sg_map);
|
|
|
|
slot->sg = NULL;
|
|
|
|
}
|
|
|
|
if (slot->data_map) {
|
|
|
|
bus_dmamap_destroy(slot->data_tag, slot->data_map);
|
|
|
|
slot->data_map = NULL;
|
|
|
|
}
|
|
|
|
if (slot->sg_tag) {
|
|
|
|
bus_dma_tag_destroy(slot->sg_tag);
|
|
|
|
slot->sg_tag = NULL;
|
|
|
|
}
|
|
|
|
if (slot->data_tag) {
|
|
|
|
bus_dma_tag_destroy(slot->data_tag);
|
|
|
|
slot->data_tag = NULL;
|
|
|
|
}
|
2000-03-05 16:52:26 +00:00
|
|
|
}
|
Fourth update to the new ATA/ATAPI driver:
Well, better late than newer, but things has been hectic
around here, sorry for the long delay.
DMA support has been added to the ATA disk driver.
This only works on Intel PIIX3/4, Acer Aladdin and Promise controllers.
The promise support works without the BIOS on the board,
and timing modes are set to support up to UDMA speed. This
solves the problems with having more than one promise controller
in the same system.
There is support for "generic" DMA, that might work on other
controllers, but now you have been warned :)
More chipset specific code will come soon, I have to find testers
with the approbiate HW, more on that when I have it ready.
The system now uses its own major numbers, please run MAKEDEV
with the devices you need (ad?, acd?, afd?, ast?).
For now the disk driver will also attach to the old wd major
so one can at least boot without this step, but be warned, this
will eventually go away. The bootblocks will have to be changed
before one can boot directly from an "ad" device though.
Fixed problems:
All known hang problems should be solved
The probe code has been sligthly changed, this should solve
the reports I have lying around (I hope).
Hangs when accessing ata & atapi device on the same channel simultaniously.
A real braino in ata_start caused this, fixed.
As usual USE AT YOUR OWN RISK!!, this is still pre alpha level code.
Especially the DMA support can hose your disk real bad if anything
goes wrong, agaiin you have been warned :)
But please tell me how it works for you!
Enjoy!
-Søren
1999-03-28 18:57:20 +00:00
|
|
|
}
|
|
|
|
|
2002-04-05 13:13:56 +00:00
|
|
|
static void
|
2004-08-13 08:14:27 +00:00
|
|
|
ata_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
|
2002-04-05 13:13:56 +00:00
|
|
|
{
|
2004-08-13 08:14:27 +00:00
|
|
|
struct ata_dmasetprd_args *args = xsc;
|
|
|
|
struct ata_dma_prdentry *prd = args->dmatab;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if ((args->error = error))
|
2002-04-05 13:13:56 +00:00
|
|
|
return;
|
2004-08-13 08:14:27 +00:00
|
|
|
|
2002-04-05 13:13:56 +00:00
|
|
|
for (i = 0; i < nsegs; i++) {
|
2004-08-13 08:14:27 +00:00
|
|
|
prd[i].addr = htole32(segs[i].ds_addr);
|
|
|
|
prd[i].count = htole32(segs[i].ds_len);
|
2002-04-05 13:13:56 +00:00
|
|
|
}
|
2004-08-13 08:14:27 +00:00
|
|
|
prd[i - 1].count |= htole32(ATA_DMA_EOT);
|
2007-11-20 04:52:19 +00:00
|
|
|
KASSERT(nsegs <= ATA_DMA_ENTRIES, ("too many DMA segment entries\n"));
|
2005-05-03 07:55:07 +00:00
|
|
|
args->nsegs = nsegs;
|
2002-04-05 13:13:56 +00:00
|
|
|
}
|
|
|
|
|
2003-02-20 20:02:32 +00:00
|
|
|
static int
|
2008-04-10 13:05:05 +00:00
|
|
|
ata_dmaload(struct ata_request *request, void *addr, int *entries)
|
Fourth update to the new ATA/ATAPI driver:
Well, better late than newer, but things has been hectic
around here, sorry for the long delay.
DMA support has been added to the ATA disk driver.
This only works on Intel PIIX3/4, Acer Aladdin and Promise controllers.
The promise support works without the BIOS on the board,
and timing modes are set to support up to UDMA speed. This
solves the problems with having more than one promise controller
in the same system.
There is support for "generic" DMA, that might work on other
controllers, but now you have been warned :)
More chipset specific code will come soon, I have to find testers
with the approbiate HW, more on that when I have it ready.
The system now uses its own major numbers, please run MAKEDEV
with the devices you need (ad?, acd?, afd?, ast?).
For now the disk driver will also attach to the old wd major
so one can at least boot without this step, but be warned, this
will eventually go away. The bootblocks will have to be changed
before one can boot directly from an "ad" device though.
Fixed problems:
All known hang problems should be solved
The probe code has been sligthly changed, this should solve
the reports I have lying around (I hope).
Hangs when accessing ata & atapi device on the same channel simultaniously.
A real braino in ata_start caused this, fixed.
As usual USE AT YOUR OWN RISK!!, this is still pre alpha level code.
Especially the DMA support can hose your disk real bad if anything
goes wrong, agaiin you have been warned :)
But please tell me how it works for you!
Enjoy!
-Søren
1999-03-28 18:57:20 +00:00
|
|
|
{
|
2008-04-10 13:05:05 +00:00
|
|
|
struct ata_channel *ch = device_get_softc(request->parent);
|
|
|
|
struct ata_dmasetprd_args dspa;
|
2005-12-05 22:31:55 +00:00
|
|
|
int error;
|
Fourth update to the new ATA/ATAPI driver:
Well, better late than newer, but things has been hectic
around here, sorry for the long delay.
DMA support has been added to the ATA disk driver.
This only works on Intel PIIX3/4, Acer Aladdin and Promise controllers.
The promise support works without the BIOS on the board,
and timing modes are set to support up to UDMA speed. This
solves the problems with having more than one promise controller
in the same system.
There is support for "generic" DMA, that might work on other
controllers, but now you have been warned :)
More chipset specific code will come soon, I have to find testers
with the approbiate HW, more on that when I have it ready.
The system now uses its own major numbers, please run MAKEDEV
with the devices you need (ad?, acd?, afd?, ast?).
For now the disk driver will also attach to the old wd major
so one can at least boot without this step, but be warned, this
will eventually go away. The bootblocks will have to be changed
before one can boot directly from an "ad" device though.
Fixed problems:
All known hang problems should be solved
The probe code has been sligthly changed, this should solve
the reports I have lying around (I hope).
Hangs when accessing ata & atapi device on the same channel simultaniously.
A real braino in ata_start caused this, fixed.
As usual USE AT YOUR OWN RISK!!, this is still pre alpha level code.
Especially the DMA support can hose your disk real bad if anything
goes wrong, agaiin you have been warned :)
But please tell me how it works for you!
Enjoy!
-Søren
1999-03-28 18:57:20 +00:00
|
|
|
|
2008-04-10 13:05:05 +00:00
|
|
|
ATA_DEBUG_RQ(request, "dmaload");
|
|
|
|
|
2008-04-17 12:29:35 +00:00
|
|
|
if (request->dma) {
|
2009-10-31 13:24:14 +00:00
|
|
|
device_printf(request->parent,
|
2008-04-10 13:05:05 +00:00
|
|
|
"FAILURE - already active DMA on this device\n");
|
2005-12-05 22:31:55 +00:00
|
|
|
return EIO;
|
2000-09-19 11:08:39 +00:00
|
|
|
}
|
2008-04-10 13:05:05 +00:00
|
|
|
if (!request->bytecount) {
|
2009-10-31 13:24:14 +00:00
|
|
|
device_printf(request->parent,
|
2008-04-10 13:05:05 +00:00
|
|
|
"FAILURE - zero length DMA transfer attempted\n");
|
2005-12-05 22:31:55 +00:00
|
|
|
return EIO;
|
2003-08-24 09:22:26 +00:00
|
|
|
}
|
2009-09-06 14:23:26 +00:00
|
|
|
if (request->bytecount & (ch->dma.alignment - 1)) {
|
2009-10-31 13:24:14 +00:00
|
|
|
device_printf(request->parent,
|
2009-09-06 14:23:26 +00:00
|
|
|
"FAILURE - odd-sized DMA transfer attempt %d %% %d\n",
|
|
|
|
request->bytecount, ch->dma.alignment);
|
2005-12-05 22:31:55 +00:00
|
|
|
return EIO;
|
2003-10-21 19:20:37 +00:00
|
|
|
}
|
2008-04-10 13:05:05 +00:00
|
|
|
if (request->bytecount > ch->dma.max_iosize) {
|
2009-10-31 13:24:14 +00:00
|
|
|
device_printf(request->parent,
|
2008-04-10 13:05:05 +00:00
|
|
|
"FAILURE - oversized DMA transfer attempt %d > %d\n",
|
|
|
|
request->bytecount, ch->dma.max_iosize);
|
2005-12-05 22:31:55 +00:00
|
|
|
return EIO;
|
Fourth update to the new ATA/ATAPI driver:
Well, better late than newer, but things has been hectic
around here, sorry for the long delay.
DMA support has been added to the ATA disk driver.
This only works on Intel PIIX3/4, Acer Aladdin and Promise controllers.
The promise support works without the BIOS on the board,
and timing modes are set to support up to UDMA speed. This
solves the problems with having more than one promise controller
in the same system.
There is support for "generic" DMA, that might work on other
controllers, but now you have been warned :)
More chipset specific code will come soon, I have to find testers
with the approbiate HW, more on that when I have it ready.
The system now uses its own major numbers, please run MAKEDEV
with the devices you need (ad?, acd?, afd?, ast?).
For now the disk driver will also attach to the old wd major
so one can at least boot without this step, but be warned, this
will eventually go away. The bootblocks will have to be changed
before one can boot directly from an "ad" device though.
Fixed problems:
All known hang problems should be solved
The probe code has been sligthly changed, this should solve
the reports I have lying around (I hope).
Hangs when accessing ata & atapi device on the same channel simultaniously.
A real braino in ata_start caused this, fixed.
As usual USE AT YOUR OWN RISK!!, this is still pre alpha level code.
Especially the DMA support can hose your disk real bad if anything
goes wrong, agaiin you have been warned :)
But please tell me how it works for you!
Enjoy!
-Søren
1999-03-28 18:57:20 +00:00
|
|
|
}
|
2002-04-18 19:11:45 +00:00
|
|
|
|
2009-10-31 13:24:14 +00:00
|
|
|
/* set our slot. XXX SOS NCQ will change that */
|
|
|
|
request->dma = &ch->dma.slot[0];
|
2008-04-10 13:05:05 +00:00
|
|
|
|
|
|
|
if (addr)
|
|
|
|
dspa.dmatab = addr;
|
|
|
|
else
|
2008-04-17 12:29:35 +00:00
|
|
|
dspa.dmatab = request->dma->sg;
|
2008-04-10 13:05:05 +00:00
|
|
|
|
2013-02-22 21:43:21 +00:00
|
|
|
if (request->flags & ATA_R_DATA_IN_CCB)
|
2013-02-12 16:57:20 +00:00
|
|
|
error = bus_dmamap_load_ccb(request->dma->data_tag,
|
|
|
|
request->dma->data_map, request->ccb,
|
|
|
|
ch->dma.setprd, &dspa, BUS_DMA_NOWAIT);
|
|
|
|
else
|
|
|
|
error = bus_dmamap_load(request->dma->data_tag, request->dma->data_map,
|
|
|
|
request->data, request->bytecount,
|
|
|
|
ch->dma.setprd, &dspa, BUS_DMA_NOWAIT);
|
|
|
|
if (error || (error = dspa.error)) {
|
2009-10-31 13:24:14 +00:00
|
|
|
device_printf(request->parent, "FAILURE - load data\n");
|
2008-04-10 13:05:05 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2003-10-21 19:20:37 +00:00
|
|
|
|
2008-04-10 13:05:05 +00:00
|
|
|
if (entries)
|
|
|
|
*entries = dspa.nsegs;
|
2002-04-18 19:11:45 +00:00
|
|
|
|
2008-04-17 12:29:35 +00:00
|
|
|
bus_dmamap_sync(request->dma->sg_tag, request->dma->sg_map,
|
2008-04-10 13:05:05 +00:00
|
|
|
BUS_DMASYNC_PREWRITE);
|
2008-04-17 12:29:35 +00:00
|
|
|
bus_dmamap_sync(request->dma->data_tag, request->dma->data_map,
|
2008-04-10 13:05:05 +00:00
|
|
|
(request->flags & ATA_R_READ) ?
|
|
|
|
BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
|
2002-04-18 19:11:45 +00:00
|
|
|
return 0;
|
2008-04-10 13:05:05 +00:00
|
|
|
|
|
|
|
error:
|
|
|
|
ata_dmaunload(request);
|
|
|
|
return EIO;
|
Fourth update to the new ATA/ATAPI driver:
Well, better late than newer, but things has been hectic
around here, sorry for the long delay.
DMA support has been added to the ATA disk driver.
This only works on Intel PIIX3/4, Acer Aladdin and Promise controllers.
The promise support works without the BIOS on the board,
and timing modes are set to support up to UDMA speed. This
solves the problems with having more than one promise controller
in the same system.
There is support for "generic" DMA, that might work on other
controllers, but now you have been warned :)
More chipset specific code will come soon, I have to find testers
with the approbiate HW, more on that when I have it ready.
The system now uses its own major numbers, please run MAKEDEV
with the devices you need (ad?, acd?, afd?, ast?).
For now the disk driver will also attach to the old wd major
so one can at least boot without this step, but be warned, this
will eventually go away. The bootblocks will have to be changed
before one can boot directly from an "ad" device though.
Fixed problems:
All known hang problems should be solved
The probe code has been sligthly changed, this should solve
the reports I have lying around (I hope).
Hangs when accessing ata & atapi device on the same channel simultaniously.
A real braino in ata_start caused this, fixed.
As usual USE AT YOUR OWN RISK!!, this is still pre alpha level code.
Especially the DMA support can hose your disk real bad if anything
goes wrong, agaiin you have been warned :)
But please tell me how it works for you!
Enjoy!
-Søren
1999-03-28 18:57:20 +00:00
|
|
|
}
|
|
|
|
|
2000-09-19 11:08:39 +00:00
|
|
|
int
|
2008-04-10 13:05:05 +00:00
|
|
|
ata_dmaunload(struct ata_request *request)
|
Fourth update to the new ATA/ATAPI driver:
Well, better late than newer, but things has been hectic
around here, sorry for the long delay.
DMA support has been added to the ATA disk driver.
This only works on Intel PIIX3/4, Acer Aladdin and Promise controllers.
The promise support works without the BIOS on the board,
and timing modes are set to support up to UDMA speed. This
solves the problems with having more than one promise controller
in the same system.
There is support for "generic" DMA, that might work on other
controllers, but now you have been warned :)
More chipset specific code will come soon, I have to find testers
with the approbiate HW, more on that when I have it ready.
The system now uses its own major numbers, please run MAKEDEV
with the devices you need (ad?, acd?, afd?, ast?).
For now the disk driver will also attach to the old wd major
so one can at least boot without this step, but be warned, this
will eventually go away. The bootblocks will have to be changed
before one can boot directly from an "ad" device though.
Fixed problems:
All known hang problems should be solved
The probe code has been sligthly changed, this should solve
the reports I have lying around (I hope).
Hangs when accessing ata & atapi device on the same channel simultaniously.
A real braino in ata_start caused this, fixed.
As usual USE AT YOUR OWN RISK!!, this is still pre alpha level code.
Especially the DMA support can hose your disk real bad if anything
goes wrong, agaiin you have been warned :)
But please tell me how it works for you!
Enjoy!
-Søren
1999-03-28 18:57:20 +00:00
|
|
|
{
|
2008-04-10 13:05:05 +00:00
|
|
|
ATA_DEBUG_RQ(request, "dmaunload");
|
2003-08-24 09:22:26 +00:00
|
|
|
|
2008-04-17 12:29:35 +00:00
|
|
|
if (request->dma) {
|
|
|
|
bus_dmamap_sync(request->dma->sg_tag, request->dma->sg_map,
|
2005-05-03 07:55:07 +00:00
|
|
|
BUS_DMASYNC_POSTWRITE);
|
2008-04-17 12:29:35 +00:00
|
|
|
bus_dmamap_sync(request->dma->data_tag, request->dma->data_map,
|
2008-04-10 13:05:05 +00:00
|
|
|
(request->flags & ATA_R_READ) ?
|
2005-05-03 07:55:07 +00:00
|
|
|
BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
|
|
|
|
|
2008-04-17 12:29:35 +00:00
|
|
|
bus_dmamap_unload(request->dma->data_tag, request->dma->data_map);
|
|
|
|
request->dma = NULL;
|
2008-04-10 13:05:05 +00:00
|
|
|
}
|
2003-03-29 13:37:09 +00:00
|
|
|
return 0;
|
Fourth update to the new ATA/ATAPI driver:
Well, better late than newer, but things has been hectic
around here, sorry for the long delay.
DMA support has been added to the ATA disk driver.
This only works on Intel PIIX3/4, Acer Aladdin and Promise controllers.
The promise support works without the BIOS on the board,
and timing modes are set to support up to UDMA speed. This
solves the problems with having more than one promise controller
in the same system.
There is support for "generic" DMA, that might work on other
controllers, but now you have been warned :)
More chipset specific code will come soon, I have to find testers
with the approbiate HW, more on that when I have it ready.
The system now uses its own major numbers, please run MAKEDEV
with the devices you need (ad?, acd?, afd?, ast?).
For now the disk driver will also attach to the old wd major
so one can at least boot without this step, but be warned, this
will eventually go away. The bootblocks will have to be changed
before one can boot directly from an "ad" device though.
Fixed problems:
All known hang problems should be solved
The probe code has been sligthly changed, this should solve
the reports I have lying around (I hope).
Hangs when accessing ata & atapi device on the same channel simultaniously.
A real braino in ata_start caused this, fixed.
As usual USE AT YOUR OWN RISK!!, this is still pre alpha level code.
Especially the DMA support can hose your disk real bad if anything
goes wrong, agaiin you have been warned :)
But please tell me how it works for you!
Enjoy!
-Søren
1999-03-28 18:57:20 +00:00
|
|
|
}
|