- Remove most of direct relations between ATA(4) peripherial and controller
levels. It makes logic more transparent and is a mandatory step to wrap
ATA(4) controller level into ATA-native CAM SIM.
- Tune AHCI and SATA2 SiI drivers memory allocation a bit to allow bigger
I/O transaction sizes without additional cost.
This commit is contained in:
Alexander Motin 2009-10-31 13:24:14 +00:00
parent a65653d16a
commit ebbb35ba70
14 changed files with 138 additions and 155 deletions

View File

@ -548,14 +548,16 @@ sata_channel_begin_transaction(struct ata_request *request)
uint32_t req_in; uint32_t req_in;
int error, slot; int error, slot;
sc = device_get_softc(GRANDPARENT(request->dev)); sc = device_get_softc(device_get_parent(request->parent));
ch = device_get_softc(request->parent); ch = device_get_softc(request->parent);
mtx_assert(&ch->state_mtx, MA_OWNED); mtx_assert(&ch->state_mtx, MA_OWNED);
/* Only DMA R/W goes through the EDMA machine. */ /* Only DMA R/W goes through the EDMA machine. */
if (request->u.ata.command != ATA_READ_DMA && if (request->u.ata.command != ATA_READ_DMA &&
request->u.ata.command != ATA_WRITE_DMA) { request->u.ata.command != ATA_WRITE_DMA &&
request->u.ata.command != ATA_READ_DMA48 &&
request->u.ata.command != ATA_WRITE_DMA48) {
/* Disable EDMA before accessing legacy registers */ /* Disable EDMA before accessing legacy registers */
if (sata_edma_is_running(request->parent)) { if (sata_edma_is_running(request->parent)) {
@ -569,12 +571,9 @@ sata_channel_begin_transaction(struct ata_request *request)
return (ata_begin_transaction(request)); return (ata_begin_transaction(request));
} }
/* Check for 48 bit access and convert if needed */
ata_modify_if_48bit(request);
/* Prepare data for DMA */ /* Prepare data for DMA */
if ((error = ch->dma.load(request, NULL, NULL))) { if ((error = ch->dma.load(request, NULL, NULL))) {
device_printf(request->dev, "setting up DMA failed!\n"); device_printf(request->parent, "setting up DMA failed!\n");
request->result = error; request->result = error;
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
} }
@ -633,7 +632,7 @@ sata_channel_end_transaction(struct ata_request *request)
uint32_t res_in, res_out, icr; uint32_t res_in, res_out, icr;
int slot; int slot;
sc = device_get_softc(GRANDPARENT(request->dev)); sc = device_get_softc(device_get_parent(request->parent));
ch = device_get_softc(request->parent); ch = device_get_softc(request->parent);
mtx_assert(&ch->state_mtx, MA_OWNED); mtx_assert(&ch->state_mtx, MA_OWNED);

View File

@ -798,10 +798,10 @@ ata_default_registers(device_t dev)
void void
ata_modify_if_48bit(struct ata_request *request) ata_modify_if_48bit(struct ata_request *request)
{ {
struct ata_channel *ch = device_get_softc(device_get_parent(request->dev)); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_device *atadev = device_get_softc(request->dev); struct ata_device *atadev = device_get_softc(request->dev);
atadev->flags &= ~ATA_D_48BIT_ACTIVE; request->flags &= ~ATA_R_48BIT;
if (((request->u.ata.lba + request->u.ata.count) >= ATA_MAX_28BIT_LBA || if (((request->u.ata.lba + request->u.ata.count) >= ATA_MAX_28BIT_LBA ||
request->u.ata.count > 256) && request->u.ata.count > 256) &&
@ -875,7 +875,7 @@ ata_modify_if_48bit(struct ata_request *request)
default: default:
return; return;
} }
atadev->flags |= ATA_D_48BIT_ACTIVE; request->flags |= ATA_R_48BIT;
} }
else if (atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48) { else if (atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48) {
@ -893,7 +893,7 @@ ata_modify_if_48bit(struct ata_request *request)
default: default:
return; return;
} }
atadev->flags |= ATA_D_48BIT_ACTIVE; request->flags |= ATA_R_48BIT;
} }
} }

View File

@ -255,7 +255,7 @@
#define ATA_AHCI_CL_OFFSET 0 #define ATA_AHCI_CL_OFFSET 0
#define ATA_AHCI_FB_OFFSET (ATA_AHCI_CL_SIZE * 32) #define ATA_AHCI_FB_OFFSET (ATA_AHCI_CL_SIZE * 32)
#define ATA_AHCI_CT_OFFSET (ATA_AHCI_FB_OFFSET + 4096) #define ATA_AHCI_CT_OFFSET (ATA_AHCI_FB_OFFSET + 4096)
#define ATA_AHCI_CT_SIZE (1024 + 128) #define ATA_AHCI_CT_SIZE (2176 + 128)
struct ata_ahci_dma_prd { struct ata_ahci_dma_prd {
u_int64_t dba; u_int64_t dba;
@ -269,7 +269,7 @@ struct ata_ahci_cmd_tab {
u_int8_t cfis[64]; u_int8_t cfis[64];
u_int8_t acmd[32]; u_int8_t acmd[32];
u_int8_t reserved[32]; u_int8_t reserved[32];
#define ATA_AHCI_DMA_ENTRIES 64 #define ATA_AHCI_DMA_ENTRIES 129
struct ata_ahci_dma_prd prd_tab[ATA_AHCI_DMA_ENTRIES]; struct ata_ahci_dma_prd prd_tab[ATA_AHCI_DMA_ENTRIES];
} __packed; } __packed;
@ -364,6 +364,7 @@ struct ata_composite {
struct ata_request { struct ata_request {
device_t dev; /* device handle */ device_t dev; /* device handle */
device_t parent; /* channel handle */ device_t parent; /* channel handle */
int unit; /* physical unit */
union { union {
struct { struct {
u_int8_t command; /* command reg */ u_int8_t command; /* command reg */
@ -389,6 +390,7 @@ struct ata_request {
#define ATA_R_DMA 0x00000010 #define ATA_R_DMA 0x00000010
#define ATA_R_QUIET 0x00000020 #define ATA_R_QUIET 0x00000020
#define ATA_R_TIMEOUT 0x00000040 #define ATA_R_TIMEOUT 0x00000040
#define ATA_R_48BIT 0x00000080
#define ATA_R_ORDERED 0x00000100 #define ATA_R_ORDERED 0x00000100
#define ATA_R_AT_HEAD 0x00000200 #define ATA_R_AT_HEAD 0x00000200
@ -396,6 +398,9 @@ struct ata_request {
#define ATA_R_THREAD 0x00000800 #define ATA_R_THREAD 0x00000800
#define ATA_R_DIRECT 0x00001000 #define ATA_R_DIRECT 0x00001000
#define ATA_R_ATAPI16 0x00010000
#define ATA_R_ATAPI_INTR 0x00020000
#define ATA_R_DEBUG 0x10000000 #define ATA_R_DEBUG 0x10000000
#define ATA_R_DANGER1 0x20000000 #define ATA_R_DANGER1 0x20000000
#define ATA_R_DANGER2 0x40000000 #define ATA_R_DANGER2 0x40000000
@ -423,7 +428,7 @@ struct ata_request {
#define ATA_DEBUG_RQ(request, string) \ #define ATA_DEBUG_RQ(request, string) \
{ \ { \
if (request->flags & ATA_R_DEBUG) \ if (request->flags & ATA_R_DEBUG) \
device_printf(request->dev, "req=%p %s " string "\n", \ device_printf(request->parent, "req=%p %s " string "\n", \
request, ata_cmd2str(request)); \ request, ata_cmd2str(request)); \
} }
#else #else
@ -449,7 +454,6 @@ struct ata_device {
#define ATA_D_USE_CHS 0x0001 #define ATA_D_USE_CHS 0x0001
#define ATA_D_MEDIA_CHANGED 0x0002 #define ATA_D_MEDIA_CHANGED 0x0002
#define ATA_D_ENC_PRESENT 0x0004 #define ATA_D_ENC_PRESENT 0x0004
#define ATA_D_48BIT_ACTIVE 0x0008
}; };
/* structure for holding DMA Physical Region Descriptors (PRD) entries */ /* structure for holding DMA Physical Region Descriptors (PRD) entries */
@ -483,7 +487,7 @@ struct ata_dma {
u_int8_t *work; /* workspace */ u_int8_t *work; /* workspace */
bus_addr_t work_bus; /* bus address of dmatab */ bus_addr_t work_bus; /* bus address of dmatab */
#define ATA_DMA_SLOTS 32 #define ATA_DMA_SLOTS 1
int dma_slots; /* DMA slots allocated */ int dma_slots; /* DMA slots allocated */
struct ata_dmaslot slot[ATA_DMA_SLOTS]; struct ata_dmaslot slot[ATA_DMA_SLOTS];
u_int32_t alignment; /* DMA SG list alignment */ u_int32_t alignment; /* DMA SG list alignment */

View File

@ -78,7 +78,7 @@ ata_dmainit(device_t dev)
ch->dma.segsize = 65536; ch->dma.segsize = 65536;
ch->dma.max_iosize = 128 * DEV_BSIZE; ch->dma.max_iosize = 128 * DEV_BSIZE;
ch->dma.max_address = BUS_SPACE_MAXADDR_32BIT; ch->dma.max_address = BUS_SPACE_MAXADDR_32BIT;
ch->dma.dma_slots = 6; ch->dma.dma_slots = 1;
if (bus_dma_tag_create(bus_get_dma_tag(dev), ch->dma.alignment, 0, if (bus_dma_tag_create(bus_get_dma_tag(dev), ch->dma.alignment, 0,
ch->dma.max_address, BUS_SPACE_MAXADDR, ch->dma.max_address, BUS_SPACE_MAXADDR,
@ -256,37 +256,36 @@ static int
ata_dmaload(struct ata_request *request, void *addr, int *entries) ata_dmaload(struct ata_request *request, void *addr, int *entries)
{ {
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_device *atadev = device_get_softc(request->dev);
struct ata_dmasetprd_args dspa; struct ata_dmasetprd_args dspa;
int error; int error;
ATA_DEBUG_RQ(request, "dmaload"); ATA_DEBUG_RQ(request, "dmaload");
if (request->dma) { if (request->dma) {
device_printf(request->dev, device_printf(request->parent,
"FAILURE - already active DMA on this device\n"); "FAILURE - already active DMA on this device\n");
return EIO; return EIO;
} }
if (!request->bytecount) { if (!request->bytecount) {
device_printf(request->dev, device_printf(request->parent,
"FAILURE - zero length DMA transfer attempted\n"); "FAILURE - zero length DMA transfer attempted\n");
return EIO; return EIO;
} }
if (request->bytecount & (ch->dma.alignment - 1)) { if (request->bytecount & (ch->dma.alignment - 1)) {
device_printf(request->dev, device_printf(request->parent,
"FAILURE - odd-sized DMA transfer attempt %d %% %d\n", "FAILURE - odd-sized DMA transfer attempt %d %% %d\n",
request->bytecount, ch->dma.alignment); request->bytecount, ch->dma.alignment);
return EIO; return EIO;
} }
if (request->bytecount > ch->dma.max_iosize) { if (request->bytecount > ch->dma.max_iosize) {
device_printf(request->dev, device_printf(request->parent,
"FAILURE - oversized DMA transfer attempt %d > %d\n", "FAILURE - oversized DMA transfer attempt %d > %d\n",
request->bytecount, ch->dma.max_iosize); request->bytecount, ch->dma.max_iosize);
return EIO; return EIO;
} }
/* set our slot, unit for simplicity XXX SOS NCQ will change that */ /* set our slot. XXX SOS NCQ will change that */
request->dma = &ch->dma.slot[atadev->unit]; request->dma = &ch->dma.slot[0];
if (addr) if (addr)
dspa.dmatab = addr; dspa.dmatab = addr;
@ -297,7 +296,7 @@ ata_dmaload(struct ata_request *request, void *addr, int *entries)
request->data, request->bytecount, request->data, request->bytecount,
ch->dma.setprd, &dspa, BUS_DMA_NOWAIT)) || ch->dma.setprd, &dspa, BUS_DMA_NOWAIT)) ||
(error = dspa.error)) { (error = dspa.error)) {
device_printf(request->dev, "FAILURE - load data\n"); device_printf(request->parent, "FAILURE - load data\n");
goto error; goto error;
} }

View File

@ -47,7 +47,7 @@ __FBSDID("$FreeBSD$");
/* prototypes */ /* prototypes */
static int ata_generic_status(device_t dev); static int ata_generic_status(device_t dev);
static int ata_wait(struct ata_channel *ch, struct ata_device *, u_int8_t); static int ata_wait(struct ata_channel *ch, int unit, u_int8_t);
static void ata_pio_read(struct ata_request *, int); static void ata_pio_read(struct ata_request *, int);
static void ata_pio_write(struct ata_request *, int); static void ata_pio_write(struct ata_request *, int);
static void ata_tf_read(struct ata_request *); static void ata_tf_read(struct ata_request *);
@ -77,7 +77,6 @@ int
ata_begin_transaction(struct ata_request *request) ata_begin_transaction(struct ata_request *request)
{ {
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_device *atadev = device_get_softc(request->dev);
int dummy, error; int dummy, error;
ATA_DEBUG_RQ(request, "begin transaction"); ATA_DEBUG_RQ(request, "begin transaction");
@ -88,9 +87,6 @@ ata_begin_transaction(struct ata_request *request)
(ATA_R_ATAPI | ATA_R_DMA | ATA_R_WRITE))) (ATA_R_ATAPI | ATA_R_DMA | ATA_R_WRITE)))
request->flags &= ~ATA_R_DMA; request->flags &= ~ATA_R_DMA;
/* check for 48 bit access and convert if needed */
ata_modify_if_48bit(request);
switch (request->flags & (ATA_R_ATAPI | ATA_R_DMA)) { switch (request->flags & (ATA_R_ATAPI | ATA_R_DMA)) {
/* ATA PIO data transfer and control commands */ /* ATA PIO data transfer and control commands */
@ -101,7 +97,7 @@ ata_begin_transaction(struct ata_request *request)
/* issue command */ /* issue command */
if (ch->hw.command(request)) { if (ch->hw.command(request)) {
device_printf(request->dev, "error issuing %s command\n", device_printf(request->parent, "error issuing %s command\n",
ata_cmd2str(request)); ata_cmd2str(request));
request->result = EIO; request->result = EIO;
goto begin_finished; goto begin_finished;
@ -122,8 +118,8 @@ ata_begin_transaction(struct ata_request *request)
/* if write command output the data */ /* if write command output the data */
if (write) { if (write) {
if (ata_wait(ch, atadev, (ATA_S_READY | ATA_S_DRQ)) < 0) { if (ata_wait(ch, request->unit, (ATA_S_READY | ATA_S_DRQ)) < 0) {
device_printf(request->dev, device_printf(request->parent,
"timeout waiting for write DRQ\n"); "timeout waiting for write DRQ\n");
request->result = EIO; request->result = EIO;
goto begin_finished; goto begin_finished;
@ -137,14 +133,14 @@ ata_begin_transaction(struct ata_request *request)
case ATA_R_DMA: case ATA_R_DMA:
/* check sanity, setup SG list and DMA engine */ /* check sanity, setup SG list and DMA engine */
if ((error = ch->dma.load(request, NULL, &dummy))) { if ((error = ch->dma.load(request, NULL, &dummy))) {
device_printf(request->dev, "setting up DMA failed\n"); device_printf(request->parent, "setting up DMA failed\n");
request->result = error; request->result = error;
goto begin_finished; goto begin_finished;
} }
/* issue command */ /* issue command */
if (ch->hw.command(request)) { if (ch->hw.command(request)) {
device_printf(request->dev, "error issuing %s command\n", device_printf(request->parent, "error issuing %s command\n",
ata_cmd2str(request)); ata_cmd2str(request));
request->result = EIO; request->result = EIO;
goto begin_finished; goto begin_finished;
@ -152,7 +148,7 @@ ata_begin_transaction(struct ata_request *request)
/* start DMA engine */ /* start DMA engine */
if (ch->dma.start && ch->dma.start(request)) { if (ch->dma.start && ch->dma.start(request)) {
device_printf(request->dev, "error starting DMA\n"); device_printf(request->parent, "error starting DMA\n");
request->result = EIO; request->result = EIO;
goto begin_finished; goto begin_finished;
} }
@ -162,7 +158,7 @@ ata_begin_transaction(struct ata_request *request)
case ATA_R_ATAPI: case ATA_R_ATAPI:
/* is this just a POLL DSC command ? */ /* is this just a POLL DSC command ? */
if (request->u.atapi.ccb[0] == ATAPI_POLL_DSC) { if (request->u.atapi.ccb[0] == ATAPI_POLL_DSC) {
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(atadev->unit)); ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit));
DELAY(10); DELAY(10);
if (!(ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_DSC)) if (!(ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_DSC))
request->result = EBUSY; request->result = EBUSY;
@ -171,7 +167,7 @@ ata_begin_transaction(struct ata_request *request)
/* start ATAPI operation */ /* start ATAPI operation */
if (ch->hw.command(request)) { if (ch->hw.command(request)) {
device_printf(request->dev, "error issuing ATA PACKET command\n"); device_printf(request->parent, "error issuing ATA PACKET command\n");
request->result = EIO; request->result = EIO;
goto begin_finished; goto begin_finished;
} }
@ -181,7 +177,7 @@ ata_begin_transaction(struct ata_request *request)
case ATA_R_ATAPI|ATA_R_DMA: case ATA_R_ATAPI|ATA_R_DMA:
/* is this just a POLL DSC command ? */ /* is this just a POLL DSC command ? */
if (request->u.atapi.ccb[0] == ATAPI_POLL_DSC) { if (request->u.atapi.ccb[0] == ATAPI_POLL_DSC) {
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(atadev->unit)); ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit));
DELAY(10); DELAY(10);
if (!(ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_DSC)) if (!(ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_DSC))
request->result = EBUSY; request->result = EBUSY;
@ -190,14 +186,14 @@ ata_begin_transaction(struct ata_request *request)
/* check sanity, setup SG list and DMA engine */ /* check sanity, setup SG list and DMA engine */
if ((error = ch->dma.load(request, NULL, &dummy))) { if ((error = ch->dma.load(request, NULL, &dummy))) {
device_printf(request->dev, "setting up DMA failed\n"); device_printf(request->parent, "setting up DMA failed\n");
request->result = error; request->result = error;
goto begin_finished; goto begin_finished;
} }
/* start ATAPI operation */ /* start ATAPI operation */
if (ch->hw.command(request)) { if (ch->hw.command(request)) {
device_printf(request->dev, "error issuing ATA PACKET command\n"); device_printf(request->parent, "error issuing ATA PACKET command\n");
request->result = EIO; request->result = EIO;
goto begin_finished; goto begin_finished;
} }
@ -229,7 +225,6 @@ int
ata_end_transaction(struct ata_request *request) ata_end_transaction(struct ata_request *request)
{ {
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_device *atadev = device_get_softc(request->dev);
int length; int length;
ATA_DEBUG_RQ(request, "end transaction"); ATA_DEBUG_RQ(request, "end transaction");
@ -266,8 +261,8 @@ ata_end_transaction(struct ata_request *request)
if (request->u.ata.command != ATA_ATAPI_IDENTIFY) if (request->u.ata.command != ATA_ATAPI_IDENTIFY)
flags |= ATA_S_READY; flags |= ATA_S_READY;
if (ata_wait(ch, atadev, flags) < 0) { if (ata_wait(ch, request->unit, flags) < 0) {
device_printf(request->dev, device_printf(request->parent,
"timeout waiting for read DRQ\n"); "timeout waiting for read DRQ\n");
request->result = EIO; request->result = EIO;
goto end_finished; goto end_finished;
@ -290,8 +285,8 @@ ata_end_transaction(struct ata_request *request)
if (request->flags & ATA_R_WRITE) { if (request->flags & ATA_R_WRITE) {
/* if we get an error here we are done with the HW */ /* if we get an error here we are done with the HW */
if (ata_wait(ch, atadev, (ATA_S_READY | ATA_S_DRQ)) < 0) { if (ata_wait(ch, request->unit, (ATA_S_READY | ATA_S_DRQ)) < 0) {
device_printf(request->dev, device_printf(request->parent,
"timeout waiting for write DRQ\n"); "timeout waiting for write DRQ\n");
request->status = ATA_IDX_INB(ch, ATA_STATUS); request->status = ATA_IDX_INB(ch, ATA_STATUS);
goto end_finished; goto end_finished;
@ -347,20 +342,19 @@ ata_end_transaction(struct ata_request *request)
DELAY(10); DELAY(10);
if (!(request->status & ATA_S_DRQ)) { if (!(request->status & ATA_S_DRQ)) {
device_printf(request->dev, "command interrupt without DRQ\n"); device_printf(request->parent, "command interrupt without DRQ\n");
request->status = ATA_S_ERROR; request->status = ATA_S_ERROR;
goto end_finished; goto end_finished;
} }
ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (int16_t *)request->u.atapi.ccb, ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (int16_t *)request->u.atapi.ccb,
(atadev->param.config & (request->flags & ATA_R_ATAPI16) ? 8 : 6);
ATA_PROTO_MASK)== ATA_PROTO_ATAPI_12 ? 6 : 8);
/* return wait for interrupt */ /* return wait for interrupt */
goto end_continue; goto end_continue;
case ATAPI_P_WRITE: case ATAPI_P_WRITE:
if (request->flags & ATA_R_READ) { if (request->flags & ATA_R_READ) {
request->status = ATA_S_ERROR; request->status = ATA_S_ERROR;
device_printf(request->dev, device_printf(request->parent,
"%s trying to write on read buffer\n", "%s trying to write on read buffer\n",
ata_cmd2str(request)); ata_cmd2str(request));
goto end_finished; goto end_finished;
@ -378,7 +372,7 @@ ata_end_transaction(struct ata_request *request)
case ATAPI_P_READ: case ATAPI_P_READ:
if (request->flags & ATA_R_WRITE) { if (request->flags & ATA_R_WRITE) {
request->status = ATA_S_ERROR; request->status = ATA_S_ERROR;
device_printf(request->dev, device_printf(request->parent,
"%s trying to read on write buffer\n", "%s trying to read on write buffer\n",
ata_cmd2str(request)); ata_cmd2str(request));
goto end_finished; goto end_finished;
@ -393,7 +387,7 @@ ata_end_transaction(struct ata_request *request)
goto end_continue; goto end_continue;
case ATAPI_P_DONEDRQ: case ATAPI_P_DONEDRQ:
device_printf(request->dev, device_printf(request->parent,
"WARNING - %s DONEDRQ non conformant device\n", "WARNING - %s DONEDRQ non conformant device\n",
ata_cmd2str(request)); ata_cmd2str(request));
if (request->flags & ATA_R_READ) { if (request->flags & ATA_R_READ) {
@ -415,7 +409,7 @@ ata_end_transaction(struct ata_request *request)
goto end_finished; goto end_finished;
default: default:
device_printf(request->dev, "unknown transfer phase\n"); device_printf(request->parent, "unknown transfer phase\n");
request->status = ATA_S_ERROR; request->status = ATA_S_ERROR;
} }
@ -603,7 +597,7 @@ ata_generic_status(device_t dev)
} }
static int static int
ata_wait(struct ata_channel *ch, struct ata_device *atadev, u_int8_t mask) ata_wait(struct ata_channel *ch, int unit, u_int8_t mask)
{ {
u_int8_t status; u_int8_t status;
int timeout = 0; int timeout = 0;
@ -616,7 +610,7 @@ ata_wait(struct ata_channel *ch, struct ata_device *atadev, u_int8_t mask)
/* if drive fails status, reselect the drive and try again */ /* if drive fails status, reselect the drive and try again */
if (status == 0xff) { if (status == 0xff) {
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(atadev->unit)); ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(unit));
timeout += 1000; timeout += 1000;
DELAY(1000); DELAY(1000);
continue; continue;
@ -657,14 +651,13 @@ int
ata_generic_command(struct ata_request *request) ata_generic_command(struct ata_request *request)
{ {
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_device *atadev = device_get_softc(request->dev);
/* select device */ /* select device */
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(atadev->unit)); ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit));
/* ready to issue command ? */ /* ready to issue command ? */
if (ata_wait(ch, atadev, 0) < 0) { if (ata_wait(ch, request->unit, 0) < 0) {
device_printf(request->dev, "timeout waiting to issue command\n"); device_printf(request->parent, "timeout waiting to issue command\n");
return -1; return -1;
} }
@ -673,6 +666,7 @@ ata_generic_command(struct ata_request *request)
if (request->flags & ATA_R_ATAPI) { if (request->flags & ATA_R_ATAPI) {
int timeout = 5000; int timeout = 5000;
int res;
/* issue packet command to controller */ /* issue packet command to controller */
if (request->flags & ATA_R_DMA) { if (request->flags & ATA_R_DMA) {
@ -688,9 +682,16 @@ ata_generic_command(struct ata_request *request)
ATA_IDX_OUTB(ch, ATA_COMMAND, ATA_PACKET_CMD); ATA_IDX_OUTB(ch, ATA_COMMAND, ATA_PACKET_CMD);
/* command interrupt device ? just return and wait for interrupt */ /* command interrupt device ? just return and wait for interrupt */
if ((atadev->param.config & ATA_DRQ_MASK) == ATA_DRQ_INTR) if (request->flags & ATA_R_ATAPI_INTR)
return 0; return 0;
/* command processed ? */
res = ata_wait(ch, request->unit, 0);
if (res != 0) {
if (res < 0)
device_printf(request->parent, "timeout waiting for PACKET command\n");
return (-1);
}
/* wait for ready to write ATAPI command block */ /* wait for ready to write ATAPI command block */
while (timeout--) { while (timeout--) {
int reason = ATA_IDX_INB(ch, ATA_IREASON); int reason = ATA_IDX_INB(ch, ATA_IREASON);
@ -702,7 +703,7 @@ ata_generic_command(struct ata_request *request)
DELAY(20); DELAY(20);
} }
if (timeout <= 0) { if (timeout <= 0) {
device_printf(request->dev, "timeout waiting for ATAPI ready\n"); device_printf(request->parent, "timeout waiting for ATAPI ready\n");
request->result = EIO; request->result = EIO;
return -1; return -1;
} }
@ -712,8 +713,7 @@ ata_generic_command(struct ata_request *request)
/* output command block */ /* output command block */
ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (int16_t *)request->u.atapi.ccb, ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (int16_t *)request->u.atapi.ccb,
(atadev->param.config & ATA_PROTO_MASK) == (request->flags & ATA_R_ATAPI16) ? 8 : 6);
ATA_PROTO_ATAPI_12 ? 6 : 8);
} }
else { else {
ch->hw.tf_write(request); ch->hw.tf_write(request);
@ -728,9 +728,8 @@ static void
ata_tf_read(struct ata_request *request) ata_tf_read(struct ata_request *request)
{ {
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_device *atadev = device_get_softc(request->dev);
if (atadev->flags & ATA_D_48BIT_ACTIVE) { if (request->flags & ATA_R_48BIT) {
ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_4BIT | ATA_A_HOB); ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_4BIT | ATA_A_HOB);
request->u.ata.count = (ATA_IDX_INB(ch, ATA_COUNT) << 8); request->u.ata.count = (ATA_IDX_INB(ch, ATA_COUNT) << 8);
request->u.ata.lba = request->u.ata.lba =
@ -760,7 +759,7 @@ ata_tf_write(struct ata_request *request)
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_device *atadev = device_get_softc(request->dev); struct ata_device *atadev = device_get_softc(request->dev);
if (atadev->flags & ATA_D_48BIT_ACTIVE) { if (request->flags & ATA_R_48BIT) {
ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature >> 8); ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature >> 8);
ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature);
ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count >> 8); ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count >> 8);
@ -771,7 +770,7 @@ ata_tf_write(struct ata_request *request)
ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8);
ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 40); ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 40);
ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16);
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_LBA | ATA_DEV(atadev->unit)); ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_LBA | ATA_DEV(request->unit));
} }
else { else {
ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature);
@ -793,7 +792,7 @@ ata_tf_write(struct ata_request *request)
(request->u.ata.lba / (sectors * heads))); (request->u.ata.lba / (sectors * heads)));
ATA_IDX_OUTB(ch, ATA_CYL_MSB, ATA_IDX_OUTB(ch, ATA_CYL_MSB,
(request->u.ata.lba / (sectors * heads)) >> 8); (request->u.ata.lba / (sectors * heads)) >> 8);
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(atadev->unit) | ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit) |
(((request->u.ata.lba% (sectors * heads)) / (((request->u.ata.lba% (sectors * heads)) /
sectors) & 0xf)); sectors) & 0xf));
} }
@ -802,7 +801,7 @@ ata_tf_write(struct ata_request *request)
ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8);
ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16);
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_IDX_OUTB(ch, ATA_DRIVE,
ATA_D_IBM | ATA_D_LBA | ATA_DEV(atadev->unit) | ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit) |
((request->u.ata.lba >> 24) & 0x0f)); ((request->u.ata.lba >> 24) & 0x0f));
} }
} }
@ -825,7 +824,7 @@ ata_pio_read(struct ata_request *request, int length)
size / sizeof(int32_t)); size / sizeof(int32_t));
if (request->transfersize < length) { if (request->transfersize < length) {
device_printf(request->dev, "WARNING - %s read data overrun %d>%d\n", device_printf(request->parent, "WARNING - %s read data overrun %d>%d\n",
ata_cmd2str(request), length, request->transfersize); ata_cmd2str(request), length, request->transfersize);
for (resid = request->transfersize; resid < length; for (resid = request->transfersize; resid < length;
resid += sizeof(int16_t)) resid += sizeof(int16_t))
@ -850,7 +849,7 @@ ata_pio_write(struct ata_request *request, int length)
size / sizeof(int32_t)); size / sizeof(int32_t));
if (request->transfersize < length) { if (request->transfersize < length) {
device_printf(request->dev, "WARNING - %s write data underrun %d>%d\n", device_printf(request->parent, "WARNING - %s write data underrun %d>%d\n",
ata_cmd2str(request), length, request->transfersize); ata_cmd2str(request), length, request->transfersize);
for (resid = request->transfersize; resid < length; for (resid = request->transfersize; resid < length;
resid += sizeof(int16_t)) resid += sizeof(int16_t))

View File

@ -477,7 +477,7 @@ ata_pci_dmareset(device_t dev)
ch->dma.flags &= ~ATA_DMA_ACTIVE; ch->dma.flags &= ~ATA_DMA_ACTIVE;
ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR); ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR);
if ((request = ch->running)) { if ((request = ch->running)) {
device_printf(request->dev, "DMA reset calling unload\n"); device_printf(dev, "DMA reset calling unload\n");
ch->dma.unload(request); ch->dma.unload(request);
} }
} }

View File

@ -52,17 +52,25 @@ void
ata_queue_request(struct ata_request *request) ata_queue_request(struct ata_request *request)
{ {
struct ata_channel *ch; struct ata_channel *ch;
struct ata_device *atadev = device_get_softc(request->dev);
/* treat request as virgin (this might be an ATA_R_REQUEUE) */ /* treat request as virgin (this might be an ATA_R_REQUEUE) */
request->result = request->status = request->error = 0; request->result = request->status = request->error = 0;
/* check that the device is still valid */ /* Prepare paramers required by low-level code. */
request->unit = atadev->unit;
if (!(request->parent = device_get_parent(request->dev))) { if (!(request->parent = device_get_parent(request->dev))) {
request->result = ENXIO; request->result = ENXIO;
if (request->callback) if (request->callback)
(request->callback)(request); (request->callback)(request);
return; return;
} }
if ((atadev->param.config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_16)
request->flags |= ATA_R_ATAPI16;
if ((atadev->param.config & ATA_DRQ_MASK) == ATA_DRQ_INTR)
request->flags |= ATA_R_ATAPI_INTR;
if ((request->flags & ATA_R_ATAPI) == 0)
ata_modify_if_48bit(request);
ch = device_get_softc(request->parent); ch = device_get_softc(request->parent);
callout_init_mtx(&request->callout, &ch->state_mtx, CALLOUT_RETURNUNLOCKED); callout_init_mtx(&request->callout, &ch->state_mtx, CALLOUT_RETURNUNLOCKED);
if (!request->callback && !(request->flags & ATA_R_REQUEUE)) if (!request->callback && !(request->flags & ATA_R_REQUEUE))

View File

@ -246,11 +246,10 @@ ata_sata_setmode(device_t dev, int mode)
int int
ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis) ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis)
{ {
struct ata_device *atadev = device_get_softc(request->dev);
if (request->flags & ATA_R_ATAPI) { if (request->flags & ATA_R_ATAPI) {
fis[0] = 0x27; /* host to device */ fis[0] = 0x27; /* host to device */
fis[1] = 0x80 | (atadev->unit & 0x0f); fis[1] = 0x80 | (request->unit & 0x0f);
fis[2] = ATA_PACKET_CMD; fis[2] = ATA_PACKET_CMD;
if (request->flags & (ATA_R_READ | ATA_R_WRITE)) if (request->flags & (ATA_R_READ | ATA_R_WRITE))
fis[3] = ATA_F_DMA; fis[3] = ATA_F_DMA;
@ -263,16 +262,15 @@ ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis)
return 20; return 20;
} }
else { else {
ata_modify_if_48bit(request);
fis[0] = 0x27; /* host to device */ fis[0] = 0x27; /* host to device */
fis[1] = 0x80 | (atadev->unit & 0x0f); fis[1] = 0x80 | (request->unit & 0x0f);
fis[2] = request->u.ata.command; fis[2] = request->u.ata.command;
fis[3] = request->u.ata.feature; fis[3] = request->u.ata.feature;
fis[4] = request->u.ata.lba; fis[4] = request->u.ata.lba;
fis[5] = request->u.ata.lba >> 8; fis[5] = request->u.ata.lba >> 8;
fis[6] = request->u.ata.lba >> 16; fis[6] = request->u.ata.lba >> 16;
fis[7] = ATA_D_LBA; fis[7] = ATA_D_LBA;
if (!(atadev->flags & ATA_D_48BIT_ACTIVE)) if (!(request->flags & ATA_R_48BIT))
fis[7] |= (ATA_D_IBM | (request->u.ata.lba >> 24 & 0x0f)); fis[7] |= (ATA_D_IBM | (request->u.ata.lba >> 24 & 0x0f));
fis[8] = request->u.ata.lba >> 24; fis[8] = request->u.ata.lba >> 24;
fis[9] = request->u.ata.lba >> 32; fis[9] = request->u.ata.lba >> 32;
@ -339,9 +337,6 @@ ata_pm_identify(device_t dev)
pm_chipid, pm_revision, pm_ports); pm_chipid, pm_revision, pm_ports);
} }
/* realloc space for needed DMA slots */
ch->dma.dma_slots = pm_ports;
/* reset all ports and register if anything connected */ /* reset all ports and register if anything connected */
for (port=0; port < pm_ports; port++) { for (port=0; port < pm_ports; port++) {
u_int32_t signature; u_int32_t signature;

View File

@ -385,23 +385,22 @@ ata_ahci_status(device_t dev)
static int static int
ata_ahci_begin_transaction(struct ata_request *request) ata_ahci_begin_transaction(struct ata_request *request)
{ {
struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev)); struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_device *atadev = device_get_softc(request->dev);
struct ata_ahci_cmd_tab *ctp; struct ata_ahci_cmd_tab *ctp;
struct ata_ahci_cmd_list *clp; struct ata_ahci_cmd_list *clp;
int offset = ch->unit << 7; int offset = ch->unit << 7;
int port = atadev->unit & 0x0f; int port = request->unit & 0x0f;
int entries = 0; int entries = 0;
int fis_size; int fis_size;
/* get a piece of the workspace for this request */ /* get a piece of the workspace for this request */
ctp = (struct ata_ahci_cmd_tab *) ctp = (struct ata_ahci_cmd_tab *)
(ch->dma.work + ATA_AHCI_CT_OFFSET + (ATA_AHCI_CT_SIZE*request->tag)); (ch->dma.work + ATA_AHCI_CT_OFFSET);
/* setup the FIS for this request */ /* setup the FIS for this request */
if (!(fis_size = ata_ahci_setup_fis(ctp, request))) { if (!(fis_size = ata_ahci_setup_fis(ctp, request))) {
device_printf(request->dev, "setting up SATA FIS failed\n"); device_printf(request->parent, "setting up SATA FIS failed\n");
request->result = EIO; request->result = EIO;
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
} }
@ -409,7 +408,7 @@ ata_ahci_begin_transaction(struct ata_request *request)
/* if request moves data setup and load SG list */ /* if request moves data setup and load SG list */
if (request->flags & (ATA_R_READ | ATA_R_WRITE)) { if (request->flags & (ATA_R_READ | ATA_R_WRITE)) {
if (ch->dma.load(request, ctp->prd_tab, &entries)) { if (ch->dma.load(request, ctp->prd_tab, &entries)) {
device_printf(request->dev, "setting up DMA failed\n"); device_printf(request->parent, "setting up DMA failed\n");
request->result = EIO; request->result = EIO;
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
} }
@ -417,7 +416,7 @@ ata_ahci_begin_transaction(struct ata_request *request)
/* setup the command list entry */ /* setup the command list entry */
clp = (struct ata_ahci_cmd_list *) clp = (struct ata_ahci_cmd_list *)
(ch->dma.work + ATA_AHCI_CL_OFFSET + (ATA_AHCI_CL_SIZE*request->tag)); (ch->dma.work + ATA_AHCI_CL_OFFSET);
clp->prd_length = entries; clp->prd_length = entries;
clp->cmd_flags = (request->flags & ATA_R_WRITE ? ATA_AHCI_CMD_WRITE : 0) | clp->cmd_flags = (request->flags & ATA_R_WRITE ? ATA_AHCI_CMD_WRITE : 0) |
@ -426,12 +425,7 @@ ata_ahci_begin_transaction(struct ata_request *request)
(fis_size / sizeof(u_int32_t)) | (fis_size / sizeof(u_int32_t)) |
(port << 12); (port << 12);
clp->bytecount = 0; clp->bytecount = 0;
clp->cmd_table_phys = htole64(ch->dma.work_bus + ATA_AHCI_CT_OFFSET + clp->cmd_table_phys = htole64(ch->dma.work_bus + ATA_AHCI_CT_OFFSET);
(ATA_AHCI_CT_SIZE * request->tag));
/* clear eventual ACTIVE bit */
ATA_IDX_OUTL(ch, ATA_SACTIVE,
ATA_IDX_INL(ch, ATA_SACTIVE) & (1 << request->tag));
/* set command type bit */ /* set command type bit */
if (request->flags & ATA_R_ATAPI) if (request->flags & ATA_R_ATAPI)
@ -444,7 +438,7 @@ ata_ahci_begin_transaction(struct ata_request *request)
~ATA_AHCI_P_CMD_ATAPI); ~ATA_AHCI_P_CMD_ATAPI);
/* issue command to controller */ /* issue command to controller */
ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CI + offset, (1 << request->tag)); ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CI + offset, 1);
if (!(request->flags & ATA_R_ATAPI)) { if (!(request->flags & ATA_R_ATAPI)) {
/* device reset doesn't interrupt */ /* device reset doesn't interrupt */
@ -476,7 +470,7 @@ ata_ahci_begin_transaction(struct ata_request *request)
static int static int
ata_ahci_end_transaction(struct ata_request *request) ata_ahci_end_transaction(struct ata_request *request)
{ {
struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev)); struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_ahci_cmd_list *clp; struct ata_ahci_cmd_list *clp;
u_int32_t tf_data; u_int32_t tf_data;
@ -495,13 +489,12 @@ ata_ahci_end_transaction(struct ata_request *request)
/* on control commands read back registers to the request struct */ /* on control commands read back registers to the request struct */
if (request->flags & ATA_R_CONTROL) { if (request->flags & ATA_R_CONTROL) {
struct ata_device *atadev = device_get_softc(request->dev);
u_int8_t *fis = ch->dma.work + ATA_AHCI_FB_OFFSET + 0x40; u_int8_t *fis = ch->dma.work + ATA_AHCI_FB_OFFSET + 0x40;
request->u.ata.count = fis[12] | ((u_int16_t)fis[13] << 8); request->u.ata.count = fis[12] | ((u_int16_t)fis[13] << 8);
request->u.ata.lba = fis[4] | ((u_int64_t)fis[5] << 8) | request->u.ata.lba = fis[4] | ((u_int64_t)fis[5] << 8) |
((u_int64_t)fis[6] << 16); ((u_int64_t)fis[6] << 16);
if (atadev->flags & ATA_D_48BIT_ACTIVE) if (request->flags & ATA_R_48BIT)
request->u.ata.lba |= ((u_int64_t)fis[8] << 24) | request->u.ata.lba |= ((u_int64_t)fis[8] << 24) |
((u_int64_t)fis[9] << 32) | ((u_int64_t)fis[9] << 32) |
((u_int64_t)fis[10] << 40); ((u_int64_t)fis[10] << 40);
@ -511,7 +504,7 @@ ata_ahci_end_transaction(struct ata_request *request)
/* record how much data we actually moved */ /* record how much data we actually moved */
clp = (struct ata_ahci_cmd_list *) clp = (struct ata_ahci_cmd_list *)
(ch->dma.work + ATA_AHCI_CL_OFFSET + (ATA_AHCI_CL_SIZE*request->tag)); (ch->dma.work + ATA_AHCI_CL_OFFSET);
request->donecount = clp->bytecount; request->donecount = clp->bytecount;
/* release SG list etc */ /* release SG list etc */

View File

@ -466,10 +466,10 @@ ata_intel_31244_status(device_t dev)
static void static void
ata_intel_31244_tf_write(struct ata_request *request) ata_intel_31244_tf_write(struct ata_request *request)
{ {
struct ata_channel *ch = device_get_softc(device_get_parent(request->dev)); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_device *atadev = device_get_softc(request->dev); struct ata_device *atadev = device_get_softc(request->dev);
if (atadev->flags & ATA_D_48BIT_ACTIVE) { if (request->flags & ATA_R_48BIT) {
ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature); ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature);
ATA_IDX_OUTW(ch, ATA_COUNT, request->u.ata.count); ATA_IDX_OUTW(ch, ATA_COUNT, request->u.ata.count);
ATA_IDX_OUTW(ch, ATA_SECTOR, ((request->u.ata.lba >> 16) & 0xff00) | ATA_IDX_OUTW(ch, ATA_SECTOR, ((request->u.ata.lba >> 16) & 0xff00) |
@ -478,7 +478,7 @@ ata_intel_31244_tf_write(struct ata_request *request)
((request->u.ata.lba >> 8) & 0x00ff)); ((request->u.ata.lba >> 8) & 0x00ff));
ATA_IDX_OUTW(ch, ATA_CYL_MSB, ((request->u.ata.lba >> 32) & 0xff00) | ATA_IDX_OUTW(ch, ATA_CYL_MSB, ((request->u.ata.lba >> 32) & 0xff00) |
((request->u.ata.lba >> 16) & 0x00ff)); ((request->u.ata.lba >> 16) & 0x00ff));
ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_LBA | ATA_DEV(atadev->unit)); ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_LBA | ATA_DEV(request->unit));
} }
else { else {
ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature);
@ -499,7 +499,7 @@ ata_intel_31244_tf_write(struct ata_request *request)
(request->u.ata.lba / (sectors * heads))); (request->u.ata.lba / (sectors * heads)));
ATA_IDX_OUTB(ch, ATA_CYL_MSB, ATA_IDX_OUTB(ch, ATA_CYL_MSB,
(request->u.ata.lba / (sectors * heads)) >> 8); (request->u.ata.lba / (sectors * heads)) >> 8);
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(atadev->unit) | ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit) |
(((request->u.ata.lba% (sectors * heads)) / (((request->u.ata.lba% (sectors * heads)) /
sectors) & 0xf)); sectors) & 0xf));
} }
@ -508,7 +508,7 @@ ata_intel_31244_tf_write(struct ata_request *request)
ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8);
ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16);
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_IDX_OUTB(ch, ATA_DRIVE,
ATA_D_IBM | ATA_D_LBA | ATA_DEV(atadev->unit) | ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit) |
((request->u.ata.lba >> 24) & 0x0f)); ((request->u.ata.lba >> 24) & 0x0f));
} }
} }

View File

@ -354,7 +354,7 @@ ata_marvell_edma_status(device_t dev)
static int static int
ata_marvell_edma_begin_transaction(struct ata_request *request) ata_marvell_edma_begin_transaction(struct ata_request *request)
{ {
struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev)); struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
u_int32_t req_in; u_int32_t req_in;
u_int8_t *bytep; u_int8_t *bytep;
@ -363,7 +363,9 @@ ata_marvell_edma_begin_transaction(struct ata_request *request)
/* only DMA R/W goes through the EMDA machine */ /* only DMA R/W goes through the EMDA machine */
if (request->u.ata.command != ATA_READ_DMA && if (request->u.ata.command != ATA_READ_DMA &&
request->u.ata.command != ATA_WRITE_DMA) { request->u.ata.command != ATA_WRITE_DMA &&
request->u.ata.command != ATA_READ_DMA48 &&
request->u.ata.command != ATA_WRITE_DMA48) {
/* disable the EDMA machinery */ /* disable the EDMA machinery */
if (ATA_INL(ctlr->r_res1, 0x02028 + ATA_MV_EDMA_BASE(ch)) & 0x00000001) if (ATA_INL(ctlr->r_res1, 0x02028 + ATA_MV_EDMA_BASE(ch)) & 0x00000001)
@ -371,12 +373,9 @@ ata_marvell_edma_begin_transaction(struct ata_request *request)
return ata_begin_transaction(request); return ata_begin_transaction(request);
} }
/* check for 48 bit access and convert if needed */
ata_modify_if_48bit(request);
/* check sanity, setup SG list and DMA engine */ /* check sanity, setup SG list and DMA engine */
if ((error = ch->dma.load(request, NULL, NULL))) { if ((error = ch->dma.load(request, NULL, NULL))) {
device_printf(request->dev, "setting up DMA failed\n"); device_printf(request->parent, "setting up DMA failed\n");
request->result = error; request->result = error;
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
} }
@ -472,7 +471,7 @@ ata_marvell_edma_begin_transaction(struct ata_request *request)
static int static int
ata_marvell_edma_end_transaction(struct ata_request *request) ata_marvell_edma_end_transaction(struct ata_request *request)
{ {
struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev)); struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
int offset = (ch->unit > 3 ? 0x30014 : 0x20014); int offset = (ch->unit > 3 ? 0x30014 : 0x20014);
u_int32_t icr = ATA_INL(ctlr->r_res1, offset); u_int32_t icr = ATA_INL(ctlr->r_res1, offset);

View File

@ -387,11 +387,10 @@ ata_promise_status(device_t dev)
static int static int
ata_promise_dmastart(struct ata_request *request) ata_promise_dmastart(struct ata_request *request)
{ {
struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev)); struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_device *atadev = device_get_softc(request->dev);
if (atadev->flags & ATA_D_48BIT_ACTIVE) { if (request->flags & ATA_R_48BIT) {
ATA_OUTB(ctlr->r_res1, 0x11, ATA_OUTB(ctlr->r_res1, 0x11,
ATA_INB(ctlr->r_res1, 0x11) | (ch->unit ? 0x08 : 0x02)); ATA_INB(ctlr->r_res1, 0x11) | (ch->unit ? 0x08 : 0x02));
ATA_OUTL(ctlr->r_res1, ch->unit ? 0x24 : 0x20, ATA_OUTL(ctlr->r_res1, ch->unit ? 0x24 : 0x20,
@ -411,12 +410,11 @@ ata_promise_dmastart(struct ata_request *request)
static int static int
ata_promise_dmastop(struct ata_request *request) ata_promise_dmastop(struct ata_request *request)
{ {
struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev)); struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_device *atadev = device_get_softc(request->dev);
int error; int error;
if (atadev->flags & ATA_D_48BIT_ACTIVE) { if (request->flags & ATA_R_48BIT) {
ATA_OUTB(ctlr->r_res1, 0x11, ATA_OUTB(ctlr->r_res1, 0x11,
ATA_INB(ctlr->r_res1, 0x11) & ~(ch->unit ? 0x08 : 0x02)); ATA_INB(ctlr->r_res1, 0x11) & ~(ch->unit ? 0x08 : 0x02));
ATA_OUTL(ctlr->r_res1, ch->unit ? 0x24 : 0x20, 0); ATA_OUTL(ctlr->r_res1, ch->unit ? 0x24 : 0x20, 0);
@ -682,9 +680,8 @@ ata_promise_mio_status(device_t dev)
static int static int
ata_promise_mio_command(struct ata_request *request) ata_promise_mio_command(struct ata_request *request)
{ {
struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev)); struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_device *atadev = device_get_softc(request->dev);
u_int32_t *wordp = (u_int32_t *)ch->dma.work; u_int32_t *wordp = (u_int32_t *)ch->dma.work;
@ -693,7 +690,7 @@ ata_promise_mio_command(struct ata_request *request)
if ((ctlr->chip->cfg2 == PR_SATA2) || if ((ctlr->chip->cfg2 == PR_SATA2) ||
((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) { ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2))) {
/* set portmultiplier port */ /* set portmultiplier port */
ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), atadev->unit & 0x0f); ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), request->unit & 0x0f);
} }
/* XXX SOS add ATAPI commands support later */ /* XXX SOS add ATAPI commands support later */
@ -1051,7 +1048,7 @@ ata_promise_sx4_intr(void *data)
static int static int
ata_promise_sx4_command(struct ata_request *request) ata_promise_sx4_command(struct ata_request *request)
{ {
device_t gparent = GRANDPARENT(request->dev); device_t gparent = device_get_parent(request->parent);
struct ata_pci_controller *ctlr = device_get_softc(gparent); struct ata_pci_controller *ctlr = device_get_softc(gparent);
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_dma_prdentry *prd; struct ata_dma_prdentry *prd;
@ -1158,15 +1155,14 @@ ata_promise_sx4_command(struct ata_request *request)
static int static int
ata_promise_apkt(u_int8_t *bytep, struct ata_request *request) ata_promise_apkt(u_int8_t *bytep, struct ata_request *request)
{ {
struct ata_device *atadev = device_get_softc(request->dev);
int i = 12; int i = 12;
bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_PDC_WAIT_NBUSY|ATA_DRIVE; bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_PDC_WAIT_NBUSY|ATA_DRIVE;
bytep[i++] = ATA_D_IBM | ATA_D_LBA | ATA_DEV(atadev->unit); bytep[i++] = ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit);
bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_CTL; bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_CTL;
bytep[i++] = ATA_A_4BIT; bytep[i++] = ATA_A_4BIT;
if (atadev->flags & ATA_D_48BIT_ACTIVE) { if (request->flags & ATA_R_48BIT) {
bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_FEATURE; bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_FEATURE;
bytep[i++] = request->u.ata.feature >> 8; bytep[i++] = request->u.ata.feature >> 8;
bytep[i++] = request->u.ata.feature; bytep[i++] = request->u.ata.feature;
@ -1183,7 +1179,7 @@ ata_promise_apkt(u_int8_t *bytep, struct ata_request *request)
bytep[i++] = request->u.ata.lba >> 40; bytep[i++] = request->u.ata.lba >> 40;
bytep[i++] = request->u.ata.lba >> 16; bytep[i++] = request->u.ata.lba >> 16;
bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_DRIVE; bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_DRIVE;
bytep[i++] = ATA_D_LBA | ATA_DEV(atadev->unit); bytep[i++] = ATA_D_LBA | ATA_DEV(request->unit);
} }
else { else {
bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_FEATURE; bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_FEATURE;
@ -1197,8 +1193,7 @@ ata_promise_apkt(u_int8_t *bytep, struct ata_request *request)
bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_CYL_MSB; bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_CYL_MSB;
bytep[i++] = request->u.ata.lba >> 16; bytep[i++] = request->u.ata.lba >> 16;
bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_DRIVE; bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_DRIVE;
bytep[i++] = (atadev->flags & ATA_D_USE_CHS ? 0 : ATA_D_LBA) | bytep[i++] = ATA_D_LBA | ATA_D_IBM | ATA_DEV(request->unit) |
ATA_D_IBM | ATA_DEV(atadev->unit) |
((request->u.ata.lba >> 24)&0xf); ((request->u.ata.lba >> 24)&0xf);
} }
bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_END | ATA_COMMAND; bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_END | ATA_COMMAND;

View File

@ -259,9 +259,8 @@ static void
ata_serverworks_tf_read(struct ata_request *request) ata_serverworks_tf_read(struct ata_request *request)
{ {
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_device *atadev = device_get_softc(request->dev);
if (atadev->flags & ATA_D_48BIT_ACTIVE) { if (request->flags & ATA_R_48BIT) {
u_int16_t temp; u_int16_t temp;
request->u.ata.count = ATA_IDX_INW(ch, ATA_COUNT); request->u.ata.count = ATA_IDX_INW(ch, ATA_COUNT);
@ -290,7 +289,7 @@ ata_serverworks_tf_write(struct ata_request *request)
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_device *atadev = device_get_softc(request->dev); struct ata_device *atadev = device_get_softc(request->dev);
if (atadev->flags & ATA_D_48BIT_ACTIVE) { if (request->flags & ATA_R_48BIT) {
ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature); ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature);
ATA_IDX_OUTW(ch, ATA_COUNT, request->u.ata.count); ATA_IDX_OUTW(ch, ATA_COUNT, request->u.ata.count);
ATA_IDX_OUTW(ch, ATA_SECTOR, ((request->u.ata.lba >> 16) & 0xff00) | ATA_IDX_OUTW(ch, ATA_SECTOR, ((request->u.ata.lba >> 16) & 0xff00) |
@ -299,7 +298,7 @@ ata_serverworks_tf_write(struct ata_request *request)
((request->u.ata.lba >> 8) & 0x00ff)); ((request->u.ata.lba >> 8) & 0x00ff));
ATA_IDX_OUTW(ch, ATA_CYL_MSB, ((request->u.ata.lba >> 32) & 0xff00) | ATA_IDX_OUTW(ch, ATA_CYL_MSB, ((request->u.ata.lba >> 32) & 0xff00) |
((request->u.ata.lba >> 16) & 0x00ff)); ((request->u.ata.lba >> 16) & 0x00ff));
ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_LBA | ATA_DEV(atadev->unit)); ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_LBA | ATA_DEV(request->unit));
} }
else { else {
ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature); ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature);
@ -320,7 +319,7 @@ ata_serverworks_tf_write(struct ata_request *request)
(request->u.ata.lba / (sectors * heads))); (request->u.ata.lba / (sectors * heads)));
ATA_IDX_OUTW(ch, ATA_CYL_MSB, ATA_IDX_OUTW(ch, ATA_CYL_MSB,
(request->u.ata.lba / (sectors * heads)) >> 8); (request->u.ata.lba / (sectors * heads)) >> 8);
ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(atadev->unit) | ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit) |
(((request->u.ata.lba% (sectors * heads)) / (((request->u.ata.lba% (sectors * heads)) /
sectors) & 0xf)); sectors) & 0xf));
} }
@ -329,7 +328,7 @@ ata_serverworks_tf_write(struct ata_request *request)
ATA_IDX_OUTW(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); ATA_IDX_OUTW(ch, ATA_CYL_LSB, request->u.ata.lba >> 8);
ATA_IDX_OUTW(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); ATA_IDX_OUTW(ch, ATA_CYL_MSB, request->u.ata.lba >> 16);
ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_IDX_OUTW(ch, ATA_DRIVE,
ATA_D_IBM | ATA_D_LBA | ATA_DEV(atadev->unit) | ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit) |
((request->u.ata.lba >> 24) & 0x0f)); ((request->u.ata.lba >> 24) & 0x0f));
} }
} }

View File

@ -457,7 +457,7 @@ struct ata_siiprb_dma_prdentry {
u_int32_t control; u_int32_t control;
} __packed; } __packed;
#define ATA_SIIPRB_DMA_ENTRIES 125 #define ATA_SIIPRB_DMA_ENTRIES 129
struct ata_siiprb_ata_command { struct ata_siiprb_ata_command {
struct ata_siiprb_dma_prdentry prd[ATA_SIIPRB_DMA_ENTRIES]; struct ata_siiprb_dma_prdentry prd[ATA_SIIPRB_DMA_ENTRIES];
} __packed; } __packed;
@ -542,7 +542,7 @@ ata_siiprb_status(device_t dev)
static int static int
ata_siiprb_begin_transaction(struct ata_request *request) ata_siiprb_begin_transaction(struct ata_request *request)
{ {
struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev)); struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_siiprb_command *prb; struct ata_siiprb_command *prb;
struct ata_siiprb_dma_prdentry *prd; struct ata_siiprb_dma_prdentry *prd;
@ -556,28 +556,25 @@ ata_siiprb_begin_transaction(struct ata_request *request)
} }
/* get a piece of the workspace for this request */ /* get a piece of the workspace for this request */
prb = (struct ata_siiprb_command *) prb = (struct ata_siiprb_command *)ch->dma.work;
(ch->dma.work + (sizeof(struct ata_siiprb_command) * request->tag));
/* clear the prb structure */ /* clear the prb structure */
bzero(prb, sizeof(struct ata_siiprb_command)); bzero(prb, sizeof(struct ata_siiprb_command));
/* setup the FIS for this request */ /* setup the FIS for this request */
if (!ata_request2fis_h2d(request, &prb->fis[0])) { if (!ata_request2fis_h2d(request, &prb->fis[0])) {
device_printf(request->dev, "setting up SATA FIS failed\n"); device_printf(request->parent, "setting up SATA FIS failed\n");
request->result = EIO; request->result = EIO;
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
} }
/* setup transfer type */ /* setup transfer type */
if (request->flags & ATA_R_ATAPI) { if (request->flags & ATA_R_ATAPI) {
struct ata_device *atadev = device_get_softc(request->dev);
bcopy(request->u.atapi.ccb, prb->u.atapi.ccb, 16); bcopy(request->u.atapi.ccb, prb->u.atapi.ccb, 16);
if ((atadev->param.config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_12) if (request->flags & ATA_R_ATAPI16)
ATA_OUTL(ctlr->r_res2, 0x1004 + offset, 0x00000020);
else
ATA_OUTL(ctlr->r_res2, 0x1000 + offset, 0x00000020); ATA_OUTL(ctlr->r_res2, 0x1000 + offset, 0x00000020);
else
ATA_OUTL(ctlr->r_res2, 0x1004 + offset, 0x00000020);
if (request->flags & ATA_R_READ) if (request->flags & ATA_R_READ)
prb->control = htole16(0x0010); prb->control = htole16(0x0010);
if (request->flags & ATA_R_WRITE) if (request->flags & ATA_R_WRITE)
@ -590,19 +587,16 @@ ata_siiprb_begin_transaction(struct ata_request *request)
/* if request moves data setup and load SG list */ /* if request moves data setup and load SG list */
if (request->flags & (ATA_R_READ | ATA_R_WRITE)) { if (request->flags & (ATA_R_READ | ATA_R_WRITE)) {
if (ch->dma.load(request, prd, NULL)) { if (ch->dma.load(request, prd, NULL)) {
device_printf(request->dev, "setting up DMA failed\n"); device_printf(request->parent, "setting up DMA failed\n");
request->result = EIO; request->result = EIO;
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
} }
} }
/* activate the prb */ /* activate the prb */
prb_bus = ch->dma.work_bus + prb_bus = ch->dma.work_bus;
(sizeof(struct ata_siiprb_command) * request->tag); ATA_OUTL(ctlr->r_res2, 0x1c00 + offset, prb_bus);
ATA_OUTL(ctlr->r_res2, ATA_OUTL(ctlr->r_res2, 0x1c04 + offset, prb_bus>>32);
0x1c00 + offset + (request->tag * sizeof(u_int64_t)), prb_bus);
ATA_OUTL(ctlr->r_res2,
0x1c04 + offset + (request->tag * sizeof(u_int64_t)), prb_bus>>32);
/* start the timeout */ /* start the timeout */
callout_reset(&request->callout, request->timeout * hz, callout_reset(&request->callout, request->timeout * hz,
@ -613,7 +607,7 @@ ata_siiprb_begin_transaction(struct ata_request *request)
static int static int
ata_siiprb_end_transaction(struct ata_request *request) ata_siiprb_end_transaction(struct ata_request *request)
{ {
struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev)); struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent));
struct ata_channel *ch = device_get_softc(request->parent); struct ata_channel *ch = device_get_softc(request->parent);
struct ata_siiprb_command *prb; struct ata_siiprb_command *prb;
int offset = ch->unit * 0x2000; int offset = ch->unit * 0x2000;
@ -623,7 +617,7 @@ ata_siiprb_end_transaction(struct ata_request *request)
callout_stop(&request->callout); callout_stop(&request->callout);
prb = (struct ata_siiprb_command *) prb = (struct ata_siiprb_command *)
((u_int8_t *)rman_get_virtual(ctlr->r_res2)+(request->tag << 7)+offset); ((u_int8_t *)rman_get_virtual(ctlr->r_res2) + offset);
/* any controller errors flagged ? */ /* any controller errors flagged ? */
if ((error = ATA_INL(ctlr->r_res2, 0x1024 + offset))) { if ((error = ATA_INL(ctlr->r_res2, 0x1024 + offset))) {
@ -659,12 +653,10 @@ ata_siiprb_end_transaction(struct ata_request *request)
/* on control commands read back registers to the request struct */ /* on control commands read back registers to the request struct */
if (request->flags & ATA_R_CONTROL) { if (request->flags & ATA_R_CONTROL) {
struct ata_device *atadev = device_get_softc(request->dev);
request->u.ata.count = prb->fis[12] | ((u_int16_t)prb->fis[13] << 8); request->u.ata.count = prb->fis[12] | ((u_int16_t)prb->fis[13] << 8);
request->u.ata.lba = prb->fis[4] | ((u_int64_t)prb->fis[5] << 8) | request->u.ata.lba = prb->fis[4] | ((u_int64_t)prb->fis[5] << 8) |
((u_int64_t)prb->fis[6] << 16); ((u_int64_t)prb->fis[6] << 16);
if (atadev->flags & ATA_D_48BIT_ACTIVE) if (request->flags & ATA_R_48BIT)
request->u.ata.lba |= ((u_int64_t)prb->fis[8] << 24) | request->u.ata.lba |= ((u_int64_t)prb->fis[8] << 24) |
((u_int64_t)prb->fis[9] << 32) | ((u_int64_t)prb->fis[9] << 32) |
((u_int64_t)prb->fis[10] << 40); ((u_int64_t)prb->fis[10] << 40);
@ -907,6 +899,7 @@ ata_siiprb_dmainit(device_t dev)
/* note start and stop are not used here */ /* note start and stop are not used here */
ch->dma.setprd = ata_siiprb_dmasetprd; ch->dma.setprd = ata_siiprb_dmasetprd;
ch->dma.max_address = BUS_SPACE_MAXADDR; ch->dma.max_address = BUS_SPACE_MAXADDR;
ch->dma.max_iosize = (ATA_SIIPRB_DMA_ENTRIES - 1) * PAGE_SIZE;
} }
ATA_DECLARE_DRIVER(ata_sii); ATA_DECLARE_DRIVER(ata_sii);