#include "boot.h" // add_bcv_hd
#include "disk.h" // struct ata_s
#include "ata.h" // ATA_CB_STAT
+#include "blockcmd.h" // CDB_CMD_READ_10
#define IDE_TIMEOUT 32000 //32 seconds max for IDE ops
if ((status & mask) == flags)
return status;
if (check_time(end)) {
- dprintf(1, "IDE time out\n");
+ warn_timeout();
return -1;
}
yield();
break;
// Change drive request failed to take effect - retry.
if (check_time(end)) {
- dprintf(1, "ata_reset slave time out\n");
+ warn_timeout();
goto done;
}
}
static int
ata_try_dma(struct disk_op_s *op, int iswrite, int blocksize)
{
+ if (! CONFIG_ATA_DMA)
+ return -1;
u32 dest = (u32)op->buf_fl;
if (dest & 1)
// Need minimum alignment of 1.
static int
ata_dma_transfer(struct disk_op_s *op)
{
+ if (! CONFIG_ATA_DMA)
+ return -1;
dprintf(16, "ata_dma_transfer id=%p buf=%p\n"
, op->drive_g, op->buf_fl);
// Transfer in progress
if (check_time(end)) {
// Timeout.
- dprintf(1, "IDE DMA timeout\n");
+ warn_timeout();
break;
}
yield();
static int
ata_dma_cmd_data(struct disk_op_s *op, struct ata_pio_command *cmd)
{
+ if (! CONFIG_ATA_DMA)
+ return -1;
int ret = send_cmd(op->drive_g, cmd);
if (ret)
return ret;
* ATAPI functions
****************************************************************/
+#define CDROM_CDB_SIZE 12
+
// Low-level atapi command transmit function.
-static int
-atapi_cmd_data(struct disk_op_s *op, u8 *cmdbuf, u8 cmdlen, u16 blocksize)
+int
+atapi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize)
{
u8 ataid = GET_GLOBAL(op->drive_g->cntl_id);
u8 channel = ataid / 2;
goto fail;
// Send command to device
- outsw_fl(iobase1, MAKE_FLATPTR(GET_SEG(SS), cmdbuf), cmdlen / 2);
+ outsw_fl(iobase1, MAKE_FLATPTR(GET_SEG(SS), cdbcmd), CDROM_CDB_SIZE / 2);
int status = pause_await_not_bsy(iobase1, iobase2);
if (status < 0) {
fail:
// Enable interrupts
outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
- return ret;
-}
-
-// Read sectors from the cdrom.
-int
-cdrom_read(struct disk_op_s *op)
-{
- u8 atacmd[12];
- memset(atacmd, 0, sizeof(atacmd));
- atacmd[0]=0x28; // READ command
- atacmd[7]=(op->count & 0xff00) >> 8; // Sectors
- atacmd[8]=(op->count & 0x00ff);
- atacmd[2]=(op->lba & 0xff000000) >> 24; // LBA
- atacmd[3]=(op->lba & 0x00ff0000) >> 16;
- atacmd[4]=(op->lba & 0x0000ff00) >> 8;
- atacmd[5]=(op->lba & 0x000000ff);
-
- return atapi_cmd_data(op, atacmd, sizeof(atacmd), CDROM_SECTOR_SIZE);
+ if (ret)
+ return DISK_RET_EBADTRACK;
+ return DISK_RET_SUCCESS;
}
// 16bit command demuxer for ATAPI cdroms.
int
process_atapi_op(struct disk_op_s *op)
{
- int ret;
switch (op->command) {
case CMD_READ:
- ret = cdrom_read(op);
- if (ret)
- return DISK_RET_EBADTRACK;
- return DISK_RET_SUCCESS;
+ return cdb_read(op);
case CMD_FORMAT:
case CMD_WRITE:
return DISK_RET_EWRITEPROTECT;
}
}
-// Send a simple atapi command to a drive.
-int
-ata_cmd_packet(struct drive_s *drive_g, u8 *cmdbuf, u8 cmdlen
- , u32 length, void *buf_fl)
-{
- struct disk_op_s dop;
- memset(&dop, 0, sizeof(dop));
- dop.drive_g = drive_g;
- dop.count = 1;
- dop.buf_fl = buf_fl;
-
- return atapi_cmd_data(&dop, cmdbuf, cmdlen, length);
-}
-
/****************************************************************
* ATA detect and init
return NULL;
// Success - setup as ATAPI.
- struct drive_s *drive_g = allocDrive();
- if (! drive_g)
+ struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g));
+ if (! drive_g) {
+ warn_noalloc();
return NULL;
+ }
+ memset(drive_g, 0, sizeof(*drive_g));
SET_GLOBAL(drive_g->cntl_id, dummy->cntl_id);
extract_identify(drive_g, buffer);
SET_GLOBAL(drive_g->type, DTYPE_ATAPI);
return NULL;
// Success - setup as ATA.
- struct drive_s *drive_g = allocDrive();
- if (! drive_g)
+ struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g));
+ if (! drive_g) {
+ warn_noalloc();
return NULL;
+ }
+ memset(drive_g, 0, sizeof(*drive_g));
SET_GLOBAL(drive_g->cntl_id, dummy->cntl_id);
extract_identify(drive_g, buffer);
SET_GLOBAL(drive_g->type, DTYPE_ATA);
return orstatus;
}
if (check_time(SpinupEnd)) {
- dprintf(1, "powerup IDE time out\n");
+ warn_timeout();
return -1;
}
yield();
u8 pciirq = pci_config_readb(bdf, PCI_INTERRUPT_LINE);
u8 prog_if = pci_config_readb(bdf, PCI_CLASS_PROG);
int master = 0;
- if (prog_if & 0x80) {
+ if (CONFIG_ATA_DMA && prog_if & 0x80) {
// Check for bus-mastering.
u32 bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_4);
if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
void
ata_setup(void)
{
+ ASSERT32FLAT();
if (!CONFIG_ATA)
return;