Lines Matching +full:inactive +full:- +full:delay
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 1998 - 2008 Søren Schmidt <sos@FreeBSD.org>
43 #include <dev/ata/ata-all.h>
44 #include <dev/ata/ata-pci.h>
69 ch->hw.begin_transaction = ata_begin_transaction; in ata_generic_hw()
70 ch->hw.end_transaction = ata_end_transaction; in ata_generic_hw()
71 ch->hw.status = ata_generic_status; in ata_generic_hw()
72 ch->hw.softreset = NULL; in ata_generic_hw()
73 ch->hw.command = ata_generic_command; in ata_generic_hw()
74 ch->hw.tf_read = ata_tf_read; in ata_generic_hw()
75 ch->hw.tf_write = ata_tf_write; in ata_generic_hw()
76 ch->hw.pm_read = NULL; in ata_generic_hw()
77 ch->hw.pm_write = NULL; in ata_generic_hw()
84 struct ata_channel *ch = device_get_softc(request->parent); in ata_begin_transaction()
90 if ((ch->flags & ATA_NO_ATAPI_DMA) && in ata_begin_transaction()
91 (request->flags & ATA_R_ATAPI) == ATA_R_ATAPI) in ata_begin_transaction()
92 request->flags &= ~ATA_R_DMA; in ata_begin_transaction()
93 if ((ch->flags & ATA_ATAPI_DMA_RO) && in ata_begin_transaction()
94 ((request->flags & (ATA_R_ATAPI | ATA_R_DMA | ATA_R_WRITE)) == in ata_begin_transaction()
96 request->flags &= ~ATA_R_DMA; in ata_begin_transaction()
98 switch (request->flags & (ATA_R_ATAPI | ATA_R_DMA)) { in ata_begin_transaction()
103 int write = (request->flags & ATA_R_WRITE); in ata_begin_transaction()
106 if (ch->hw.command(request)) { in ata_begin_transaction()
107 device_printf(request->parent, "error issuing %s command\n", in ata_begin_transaction()
109 request->result = EIO; in ata_begin_transaction()
114 if (request->u.ata.command == ATA_DEVICE_RESET) { in ata_begin_transaction()
117 DELAY(10); in ata_begin_transaction()
118 request->status = ATA_IDX_INB(ch, ATA_STATUS); in ata_begin_transaction()
119 } while (request->status & ATA_S_BUSY && timeout--); in ata_begin_transaction()
120 if (request->status & ATA_S_ERROR) in ata_begin_transaction()
121 request->error = ATA_IDX_INB(ch, ATA_ERROR); in ata_begin_transaction()
122 ch->hw.tf_read(request); in ata_begin_transaction()
128 if (ata_wait(ch, request->unit, (ATA_S_READY | ATA_S_DRQ)) < 0) { in ata_begin_transaction()
129 device_printf(request->parent, in ata_begin_transaction()
131 request->result = EIO; in ata_begin_transaction()
134 ata_pio_write(request, request->transfersize); in ata_begin_transaction()
142 if ((error = ch->dma.load(request, NULL, &dummy))) { in ata_begin_transaction()
143 device_printf(request->parent, "setting up DMA failed\n"); in ata_begin_transaction()
144 request->result = error; in ata_begin_transaction()
149 if ((ch->flags & ATA_DMA_BEFORE_CMD) && in ata_begin_transaction()
150 ch->dma.start && ch->dma.start(request)) { in ata_begin_transaction()
151 device_printf(request->parent, "error starting DMA\n"); in ata_begin_transaction()
152 request->result = EIO; in ata_begin_transaction()
157 if (ch->hw.command(request)) { in ata_begin_transaction()
158 device_printf(request->parent, "error issuing %s command\n", in ata_begin_transaction()
160 request->result = EIO; in ata_begin_transaction()
165 if (!(ch->flags & ATA_DMA_BEFORE_CMD) && in ata_begin_transaction()
166 ch->dma.start && ch->dma.start(request)) { in ata_begin_transaction()
167 device_printf(request->parent, "error starting DMA\n"); in ata_begin_transaction()
168 request->result = EIO; in ata_begin_transaction()
176 if (request->u.atapi.ccb[0] == ATAPI_POLL_DSC) { in ata_begin_transaction()
177 ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit)); in ata_begin_transaction()
178 DELAY(10); in ata_begin_transaction()
180 request->result = EBUSY; in ata_begin_transaction()
185 if (ch->hw.command(request)) { in ata_begin_transaction()
186 device_printf(request->parent, "error issuing ATA PACKET command\n"); in ata_begin_transaction()
187 request->result = EIO; in ata_begin_transaction()
195 if (request->u.atapi.ccb[0] == ATAPI_POLL_DSC) { in ata_begin_transaction()
196 ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit)); in ata_begin_transaction()
197 DELAY(10); in ata_begin_transaction()
199 request->result = EBUSY; in ata_begin_transaction()
204 if ((error = ch->dma.load(request, NULL, &dummy))) { in ata_begin_transaction()
205 device_printf(request->parent, "setting up DMA failed\n"); in ata_begin_transaction()
206 request->result = error; in ata_begin_transaction()
211 if (ch->hw.command(request)) { in ata_begin_transaction()
212 device_printf(request->parent, "error issuing ATA PACKET command\n"); in ata_begin_transaction()
213 request->result = EIO; in ata_begin_transaction()
218 if (ch->dma.start && ch->dma.start(request)) { in ata_begin_transaction()
219 request->result = EIO; in ata_begin_transaction()
228 if (ch->dma.unload) { in ata_begin_transaction()
229 ch->dma.unload(request); in ata_begin_transaction()
234 callout_reset(&request->callout, request->timeout * hz, in ata_begin_transaction()
243 struct ata_channel *ch = device_get_softc(request->parent); in ata_end_transaction()
249 request->status = ATA_IDX_INB(ch, ATA_STATUS); in ata_end_transaction()
251 switch (request->flags & (ATA_R_ATAPI | ATA_R_DMA | ATA_R_CONTROL)) { in ata_end_transaction()
256 if (request->flags & ATA_R_TIMEOUT) in ata_end_transaction()
260 if ((request->status & ATA_S_ERROR) || in ata_end_transaction()
261 (request->flags & (ATA_R_CONTROL | ATA_R_NEEDRESULT))) { in ata_end_transaction()
262 ch->hw.tf_read(request); in ata_end_transaction()
266 if (request->status & ATA_S_ERROR) { in ata_end_transaction()
267 request->error = ATA_IDX_INB(ch, ATA_ERROR); in ata_end_transaction()
272 if (request->flags & (ATA_R_READ | ATA_R_WRITE)) { in ata_end_transaction()
274 if (request->flags & ATA_R_READ) { in ata_end_transaction()
277 if (request->u.ata.command != ATA_ATAPI_IDENTIFY) in ata_end_transaction()
279 if (ata_wait(ch, request->unit, flags) < 0) { in ata_end_transaction()
280 device_printf(request->parent, in ata_end_transaction()
282 request->result = EIO; in ata_end_transaction()
285 ata_pio_read(request, request->transfersize); in ata_end_transaction()
289 request->donecount += request->transfersize; in ata_end_transaction()
292 if (request->bytecount > request->donecount) { in ata_end_transaction()
294 request->transfersize = in ata_end_transaction()
295 min((request->bytecount - request->donecount), in ata_end_transaction()
296 request->transfersize); in ata_end_transaction()
299 if (request->flags & ATA_R_WRITE) { in ata_end_transaction()
301 if (ata_wait(ch, request->unit, (ATA_S_READY | ATA_S_DRQ)) < 0) { in ata_end_transaction()
302 device_printf(request->parent, in ata_end_transaction()
304 request->status = ATA_IDX_INB(ch, ATA_STATUS); in ata_end_transaction()
309 ata_pio_write(request, request->transfersize); in ata_end_transaction()
314 if (request->flags & ATA_R_READ) in ata_end_transaction()
325 if (ch->dma.stop) in ata_end_transaction()
326 request->dma->status = ch->dma.stop(request); in ata_end_transaction()
329 if (request->status & ATA_S_ERROR) in ata_end_transaction()
330 request->error = ATA_IDX_INB(ch, ATA_ERROR); in ata_end_transaction()
331 else if (request->dma->status & ATA_BMSTAT_ERROR) in ata_end_transaction()
332 request->status |= ATA_S_ERROR; in ata_end_transaction()
333 else if (!(request->flags & ATA_R_TIMEOUT)) in ata_end_transaction()
334 request->donecount = request->bytecount; in ata_end_transaction()
337 if ((request->status & ATA_S_ERROR) || in ata_end_transaction()
338 (request->flags & (ATA_R_CONTROL | ATA_R_NEEDRESULT))) { in ata_end_transaction()
339 ch->hw.tf_read(request); in ata_end_transaction()
343 ch->dma.unload(request); in ata_end_transaction()
353 if (request->flags & ATA_R_TIMEOUT) in ata_end_transaction()
357 (request->status & ATA_S_DRQ)) { in ata_end_transaction()
360 DELAY(10); in ata_end_transaction()
362 if (!(request->status & ATA_S_DRQ)) { in ata_end_transaction()
363 device_printf(request->parent, "command interrupt without DRQ\n"); in ata_end_transaction()
364 request->status = ATA_S_ERROR; in ata_end_transaction()
367 ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (int16_t *)request->u.atapi.ccb, in ata_end_transaction()
368 (request->flags & ATA_R_ATAPI16) ? 8 : 6); in ata_end_transaction()
373 if (request->flags & ATA_R_READ) { in ata_end_transaction()
374 request->status = ATA_S_ERROR; in ata_end_transaction()
375 device_printf(request->parent, in ata_end_transaction()
381 request->donecount += length; in ata_end_transaction()
384 request->transfersize = min((request->bytecount-request->donecount), in ata_end_transaction()
385 request->transfersize); in ata_end_transaction()
390 if (request->flags & ATA_R_WRITE) { in ata_end_transaction()
391 request->status = ATA_S_ERROR; in ata_end_transaction()
392 device_printf(request->parent, in ata_end_transaction()
398 request->donecount += length; in ata_end_transaction()
401 request->transfersize = min((request->bytecount-request->donecount), in ata_end_transaction()
402 request->transfersize); in ata_end_transaction()
407 device_printf(request->parent, in ata_end_transaction()
408 "WARNING - %s DONEDRQ non conformant device\n", in ata_end_transaction()
410 if (request->flags & ATA_R_READ) { in ata_end_transaction()
412 request->donecount += length; in ata_end_transaction()
414 else if (request->flags & ATA_R_WRITE) { in ata_end_transaction()
416 request->donecount += length; in ata_end_transaction()
419 request->status = ATA_S_ERROR; in ata_end_transaction()
424 if (request->status & (ATA_S_ERROR | ATA_S_DWF)) in ata_end_transaction()
425 request->error = ATA_IDX_INB(ch, ATA_ERROR); in ata_end_transaction()
429 device_printf(request->parent, "unknown transfer phase\n"); in ata_end_transaction()
430 request->status = ATA_S_ERROR; in ata_end_transaction()
440 if (ch->dma.stop) in ata_end_transaction()
441 request->dma->status = ch->dma.stop(request); in ata_end_transaction()
444 if (request->status & (ATA_S_ERROR | ATA_S_DWF)) in ata_end_transaction()
445 request->error = ATA_IDX_INB(ch, ATA_ERROR); in ata_end_transaction()
446 else if (request->dma->status & ATA_BMSTAT_ERROR) in ata_end_transaction()
447 request->status |= ATA_S_ERROR; in ata_end_transaction()
448 else if (!(request->flags & ATA_R_TIMEOUT)) in ata_end_transaction()
449 request->donecount = request->bytecount; in ata_end_transaction()
452 ch->dma.unload(request); in ata_end_transaction()
461 callout_stop(&request->callout); in ata_end_transaction()
480 DELAY(10); in ata_generic_reset()
482 if (((ostat0 & 0xf8) != 0xf8 || (ch->flags & ATA_KNOWN_PRESENCE)) && in ata_generic_reset()
489 if (!(ch->flags & ATA_NO_SLAVE)) { in ata_generic_reset()
491 DELAY(10); in ata_generic_reset()
493 if (((ostat1 & 0xf8) != 0xf8 || (ch->flags & ATA_KNOWN_PRESENCE)) && in ata_generic_reset()
506 ch->devices = 0; in ata_generic_reset()
512 DELAY(10); in ata_generic_reset()
519 /* wait for BUSY to go inactive */ in ata_generic_reset()
523 DELAY(10); in ata_generic_reset()
524 if (ch->flags & ATA_STATUS_IS_LONG) in ata_generic_reset()
541 ch->devices |= ATA_ATAPI_MASTER; in ata_generic_reset()
544 ch->devices |= ATA_ATA_MASTER; in ata_generic_reset()
556 DELAY(10); in ata_generic_reset()
557 if (ch->flags & ATA_STATUS_IS_LONG) in ata_generic_reset()
574 ch->devices |= ATA_ATAPI_SLAVE; in ata_generic_reset()
577 ch->devices |= ATA_ATA_SLAVE; in ata_generic_reset()
586 if ((ch->flags & ATA_KNOWN_PRESENCE) == 0 && in ata_generic_reset()
601 stat0, stat1, ch->devices); in ata_generic_reset()
611 DELAY(100); in ata_generic_status()
624 DELAY(1); in ata_wait()
634 DELAY(1000); in ata_wait()
644 DELAY(1000); in ata_wait()
648 DELAY(10); in ata_wait()
652 return -2; in ata_wait()
656 DELAY(1); in ata_wait()
660 while (timeout--) { in ata_wait()
664 DELAY(10); in ata_wait()
666 return -3; in ata_wait()
672 struct ata_channel *ch = device_get_softc(request->parent); in ata_generic_command()
675 ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit)); in ata_generic_command()
678 if (ata_wait(ch, request->unit, 0) < 0) { in ata_generic_command()
679 device_printf(request->parent, "timeout waiting to issue command\n"); in ata_generic_command()
680 request->flags |= ATA_R_TIMEOUT; in ata_generic_command()
681 return (-1); in ata_generic_command()
687 if (request->flags & ATA_R_ATAPI) { in ata_generic_command()
692 if (request->flags & ATA_R_DMA) { in ata_generic_command()
699 ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->transfersize); in ata_generic_command()
700 ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->transfersize >> 8); in ata_generic_command()
705 if (request->flags & ATA_R_ATAPI_INTR) in ata_generic_command()
709 res = ata_wait(ch, request->unit, 0); in ata_generic_command()
712 device_printf(request->parent, in ata_generic_command()
714 request->flags |= ATA_R_TIMEOUT; in ata_generic_command()
716 return (-1); in ata_generic_command()
719 while (timeout--) { in ata_generic_command()
726 DELAY(20); in ata_generic_command()
729 device_printf(request->parent, in ata_generic_command()
731 request->flags |= ATA_R_TIMEOUT; in ata_generic_command()
732 return (-1); in ata_generic_command()
736 DELAY(10); in ata_generic_command()
739 ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (int16_t *)request->u.atapi.ccb, in ata_generic_command()
740 (request->flags & ATA_R_ATAPI16) ? 8 : 6); in ata_generic_command()
743 ch->hw.tf_write(request); in ata_generic_command()
746 ATA_IDX_OUTB(ch, ATA_COMMAND, request->u.ata.command); in ata_generic_command()
754 struct ata_channel *ch = device_get_softc(request->parent); in ata_tf_read()
756 if (request->flags & ATA_R_48BIT) { in ata_tf_read()
758 request->u.ata.count = (ATA_IDX_INB(ch, ATA_COUNT) << 8); in ata_tf_read()
759 request->u.ata.lba = in ata_tf_read()
765 request->u.ata.count |= ATA_IDX_INB(ch, ATA_COUNT); in ata_tf_read()
766 request->u.ata.lba |= in ata_tf_read()
772 request->u.ata.count = ATA_IDX_INB(ch, ATA_COUNT); in ata_tf_read()
773 request->u.ata.lba = ATA_IDX_INB(ch, ATA_SECTOR) | in ata_tf_read()
783 struct ata_channel *ch = device_get_softc(request->parent); in ata_tf_write()
785 if (request->flags & ATA_R_48BIT) { in ata_tf_write()
786 ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature >> 8); in ata_tf_write()
787 ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); in ata_tf_write()
788 ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count >> 8); in ata_tf_write()
789 ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); in ata_tf_write()
790 ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba >> 24); in ata_tf_write()
791 ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba); in ata_tf_write()
792 ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 32); in ata_tf_write()
793 ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); in ata_tf_write()
794 ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 40); in ata_tf_write()
795 ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); in ata_tf_write()
796 ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_LBA | ATA_DEV(request->unit)); in ata_tf_write()
799 ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); in ata_tf_write()
800 ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); in ata_tf_write()
801 ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba); in ata_tf_write()
802 ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); in ata_tf_write()
803 ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); in ata_tf_write()
805 ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit) | in ata_tf_write()
806 ((request->u.ata.lba >> 24) & 0x0f)); in ata_tf_write()
813 struct ata_channel *ch = device_get_softc(request->parent); in ata_pio_read()
820 todo = min(request->transfersize, length); in ata_pio_read()
823 size = todo - done; in ata_pio_read()
826 off = request->donecount + done; in ata_pio_read()
827 if ((request->flags & ATA_R_DATA_IN_CCB) == 0 || in ata_pio_read()
828 (request->ccb->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_VADDR) { in ata_pio_read()
829 addr = (uint8_t *)request->data + off; in ata_pio_read()
830 } else if ((request->ccb->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_BIO) { in ata_pio_read()
831 bio = (struct bio *)request->data; in ata_pio_read()
832 if ((bio->bio_flags & BIO_UNMAPPED) == 0) { in ata_pio_read()
833 addr = (uint8_t *)bio->bio_data + off; in ata_pio_read()
835 moff = bio->bio_ma_offset + off; in ata_pio_read()
837 bio->bio_ma[moff / PAGE_SIZE]); in ata_pio_read()
839 size = min(size, PAGE_SIZE - moff); in ata_pio_read()
844 (request->ccb->ccb_h.flags & CAM_DATA_MASK)); in ata_pio_read()
851 size--; in ata_pio_read()
856 if (__predict_false((ch->flags & ATA_USE_16BIT) || in ata_pio_read()
875 addr[size - 1] = buf[0]; in ata_pio_read()
888 device_printf(request->parent, in ata_pio_read()
889 "WARNING - %s read data overrun %d > %d\n", in ata_pio_read()
899 struct ata_channel *ch = device_get_softc(request->parent); in ata_pio_write()
906 todo = min(request->transfersize, length); in ata_pio_write()
909 size = todo - done; in ata_pio_write()
912 off = request->donecount + done; in ata_pio_write()
913 if ((request->flags & ATA_R_DATA_IN_CCB) == 0 || in ata_pio_write()
914 (request->ccb->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_VADDR) { in ata_pio_write()
915 addr = (uint8_t *)request->data + off; in ata_pio_write()
916 } else if ((request->ccb->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_BIO) { in ata_pio_write()
917 bio = (struct bio *)request->data; in ata_pio_write()
918 if ((bio->bio_flags & BIO_UNMAPPED) == 0) { in ata_pio_write()
919 addr = (uint8_t *)bio->bio_data + off; in ata_pio_write()
921 moff = bio->bio_ma_offset + off; in ata_pio_write()
923 bio->bio_ma[moff / PAGE_SIZE]); in ata_pio_write()
925 size = min(size, PAGE_SIZE - moff); in ata_pio_write()
930 (request->ccb->ccb_h.flags & CAM_DATA_MASK)); in ata_pio_write()
938 size--; in ata_pio_write()
943 if (__predict_false((ch->flags & ATA_USE_16BIT) || in ata_pio_write()
960 buf[0] = addr[size - 1]; in ata_pio_write()
979 device_printf(request->parent, in ata_pio_write()
980 "WARNING - %s write data underrun %d > %d\n", in ata_pio_write()