fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 1086 lines 22 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/devices/ata.c * 7 * Created: 2004-12-03 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2004-2018 Hampa Hug <hampa@hampa.ch> * 9 *****************************************************************************/ 10 11/***************************************************************************** 12 * This program is free software. You can redistribute it and / or modify it * 13 * under the terms of the GNU General Public License version 2 as published * 14 * by the Free Software Foundation. * 15 * * 16 * This program is distributed in the hope that it will be useful, but * 17 * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 * Public License for more details. * 20 *****************************************************************************/ 21 22 23#include <stdio.h> 24#include <stdlib.h> 25#include <string.h> 26 27#include "ata.h" 28 29 30#ifndef DEBUG_ATA 31#define DEBUG_ATA 0 32#endif 33 34 35#define ATA_REG_COMMAND 0x07 36#define ATA_REG_STATUS 0x07 37#define ATA_REG_DEVICE_HEAD 0x06 38#define ATA_REG_CYLINDER_HIGH 0x05 39#define ATA_REG_CYLINDER_LOW 0x04 40#define ATA_REG_SECTOR_NUMBER 0x03 41#define ATA_REG_SECTOR_COUNT 0x02 42#define ATA_REG_ERROR 0x01 43#define ATA_REG_FEATURES 0x01 44#define ATA_REG_DATA 0x00 45 46#define ATA_STATUS_BSY 0x80 47#define ATA_STATUS_DRDY 0x40 48#define ATA_STATUS_DF 0x20 49#define ATA_STATUS_DSC 0x10 50#define ATA_STATUS_DRQ 0x08 51#define ATA_STATUS_CORR 0x04 52#define ATA_STATUS_IDX 0x02 53#define ATA_STATUS_ERR 0x01 54 55#define ATA_ERROR_UNC 0x40 56#define ATA_ERROR_MC 0x20 57#define ATA_ERROR_IDNF 0x10 58#define ATA_ERROR_MCR 0x08 59#define ATA_ERROR_ABRT 0x04 60#define ATA_ERROR_TK0NF 0x02 61#define ATA_ERROR_AMNF 0x01 62 63#define ATA_BUF_MODE_NONE 0 64#define ATA_BUF_MODE_READ 1 65#define ATA_BUF_MODE_WRITE 2 66 67#define ATA_CMD_RECALIBRATE 0x10 68#define ATA_CMD_READ 0x20 69#define ATA_CMD_READ_RETRY 0x21 70#define ATA_CMD_WRITE 0x30 71#define ATA_CMD_WRITE_RETRY 0x31 72#define ATA_CMD_DIAGNOSTIC 0x90 73#define ATA_CMD_SET_GEOMETRY 0x91 74#define ATA_CMD_STANDBY_IMMEDIATE1 0x94 75#define ATA_CMD_READ_MULTIPLE 0xc4 76#define ATA_CMD_WRITE_MULTIPLE 0xc5 77#define ATA_CMD_SET_MULTIPLE_MODE 0xc6 78#define ATA_CMD_STANDBY_IMMEDIATE2 0xe0 79#define ATA_CMD_FLUSH_CACHE 0xe7 80#define ATA_CMD_IDENTIFY 0xec 81 82 83unsigned char ata_ctl_get_uint8 (ata_chn_t *ata, unsigned long addr); 84unsigned short ata_ctl_get_uint16 (ata_chn_t *ata, unsigned long addr); 85unsigned long ata_ctl_get_uint32 (ata_chn_t *ata, unsigned long addr); 86 87void ata_ctl_set_uint8 (ata_chn_t *ata, unsigned long addr, unsigned char val); 88void ata_ctl_set_uint16 (ata_chn_t *ata, unsigned long addr, unsigned short val); 89void ata_ctl_set_uint32 (ata_chn_t *ata, unsigned long addr, unsigned long val); 90 91 92void ata_dev_init (ata_dev_t *dev) 93{ 94 static unsigned serial = 0; 95 96 dev->chn = NULL; 97 98 dev->blk = NULL; 99 100 dev->reg_cmd = 0; 101 dev->reg_status = ATA_STATUS_DRDY | ATA_STATUS_DSC; 102 dev->reg_features = 0; 103 dev->reg_error = 0; 104 dev->reg_cyl_lo = 0; 105 dev->reg_cyl_hi = 0; 106 dev->reg_head = 0; 107 dev->reg_sec = 0; 108 dev->reg_sec_cnt = 0; 109 dev->reg_dev_ctl = 0; 110 111 dev->c = 0; 112 dev->h = 0; 113 dev->s = 0; 114 115 dev->default_c = 0; 116 dev->default_h = 0; 117 dev->default_s = 0; 118 119 dev->multi_block_max = 0; 120 dev->multi_block_size = 0; 121 122 dev->buf_i = 0; 123 dev->buf_n = 0; 124 dev->buf_m = 0; 125 dev->buf_mult_i = 0; 126 dev->buf_mult_n = 0; 127 dev->buf_mode = ATA_BUF_MODE_NONE; 128 dev->callback = NULL; 129 130 strcpy (dev->model, "PCEDISK"); 131 strcpy (dev->firmware, "0"); 132 sprintf (dev->serial, "PD%u", serial); 133 serial += 1; 134} 135 136void ata_dev_free (ata_dev_t *dev) 137{ 138} 139 140 141void ata_init (ata_chn_t *ata, unsigned long addr1, unsigned long addr2) 142{ 143 mem_blk_init (&ata->reg_cmd, addr1, 8, 0); 144 ata->reg_cmd.ext = ata; 145 ata->reg_cmd.get_uint8 = (mem_get_uint8_f) ata_cmd_get_uint8; 146 ata->reg_cmd.get_uint16 = (mem_get_uint16_f) ata_cmd_get_uint16; 147 ata->reg_cmd.get_uint32 = (mem_get_uint32_f) ata_cmd_get_uint32; 148 ata->reg_cmd.set_uint8 = (mem_set_uint8_f) ata_cmd_set_uint8; 149 ata->reg_cmd.set_uint16 = (mem_set_uint16_f) ata_cmd_set_uint16; 150 ata->reg_cmd.set_uint32 = (mem_set_uint32_f) ata_cmd_set_uint32; 151 152 mem_blk_init (&ata->reg_ctl, addr2, 4, 0); 153 ata->reg_ctl.ext = ata; 154 ata->reg_ctl.get_uint8 = (mem_get_uint8_f) ata_ctl_get_uint8; 155 ata->reg_ctl.get_uint16 = (mem_get_uint16_f) ata_ctl_get_uint16; 156 ata->reg_ctl.get_uint32 = (mem_get_uint32_f) ata_ctl_get_uint32; 157 ata->reg_ctl.set_uint8 = (mem_set_uint8_f) ata_ctl_set_uint8; 158 ata->reg_ctl.set_uint16 = (mem_set_uint16_f) ata_ctl_set_uint16; 159 ata->reg_ctl.set_uint32 = (mem_set_uint32_f) ata_ctl_set_uint32; 160 161 ata->irq_val = 0; 162 ata->irq_ext = 0; 163 ata->irq = NULL; 164 165 ata_dev_init (&ata->dev[0]); 166 ata_dev_init (&ata->dev[1]); 167 168 ata->dev[0].chn = ata; 169 ata->dev[1].chn = ata; 170 171 ata->sel = &ata->dev[0]; 172} 173 174void ata_free (ata_chn_t *ata) 175{ 176 ata_dev_free (&ata->dev[1]); 177 ata_dev_free (&ata->dev[0]); 178 179 mem_blk_free (&ata->reg_ctl); 180 mem_blk_free (&ata->reg_cmd); 181} 182 183ata_chn_t *ata_new (unsigned long addr1, unsigned long addr2) 184{ 185 ata_chn_t *ata; 186 187 ata = malloc (sizeof (ata_chn_t)); 188 if (ata == NULL) { 189 return (NULL); 190 } 191 192 ata_init (ata, addr1, addr2); 193 194 return (ata); 195} 196 197void ata_del (ata_chn_t *ata) 198{ 199 if (ata != NULL) { 200 ata_free (ata); 201 free (ata); 202 } 203} 204 205void ata_set_irq_f (ata_chn_t *ata, void *irq, void *ext) 206{ 207 ata->irq = irq; 208 ata->irq_ext = ext; 209} 210 211void ata_set_block (ata_chn_t *ata, disk_t *blk, unsigned devi) 212{ 213 ata_dev_t *dev; 214 215 if (devi >= 2) { 216 return; 217 } 218 219 dev = &ata->dev[devi]; 220 221 dev->blk = blk; 222 223 dev->default_c = blk->c; 224 dev->default_h = blk->h; 225 dev->default_s = blk->s; 226 227 if (dev->default_h > 16) { 228 dev->default_s = 63; 229 dev->default_h = 16; 230 dev->default_c = dsk_get_block_cnt (blk) / (16UL * 63UL); 231 } 232 233 dev->c = dev->default_c; 234 dev->h = dev->default_h; 235 dev->s = dev->default_s; 236} 237 238void ata_set_model (ata_chn_t *ata, unsigned devi, const char *name) 239{ 240 char *dst; 241 242 if (devi < 2) { 243 dst = ata->dev[devi].model; 244 strncpy (dst, name, 64); 245 dst[63] = 0; 246 } 247} 248 249void ata_set_multi_mode (ata_chn_t *ata, unsigned devi, unsigned max) 250{ 251 if (max > 255) { 252 max = 255; 253 } 254 255 if (devi < 2) { 256 ata->dev[devi].multi_block_max = max; 257 } 258} 259 260static 261void ata_set_irq (ata_chn_t *ata, unsigned char val) 262{ 263 if (ata->sel->reg_dev_ctl & 0x02) { 264 return; 265 } 266 267 val = (val != 0); 268 269 if (val != ata->irq_val) { 270#if DEBUG_ATA >= 3 271 fprintf (stderr, "ata: irq = %d\n", val); 272#endif 273 274 ata->irq_val = val; 275 276 if (ata->irq != NULL) { 277 ata->irq (ata->irq_ext, val); 278 } 279 } 280} 281 282static inline 283unsigned short ata_get_uint16_le (void *buf, unsigned i) 284{ 285 unsigned short val; 286 unsigned char *tmp = (unsigned char *) buf + i; 287 288 val = tmp[1]; 289 val = (val << 8) | tmp[0]; 290 291 return (val); 292} 293 294static inline 295void ata_set_uint16_le (void *buf, unsigned i, unsigned short val) 296{ 297 unsigned char *tmp = (unsigned char *) buf + i; 298 299 tmp[0] = val & 0xff; 300 tmp[1] = (val >> 8) & 0xff; 301} 302 303static 304void ata_set_string (void *buf, unsigned i, const char *str, unsigned cnt) 305{ 306 unsigned char *tmp = (unsigned char *) buf + i; 307 unsigned char c1, c2; 308 309 while (cnt >= 2) { 310 c1 = (*str == 0) ? ' ' : *(str++); 311 c2 = (*str == 0) ? ' ' : *(str++); 312 313 tmp[0] = c2; 314 tmp[1] = c1; 315 316 tmp += 2; 317 cnt -= 2; 318 } 319 320 if (cnt > 0) { 321 c1 = (*str == 0) ? ' ' : *(str++); 322 tmp[1] = c1; 323 } 324} 325 326 327/* Get the current sector address as LBA */ 328static 329int ata_get_lba (ata_dev_t *dev, uint32_t *lba) 330{ 331 uint32_t c, h, s; 332 333 if (dev->reg_head & 0x40) { 334 *lba = dev->reg_head & 0x0f; 335 *lba = (*lba << 8) | dev->reg_cyl_hi; 336 *lba = (*lba << 8) | dev->reg_cyl_lo; 337 *lba = (*lba << 8) | dev->reg_sec; 338 } 339 else { 340 c = (dev->reg_cyl_hi << 8) | dev->reg_cyl_lo; 341 h = dev->reg_head & 0x0f; 342 s = dev->reg_sec; 343 344 if ((c >= dev->c) || (h >= dev->h) || (s == 0) || (s > dev->s)) { 345 return (1); 346 } 347 348 *lba = (c * dev->h + h) * dev->s + s - 1; 349 } 350 351 return (0); 352} 353 354 355static 356void ata_cmd_ok (ata_dev_t *dev) 357{ 358 dev->reg_status = ATA_STATUS_DRDY | ATA_STATUS_DSC; 359 ata_set_irq (dev->chn, 1); 360} 361 362static 363void ata_cmd_abort (ata_dev_t *dev) 364{ 365 dev->reg_status = ATA_STATUS_DRDY | ATA_STATUS_ERR; 366 dev->reg_error = ATA_ERROR_ABRT; 367 ata_set_irq (dev->chn, 1); 368} 369 370static 371void ata_cmd_recalibrate (ata_dev_t *dev) 372{ 373#if DEBUG_ATA >= 1 374 fprintf (stderr, "ata: RECALIBRATE\n"); 375#endif 376 377 dev->reg_cyl_lo = 0; 378 dev->reg_cyl_hi = 0; 379 dev->reg_head &= 0xf0; 380 dev->reg_sec = (dev->reg_head & 0x40) ? 0 : 1; 381 ata_cmd_ok (dev); 382} 383 384static 385void ata_buf_reset (ata_dev_t *dev) 386{ 387 dev->buf_i = 0; 388 dev->buf_n = 0; 389 dev->buf_m = 0; 390 391 dev->buf_blk_i = 0; 392 dev->buf_blk_n = 0; 393 394 dev->buf_mult_i = 0; 395 dev->buf_mult_n = 0; 396 397 dev->buf_mode = ATA_BUF_MODE_NONE; 398} 399 400static 401void ata_cmd_read_cb (ata_dev_t *dev) 402{ 403 unsigned cnt; 404 405 /* move to next sector in buffer */ 406 dev->buf_i = dev->buf_n; 407 dev->buf_n += 512; 408 409 if (dev->buf_n > dev->buf_m) { 410 if (dev->buf_blk_n == 0) { 411 /* all done */ 412 ata_buf_reset (dev); 413 414 dev->reg_status = ATA_STATUS_DRDY | ATA_STATUS_DSC; 415 dev->callback = NULL; 416 return; 417 } 418 419 cnt = ATA_BUF_MAX / 512; 420 if (cnt > dev->buf_blk_n) { 421 cnt = dev->buf_blk_n; 422 } 423 424 while (dsk_read_lba (dev->blk, dev->buf, dev->buf_blk_i, cnt)) { 425 if (cnt == 1) { 426 ata_cmd_abort (dev); 427 return; 428 } 429 cnt = 1; 430 } 431 432 dev->buf_m = 512 * cnt; 433 434 dev->buf_blk_i += cnt; 435 dev->buf_blk_n -= cnt; 436 437 dev->buf_i = 0; 438 dev->buf_n = 512; 439 } 440 441 dev->buf_mode = ATA_BUF_MODE_READ; 442 dev->reg_status = ATA_STATUS_DRDY | ATA_STATUS_DRQ | ATA_STATUS_DSC; 443 444 dev->buf_mult_i += 1; 445 446 if (dev->buf_mult_i >= dev->buf_mult_n) { 447 dev->buf_mult_i = 0; 448 ata_set_irq (dev->chn, 1); 449 } 450} 451 452static 453void ata_cmd_read (ata_dev_t *dev) 454{ 455 uint32_t idx; 456 457 if (ata_get_lba (dev, &idx)) { 458 ata_cmd_abort (dev); 459 return; 460 } 461 462#if DEBUG_ATA >= 2 463 fprintf (stderr, "ata: READ (%lu, %u)\n", 464 (unsigned long) idx, dev->reg_sec_cnt 465 ); 466#endif 467 468 ata_buf_reset (dev); 469 470 dev->buf_blk_i = idx; 471 dev->buf_blk_n = (dev->reg_sec_cnt == 0) ? 256 : dev->reg_sec_cnt; 472 dev->callback = ata_cmd_read_cb; 473 474 ata_cmd_read_cb (dev); 475} 476 477static 478void ata_cmd_read_multiple (ata_dev_t *dev) 479{ 480 uint32_t idx; 481 482 if (dev->multi_block_size == 0) { 483 ata_cmd_abort (dev); 484 return; 485 } 486 487 if (ata_get_lba (dev, &idx)) { 488 ata_cmd_abort (dev); 489 return; 490 } 491 492#if DEBUG_ATA >= 2 493 fprintf (stderr, "ata: READ MULTIPLE (%lu, %u)\n", 494 (unsigned long) idx, dev->reg_sec_cnt 495 ); 496#endif 497 498 ata_buf_reset (dev); 499 500 dev->buf_blk_i = idx; 501 dev->buf_blk_n = (dev->reg_sec_cnt == 0) ? 256 : dev->reg_sec_cnt; 502 dev->buf_mult_n = dev->multi_block_size; 503 dev->buf_mult_i = dev->buf_mult_n; 504 dev->callback = ata_cmd_read_cb; 505 506 ata_cmd_read_cb (dev); 507} 508 509static 510void ata_cmd_write_cb (ata_dev_t *dev) 511{ 512 unsigned cnt; 513 514 dev->buf_i = dev->buf_n; 515 dev->buf_n += 512; 516 517 if (dev->buf_n > dev->buf_m) { 518 cnt = dev->buf_i / 512; 519 520 if (dsk_write_lba (dev->blk, dev->buf, dev->buf_blk_i, cnt)) { 521 ata_cmd_abort (dev); 522 return; 523 } 524 525 dev->buf_blk_i += cnt; 526 dev->buf_blk_n -= cnt; 527 528 if (dev->buf_blk_n == 0) { 529 ata_buf_reset (dev); 530 dev->callback = NULL; 531 dev->reg_status = ATA_STATUS_DRDY | ATA_STATUS_DSC; 532 ata_set_irq (dev->chn, 1); 533 return; 534 } 535 else { 536 cnt = ATA_BUF_MAX / 512; 537 if (cnt > dev->buf_blk_n) { 538 cnt = dev->buf_blk_n; 539 } 540 dev->buf_i = 0; 541 dev->buf_n = 512; 542 dev->buf_m = 512 * cnt; 543 dev->buf_mode = ATA_BUF_MODE_WRITE; 544 dev->reg_status = ATA_STATUS_DRDY | ATA_STATUS_DRQ | ATA_STATUS_DSC; 545 } 546 } 547 548 dev->buf_mult_i += 1; 549 550 if (dev->buf_mult_i >= dev->buf_mult_n) { 551 dev->buf_mult_i = 0; 552 ata_set_irq (dev->chn, 1); 553 } 554} 555 556static 557void ata_cmd_write (ata_dev_t *dev) 558{ 559 unsigned cnt; 560 uint32_t idx; 561 562 if (ata_get_lba (dev, &idx)) { 563 ata_cmd_abort (dev); 564 return; 565 } 566 567#if DEBUG_ATA >= 2 568 fprintf (stderr, "ata: WRITE (%lu, %u)\n", 569 (unsigned long) idx, dev->reg_sec_cnt 570 ); 571#endif 572 573 ata_buf_reset (dev); 574 575 dev->buf_i = 0; 576 dev->buf_n = 512; 577 578 dev->buf_mode = ATA_BUF_MODE_WRITE; 579 580 dev->buf_blk_i = idx; 581 dev->buf_blk_n = (dev->reg_sec_cnt == 0) ? 256 : dev->reg_sec_cnt; 582 583 dev->callback = ata_cmd_write_cb; 584 585 cnt = ATA_BUF_MAX / 512; 586 if (cnt > dev->buf_blk_n) { 587 cnt = dev->buf_blk_n; 588 } 589 590 dev->buf_m = 512 * cnt; 591 592 dev->reg_status = ATA_STATUS_DRDY | ATA_STATUS_DRQ | ATA_STATUS_DSC; 593} 594 595static 596void ata_cmd_write_multiple (ata_dev_t *dev) 597{ 598 unsigned cnt; 599 uint32_t idx; 600 601 if (ata_get_lba (dev, &idx)) { 602 ata_cmd_abort (dev); 603 return; 604 } 605 606#if DEBUG_ATA >= 2 607 fprintf (stderr, "ata: WRITE MULTIPLE (%lu, %u)\n", 608 (unsigned long) idx, dev->reg_sec_cnt 609 ); 610#endif 611 612 ata_buf_reset (dev); 613 614 dev->buf_i = 0; 615 dev->buf_n = 512; 616 617 dev->buf_mode = ATA_BUF_MODE_WRITE; 618 619 dev->buf_blk_i = idx; 620 dev->buf_blk_n = (dev->reg_sec_cnt == 0) ? 256 : dev->reg_sec_cnt; 621 dev->buf_mult_i = 0; 622 dev->buf_mult_n = dev->multi_block_size; 623 624 dev->callback = ata_cmd_write_cb; 625 626 cnt = ATA_BUF_MAX / 512; 627 if (cnt > dev->buf_blk_n) { 628 cnt = dev->buf_blk_n; 629 } 630 631 dev->buf_m = 512 * cnt; 632 633 dev->reg_status = ATA_STATUS_DRDY | ATA_STATUS_DRQ | ATA_STATUS_DSC; 634} 635 636static 637void ata_cmd_set_multiple_mode (ata_dev_t *dev) 638{ 639 unsigned cnt; 640 641#if DEBUG_ATA >= 1 642 fprintf (stderr, "ata: SET MULTIPLE MODE (%u)\n", 643 dev->reg_sec_cnt 644 ); 645#endif 646 647 cnt = dev->reg_sec_cnt; 648 649 if (cnt > dev->multi_block_max) { 650 ata_cmd_abort (dev); 651 return; 652 } 653 654 dev->multi_block_size = cnt; 655 656 ata_cmd_ok (dev); 657} 658 659static 660void ata_cmd_device_diagnostic (ata_chn_t *ata) 661{ 662 unsigned i; 663 664#if DEBUG_ATA >= 1 665 fprintf (stderr, "ata: DEVICE DIAGNOSTIC\n"); 666#endif 667 668 for (i = 0; i < 2; i++) { 669 ata->dev[i].reg_cyl_lo = 0; 670 ata->dev[i].reg_cyl_hi = 0; 671 ata->dev[i].reg_sec = 1; 672 ata->dev[i].reg_sec_cnt = 1; 673 ata->dev[i].reg_head = 0; 674 ata->dev[i].reg_error = 0x01; 675 ata->dev[i].reg_status = ATA_STATUS_DRDY | ATA_STATUS_DSC; 676 } 677 678 ata->sel = &ata->dev[0]; 679} 680 681static 682void ata_cmd_set_geometry (ata_dev_t *dev) 683{ 684 dev->s = (dev->reg_sec_cnt == 0) ? 256 : dev->reg_sec_cnt; 685 dev->h = (dev->reg_head & 0x0f) + 1; 686 dev->c = dsk_get_block_cnt (dev->blk) / ((uint32_t) dev->s * dev->h); 687 688#if DEBUG_ATA >= 1 689 fprintf (stderr, "ata: SET GEOMETRY (%u / %u / %u)\n", 690 dev->c, dev->h, dev->s 691 ); 692#endif 693 694 ata_cmd_ok (dev); 695} 696 697static 698void ata_cmd_standby_immediate (ata_dev_t *dev) 699{ 700#if DEBUG_ATA >= 1 701 fprintf (stderr, "ata: STANDBY IMMEDIATE\n"); 702#endif 703 704 ata_cmd_ok (dev); 705} 706 707static 708void ata_cmd_flush_cache (ata_dev_t *dev) 709{ 710#if DEBUG_ATA >= 1 711 fprintf (stderr, "ata: FLUSH CACHE\n"); 712#endif 713 714 ata_cmd_ok (dev); 715} 716 717static 718void ata_cmd_identify (ata_dev_t *dev) 719{ 720 uint32_t cnt1, cnt2; 721 722#if DEBUG_ATA >= 1 723 fprintf (stderr, "ata: IDENTIFY\n"); 724#endif 725 726 memset (dev->buf, 0, 512); 727 728 cnt1 = dev->c * dev->h * dev->s; 729 cnt2 = dsk_get_block_cnt (dev->blk); 730 731 ata_set_uint16_le (dev->buf, 2 * 0, 0x0040); 732 ata_set_uint16_le (dev->buf, 2 * 1, dev->default_c); 733 ata_set_uint16_le (dev->buf, 2 * 3, dev->default_h); 734 ata_set_uint16_le (dev->buf, 2 * 6, dev->default_s); 735 ata_set_string (dev->buf, 2 * 10, dev->serial, 20); 736 ata_set_uint16_le (dev->buf, 2 * 22, 0x0000); /* vendor specific bytes */ 737 ata_set_string (dev->buf, 2 * 23, dev->firmware, 8); 738 ata_set_string (dev->buf, 2 * 27, dev->model, 40); 739 ata_set_uint16_le (dev->buf, 2 * 47, dev->multi_block_max & 0xff); 740 ata_set_uint16_le (dev->buf, 2 * 49, 0x0200); /* lba */ 741 ata_set_uint16_le (dev->buf, 2 * 53, 0x0001); 742 ata_set_uint16_le (dev->buf, 2 * 54, dev->c); 743 ata_set_uint16_le (dev->buf, 2 * 55, dev->h); 744 ata_set_uint16_le (dev->buf, 2 * 56, dev->s); 745 ata_set_uint16_le (dev->buf, 2 * 57, cnt1 & 0xffff); 746 ata_set_uint16_le (dev->buf, 2 * 58, (cnt1 >> 16) & 0xffff); 747 ata_set_uint16_le (dev->buf, 2 * 60, cnt2 & 0xffff); 748 ata_set_uint16_le (dev->buf, 2 * 61, (cnt2 >> 16) & 0xffff); 749 750 dev->buf_i = 0; 751 dev->buf_n = 512; 752 dev->buf_mode = ATA_BUF_MODE_READ; 753 dev->callback = NULL; 754 755 dev->reg_status = ATA_STATUS_DRQ | 0x50; 756 757 ata_set_irq (dev->chn, 1); 758} 759 760static 761void ata_command (ata_chn_t *ata, unsigned cmd) 762{ 763 if (ata->sel->blk == NULL) { 764 ata_cmd_abort (ata->sel); 765 return; 766 } 767 768 switch (cmd) { 769 case ATA_CMD_RECALIBRATE: 770 ata_cmd_recalibrate (ata->sel); 771 break; 772 773 case ATA_CMD_READ: 774 case ATA_CMD_READ_RETRY: 775 ata_cmd_read (ata->sel); 776 break; 777 778 case ATA_CMD_READ_MULTIPLE: 779 ata_cmd_read_multiple (ata->sel); 780 break; 781 782 case ATA_CMD_WRITE: 783 case ATA_CMD_WRITE_RETRY: 784 ata_cmd_write (ata->sel); 785 break; 786 787 case ATA_CMD_WRITE_MULTIPLE: 788 ata_cmd_write_multiple (ata->sel); 789 break; 790 791 case ATA_CMD_SET_MULTIPLE_MODE: 792 ata_cmd_set_multiple_mode (ata->sel); 793 break; 794 795 case ATA_CMD_DIAGNOSTIC: 796 ata_cmd_device_diagnostic (ata); 797 break; 798 799 case ATA_CMD_SET_GEOMETRY: 800 ata_cmd_set_geometry (ata->sel); 801 break; 802 803 case ATA_CMD_STANDBY_IMMEDIATE1: 804 case ATA_CMD_STANDBY_IMMEDIATE2: 805 ata_cmd_standby_immediate (ata->sel); 806 break; 807 808 case ATA_CMD_FLUSH_CACHE: 809 ata_cmd_flush_cache (ata->sel); 810 break; 811 812 case ATA_CMD_IDENTIFY: 813 ata_cmd_identify (ata->sel); 814 break; 815 816 default: 817 fprintf (stderr, "ata: unknown command (%02X)\n", cmd); 818 fflush (stderr); 819 ata_cmd_abort (ata->sel); 820 break; 821 } 822} 823 824static 825unsigned short ata_get_data16 (ata_chn_t *ata) 826{ 827 unsigned short val; 828 ata_dev_t *sel; 829 830 sel = ata->sel; 831 832 if (sel->buf_mode != ATA_BUF_MODE_READ) { 833 return (0); 834 } 835 836 val = ata_get_uint16_le (sel->buf, sel->buf_i); 837 838 sel->buf_i += 2; 839 if (sel->buf_i >= sel->buf_n) { 840 if (sel->callback != NULL) { 841 sel->callback (sel); 842 } 843 else { 844 sel->buf_i = 0; 845 sel->buf_n = 0; 846 sel->buf_m = 0; 847 sel->buf_mode = ATA_BUF_MODE_NONE; 848 sel->reg_status = ATA_STATUS_DRDY | ATA_STATUS_DSC; 849 } 850 } 851 852 return (val); 853} 854 855unsigned char ata_cmd_get_uint8 (ata_chn_t *ata, unsigned long addr) 856{ 857 ata_dev_t *sel; 858 unsigned char val; 859 860 sel = ata->sel; 861 862 if (sel->blk == NULL) { 863 return (0x00); 864 } 865 866 switch (addr) { 867 case 0x00: /* data */ 868 val = 0; 869 break; 870 871 case 0x01: /* error */ 872 val = sel->reg_error; 873 break; 874 875 case 0x02: /* sector count */ 876 val = sel->reg_sec_cnt; 877 break; 878 879 case 0x03: /* sector number */ 880 val = sel->reg_sec; 881 break; 882 883 case 0x04: /* cylinder low */ 884 val = sel->reg_cyl_lo; 885 break; 886 887 case 0x05: /* cylinder high */ 888 val = sel->reg_cyl_hi; 889 break; 890 891 case 0x06: /* device / head */ 892 val = sel->reg_head; 893 break; 894 895 case 0x07: /* status */ 896 ata_set_irq (ata, 0); 897 val = sel->reg_status; 898 break; 899 900 default: 901 val = 0xff; 902 break; 903 } 904 905#if DEBUG_ATA >= 2 906 fprintf (stderr, "ata: get8 %08lX -> %02X\n", addr, val); 907 fflush (stderr); 908#endif 909 910 return (val); 911} 912 913unsigned short ata_cmd_get_uint16 (ata_chn_t *ata, unsigned long addr) 914{ 915 if (addr == 0) { 916 return (ata_get_data16 (ata)); 917 } 918 919 return (ata_cmd_get_uint8 (ata, addr)); 920} 921 922unsigned long ata_cmd_get_uint32 (ata_chn_t *ata, unsigned long addr) 923{ 924 return (ata_cmd_get_uint8 (ata, addr)); 925} 926 927static 928void ata_set_data16 (ata_chn_t *ata, unsigned short val) 929{ 930 ata_dev_t *sel; 931 932 sel = ata->sel; 933 934 if (sel->buf_mode != ATA_BUF_MODE_WRITE) { 935 return; 936 } 937 938 ata_set_uint16_le (sel->buf, sel->buf_i, val); 939 940 sel->buf_i += 2; 941 if (sel->buf_i >= sel->buf_n) { 942 if (sel->callback != NULL) { 943 sel->callback (sel); 944 } 945 else { 946 ata_buf_reset (sel); 947 sel->reg_status = ATA_STATUS_DRDY | ATA_STATUS_DSC; 948 } 949 } 950} 951 952void ata_cmd_set_uint8 (ata_chn_t *ata, unsigned long addr, unsigned char val) 953{ 954#if DEBUG_ATA >= 2 955 fprintf (stderr, "ata: set8 %08lX <- %02X\n", addr, val); 956 fflush (stderr); 957#endif 958 959 switch (addr) { 960 case 0x00: /* data */ 961 break; 962 963 case 0x01: /* features */ 964 ata->dev[0].reg_features = val; 965 ata->dev[1].reg_features = val; 966 break; 967 968 case 0x02: /* sector count */ 969 ata->dev[0].reg_sec_cnt = val; 970 ata->dev[1].reg_sec_cnt = val; 971 break; 972 973 case 0x03: /* sector number */ 974 ata->dev[0].reg_sec = val; 975 ata->dev[1].reg_sec = val; 976 break; 977 978 case 0x04: /* cylinder low */ 979 ata->dev[0].reg_cyl_lo = val; 980 ata->dev[1].reg_cyl_lo = val; 981 break; 982 983 case 0x05: /* cylinder high */ 984 ata->dev[0].reg_cyl_hi = val; 985 ata->dev[1].reg_cyl_hi = val; 986 break; 987 988 case 0x06: /* device / head */ 989 ata->dev[0].reg_head = val; 990 ata->dev[1].reg_head = val; 991 ata->sel = &ata->dev[(val & 0x10) ? 1 : 0]; 992 break; 993 994 case 0x07: /* command */ 995 ata_command (ata, val); 996 break; 997 } 998} 999 1000void ata_cmd_set_uint16 (ata_chn_t *ata, unsigned long addr, unsigned short val) 1001{ 1002 if (addr == 0) { 1003 ata_set_data16 (ata, val); 1004 } 1005} 1006 1007void ata_cmd_set_uint32 (ata_chn_t *ata, unsigned long addr, unsigned long val) 1008{ 1009} 1010 1011 1012unsigned char ata_ctl_get_uint8 (ata_chn_t *ata, unsigned long addr) 1013{ 1014 unsigned char val; 1015 1016 switch (addr) { 1017 case 0x02: /* alternate status */ 1018 val = ata->sel->reg_status; 1019 break; 1020 1021 default: 1022 val = 0; 1023 break; 1024 } 1025 1026#if DEBUG_ATA >= 2 1027 fprintf (stderr, "ata: get ctl8 %08lX -> %02X\n", addr, val); 1028 fflush (stderr); 1029#endif 1030 1031 return (val); 1032} 1033 1034unsigned short ata_ctl_get_uint16 (ata_chn_t *ata, unsigned long addr) 1035{ 1036 return (ata_ctl_get_uint8 (ata, addr)); 1037} 1038 1039unsigned long ata_ctl_get_uint32 (ata_chn_t *ata, unsigned long addr) 1040{ 1041 return (ata_ctl_get_uint8 (ata, addr)); 1042} 1043 1044void ata_ctl_set_uint8 (ata_chn_t *ata, unsigned long addr, unsigned char val) 1045{ 1046#if DEBUG_ATA >= 2 1047 fprintf (stderr, "ata: set ctl8 %08lX <- %02X\n", addr, val); 1048 fflush (stderr); 1049#endif 1050 1051 switch (addr) { 1052 case 0x02: 1053 if ((ata->sel->reg_dev_ctl ^ val) & ~val & 0x04) { 1054 /* reset 1 -> 0 */ 1055 unsigned i; 1056 1057 for (i = 0; i < 2; i++) { 1058 ata->dev[i].reg_cyl_lo = 0; 1059 ata->dev[i].reg_cyl_hi = 0; 1060 ata->dev[i].reg_sec = 1; 1061 ata->dev[i].reg_sec_cnt = 1; 1062 ata->dev[i].reg_head = 0; 1063 ata->dev[i].reg_error = 0x01; 1064 ata->dev[i].reg_status = ATA_STATUS_DRDY | ATA_STATUS_DSC; 1065 } 1066 1067 ata->sel = &ata->dev[0]; 1068 } 1069 1070 if (val & 0x02) { 1071 ata_set_irq (ata, 0); 1072 } 1073 1074 ata->dev[0].reg_dev_ctl = val; 1075 ata->dev[1].reg_dev_ctl = val; 1076 break; 1077 } 1078} 1079 1080void ata_ctl_set_uint16 (ata_chn_t *ata, unsigned long addr, unsigned short val) 1081{ 1082} 1083 1084void ata_ctl_set_uint32 (ata_chn_t *ata, unsigned long addr, unsigned long val) 1085{ 1086}