Changeset 125
- Timestamp:
- Oct 8, 2011, 10:28:48 PM (14 years ago)
- Location:
- trunk/src/os2ahci
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/os2ahci/Makefile
r112 r125 108 108 apm.obj: apm.c Makefile $(INCS) 109 109 110 ioctl.obj: ioctl.c Makefile $(INCS) ata pi.h ioctl.h110 ioctl.obj: ioctl.c Makefile $(INCS) ata.h atapi.h ioctl.h 111 111 112 112 trace.obj: trace.c Makefile $(INCS) -
trunk/src/os2ahci/ata.c
r121 r125 234 234 * 22 bits into 2 AHCI_SG elements. 235 235 * 236 * - The S/G element size for AHCI is what the spec calls "'0' based"236 * - The S/G element size for AHCI is what the spec calls '0'-based 237 237 * (i.e. 0 means 1 bytes). On top of that, the spec requires S/G transfer 238 238 * sizes to be even in the context of 16-bit transfers, thus bit '1' … … 248 248 * of this function will indicate how many OS/2 S/G entries were 249 249 * successfully mapped. 250 *251 250 */ 252 251 for (i = n = 0; i < sg_cnt; i++) { … … 891 890 AP_END); 892 891 892 if (rc == 0) { 893 add_workspace(iorb)->ppfunc = ata_execute_ata_pp; 894 } 895 893 896 return(rc); 897 } 898 899 /****************************************************************************** 900 * Post processing function for ata_execute_ata(); the main purpose of this 901 * function is to copy the received D2H FIS (i.e. the device registers after 902 * command completion) back to the ATA command structure. 903 * 904 * See ata_cmd_to_fis() for an explanation of the mapping. 905 */ 906 void ata_execute_ata_pp(IORBH _far *iorb) 907 { 908 AHCI_PORT_DMA _far *dma_base; 909 ATA_CMD _far *cmd; 910 AD_INFO *ai; 911 u8 _far *fis; 912 int p; 913 914 /* get address of D2H FIS */ 915 ai = ad_infos + iorb_unit_adapter(iorb); 916 p = iorb_unit_port(iorb); 917 dma_base = port_dma_base(ai, p); 918 fis = dma_base->rx_fis + 0x40; 919 920 if (fis[0] != 0x34) { 921 /* this is not a D2H FIS - give up silently */ 922 ddprintf("ata_execute_ata_pp(): D2H FIS type incorrect: %d\n", fis[0]); 923 add_workspace(iorb)->complete = 1; 924 return; 925 } 926 927 /* map D2H FIS to the original ATA controller command structure */ 928 cmd = (ATA_CMD _far *) ((IORB_ADAPTER_PASSTHRU _far *) iorb)->pControllerCmd; 929 930 cmd->cmd = fis[2]; 931 cmd->device = fis[7]; 932 cmd->features = ((u16) fis[3]) 933 | ((u16) fis[11]); 934 cmd->lba_l = ((u32) fis[4]) 935 | ((u32) fis[5] << 8) 936 | ((u32) fis[6] << 16) 937 | ((u32) fis[8] << 24); 938 cmd->lba_h = ((u16) fis[9]) 939 | ((u16) fis[10] << 8); 940 cmd->count = ((u16) fis[12]) 941 | ((u16) fis[13] << 8); 942 943 dphex(cmd, sizeof(*cmd), "ahci_execute_ata_pp(): cmd after completion:\n"); 944 945 /* signal completion to interrupt handler */ 946 add_workspace(iorb)->complete = 1; 894 947 } 895 948 … … 1036 1089 AP_SECTOR_48, (u32) sector, (u16) 0, 1037 1090 AP_FEATURES, (u16) count, 1038 AP_COUNT, (u16) (slot << 3), /* tag = slot */ 1091 /* tag = slot */ 1092 AP_COUNT, (u16) (slot << 3), 1039 1093 AP_SGLIST, sg_list, (u16) sg_cnt, 1040 1094 AP_DEVICE, 0x40, 1041 AP_DEVICE, (write_through) ? 0x80 : 0, /* force unit access */ 1095 /* force unit access */ 1096 AP_DEVICE, (write_through && !force_write_cache) ? 0x80 : 0, 1042 1097 AP_WRITE, 1, 1043 1098 AP_END); -
trunk/src/os2ahci/ata.h
r110 r125 344 344 345 345 /* feature values for SMART */ 346 #define ATA_SMART_ENABLE 0xD8 347 #define ATA_SMART_READ_VALUES 0xD0 348 #define ATA_SMART_READ_THRESHOLDS 0xD1 346 #define ATA_SMART_READ_VALUES 0xD0 347 #define ATA_SMART_READ_THRESHOLDS 0xD1 348 #define ATA_SMART_AUTOSAVE 0xD2 349 #define ATA_SMART_SAVE 0xD3 350 #define ATA_SMART_IMMEDIATE_OFFLINE 0xD4 351 #define ATA_SMART_READ_LOG 0xD5 352 #define ATA_SMART_WRITE_LOG 0xD6 353 #define ATA_SMART_ENABLE 0xD8 354 #define ATA_SMART_DISABLE 0xD9 355 #define ATA_SMART_STATUS 0xDA 356 #define ATA_SMART_AUTO_OFFLINE 0xDB 349 357 350 358 /* feature values for Data Set Management */ … … 505 513 extern void ata_write_pp (IORBH _far *iorb); 506 514 extern int ata_execute_ata (IORBH _far *iorb, int slot); 515 extern void ata_execute_ata_pp (IORBH _far *iorb); 507 516 extern int ata_req_sense (IORBH _far *iorb, int slot); 508 517 -
trunk/src/os2ahci/ctxhook.c
r121 r125 127 127 128 128 /* get "current command slot"; only valid if there are no NCQ cmds */ 129 ccs = (int) ((readl(port_mmio + PORT_CMD) >> 8) & 0x 0f);129 ccs = (int) ((readl(port_mmio + PORT_CMD) >> 8) & 0x1f); 130 130 ddprintf(" PORT_CMD = 0x%x\n", ccs); 131 131 … … 145 145 if (aws->cmd_slot == ccs) { 146 146 /* this is the non-NCQ command that failed */ 147 ddprintf("failing IORB: %Fp\n", iorb); 147 148 problem_iorb = iorb; 148 149 } -
trunk/src/os2ahci/ioctl.c
r113 r125 27 27 #include "os2ahci.h" 28 28 #include "atapi.h" 29 #include "ata.h" 29 30 #include "ioctl.h" 30 31 … … 42 43 * we'll need to define a union to cover all IORB types in question. 43 44 */ 45 #define CMDLEN sizeof(((OS2AHCI_PASSTHROUGH *) 0)->cmd) 44 46 typedef struct { 45 47 IORB_ADAPTER_PASSTHRU iorb; /* IORB */ 46 48 SCSI_STATUS_BLOCK ssb; /* SCSI status block */ 49 UCHAR cmd[CMDLEN]; /* copy of passthrough cmd 50 * (need to fill ATA return 51 * registers at interrupt time) 52 */ 47 53 UCHAR sense[ATAPI_SENSE_LEN]; /* sense buffer */ 48 54 SCATGATENTRY sg_lst[AHCI_MAX_SG / 2]; /* scatter/gather list */ … … 53 59 /* -------------------------- function prototypes -------------------------- */ 54 60 55 static LIN lin(void _far *p); 61 static USHORT do_smart (BYTE unit, BYTE sub_func, BYTE parm, void _far *buf); 62 static int map_unit (BYTE unit, USHORT _far *a, USHORT _far *p, 63 USHORT _far *d); 64 static LIN lin (void _far *p); 56 65 57 66 IORBH _far * _far _cdecl ioctl_wakeup(IORBH _far *iorb); … … 171 180 return(STDON | STERR | ERROR_I24_BAD_UNIT); 172 181 } 173 if ((req->buflen + 4095) / 4096 + 1 > AHCI_MAX_SG / 2) { 182 if ((req->buflen + 4095) / 4096 + 1 > AHCI_MAX_SG / 2 || 183 req->cmdlen < 6 || req->cmdlen > sizeof(req->cmd)) { 174 184 return(STDON | STERR | ERROR_I24_INVALID_PARAMETER); 175 185 } … … 206 216 ic->iorb.ppSGLIST = virt_to_phys(ic->sg_lst); 207 217 218 memcpy(ic->cmd, req->cmd.cdb, sizeof(ic->cmd)); 208 219 ic->iorb.ControllerCmdLen = req->cmdlen; 209 ic->iorb.pControllerCmd = req->cmd.cdb;220 ic->iorb.pControllerCmd = ic->cmd; 210 221 ic->iorb.Flags = (req->flags & PT_WRITE) ? 0 : PT_DIRECTION_IN; 211 222 … … 236 247 spin_lock(drv_lock); 237 248 while (!(ic->iorb.iorbh.Status & IORB_DONE)) { 249 238 250 # ifndef OS2AHCI_SMP 239 251 drv_lock = 0; 240 252 # endif 253 241 254 DevHelp_ProcBlock((ULONG) (void _far *) &ic->iorb.iorbh, 30000, 1); 242 255 spin_lock(drv_lock); … … 306 319 min(ic->ssb.ReqSenseLen, req->sense_len)); 307 320 } 321 322 } else if ((req->flags & PT_ATAPI) == 0) { 323 /* Copy ATA cmd back to IOCTL request (ATA commands are effectively 324 * registers which are sometimes used to indicate return conditions, 325 * e.g. when requesting the smart status) 326 */ 327 memcpy(&req->cmd.ata, ic->cmd, sizeof(req->cmd.ata)); 308 328 } 309 329 … … 316 336 317 337 /****************************************************************************** 338 * Generic disk IOCTL handler; this IOCTL category has originally been defined 339 * in IBM1S506; the code has been more or less copied from DANIS506. 340 * 341 * NOTE: Only a subset of the IOCTL calls are implemented in OS2AHCI at this 342 * point, basically those calls required to get HDMON working. 343 */ 344 USHORT ioctl_gen_dsk(RP_GENIOCTL _far *ioctl) 345 { 346 DSKSP_CommandParameters _far *cp = (DSKSP_CommandParameters _far *) ioctl->ParmPacket; 347 UnitInformationData _far *ui; 348 OS2AHCI_PASSTHROUGH pt; 349 RP_GENIOCTL tmp_ioctl; 350 USHORT size = 0; 351 USHORT ret; 352 USHORT a; 353 USHORT p; 354 USHORT d; 355 UCHAR unit; 356 357 /* verify addressability of parm buffer (DSKSP_CommandParameters) */ 358 if (DevHelp_VerifyAccess((SEL) ((ULONG) cp >> 16), 359 sizeof(DSKSP_CommandParameters), 360 (USHORT) (ULONG) cp, 361 VERIFY_READONLY) != 0) { 362 return(STDON | STERR | 0x05); 363 } 364 unit = cp->byPhysicalUnit; 365 366 /* verify addressability of data buffer (depends on function code) */ 367 switch (ioctl->Function) { 368 369 case DSKSP_GEN_GET_COUNTERS: 370 size = sizeof(DeviceCountersData); 371 break; 372 373 case DSKSP_GET_UNIT_INFORMATION: 374 size = sizeof(UnitInformationData); 375 break; 376 377 case DSKSP_GET_INQUIRY_DATA: 378 size = ATA_ID_WORDS * sizeof(u16); 379 break; 380 } 381 382 if (size > 0) { 383 if (DevHelp_VerifyAccess((SEL) ((ULONG) ioctl->DataPacket >> 16), 384 size, (USHORT) (ULONG) ioctl->DataPacket, 385 VERIFY_READWRITE) != 0) { 386 return(STDON | STERR | 0x05); 387 } 388 } 389 390 if (map_unit(unit, &a, &p, &d)) { 391 return(STDON | STERR | ERROR_I24_BAD_UNIT); 392 } 393 394 /* execute generic disk request */ 395 switch (ioctl->Function) { 396 397 case DSKSP_GEN_GET_COUNTERS: 398 /* Not supported, yet; we would need dynamically allocated device 399 * structures to cope with the memory requirements of the corresponding 400 * statistics buffer. For the time being, we'll return an empty buffer. 401 */ 402 memset(ioctl->DataPacket, 0x00, sizeof(DeviceCountersData)); 403 ret = STDON; 404 break; 405 406 case DSKSP_GET_UNIT_INFORMATION: 407 /* get unit information; things like port addresses won't fit so we don't 408 * even bother returning those. 409 */ 410 ui = (UnitInformationData _far *) ioctl->DataPacket; 411 memset(ui, 0x00, sizeof(*ui)); 412 413 ui->wRevisionNumber = 1; 414 ui->wIRQ = ad_infos[a].irq; 415 ui->wFlags = UIF_VALID; 416 ui->wFlags |= UIF_RUNNING_BMDMA; 417 ui->wFlags |= (unit & 0x0001) ? UIF_SLAVE : 0; 418 ui->wFlags |= (ad_infos[a].ports[p].devs[d].atapi) ? UIF_ATAPI : 0; 419 ui->wFlags |= UIF_SATA; 420 421 ret = STDON; 422 break; 423 424 case DSKSP_GET_INQUIRY_DATA: 425 /* return ATA ID buffer */ 426 memset(&tmp_ioctl, 0x00, sizeof(tmp_ioctl)); 427 tmp_ioctl.Category = OS2AHCI_IOCTL_CATEGORY; 428 tmp_ioctl.Function = OS2AHCI_IOCTL_PASSTHROUGH; 429 tmp_ioctl.ParmPacket = (void _far *) &pt; 430 431 memset(&pt, 0x00, sizeof(pt)); 432 pt.adapter = a; 433 pt.port = p; 434 pt.device = d; 435 pt.cmdlen = sizeof(pt.cmd.ata); 436 pt.cmd.ata.cmd = (ad_infos[a].ports[p].devs[d].atapi) ? 437 ATA_CMD_ID_ATAPI : ATA_CMD_ID_ATA; 438 pt.buflen = size; 439 pt.buf = lin(ioctl->DataPacket); 440 441 ret = gen_ioctl(&tmp_ioctl); 442 break; 443 444 default: 445 ret = STDON | STATUS_ERR_UNKCMD; 446 break; 447 } 448 449 return(ret); 450 } 451 452 /****************************************************************************** 453 * SMART IOCTL handler; this IOCTL category has originally been defined in 454 * IBM1S506; the code has been more or less copied from DANIS506. 455 */ 456 USHORT ioctl_smart(RP_GENIOCTL _far *ioctl) 457 { 458 DSKSP_CommandParameters _far *cp = (DSKSP_CommandParameters _far *) ioctl->ParmPacket; 459 USHORT size = 0; 460 USHORT ret; 461 UCHAR unit; 462 UCHAR parm; 463 464 /* verify addressability of parm buffer (DSKSP_CommandParameters) */ 465 if (DevHelp_VerifyAccess((SEL) ((ULONG) cp >> 16), 466 sizeof(DSKSP_CommandParameters), 467 (USHORT) (ULONG) cp, 468 VERIFY_READONLY) != 0) { 469 return(STDON | STERR | 0x05); 470 } 471 unit = cp->byPhysicalUnit; 472 473 /* verify addressability of data buffer (depends on SMART function) */ 474 switch (ioctl->Function) { 475 476 case DSKSP_SMART_GETSTATUS: 477 size = sizeof(ULONG); 478 break; 479 480 case DSKSP_SMART_GET_ATTRIBUTES: 481 case DSKSP_SMART_GET_THRESHOLDS: 482 case DSKSP_SMART_GET_LOG: 483 size = 512; 484 break; 485 } 486 487 if (size > 0) { 488 if (DevHelp_VerifyAccess((SEL) ((ULONG) ioctl->DataPacket >> 16), 489 size, (USHORT) (ULONG) ioctl->DataPacket, 490 VERIFY_READWRITE) != 0) { 491 return(STDON | STERR | 0x05); 492 } 493 parm = ioctl->DataPacket[0]; 494 } 495 496 /* execute SMART request */ 497 switch (ioctl->Function) { 498 499 case DSKSP_SMART_ONOFF: 500 ret = do_smart(unit, 501 (BYTE) ((parm) ? ATA_SMART_ENABLE 502 : ATA_SMART_DISABLE), 503 0, NULL); 504 break; 505 506 case DSKSP_SMART_AUTOSAVE_ONOFF: 507 ret = do_smart(unit, ATA_SMART_AUTOSAVE, 508 (BYTE) ((parm) ? (BYTE) 0xf1 : 0), 509 NULL); 510 break; 511 512 case DSKSP_SMART_AUTO_OFFLINE: 513 ret = do_smart(unit, ATA_SMART_AUTO_OFFLINE, parm, NULL); 514 break; 515 516 case DSKSP_SMART_EXEC_OFFLINE: 517 ret = do_smart(unit, ATA_SMART_IMMEDIATE_OFFLINE, parm, NULL); 518 break; 519 520 case DSKSP_SMART_SAVE: 521 ret = do_smart(unit, ATA_SMART_SAVE, 0, NULL); 522 break; 523 524 case DSKSP_SMART_GETSTATUS: 525 ret = do_smart(unit, ATA_SMART_STATUS, 0, ioctl->DataPacket); 526 break; 527 528 case DSKSP_SMART_GET_ATTRIBUTES: 529 ret = do_smart(unit, ATA_SMART_READ_VALUES, 0, ioctl->DataPacket); 530 break; 531 532 case DSKSP_SMART_GET_THRESHOLDS: 533 ret = do_smart(unit, ATA_SMART_READ_THRESHOLDS, 0, ioctl->DataPacket); 534 break; 535 536 case DSKSP_SMART_GET_LOG: 537 ret = do_smart(unit, ATA_SMART_READ_LOG, parm, ioctl->DataPacket); 538 break; 539 540 default: 541 ret = STDON | STATUS_ERR_UNKCMD; 542 } 543 544 return(ret); 545 } 546 547 /****************************************************************************** 548 * Perform SMART request. The code has been more or less copied from DANIS506. 549 */ 550 static USHORT do_smart(BYTE unit, BYTE sub_func, BYTE parm, void _far *buf) 551 { 552 OS2AHCI_PASSTHROUGH pt; 553 RP_GENIOCTL ioctl; 554 USHORT ret; 555 USHORT a; 556 USHORT p; 557 USHORT d; 558 559 if (map_unit(unit, &a, &p, &d)) { 560 return(STDON | STERR | ERROR_I24_BAD_UNIT); 561 } 562 563 /* Perform SMART request using the existing OS2AHCI_IOTCL_PASSTHROUGH IOCTL 564 * interface which already takes care of allocating an IORB, s/g lists, etc. 565 */ 566 memset(&ioctl, 0x00, sizeof(ioctl)); 567 ioctl.Category = OS2AHCI_IOCTL_CATEGORY; 568 ioctl.Function = OS2AHCI_IOCTL_PASSTHROUGH; 569 ioctl.ParmPacket = (void _far *) &pt; 570 571 memset(&pt, 0x00, sizeof(pt)); 572 pt.adapter = a; 573 pt.port = p; 574 pt.device = d; 575 pt.cmdlen = sizeof(pt.cmd.ata); 576 pt.cmd.ata.features = sub_func; 577 pt.cmd.ata.count = parm; 578 pt.cmd.ata.lba_l = (0xc24fL << 8) | parm; 579 pt.cmd.ata.cmd = ATA_CMD_SMART; 580 581 if (buf != NULL && sub_func != ATA_SMART_STATUS) { 582 pt.buflen = 512; 583 pt.buf = lin(buf); 584 } 585 586 if (((ret = gen_ioctl(&ioctl)) & STERR) == 0 && 587 sub_func == ATA_SMART_STATUS) { 588 589 /* ATA_SMART_STATUS doesn't transfer anything but instead relies on the 590 * returned D2H FIS, mapped to the ATA CMD, to have a certain value 591 * (0xf42c); the IOCTL result is expected to be returned as a ULONG in 592 * the data buffer. 593 */ 594 if (((pt.cmd.ata.lba_l >> 8) & 0xffff) == 0xf42c) { 595 *((ULONG _far *) buf) = 1; 596 } else { 597 *((ULONG _far *) buf) = 0; 598 } 599 } 600 601 return(ret); 602 } 603 604 /****************************************************************************** 605 * Map DSKSP unit number to corresponding adapter/port/device number. Units 606 * are identified by an 8-bit adapter/device number with the lowest bit 607 * selecting between master (0) and slave (1). This number is mapped to our 608 * ATA/ATAPI units sequentially. 609 */ 610 static int map_unit(BYTE unit, USHORT _far *a, USHORT _far *p, USHORT _far *d) 611 { 612 USHORT _a; 613 USHORT _p; 614 USHORT _d; 615 616 /* map unit to adapter/port/device */ 617 for (_a = 0; _a < ad_info_cnt; _a++) { 618 AD_INFO *ai = ad_infos + _a; 619 620 for (_p = 0; _p <= ai->port_max; _p++) { 621 P_INFO *pi = ai->ports + _p; 622 623 for (_d = 0; _d <= pi->dev_max; _d++) { 624 if (pi->devs[_d].present) { 625 if (--unit == 0) { 626 /* found the device */ 627 *a = _a; 628 *p = _p; 629 *d = _d; 630 return(0); 631 } 632 } 633 } 634 } 635 } 636 637 /* unit not found */ 638 return(-1); 639 } 640 641 /****************************************************************************** 318 642 * Get linear address for specified virtual address. 319 643 */ -
trunk/src/os2ahci/ioctl.h
r87 r125 28 28 29 29 /* IOCTL categories and functions */ 30 #define OS2AHCI_IOCTL_CATEGORY 0x8 030 #define OS2AHCI_IOCTL_CATEGORY 0x87 31 31 #define OS2AHCI_IOCTL_GET_DEVLIST 0x01 32 32 #define OS2AHCI_IOCTL_PASSTHROUGH 0x02 33 34 /* IOCTL definitions from s506oem.h (primarily required for SMART calls) */ 35 #define DSKSP_CAT_SMART 0x80 /* SMART IOCTL category */ 36 #define DSKSP_SMART_ONOFF 0x20 /* turn SMART on or off */ 37 #define DSKSP_SMART_AUTOSAVE_ONOFF 0x21 /* turn SMART autosave on or off */ 38 #define DSKSP_SMART_SAVE 0x22 /* force save of SMART data */ 39 #define DSKSP_SMART_GETSTATUS 0x23 /* get SMART status (pass/fail) */ 40 #define DSKSP_SMART_GET_ATTRIBUTES 0x24 /* get SMART attributes table */ 41 #define DSKSP_SMART_GET_THRESHOLDS 0x25 /* get SMART thresholds table */ 42 #define DSKSP_SMART_GET_LOG 0x26 /* get SMART log table */ 43 #define DSKSP_SMART_AUTO_OFFLINE 0x27 /* set SMART offline autosave timer */ 44 #define DSKSP_SMART_EXEC_OFFLINE 0x28 /* execute SMART immediate offline */ 45 46 #define SMART_CMD_ON 1 /* on value for related SMART functions */ 47 #define SMART_CMD_OFF 0 /* off value for related SMART functions */ 48 49 #define DSKSP_CAT_GENERIC 0x90 /* generic IOCTL category */ 50 #define DSKSP_GEN_GET_COUNTERS 0x40 /* get general counter values table */ 51 #define DSKSP_GET_UNIT_INFORMATION 0x41 /* get unit configuration and BM DMA counters */ 52 #define DSKSP_GET_INQUIRY_DATA 0x42 /* get ATA/ATAPI inquiry data */ 53 54 /* unit information structure flags from s506oem.h */ 55 #define UIF_VALID 0x8000U /* unit information valid */ 56 #define UIF_TIMINGS_VALID 0x4000U /* timing information valid */ 57 #define UIF_RUNNING_BMDMA 0x2000U /* running Bus Master DMA on unit */ 58 #define UIF_RUNNING_DMA 0x1000U /* running slave DMA on unit */ 59 #define UIF_SATA 0x0004U /* SATA */ 60 #define UIF_SLAVE 0x0002U /* slave on channel */ 61 #define UIF_ATAPI 0x0001U /* ATAPI device if 1, ATA otherwise */ 33 62 34 63 /* device flags */ … … 112 141 } OS2AHCI_PASSTHROUGH; 113 142 143 /****************************************************************************** 144 * DSKSP command parameters; copied from s506oem.h 145 */ 146 typedef struct _DSKSP_CommandParameters 147 { 148 BYTE byPhysicalUnit; /* physical unit number 0-n */ 149 /* 0 = Pri/Mas, 1=Pri/Sla, 2=Sec/Mas, etc. */ 150 } DSKSP_CommandParameters; 151 152 /****************************************************************************** 153 * DSKSP device counters data; copied from s506oem.h 154 */ 155 typedef struct _DeviceCountersData 156 { 157 USHORT wRevisionNumber; /* counter structure revision */ 158 ULONG TotalReadOperations; /* total read operations performed */ 159 ULONG TotalWriteOperations; /* total write operations performed */ 160 ULONG TotalWriteErrors; /* total write errors encountered */ 161 ULONG TotalReadErrors; /* total read errors encountered */ 162 ULONG TotalSeekErrors; /* total seek errors encountered */ 163 ULONG TotalSectorsRead; /* total number of sectors read */ 164 ULONG TotalSectorsWritten; /* total number of sectors written */ 165 166 ULONG TotalBMReadOperations; /* total bus master DMA read operations */ 167 ULONG TotalBMWriteOperations; /* total bus master DMA write operations */ 168 ULONG ByteMisalignedBuffers; /* total buffers on odd byte boundary */ 169 ULONG TransfersAcross64K; /* total buffers crossing a 64K page boundary */ 170 USHORT TotalBMStatus; /* total bad busmaster status */ 171 USHORT TotalBMErrors; /* total bad busmaster error */ 172 ULONG TotalIRQsLost; /* total lost interrupts */ 173 USHORT TotalDRQsLost; /* total lost data transfer requests */ 174 USHORT TotalBusyErrors; /* total device busy timeouts */ 175 USHORT TotalBMStatus2; /* total bad busmaster status */ 176 USHORT TotalChipStatus; /* total bad chip status */ 177 USHORT ReadErrors[4]; 178 USHORT WriteErrors[2]; 179 USHORT SeekErrors[2]; 180 USHORT SATAErrors; 181 } DeviceCountersData, NEAR *NPDeviceCountersData, FAR *PDeviceCountersData; 182 183 /****************************************************************************** 184 * DSKSP unit information data; copied from s506oem.h 185 */ 186 typedef struct _UnitInformationData 187 { 188 USHORT wRevisionNumber; /* structure revision number */ 189 union { 190 struct { 191 USHORT wTFBase; /* task file register base addr */ 192 USHORT wDevCtl; /* device control register addr */ 193 } rev0; 194 ULONG dTFBase; /* task file register base addr */ 195 }; 196 USHORT wIRQ; /* interrupt request level */ 197 USHORT wFlags; /* flags */ 198 UCHAR byPIO_Mode; /* PIO transfer mode programmed */ 199 UCHAR byDMA_Mode; /* DMA transfer mode programmed */ 200 ULONG UnitFlags1; 201 USHORT UnitFlags2; 202 } UnitInformationData, NEAR *NPUnitInformationData, FAR *PUnitInformationData; 203 204 114 205 #pragma pack() 115 206 -
trunk/src/os2ahci/os2ahci.c
r123 r125 73 73 int thorough_scan = 1; /* if != 0, perform thorough PCI scan */ 74 74 int init_reset; /* if != 0, reset ports during init */ 75 int force_write_cache; /* if != 0, force write cache */ 75 76 int verbosity = 1; /* == 1 -> show sign on banner 76 77 * > 1 -> show adapter info during boot */ … … 233 234 /* reset ports during initialization */ 234 235 init_reset = 1; 236 break; 237 238 case 'f': 239 /* force write cache regardless of IORB flags */ 240 force_write_cache = 1; 235 241 break; 236 242 … … 387 393 * Generic IOCTL via character device driver. IOCTLs are used to control the 388 394 * driver operation and to execute native ATA and ATAPI (SCSI) commands from 389 * ring 3 applications. 395 * ring 3 applications. On top of that, some predefined IOCTLs (e.g. SMART 396 * commands for ATA disks) are implemented here. 390 397 */ 391 398 USHORT gen_ioctl(RP_GENIOCTL _far *ioctl) 392 399 { 400 dprintf("IOCTL 0x%x/0x%x\n", (u16) ioctl->Category, (u16) ioctl->Function); 401 393 402 switch (ioctl->Category) { 394 403 395 404 case OS2AHCI_IOCTL_CATEGORY: 396 397 405 switch (ioctl->Function) { 398 406 … … 404 412 405 413 } 406 } 414 415 case DSKSP_CAT_GENERIC: 416 return(ioctl_gen_dsk(ioctl)); 417 418 case DSKSP_CAT_SMART: 419 return(ioctl_smart(ioctl)); 420 421 } 422 407 423 return(STDON | STATUS_ERR_UNKCMD); 408 424 } -
trunk/src/os2ahci/os2ahci.h
r123 r125 517 517 extern USHORT ioctl_get_devlist (RP_GENIOCTL _far *ioctl); 518 518 extern USHORT ioctl_passthrough (RP_GENIOCTL _far *ioctl); 519 extern USHORT ioctl_gen_dsk (RP_GENIOCTL _far *ioctl); 520 extern USHORT ioctl_smart (RP_GENIOCTL _far *ioctl); 519 521 520 522 … … 527 529 extern int thorough_scan; /* if != 0, perform thorough PCI scan */ 528 530 extern int init_reset; /* if != 0, reset ports during init */ 531 extern int force_write_cache; /* if != 0, force write cache */ 529 532 extern int verbosity; /* if != 0, show some info during boot */ 530 533 -
trunk/src/os2ahci/version.h
r121 r125 14 14 15 15 16 #define VERSION 1 19/* driver version (2 implied decimals) */16 #define VERSION 121 /* driver version (2 implied decimals) */ 17 17
Note:
See TracChangeset
for help on using the changeset viewer.