From ce43d827c254be137b93a5758e4038bc95cc7ec5 Mon Sep 17 00:00:00 2001 From: sos Date: Tue, 3 May 2005 07:55:07 +0000 Subject: Reshape the dma code to be a bit more flexible so it can cope with new HW that has new and different demands. Fix a few nits in former commit in this cleanup crusade. Sponsored by: pair.com --- sys/dev/ata/ata-all.c | 42 +++++++- sys/dev/ata/ata-all.h | 22 ++-- sys/dev/ata/ata-chipset.c | 213 ++++++++++++++++--------------------- sys/dev/ata/ata-dma.c | 28 +++-- sys/dev/ata/ata-lowlevel.c | 258 ++++++++++++++++++--------------------------- sys/dev/ata/ata-pci.c | 26 +++-- sys/dev/ata/ata-queue.c | 3 +- sys/dev/ata/atapi-cd.c | 26 +---- 8 files changed, 289 insertions(+), 329 deletions(-) (limited to 'sys') diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 0f7ae45..fe824d4 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -298,7 +298,7 @@ ata_interrupt(void *data) mtx_lock(&ch->state_mtx); do { /* do we have a running request */ - if (ch->state & ATA_TIMEOUT || !(request = ch->running)) + if (!(request = ch->running) || (request->flags & ATA_R_TIMEOUT)) break; ATA_DEBUG_RQ(request, "interrupt"); @@ -744,6 +744,46 @@ ata_default_registers(device_t dev) ch->r_io[ATA_ALTSTAT].offset = ch->r_io[ATA_CONTROL].offset; } +u_int8_t +ata_modify_if_48bit(struct ata_request *request) +{ + struct ata_device *atadev = device_get_softc(request->dev); + u_int8_t command = request->u.ata.command; + + if ((request->u.ata.lba >= ATA_MAX_28BIT_LBA || + request->u.ata.count > 256) && + atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48) { + + /* translate command into 48bit version */ + switch (command) { + case ATA_READ: + command = ATA_READ48; break; + case ATA_READ_MUL: + command = ATA_READ_MUL48; break; + case ATA_READ_DMA: + command = ATA_READ_DMA48; break; + case ATA_READ_DMA_QUEUED: + command = ATA_READ_DMA_QUEUED48; break; + case ATA_WRITE: + command = ATA_WRITE48; break; + case ATA_WRITE_MUL: + command = ATA_WRITE_MUL48; break; + case ATA_WRITE_DMA: + command = ATA_WRITE_DMA48; break; + case ATA_WRITE_DMA_QUEUED: + command = ATA_WRITE_DMA_QUEUED48; break; + case ATA_FLUSHCACHE: + command = ATA_FLUSHCACHE48; break; + default: + return command; + } + atadev->flags |= ATA_D_48BIT_ACTIVE; + } + else + atadev->flags &= ~ATA_D_48BIT_ACTIVE; + return command; +} + void ata_udelay(int interval) { diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index 2249cbc..32f0e35 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -336,6 +336,7 @@ struct ata_device { #define ATA_D_USE_CHS 0x0001 #define ATA_D_MEDIA_CHANGED 0x0002 #define ATA_D_ENC_PRESENT 0x0004 +#define ATA_D_48BIT_ACTIVE 0x0008 }; /* structure for holding DMA Physical Region Descriptors (PRD) entries */ @@ -347,6 +348,7 @@ struct ata_dma_prdentry { /* structure used by the setprd function */ struct ata_dmasetprd_args { void *dmatab; + int nsegs; int error; }; @@ -374,20 +376,21 @@ struct ata_dma { #define ATA_DMA_LOADED 0x02 /* DMA tables etc loaded */ #define ATA_DMA_ACTIVE 0x04 /* DMA transfer in progress */ - void (*alloc)(device_t); - void (*free)(device_t); + void (*alloc)(device_t dev); + void (*free)(device_t dev); void (*setprd)(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); - int (*load)(device_t, caddr_t data, int32_t count,int dir); - int (*unload)(device_t); - int (*start)(device_t); - int (*stop)(device_t); + int (*load)(device_t dev, caddr_t data, int32_t count, int dir, void *addr, int *nsegs); + int (*unload)(device_t dev); + int (*start)(device_t dev); + int (*stop)(device_t dev); + void (*reset)(device_t dev); }; /* structure holding lowlevel functions */ struct ata_lowlevel { int (*begin_transaction)(struct ata_request *request); int (*end_transaction)(struct ata_request *request); - int (*command)(device_t dev, u_int8_t command, u_int64_t lba, u_int16_t count, u_int16_t feature); + int (*command)(struct ata_request *request); }; /* structure holding resources for an ATA channel */ @@ -409,7 +412,6 @@ struct ata_channel { #define ATA_NO_SLAVE 0x01 #define ATA_USE_16BIT 0x02 #define ATA_ATAPI_DMA_RO 0x04 -#define ATA_48BIT_ACTIVE 0x08 int devices; /* what is present */ #define ATA_ATA_MASTER 0x01 @@ -422,7 +424,6 @@ struct ata_channel { #define ATA_IDLE 0x0000 #define ATA_ACTIVE 0x0001 #define ATA_STALL_QUEUE 0x0002 -#define ATA_TIMEOUT 0x0004 struct mtx queue_mtx; /* queue lock */ TAILQ_HEAD(, ata_request) ata_queue; /* head of ATA queue */ @@ -452,6 +453,7 @@ int ata_suspend(device_t dev); int ata_resume(device_t dev); int ata_identify(device_t dev); void ata_default_registers(device_t dev); +u_int8_t ata_modify_if_48bit(struct ata_request *request); void ata_udelay(int interval); char *ata_mode2str(int mode); int ata_pmode(struct ata_params *ap); @@ -473,7 +475,7 @@ char *ata_cmd2str(struct ata_request *request); /* ata-lowlevel.c: */ void ata_generic_hw(device_t dev); void ata_generic_reset(device_t dev); -int ata_generic_command(device_t dev, u_int8_t command, u_int64_t lba, u_int16_t count, u_int16_t feature); +int ata_generic_command(struct ata_request *request); /* macros for alloc/free of struct ata_request */ extern uma_zone_t ata_request_zone; diff --git a/sys/dev/ata/ata-chipset.c b/sys/dev/ata/ata-chipset.c index 8b6218a..85f8c35 100644 --- a/sys/dev/ata/ata-chipset.c +++ b/sys/dev/ata/ata-chipset.c @@ -91,11 +91,11 @@ static void ata_promise_mio_intr(void *); static void ata_promise_sx4_intr(void *); static void ata_promise_mio_dmainit(device_t); static void ata_promise_mio_reset(device_t); -static int ata_promise_mio_command(device_t dev, u_int8_t command, u_int64_t lba, u_int16_t count, u_int16_t feature); -static int ata_promise_sx4_command(device_t dev, u_int8_t command, u_int64_t lba, u_int16_t count, u_int16_t feature); -static int ata_promise_apkt(u_int8_t *bytep, device_t dev, u_int8_t command, u_int64_t lba, u_int16_t count, u_int16_t feature); -static void ata_promise_queue_hpkt(struct ata_pci_controller *ctlr, u_int32_t hpkt); -static void ata_promise_next_hpkt(struct ata_pci_controller *ctlr); +static int ata_promise_mio_command(struct ata_request *); +static int ata_promise_sx4_command(struct ata_request *); +static int ata_promise_apkt(u_int8_t *, struct ata_request *); +static void ata_promise_queue_hpkt(struct ata_pci_controller *, u_int32_t); +static void ata_promise_next_hpkt(struct ata_pci_controller *); static void ata_promise_tx2_intr(void *); static void ata_promise_old_intr(void *); static void ata_promise_new_dmainit(device_t); @@ -119,7 +119,7 @@ static int ata_via_allocate(device_t dev); static void ata_via_reset(device_t); static void ata_via_southbridge_fixup(device_t); static void ata_via_family_setmode(device_t, int); -static void ata_print_cable(device_t dev, u_int8_t *who); +static void ata_print_cable(device_t, u_int8_t *); static int ata_atapi(device_t); static int ata_check_80pin(device_t, int); static struct ata_chip_id *ata_find_chip(device_t, struct ata_chip_id *, int); @@ -226,7 +226,7 @@ ata_sata_connect(struct ata_channel *ch) ata_udelay(10000); } if (timeout >= 100) { - if (1 | bootverbose) + if (bootverbose) device_printf(ch->dev, "SATA connect status=%08x\n", status); return 0; } @@ -235,9 +235,9 @@ ata_sata_connect(struct ata_channel *ch) ATA_IDX_OUTL(ch, ATA_SERROR, ATA_IDX_INL(ch, ATA_SERROR)); /* find out what type device we got poll for spec'd 31 seconds */ - ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM); - DELAY(10); - for (timeout = 0; timeout < 3100; timeout++) { + /* XXX SOS 10 secs for now as I have little patience */ + ch->devices = 0; + for (timeout = 0; timeout < 1000; timeout++) { if (ATA_IDX_INB(ch, ATA_STATUS) & ATA_S_BUSY) DELAY(10000); else @@ -245,12 +245,17 @@ ata_sata_connect(struct ata_channel *ch) } if (1 | bootverbose) device_printf(ch->dev, "SATA connect ready time=%dms\n", timeout * 10); - if ((ATA_IDX_INB(ch, ATA_CYL_LSB) == ATAPI_MAGIC_LSB) && - (ATA_IDX_INB(ch, ATA_CYL_MSB) == ATAPI_MAGIC_MSB)) - ch->devices = ATA_ATAPI_MASTER; - else - ch->devices = ATA_ATA_MASTER; - + if (timeout < 1000) { + if ((ATA_IDX_INB(ch, ATA_CYL_LSB) == ATAPI_MAGIC_LSB) && + (ATA_IDX_INB(ch, ATA_CYL_MSB) == ATAPI_MAGIC_MSB)) + ch->devices = ATA_ATAPI_MASTER; + else /*if ((ATA_IDX_INB(ch, ATA_COUNT) == 0x01) && + (ATA_IDX_INB(ch, ATA_CYL_LSB) == 0x01)) */ + ch->devices = ATA_ATA_MASTER; + } + if (1 | bootverbose) + device_printf(ch->dev, "sata_connect devices=0x%b\n", + ch->devices, "\20\3ATAPI_MASTER\1ATA_MASTER"); return 1; } @@ -259,8 +264,7 @@ ata_sata_phy_enable(struct ata_channel *ch) { int loop, retry; - if ((ATA_IDX_INL(ch, ATA_SCONTROL) & - ATA_SC_DET_MASK) == ATA_SC_DET_IDLE) { + if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE) { ata_sata_connect(ch); return; } @@ -969,7 +973,6 @@ ata_highpoint_setmode(device_t dev, int mode) */ error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, ata_limit_mode(dev, mode, ATA_UDMA5)); - if (bootverbose) device_printf(dev, "%ssetting %s on HighPoint chip\n", (error) ? "FAILURE " : "", ata_mode2str(mode)); @@ -1630,12 +1633,7 @@ u_int32_t addr; struct ata_promise_sx4 { struct mtx mtx; -#if 0 - u_int32_t array[ATA_PDC_MAX_HPKT]; - int head, tail; -#else TAILQ_HEAD(, host_packet) queue; -#endif int busy; }; @@ -2001,25 +1999,6 @@ ata_promise_sx4_intr(void *data) } } -static int -ata_promise_mio_dmastart(device_t dev) -{ - struct ata_channel *ch = device_get_softc(dev); - - ch->flags |= ATA_DMA_ACTIVE; - return 0; -} - -static int -ata_promise_mio_dmastop(device_t dev) -{ - struct ata_channel *ch = device_get_softc(dev); - - ch->flags &= ~ATA_DMA_ACTIVE; - /* get status XXX SOS */ - return 0; -} - static void ata_promise_mio_dmainit(device_t dev) { @@ -2027,8 +2006,7 @@ ata_promise_mio_dmainit(device_t dev) ata_dmainit(dev); if (ch->dma) { - ch->dma->start = ata_promise_mio_dmastart; - ch->dma->stop = ata_promise_mio_dmastop; + /* note start and stop are not used here */ } } @@ -2132,18 +2110,18 @@ ata_promise_mio_reset(device_t dev) } static int -ata_promise_mio_command(device_t dev, u_int8_t command, - u_int64_t lba, u_int16_t count, u_int16_t feature) +ata_promise_mio_command(struct ata_request *request) { - struct ata_pci_controller *ctlr = device_get_softc(GRANDPARENT(dev)); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); + struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev)); + struct ata_channel *ch = device_get_softc(device_get_parent(request->dev)); u_int32_t *wordp = (u_int32_t *)ch->dma->work; ATA_OUTL(ctlr->r_res2, (ch->unit + 1) << 2, 0x00000001); - switch (command) { + /* XXX SOS add ATAPI commands support later */ + switch (request->u.ata.command) { default: - return ata_generic_command(dev, command, lba, count, feature); + return ata_generic_command(request); case ATA_READ_DMA: wordp[0] = htole32(0x04 | ((ch->unit + 1) << 16) | (0x00 << 24)); @@ -2155,25 +2133,25 @@ ata_promise_mio_command(device_t dev, u_int8_t command, } wordp[1] = htole32(ch->dma->sg_bus); wordp[2] = 0; - ata_promise_apkt((u_int8_t*)wordp, dev, command, lba, count, feature); + ata_promise_apkt((u_int8_t*)wordp, request); ATA_OUTL(ctlr->r_res2, 0x0240 + (ch->unit << 7), ch->dma->work_bus); return 0; } static int -ata_promise_sx4_command(device_t dev, u_int8_t command, - u_int64_t lba, u_int16_t count, u_int16_t feature) +ata_promise_sx4_command(struct ata_request *request) { - device_t gparent = GRANDPARENT(dev); + device_t gparent = GRANDPARENT(request->dev); struct ata_pci_controller *ctlr = device_get_softc(gparent); - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); + struct ata_channel *ch = device_get_softc(device_get_parent(request->dev)); struct ata_dma_prdentry *prd = ch->dma->sg; caddr_t window = rman_get_virtual(ctlr->r_res1); u_int32_t *wordp; int i, idx, length = 0; - switch (command) { + /* XXX SOS add ATAPI commands support later */ + switch (request->u.ata.command) { default: return -1; @@ -2184,7 +2162,7 @@ ata_promise_sx4_command(device_t dev, u_int8_t command, case ATA_WRITE: case ATA_WRITE_MUL: ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit + 1) << 2), 0x00000001); - return ata_generic_command(dev, command, lba, count, feature); + return ata_generic_command(request); case ATA_SETFEATURES: case ATA_FLUSHCACHE: @@ -2195,7 +2173,7 @@ ata_promise_sx4_command(device_t dev, u_int8_t command, wordp[0] = htole32(0x08 | ((ch->unit + 1)<<16) | (0x00 << 24)); wordp[1] = 0; wordp[2] = 0; - ata_promise_apkt((u_int8_t *)wordp, dev, command, lba,count,feature); + ata_promise_apkt((u_int8_t *)wordp, request); ATA_OUTL(ctlr->r_res2, 0x000c0484, 0x00000001); ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit + 1) << 2), 0x00000001); ATA_OUTL(ctlr->r_res2, 0x000c0240 + (ch->unit << 7), @@ -2208,27 +2186,26 @@ ata_promise_sx4_command(device_t dev, u_int8_t command, (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_HSG_OFFSET); i = idx = 0; do { - wordp[idx++] = htole32(prd[i].addr); - wordp[idx++] = htole32(prd[i].count & ~ATA_DMA_EOT); + wordp[idx++] = prd[i].addr; + wordp[idx++] = prd[i].count; length += (prd[i].count & ~ATA_DMA_EOT); } while (!(prd[i++].count & ATA_DMA_EOT)); - wordp[idx - 1] |= htole32(ATA_DMA_EOT); wordp = (u_int32_t *) (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_LSG_OFFSET); wordp[0] = htole32((ch->unit * ATA_PDC_BUF_OFFSET) + ATA_PDC_BUF_BASE); - wordp[1] = htole32((count * DEV_BSIZE) | ATA_DMA_EOT); + wordp[1] = htole32(request->bytecount | ATA_DMA_EOT); wordp = (u_int32_t *) (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_ASG_OFFSET); wordp[0] = htole32((ch->unit * ATA_PDC_BUF_OFFSET) + ATA_PDC_BUF_BASE); - wordp[1] = htole32((count * DEV_BSIZE) | ATA_DMA_EOT); + wordp[1] = htole32(request->bytecount | ATA_DMA_EOT); wordp = (u_int32_t *) (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_HPKT_OFFSET); - if (command == ATA_READ_DMA) + if (request->flags & ATA_R_READ) wordp[0] = htole32(0x14 | ((ch->unit+9)<<16) | ((ch->unit+5)<<24)); - if (command == ATA_WRITE_DMA) + if (request->flags & ATA_R_WRITE) wordp[0] = htole32(0x00 | ((ch->unit+13)<<16) | (0x00<<24)); wordp[1] = htole32((ch->unit * ATA_PDC_CHN_OFFSET)+ATA_PDC_HSG_OFFSET); wordp[2] = htole32((ch->unit * ATA_PDC_CHN_OFFSET)+ATA_PDC_LSG_OFFSET); @@ -2236,22 +2213,22 @@ ata_promise_sx4_command(device_t dev, u_int8_t command, wordp = (u_int32_t *) (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_APKT_OFFSET); - if (command == ATA_READ_DMA) + if (request->flags & ATA_R_READ) wordp[0] = htole32(0x04 | ((ch->unit+5)<<16) | (0x00<<24)); - if (command == ATA_WRITE_DMA) + if (request->flags & ATA_R_WRITE) wordp[0] = htole32(0x10 | ((ch->unit+1)<<16) | ((ch->unit+13)<<24)); wordp[1] = htole32((ch->unit * ATA_PDC_CHN_OFFSET)+ATA_PDC_ASG_OFFSET); wordp[2] = 0; - ata_promise_apkt((u_int8_t *)wordp, dev, command, lba,count,feature); + ata_promise_apkt((u_int8_t *)wordp, request); ATA_OUTL(ctlr->r_res2, 0x000c0484, 0x00000001); - if (command == ATA_READ_DMA) { + if (request->flags & ATA_R_READ) { ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+5)<<2), 0x00000001); ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+9)<<2), 0x00000001); ATA_OUTL(ctlr->r_res2, 0x000c0240 + (ch->unit << 7), htole32((ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_APKT_OFFSET)); } - if (command == ATA_WRITE_DMA) { + if (request->flags & ATA_R_WRITE) { ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+1)<<2), 0x00000001); ATA_OUTL(ctlr->r_res2, 0x000c0400 + ((ch->unit+13)<<2), 0x00000001); ata_promise_queue_hpkt(ctlr, @@ -2262,11 +2239,10 @@ ata_promise_sx4_command(device_t dev, u_int8_t command, } static int -ata_promise_apkt(u_int8_t *bytep, device_t dev, u_int8_t command, - u_int64_t lba, u_int16_t count, u_int16_t feature) +ata_promise_apkt(u_int8_t *bytep, struct ata_request *request) { - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); + struct ata_device *atadev = device_get_softc(request->dev); + u_int8_t command; int i = 12; bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_PDC_WAIT_NBUSY|ATA_DRIVE; @@ -2274,46 +2250,41 @@ ata_promise_apkt(u_int8_t *bytep, device_t dev, u_int8_t command, bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_CTL; bytep[i++] = ATA_A_4BIT; - if ((lba >= ATA_MAX_28BIT_LBA || count > 256) && - (atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48)) { - ch->flags |= ATA_48BIT_ACTIVE; - if (command == ATA_READ_DMA) - command = ATA_READ_DMA48; - if (command == ATA_WRITE_DMA) - command = ATA_WRITE_DMA48; + command = ata_modify_if_48bit(request); + + if (atadev->flags & ATA_D_48BIT_ACTIVE) { bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_FEATURE; - bytep[i++] = (feature >> 8) & 0xff; - bytep[i++] = feature & 0xff; + bytep[i++] = request->u.ata.feature >> 8; + bytep[i++] = request->u.ata.feature; bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_COUNT; - bytep[i++] = (count >> 8) & 0xff; - bytep[i++] = count & 0xff; + bytep[i++] = request->u.ata.count >> 8; + bytep[i++] = request->u.ata.count; bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_SECTOR; - bytep[i++] = (lba >> 24) & 0xff; - bytep[i++] = lba & 0xff; + bytep[i++] = request->u.ata.lba >> 24; + bytep[i++] = request->u.ata.lba; bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_CYL_LSB; - bytep[i++] = (lba >> 32) & 0xff; - bytep[i++] = (lba >> 8) & 0xff; + bytep[i++] = request->u.ata.lba >> 32; + bytep[i++] = request->u.ata.lba >> 8; bytep[i++] = ATA_PDC_2B | ATA_PDC_WRITE_REG | ATA_CYL_MSB; - bytep[i++] = (lba >> 40) & 0xff; - bytep[i++] = (lba >> 16) & 0xff; + bytep[i++] = request->u.ata.lba >> 40; + bytep[i++] = request->u.ata.lba >> 16; bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_DRIVE; bytep[i++] = ATA_D_LBA | atadev->unit; } else { - ch->flags &= ~ATA_48BIT_ACTIVE; bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_FEATURE; - bytep[i++] = feature; + bytep[i++] = request->u.ata.feature; bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_COUNT; - bytep[i++] = count; + bytep[i++] = request->u.ata.count; bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_SECTOR; - bytep[i++] = lba & 0xff; + bytep[i++] = request->u.ata.lba; bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_CYL_LSB; - bytep[i++] = (lba >> 8) & 0xff; + bytep[i++] = request->u.ata.lba >> 8; bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_CYL_MSB; - bytep[i++] = (lba >> 16) & 0xff; + bytep[i++] = request->u.ata.lba >> 16; bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_REG | ATA_DRIVE; bytep[i++] = (atadev->flags & ATA_D_USE_CHS ? 0 : ATA_D_LBA) | - ATA_D_IBM | atadev->unit | ((lba >> 24) & 0xf); + ATA_D_IBM | atadev->unit | ((request->u.ata.lba >> 24)&0xf); } bytep[i++] = ATA_PDC_1B | ATA_PDC_WRITE_END | ATA_COMMAND; bytep[i++] = command; @@ -2326,14 +2297,6 @@ ata_promise_queue_hpkt(struct ata_pci_controller *ctlr, u_int32_t hpkt) struct ata_promise_sx4 *hpktp = device_get_ivars(ctlr->dev); mtx_lock(&hpktp->mtx); -#if 0 - if (hpktp->tail == hpktp->head && !hpktp->busy) { - ATA_OUTL(ctlr->r_res2, 0x000c0100, hpkt); - hpktp->busy = 1; - } - else - hpktp->array[(hpktp->head++) & (ATA_PDC_MAX_HPKT - 1)] = hpkt; -#else if (hpktp->busy) { struct host_packet *hp = malloc(sizeof(struct host_packet), M_TEMP, M_NOWAIT | M_ZERO); @@ -2344,7 +2307,6 @@ ata_promise_queue_hpkt(struct ata_pci_controller *ctlr, u_int32_t hpkt) hpktp->busy = 1; ATA_OUTL(ctlr->r_res2, 0x000c0100, hpkt); } -#endif mtx_unlock(&hpktp->mtx); } @@ -2355,18 +2317,11 @@ ata_promise_next_hpkt(struct ata_pci_controller *ctlr) struct host_packet *hp; mtx_lock(&hpktp->mtx); -#if 0 - if (hpktp->tail != hpktp->head) { - ATA_OUTL(ctlr->r_res2, 0x000c0100, - hpktp->array[(hpktp->tail++) & (ATA_PDC_MAX_HPKT - 1)]); - } -#else if ((hp = TAILQ_FIRST(&hpktp->queue))) { TAILQ_REMOVE(&hpktp->queue, hp, chain); ATA_OUTL(ctlr->r_res2, 0x000c0100, hp->addr); free(hp, M_TEMP); } -#endif else hpktp->busy = 0; mtx_unlock(&hpktp->mtx); @@ -2428,10 +2383,11 @@ ata_promise_old_intr(void *data) static int ata_promise_new_dmastart(device_t dev) { - struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); - struct ata_channel *ch = device_get_softc(dev); + struct ata_pci_controller *ctlr = device_get_softc(GRANDPARENT(dev)); + struct ata_channel *ch = device_get_softc(device_get_parent(dev)); + struct ata_device *atadev = device_get_softc(dev); - if (ch->flags & ATA_48BIT_ACTIVE) { + if (atadev->flags & ATA_D_48BIT_ACTIVE) { ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | (ch->unit ? 0x08 : 0x02)); ATA_OUTL(ctlr->r_res1, 0x20, @@ -2451,11 +2407,12 @@ ata_promise_new_dmastart(device_t dev) static int ata_promise_new_dmastop(device_t dev) { - struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); - struct ata_channel *ch = device_get_softc(dev); + struct ata_pci_controller *ctlr = device_get_softc(GRANDPARENT(dev)); + struct ata_channel *ch = device_get_softc(device_get_parent(dev)); + struct ata_device *atadev = device_get_softc(dev); int error; - if (ch->flags & ATA_48BIT_ACTIVE) { + if (atadev->flags & ATA_D_48BIT_ACTIVE) { ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) & ~(ch->unit ? 0x08 : 0x02)); ATA_OUTL(ctlr->r_res1, 0x20, 0); @@ -2463,12 +2420,23 @@ ata_promise_new_dmastop(device_t dev) error = ATA_IDX_INB(ch, ATA_BMSTAT_PORT); ATA_IDX_OUTB(ch, ATA_BMCMD_PORT, ATA_IDX_INB(ch, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP); - ch->flags &= ~ATA_DMA_ACTIVE; ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR); + ch->flags &= ~ATA_DMA_ACTIVE; return error; } static void +ata_promise_new_dmareset(device_t dev) +{ + struct ata_channel *ch = device_get_softc(dev); + + ATA_IDX_OUTB(ch, ATA_BMCMD_PORT, + ATA_IDX_INB(ch, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP); + ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR); + ch->flags &= ~ATA_DMA_ACTIVE; +} + +static void ata_promise_new_dmainit(device_t dev) { struct ata_channel *ch = device_get_softc(dev); @@ -2477,6 +2445,7 @@ ata_promise_new_dmainit(device_t dev) if (ch->dma) { ch->dma->start = ata_promise_new_dmastart; ch->dma->stop = ata_promise_new_dmastop; + ch->dma->reset = ata_promise_new_dmareset; } } diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index 0413aa9..f8c4411 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$"); static void ata_dmaalloc(device_t); static void ata_dmafree(device_t); static void ata_dmasetprd(void *, bus_dma_segment_t *, int, int); -static int ata_dmaload(device_t, caddr_t, int32_t, int); +static int ata_dmaload(device_t, caddr_t, int32_t, int, void *, int *); static int ata_dmaunload(device_t); /* local vars */ @@ -213,10 +213,12 @@ ata_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) prd[i].count = htole32(segs[i].ds_len); } prd[i - 1].count |= htole32(ATA_DMA_EOT); + args->nsegs = nsegs; } static int -ata_dmaload(device_t dev, caddr_t data, int32_t count, int dir) +ata_dmaload(device_t dev, caddr_t data, int32_t count, int dir, + void *addr, int *entries) { struct ata_channel *ch = device_get_softc(dev); struct ata_dmasetprd_args cba; @@ -240,12 +242,14 @@ ata_dmaload(device_t dev, caddr_t data, int32_t count, int dir) return -1; } - cba.dmatab = ch->dma->sg; + cba.dmatab = addr; if (bus_dmamap_load(ch->dma->data_tag, ch->dma->data_map, data, count, ch->dma->setprd, &cba, 0) || cba.error) return -1; + *entries = cba.nsegs; + bus_dmamap_sync(ch->dma->sg_tag, ch->dma->sg_map, BUS_DMASYNC_PREWRITE); bus_dmamap_sync(ch->dma->data_tag, ch->dma->data_map, @@ -260,14 +264,18 @@ int ata_dmaunload(device_t dev) { struct ata_channel *ch = device_get_softc(dev); - bus_dmamap_sync(ch->dma->sg_tag, ch->dma->sg_map, BUS_DMASYNC_POSTWRITE); - bus_dmamap_sync(ch->dma->data_tag, ch->dma->data_map, - (ch->dma->flags & ATA_DMA_READ) != 0 ? - BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(ch->dma->data_tag, ch->dma->data_map); + if (ch->dma->flags & ATA_DMA_LOADED) { + bus_dmamap_sync(ch->dma->sg_tag, ch->dma->sg_map, + BUS_DMASYNC_POSTWRITE); - ch->dma->cur_iosize = 0; - ch->dma->flags &= ~ATA_DMA_LOADED; + bus_dmamap_sync(ch->dma->data_tag, ch->dma->data_map, + (ch->dma->flags & ATA_DMA_READ) != 0 ? + BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(ch->dma->data_tag, ch->dma->data_map); + + ch->dma->cur_iosize = 0; + ch->dma->flags &= ~ATA_DMA_LOADED; + } return 0; } diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c index 37bb8cb..c6aeb33 100644 --- a/sys/dev/ata/ata-lowlevel.c +++ b/sys/dev/ata/ata-lowlevel.c @@ -74,6 +74,7 @@ ata_begin_transaction(struct ata_request *request) { struct ata_channel *ch = device_get_softc(device_get_parent(request->dev)); struct ata_device *atadev = device_get_softc(request->dev); + int dummy; ATA_DEBUG_RQ(request, "begin transaction"); @@ -92,9 +93,7 @@ ata_begin_transaction(struct ata_request *request) int write = (request->flags & ATA_R_WRITE); /* issue command */ - if (ch->hw.command(request->dev, request->u.ata.command, - request->u.ata.lba, request->u.ata.count, - request->u.ata.feature)) { + if (ch->hw.command(request)) { device_printf(request->dev, "error issueing %s command\n", ata_cmd2str(request)); request->result = EIO; @@ -115,8 +114,7 @@ ata_begin_transaction(struct ata_request *request) /* if write command output the data */ if (write) { - if (ata_wait(ch, atadev, - (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)) < 0) { + if (ata_wait(ch, atadev, (ATA_S_READY | ATA_S_DRQ)) < 0) { device_printf(request->dev,"timeout waiting for write DRQ"); request->result = EIO; goto begin_finished; @@ -130,16 +128,14 @@ ata_begin_transaction(struct ata_request *request) case ATA_R_DMA: /* check sanity, setup SG list and DMA engine */ if (ch->dma->load(ch->dev, request->data, request->bytecount, - request->flags & ATA_R_READ)) { + request->flags & ATA_R_READ, ch->dma->sg, &dummy)) { device_printf(request->dev, "setting up DMA failed\n"); request->result = EIO; goto begin_finished; } /* issue command */ - if (ch->hw.command(request->dev, request->u.ata.command, - request->u.ata.lba, request->u.ata.count, - request->u.ata.feature)) { + if (ch->hw.command(request)) { device_printf(request->dev, "error issueing %s command\n", ata_cmd2str(request)); request->result = EIO; @@ -147,7 +143,7 @@ ata_begin_transaction(struct ata_request *request) } /* start DMA engine */ - if (ch->dma->start(ch->dev)) { + if (ch->dma->start && ch->dma->start(request->dev)) { device_printf(request->dev, "error starting DMA\n"); request->result = EIO; goto begin_finished; @@ -166,44 +162,11 @@ ata_begin_transaction(struct ata_request *request) } /* start ATAPI operation */ - if (ch->hw.command(request->dev, ATA_PACKET_CMD, - request->transfersize << 8, 0, 0)) { + if (ch->hw.command(request)) { device_printf(request->dev, "error issuing ATA PACKET command\n"); request->result = EIO; goto begin_finished; } - - /* command interrupt device ? just return and wait for interrupt */ - if ((atadev->param.config & ATA_DRQ_MASK) == ATA_DRQ_INTR) - goto begin_continue; - - /* wait for ready to write ATAPI command block */ - { - int timeout = 5000; /* might be less for fast devices */ - while (timeout--) { - int reason = ATA_IDX_INB(ch, ATA_IREASON); - int status = ATA_IDX_INB(ch, ATA_STATUS); - - if (((reason & (ATA_I_CMD | ATA_I_IN)) | - (status & (ATA_S_DRQ | ATA_S_BUSY))) == ATAPI_P_CMDOUT) - break; - DELAY(20); - } - if (timeout <= 0) { - device_printf(request->dev,"timeout waiting for ATAPI ready\n"); - request->result = EIO; - goto begin_finished; - } - } - - /* this seems to be needed for some (slow) devices */ - DELAY(10); - - /* output actual command block */ - ATA_IDX_OUTSW_STRM(ch, ATA_DATA, - (int16_t *)request->u.atapi.ccb, - (atadev->param.config & ATA_PROTO_MASK) == - ATA_PROTO_ATAPI_12 ? 6 : 8); goto begin_continue; /* ATAPI DMA commands */ @@ -219,49 +182,21 @@ ata_begin_transaction(struct ata_request *request) /* check sanity, setup SG list and DMA engine */ if (ch->dma->load(ch->dev, request->data, request->bytecount, - request->flags & ATA_R_READ)) { + request->flags & ATA_R_READ, ch->dma->sg, &dummy)) { device_printf(request->dev, "setting up DMA failed\n"); request->result = EIO; goto begin_finished; } /* start ATAPI operation */ - if (ch->hw.command(request->dev, ATA_PACKET_CMD, 0, 0, ATA_F_DMA)) { - device_printf(request->dev, "error issuing ATAPI packet command\n"); + if (ch->hw.command(request)) { + device_printf(request->dev, "error issuing ATA PACKET command\n"); request->result = EIO; goto begin_finished; } - /* wait for ready to write ATAPI command block */ - { - int timeout = 5000; /* might be less for fast devices */ - while (timeout--) { - int reason = ATA_IDX_INB(ch, ATA_IREASON); - int status = ATA_IDX_INB(ch, ATA_STATUS); - - if (((reason & (ATA_I_CMD | ATA_I_IN)) | - (status & (ATA_S_DRQ | ATA_S_BUSY))) == ATAPI_P_CMDOUT) - break; - DELAY(20); - } - if (timeout <= 0) { - device_printf(request->dev,"timeout waiting for ATAPI ready\n"); - request->result = EIO; - goto begin_finished; - } - } - - /* this seems to be needed for some (slow) devices */ - DELAY(10); - - /* output actual command block */ - ATA_IDX_OUTSW_STRM(ch, ATA_DATA, - (int16_t *)request->u.atapi.ccb, - (atadev->param.config & ATA_PROTO_MASK) == - ATA_PROTO_ATAPI_12 ? 6 : 8); - /* start DMA engine */ - if (ch->dma->start(ch->dev)) { + if (ch->dma->start && ch->dma->start(request->dev)) { request->result = EIO; goto begin_finished; } @@ -305,7 +240,7 @@ ata_end_transaction(struct ata_request *request) /* on control commands read back registers to the request struct */ if (request->flags & ATA_R_CONTROL) { - if (ch->flags & ATA_48BIT_ACTIVE) { + if (atadev->flags & ATA_D_48BIT_ACTIVE) { 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.lba = @@ -340,8 +275,7 @@ ata_end_transaction(struct ata_request *request) /* if read data get it */ if (request->flags & ATA_R_READ) { - if (ata_wait(ch, atadev, - (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)) < 0) { + if (ata_wait(ch, atadev, (ATA_S_READY | ATA_S_DRQ)) < 0) { device_printf(request->dev, "timeout waiting for read DRQ"); request->result = EIO; goto end_finished; @@ -364,8 +298,7 @@ ata_end_transaction(struct ata_request *request) if (request->flags & ATA_R_WRITE) { /* if we get an error here we are done with the HW */ - if (ata_wait(ch, atadev, - (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)) < 0) { + if (ata_wait(ch, atadev, (ATA_S_READY | ATA_S_DRQ)) < 0) { device_printf(request->dev, "timeout waiting for write DRQ"); request->status = ATA_IDX_INB(ch, ATA_STATUS); @@ -390,7 +323,7 @@ ata_end_transaction(struct ata_request *request) /* stop DMA engine and get status */ if (ch->dma->stop) - request->dmastat = ch->dma->stop(ch->dev); + request->dmastat = ch->dma->stop(request->dev); /* did we get error or data */ if (request->status & ATA_S_ERROR) @@ -500,9 +433,9 @@ ata_end_transaction(struct ata_request *request) /* ATAPI DMA commands */ case ATA_R_ATAPI|ATA_R_DMA: - /* stop the engine and get engine status */ + /* stop DMA engine and get status */ if (ch->dma->stop) - request->dmastat = ch->dma->stop(ch->dev); + request->dmastat = ch->dma->stop(request->dev); /* did we get error or data */ if (request->status & (ATA_S_ERROR | ATA_S_DWF)) @@ -716,97 +649,112 @@ ata_wait(struct ata_channel *ch, struct ata_device *atadev, u_int8_t mask) } int -ata_generic_command(device_t dev, u_int8_t command, - u_int64_t lba, u_int16_t count, u_int16_t feature) +ata_generic_command(struct ata_request *request) { - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); + struct ata_channel *ch = device_get_softc(device_get_parent(request->dev)); + struct ata_device *atadev = device_get_softc(request->dev); /* select device */ ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | atadev->unit); /* ready to issue command ? */ if (ata_wait(ch, atadev, 0) < 0) { - device_printf(dev, "timeout sending command=%02x\n", command); + device_printf(request->dev, "timeout waiting to issue command\n"); return -1; } /* enable interrupt */ ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_4BIT); - /* only use 48bit addressing if needed (avoid bugs and overhead) */ - if ((lba >= ATA_MAX_28BIT_LBA || count > 256) && - atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48) { - - /* translate command into 48bit version */ - switch (command) { - case ATA_READ: - command = ATA_READ48; break; - case ATA_READ_MUL: - command = ATA_READ_MUL48; break; - case ATA_READ_DMA: - command = ATA_READ_DMA48; break; - case ATA_READ_DMA_QUEUED: - command = ATA_READ_DMA_QUEUED48; break; - case ATA_WRITE: - command = ATA_WRITE48; break; - case ATA_WRITE_MUL: - command = ATA_WRITE_MUL48; break; - case ATA_WRITE_DMA: - command = ATA_WRITE_DMA48; break; - case ATA_WRITE_DMA_QUEUED: - command = ATA_WRITE_DMA_QUEUED48; break; - case ATA_FLUSHCACHE: - command = ATA_FLUSHCACHE48; break; - default: - device_printf(dev,"can't translate cmd to 48bit version\n"); - return -1; - } - ATA_IDX_OUTB(ch, ATA_FEATURE, (feature>>8) & 0xff); - ATA_IDX_OUTB(ch, ATA_FEATURE, feature & 0xff); - ATA_IDX_OUTB(ch, ATA_COUNT, (count>>8) & 0xff); - ATA_IDX_OUTB(ch, ATA_COUNT, count & 0xff); - ATA_IDX_OUTB(ch, ATA_SECTOR, (lba>>24) & 0xff); - ATA_IDX_OUTB(ch, ATA_SECTOR, lba & 0xff); - ATA_IDX_OUTB(ch, ATA_CYL_LSB, (lba>>32) & 0xff); - ATA_IDX_OUTB(ch, ATA_CYL_LSB, (lba>>8) & 0xff); - ATA_IDX_OUTB(ch, ATA_CYL_MSB, (lba>>40) & 0xff); - ATA_IDX_OUTB(ch, ATA_CYL_MSB, (lba>>16) & 0xff); - ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_LBA | atadev->unit); - ch->flags |= ATA_48BIT_ACTIVE; + if (request->flags & ATA_R_ATAPI) { + int timeout = 5000; + + /* issue packet command to controller */ + ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->transfersize); + ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->transfersize >> 8); + ATA_IDX_OUTB(ch, ATA_COMMAND, ATA_PACKET_CMD); + + /* command interrupt device ? just return and wait for interrupt */ + if ((atadev->param.config & ATA_DRQ_MASK) == ATA_DRQ_INTR) + return 0; + + /* wait for ready to write ATAPI command block */ + while (timeout--) { + int reason = ATA_IDX_INB(ch, ATA_IREASON); + int status = ATA_IDX_INB(ch, ATA_STATUS); + + if (((reason & (ATA_I_CMD | ATA_I_IN)) | + (status & (ATA_S_DRQ | ATA_S_BUSY))) == ATAPI_P_CMDOUT) + break; + DELAY(20); + } + if (timeout <= 0) { + device_printf(request->dev,"timeout waiting for ATAPI ready\n"); + request->result = EIO; + return -1; + } + + /* this seems to be needed for some (slow) devices */ + DELAY(10); + + /* output command block */ + ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (int16_t *)request->u.atapi.ccb, + (atadev->param.config & ATA_PROTO_MASK) == + ATA_PROTO_ATAPI_12 ? 6 : 8); } else { - ATA_IDX_OUTB(ch, ATA_FEATURE, feature); - ATA_IDX_OUTB(ch, ATA_COUNT, count); - if (atadev->flags & ATA_D_USE_CHS) { - int heads, sectors; - - if (atadev->param.atavalid & ATA_FLAG_54_58) { - heads = atadev->param.current_heads; - sectors = atadev->param.current_sectors; + u_int8_t command = ata_modify_if_48bit(request); + + if (atadev->flags & ATA_D_48BIT_ACTIVE) { + 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_COUNT, request->u.ata.count >> 8); + ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); + ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba >> 24); + ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba); + ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 32); + 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 >> 16); + ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_LBA | atadev->unit); + } + else { + command = request->u.ata.command; + ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); + ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); + if (atadev->flags & ATA_D_USE_CHS) { + int heads, sectors; + + if (atadev->param.atavalid & ATA_FLAG_54_58) { + heads = atadev->param.current_heads; + sectors = atadev->param.current_sectors; + } + else { + heads = atadev->param.heads; + sectors = atadev->param.sectors; + } + ATA_IDX_OUTB(ch, ATA_SECTOR, (request->u.ata.lba % sectors)+1); + ATA_IDX_OUTB(ch, ATA_CYL_LSB, + (request->u.ata.lba / (sectors * heads))); + ATA_IDX_OUTB(ch, ATA_CYL_MSB, + (request->u.ata.lba / (sectors * heads)) >> 8); + ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | atadev->unit | + (((request->u.ata.lba% (sectors * heads)) / + sectors) & 0xf)); } else { - heads = atadev->param.heads; - sectors = atadev->param.sectors; + ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba); + 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_DRIVE, + ATA_D_IBM | ATA_D_LBA | atadev->unit | + ((request->u.ata.lba >> 24) & 0x0f)); } - ATA_IDX_OUTB(ch, ATA_SECTOR, (lba % sectors) + 1); - ATA_IDX_OUTB(ch, ATA_CYL_LSB, (lba / (sectors * heads))); - ATA_IDX_OUTB(ch, ATA_CYL_MSB, (lba / (sectors * heads)) >> 8); - ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | atadev->unit | - (((lba % (sectors * heads)) / sectors) & 0xf)); } - else { - ATA_IDX_OUTB(ch, ATA_SECTOR, lba & 0xff); - ATA_IDX_OUTB(ch, ATA_CYL_LSB, (lba>>8) & 0xff); - ATA_IDX_OUTB(ch, ATA_CYL_MSB, (lba>>16) & 0xff); - ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | atadev->unit | - ((lba>>24) & 0x0f)); - } - ch->flags &= ~ATA_48BIT_ACTIVE; - } - /* issue command to controller */ - ATA_IDX_OUTB(ch, ATA_COMMAND, command); + /* issue command to controller */ + ATA_IDX_OUTB(ch, ATA_COMMAND, command); + } return 0; } diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index 94a1c51..e197227 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -419,7 +419,7 @@ ata_pci_allocate(device_t dev) static int ata_pci_dmastart(device_t dev) { - struct ata_channel *ch = device_get_softc(dev); + struct ata_channel *ch = device_get_softc(device_get_parent(dev)); ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, (ATA_IDX_INB(ch, ATA_BMSTAT_PORT) | (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR))); @@ -435,7 +435,7 @@ ata_pci_dmastart(device_t dev) static int ata_pci_dmastop(device_t dev) { - struct ata_channel *ch = device_get_softc(dev); + struct ata_channel *ch = device_get_softc(device_get_parent(dev)); int error; ATA_IDX_OUTB(ch, ATA_BMCMD_PORT, @@ -447,6 +447,18 @@ ata_pci_dmastop(device_t dev) } static void +ata_pci_dmareset(device_t dev) +{ + struct ata_channel *ch = device_get_softc(dev); + + ATA_IDX_OUTB(ch, ATA_BMCMD_PORT, + ATA_IDX_INB(ch, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP); + ch->dma->flags &= ~ATA_DMA_ACTIVE; + ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR); + ch->dma->unload(dev); +} + +static void ata_pci_dmainit(device_t dev) { struct ata_channel *ch = device_get_softc(dev); @@ -455,6 +467,7 @@ ata_pci_dmainit(device_t dev) if (ch->dma) { ch->dma->start = ata_pci_dmastart; ch->dma->stop = ata_pci_dmastop; + ch->dma->reset = ata_pci_dmareset; } } @@ -568,12 +581,11 @@ ata_pcichannel_reset(device_t dev) struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); - /* if DMA functionality present stop it */ + /* if DMA engine present reset it */ if (ch->dma) { - if (ch->dma->flags & ATA_DMA_ACTIVE) - ch->dma->stop(dev); - if (ch->dma->flags & ATA_DMA_LOADED) - ch->dma->unload(dev); + if (ch->dma->reset) + ch->dma->reset(dev); + ch->dma->unload(dev); } /* reset the controller HW */ diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c index 0dce1c0..f2a3d3d 100644 --- a/sys/dev/ata/ata-queue.c +++ b/sys/dev/ata/ata-queue.c @@ -148,6 +148,7 @@ ata_atapicmd(device_t dev, u_int8_t *ccb, caddr_t data, request->transfersize = min(request->bytecount, 65534); request->flags = flags | ATA_R_ATAPI; request->timeout = timeout; + request->retries = 0; ata_queue_request(request); error = request->result; ata_free_request(request); @@ -454,8 +455,6 @@ ata_timeout(struct ata_request *request) */ if (ch->state == ATA_ACTIVE || ch->state == ATA_STALL_QUEUE) { request->flags |= ATA_R_TIMEOUT; - ch->state |= ATA_TIMEOUT; - ch->running = NULL; mtx_unlock(&ch->state_mtx); ATA_LOCKING(ch->dev, ATA_LF_UNLOCK); ata_finish(request); diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index 673f0e0..48df3bf 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.c @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include /* prototypes */ @@ -128,6 +129,7 @@ acd_attach(device_t dev) cdp->block_size = 2048; device_set_ivars(dev, cdp); ATA_SETMODE(device_get_parent(dev), dev); + ata_controlcmd(dev, ATA_DEVICE_RESET, 0, 0, 0); acd_get_cap(dev); g_post_event(acd_geom_attach, dev, M_WAITOK, NULL); @@ -1000,7 +1002,7 @@ acd_read_toc(device_t dev) #ifdef ACD_DEBUG if (cdp->disk_size && cdp->toc.hdr.ending_track) { - device_printd(dev, "(%d sectors (%d bytes)), %d tracks ", + device_printf(dev, "(%d sectors (%d bytes)), %d tracks ", cdp->disk_size, cdp->block_size, cdp->toc.hdr.ending_track-cdp->toc.hdr.starting_track+1); if (cdp->toc.tab[0].control & 4) @@ -1249,9 +1251,6 @@ acd_send_cue(device_t dev, struct cdr_cuesheet *cuesheet) 0, 0, 0, 0, 0, 0, 0 }; int8_t *buffer; int32_t error; -#ifdef ACD_DEBUG - int i; -#endif if ((error = acd_mode_sense(dev, ATAPI_CDROM_WRITE_PARAMETERS_PAGE, (caddr_t)¶m, sizeof(param)))) @@ -1277,18 +1276,8 @@ acd_send_cue(device_t dev, struct cdr_cuesheet *cuesheet) if (!(buffer = malloc(cuesheet->len, M_ACD, M_NOWAIT))) return ENOMEM; - if (!(error = copyin(cuesheet->entries, buffer, cuesheet->len))) { -#ifdef ACD_DEBUG - printf("acd: cuesheet lenght = %d\n", cuesheet->len); - for (i=0; ilen; i++) - if (i%8) - printf(" %02x", buffer[i]); - else - printf("\n%02x", buffer[i]); - printf("\n"); -#endif + if (!(error = copyin(cuesheet->entries, buffer, cuesheet->len))) error = ata_atapicmd(dev, ccb, buffer, cuesheet->len, 0, 30); - } free(buffer, M_ACD); return error; } @@ -1613,9 +1602,6 @@ acd_mode_sense(device_t dev, int page, caddr_t pagebuf, int pagesize) int error; error = ata_atapicmd(dev, ccb, pagebuf, pagesize, ATA_R_READ, 10); -#ifdef ACD_DEBUG - atapi_dump("acd: mode sense ", pagebuf, pagesize); -#endif return error; } @@ -1625,10 +1611,6 @@ acd_mode_select(device_t dev, caddr_t pagebuf, int pagesize) int8_t ccb[16] = { ATAPI_MODE_SELECT_BIG, 0x10, 0, 0, 0, 0, 0, pagesize>>8, pagesize, 0, 0, 0, 0, 0, 0, 0 }; -#ifdef ACD_DEBUG - device_printf(dev, "modeselect pagesize=%d\n", pagesize); - atapi_dump("mode select ", pagebuf, pagesize); -#endif return ata_atapicmd(dev, ccb, pagebuf, pagesize, 0, 30); } -- cgit v1.1