- Timestamp:
- Feb 18, 2011, 10:09:10 PM (14 years ago)
- Location:
- trunk/src/os2ahci
- Files:
-
- 3 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/os2ahci/Makefile
r36 r76 50 50 -I$(DDK)\base\ibmh \ 51 51 -I$(DDK)\base\src\dev\dasd\diskh \ 52 -I$(DDK)\base\src\dev\thinkpad\dockii\apmcalls \ 52 53 -I$(CC16)\include 53 54 … … 57 58 LIB_DIRS = $(DDK)\base\lib\ \ 58 59 $(DDK)\base\src\dev\dasd\devhlp\ \ 59 $(CC16)\lib\ \ 60 $(DDK)\base\src\dev\thinkpad\dockii\apmcalls\ \ 61 $(CC16)\lib\ \ 60 62 61 63 … … 65 67 TARGET = os2ahci.add 66 68 67 LIBS = addcalls dhcalls doscalls slibcep rmcalls 69 LIBS = addcalls dhcalls doscalls slibcep rmcalls apmcalls 68 70 69 SRCS = init.asm libc.c os2ahci.c pci.c ahci.c ata.c atapi.c ctxhook.c 71 SRCS = init.asm libc.c os2ahci.c pci.c ahci.c ata.c atapi.c ctxhook.c \ 72 apm.c ioctl.c 70 73 71 74 OBJS = init.obj libc.obj os2ahci.obj pci.obj ahci.obj ata.obj atapi.obj \ 72 ctxhook.obj 75 ctxhook.obj apm.obj ioctl.obj 73 76 74 77 INCS = os2ahci.h ahci.h version.h … … 88 91 libc.obj: libc.c Makefile $(INCS) 89 92 90 os2ahci.obj: os2ahci.c Makefile $(INCS) bldday.h 93 os2ahci.obj: os2ahci.c Makefile $(INCS) bldday.h ioctl.h 91 94 92 95 pci.obj: pci.c Makefile $(INCS) … … 99 102 100 103 ctxhook.obj: ctxhook.c Makefile $(INCS) ata.h atapi.h 104 105 apm.obj: apm.c Makefile $(INCS) 106 107 ioctl.obj: ioctl.c Makefile $(INCS) atapi.h ioctl.h 101 108 102 109 ############################################################################### -
trunk/src/os2ahci/ahci.c
r75 r76 591 591 592 592 dprintf("resetting port %d.%d\n", ad_no(ai), p); 593 ddprintf(" PORT_CMD_ISSUE = 0x%lx\n", readl(port_mmio + PORT_CMD_ISSUE)); 594 ddprintf(" PORT_SCR_ACT = 0x%lx\n", readl(port_mmio + PORT_SCR_ACT)); 595 ddprintf(" PORT_SCR_ERR = 0x%lx\n", readl(port_mmio + PORT_SCR_ERR)); 596 ddprintf(" PORT_TFDATA = 0x%lx\n", readl(port_mmio + PORT_TFDATA)); 597 ddprintf(" PORT_IRQ_STAT = 0x%lx\n", readl(port_mmio + PORT_IRQ_STAT)); 598 ddprintf(" PORT_IRQ_MASK = 0x%lx\n", readl(port_mmio + PORT_IRQ_MASK)); 599 ddprintf(" HOST_IRQ_STAT = 0x%lx\n", readl(ai->mmio + HOST_IRQ_STAT)); 593 600 594 601 /* stop port engines (we don't care whether there is an error doing so) */ … … 597 604 /* clear SError */ 598 605 tmp = readl(port_mmio + PORT_SCR_ERR); 599 ddprintf(" PORT_SCR_ERR = 0x%lx\n", tmp);600 606 writel(port_mmio + PORT_SCR_ERR, tmp); 601 607 602 608 /* clear pending port IRQs */ 603 609 tmp = readl(port_mmio + PORT_IRQ_STAT); 604 ddprintf("PORT_IRQ_STAT was 0x%lx\n", tmp);605 610 if (tmp) { 606 611 writel(port_mmio + PORT_IRQ_STAT, tmp); 607 612 } 608 ddprintf(" PORT_IRQ_STAT = 0x%lx\n", tmp);609 ddprintf(" PORT_IRQ_MASK = 0x%lx\n", readl(port_mmio + PORT_IRQ_MASK));610 ddprintf(" HOST_IRQ_STAT = 0x%lx\n", readl(ai->mmio + HOST_IRQ_STAT));611 613 writel(ai->mmio + HOST_IRQ_STAT, 1UL << p); 612 614 … … 701 703 PORT_IRQ_UNK_FIS | 702 704 PORT_IRQ_SDB_FIS | 705 PORT_IRQ_DMAS_FIS | 706 PORT_IRQ_PIOS_FIS | 703 707 PORT_IRQ_D2H_REG_FIS); 704 708 } else { … … 759 763 760 764 /* disable port interrupts */ 761 writel(port_mmio + PORT_IRQ_MASK, PORT_IRQ_TF_ERR);765 writel(port_mmio + PORT_IRQ_MASK, 0); 762 766 763 767 /* disable FIS reception */ … … 839 843 840 844 return((timeout <= 0) ? -1 : 0); 845 } 846 847 /****************************************************************************** 848 * Determine whether a port is busy executing commands. 849 */ 850 ahci_port_busy(AD_INFO *ai, int p) 851 { 852 u8 _far *port_mmio = port_base(ai, p); 853 854 return(readl(port_mmio + PORT_SCR_ACT) != 0 || 855 readl(port_mmio + PORT_CMD_ISSUE) != 0); 841 856 } 842 857 … … 931 946 ADD_StartTimerMS(&aws->timer, timeout, (PFN) timeout_callback, iorb, 0); 932 947 933 /* update IORB */ 948 /* issue command to hardware */ 949 *cmds |= (1UL << port->cmd_slot); 934 950 aws->queued_hw = 1; 935 951 aws->cmd_slot = port->cmd_slot; 936 952 937 /* issue command to hardware */938 953 ddprintf("issuing command on slot %d\n", port->cmd_slot); 939 *cmds |= (1UL << port->cmd_slot);940 954 if (aws->is_ncq) { 941 955 writel(port_mmio + PORT_SCR_ACT, (1UL << port->cmd_slot)); … … 1423 1437 1424 1438 /****************************************************************************** 1425 * Execute ATA command. 1439 * Execute ATA command. Please note that this is allowed for both ATA and 1440 * ATAPI devices because ATAPI devices will process some ATA commands as well. 1426 1441 */ 1427 1442 void ahci_execute_ata(IORBH _far *iorb) … … 1433 1448 dphex(((IORB_ADAPTER_PASSTHRU _far *) iorb)->pControllerCmd, 1434 1449 ((IORB_ADAPTER_PASSTHRU _far *) iorb)->ControllerCmdLen, 1435 "ahci_execute_cdb(%d.%d.%d): ", a, p, d); 1436 1437 if (ad_infos[a].ports[p].devs[d].atapi) { 1438 iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED); 1439 iorb_done(iorb); 1440 } else { 1441 ahci_exec_iorb(iorb, 0, ata_execute_ata); 1442 } 1450 "ahci_execute_ata(%d.%d.%d): ", a, p, d); 1451 1452 ahci_exec_iorb(iorb, 0, ata_execute_ata); 1443 1453 } 1444 1454 -
trunk/src/os2ahci/ata.h
r57 r76 424 424 425 425 /****************************************************************************** 426 * Generic ATA-8 command structure. This is based on ATA-8, i.e. we won't have 427 * to deal with different command structures depending on whether a device is 428 * 48-bit capable, etc. because this is handled by the transport (AHCI in our 429 * case). Unsupported bits have to be cleared to zero, of course (e.g. the 430 * high 20 bits of the LBA when talking to a device that supports only 28 431 * bits). 426 * Generic ATA-8 command structure. This is loosely based on ATA-8, i.e. we 427 * don't have to deal with shadow registers and map them to the low bytes of 428 * adjecent words, etc. but there are still some oddities which need to be 429 * taken into consideration. For example, ATA-8 says LBA-28 sector addresses 430 * are simply the lower 28 bits in the LBA field. However, the underlying 431 * transport (SATA in our case) only looks at the three lower bytes of the 432 * LBA field, much like an IDE device would do. This means that only 3 bytes 433 * of the LBA field are processed and this yields only 24 bits. The remaining 434 * 4 bits need to be stored in the "device" register.... 435 * 436 * Everything else seems to behave normally, as far as this term can be 437 * applied to IDE/ATA. Further details can be found in section 7.1.5.1 of the 438 * ATA-8 spec (Inputs for 28-bit Read/Write Commands). 432 439 */ 433 440 typedef struct { -
trunk/src/os2ahci/atapi.c
r75 r76 168 168 * mechanism:" -- Storage Device Driver Reference, Scatter/Gather Lists 169 169 */ 170 rc = ata_cmd(ad_infos + iorb_unit_adapter(iorb), 171 iorb_unit_port(iorb), 172 iorb_unit_device(iorb), 173 slot, ATA_CMD_PACKET, 170 rc = ata_cmd(ad_infos + iorb_unit_adapter(iorb), iorb_unit_port(iorb), 171 iorb_unit_device(iorb), slot, ATA_CMD_PACKET, 174 172 AP_ATAPI_CMD, (void _far *) cdb, cdb_len, 175 173 AP_SGLIST, pt->pSGList, pt->cSGList, … … 280 278 if (ssb->SenseData != NULL) { 281 279 memcpy(ssb->SenseData, psd, max(ssb->ReqSenseLen, ATAPI_SENSE_LEN)); 282 ssb->Flags != STATUS_SENSEDATA_VALID;280 ssb->Flags |= STATUS_SENSEDATA_VALID; 283 281 } 282 iorb->Status |= IORB_STATUSBLOCK_AVAIL; 284 283 } 285 284 … … 333 332 334 333 /****************************************************************************** 335 * pad atapicommands; AHCI requires ATAPI commands to be either 12 or334 * Pad ATAPI commands; AHCI requires ATAPI commands to be either 12 or 336 335 * 16 bytes in length. This func converts commands that have a 12 byte 337 336 * equivalent, and pads the others to 12 bytes. … … 343 342 { 344 343 ATAPI_CDB_12 _far *p12; 344 u32 tmp; 345 345 346 346 if (cmd_in_len == ATAPI_MIN_CDB_LEN || cmd_in_len == ATAPI_MAX_CDB_LEN) { … … 364 364 p12->cmd = 0xa0 | (cmd_in[0] & 0x0f); 365 365 p12->flags = cmd_in[1] & 0xc0; /* 6byte cmds have no flags (FUA etc.) */ 366 SET_CDB_32(p12->lba, (u32) cmd_in[3] | (u32) cmd_in[2] << 8 |367 (u32) (cmd_in[1] & 0x1f) << 16);368 SET_CDB_32(p12->trans_len, (u32)cmd_in[4]);366 tmp = GET_CDB_24(cmd_in + 1) & 0x1fffffUL; 367 SET_CDB_32(p12->lba, tmp); 368 SET_CDB_32(p12->trans_len, cmd_in[4]); 369 369 p12->control = cmd_in[5]; 370 370 break; … … 375 375 p12->cmd = 0xa0 | (cmd_in[0] & 0x0f); 376 376 p12->flags = cmd_in[1]; 377 p12->control = cmd_in[9]; 377 378 memcpy(p12->lba, cmd_in + 2, 4); 378 SET_CDB_32(p12->trans_len, (u32) GET_CDB_16(cmd_in + 7));379 p12->control = cmd_in[9];379 tmp = GET_CDB_16(cmd_in + 7); 380 SET_CDB_32(p12->trans_len, tmp); 380 381 break; 381 382 -
trunk/src/os2ahci/init.asm
r74 r76 20 20 PUBLIC __U4M ; 32bit unsigned multiply routine 21 21 PUBLIC __U4D ; 32bit unsigned divide routine 22 PUBLIC __I4D ; 32bit signed multiplyroutine22 PUBLIC __I4D ; 32bit signed divide routine 23 23 PUBLIC _end_of_data ; end of all data (label) 24 24 PUBLIC _end_of_code ; end of all code (label) -
trunk/src/os2ahci/os2ahci.c
r75 r76 22 22 #include "os2ahci.h" 23 23 #include "bldday.h" 24 25 #include "ioctl.h" 24 26 25 27 /* -------------------------- macros and constants ------------------------- */ … … 78 80 AD_INFO ad_infos[MAX_AD]; /* adapter information list */ 79 81 int ad_info_cnt; /* number of entries in ad_infos[] */ 82 u16 ad_ignore; /* bitmap with adapter indexes to ignore */ 80 83 int init_complete; /* if != 0, initialization has completed */ 81 84 … … 109 112 case CMDShutdown: 110 113 rc = exit_drv(((RPSAVERESTORE _far *) req)->FuncCode); 114 break; 115 116 case CMDGenIOCTL: 117 rc = gen_ioctl((RP_GENIOCTL _far *) req); 111 118 break; 112 119 … … 174 181 break; 175 182 176 case ' i':183 case 'g': 177 184 /* add specfied PCI ID as a supported generic AHCI adapter */ 178 185 drv_parm_int(s, vendor, u16, 16); … … 193 200 /* reset ports during initialization */ 194 201 init_reset = 1; 202 break; 203 204 case 'i': 205 /* ignore current adapter index */ 206 if (adapter_index >= 0) { 207 ad_ignore |= 1U << adapter_index; 208 } 195 209 break; 196 210 … … 291 305 292 306 /****************************************************************************** 307 * Generic IOCTL via character device driver. IOCTLs are used to control the 308 * driver operation and to execute native ATA and ATAPI (SCSI) commands from 309 * ring 3 applications. 310 */ 311 USHORT gen_ioctl(RP_GENIOCTL _far *ioctl) 312 { 313 switch (ioctl->Category) { 314 315 case OS2AHCI_IOCTL_CATEGORY: 316 317 switch (ioctl->Function) { 318 319 case OS2AHCI_IOCTL_GET_DEVLIST: 320 return(ioctl_get_devlist(ioctl)); 321 322 case OS2AHCI_IOCTL_PASSTHROUGH: 323 return(ioctl_passthrough(ioctl)); 324 325 } 326 } 327 return(STDON | STATUS_ERR_UNKCMD); 328 } 329 330 /****************************************************************************** 293 331 * Device driver exit handler. This handler is called when OS/2 shuts down and 294 * flushes the write caches of all attached devices. 332 * flushes the write caches of all attached devices. Since this is effectively 333 * the same we do when suspending, we'll call out to the corresponding APM 334 * function. 295 335 * 296 336 * NOTE: Errors are ignored because there's no way we could stop the shutdown … … 300 340 USHORT exit_drv(int func) 301 341 { 302 int a;303 int p;304 int d;305 306 342 dprintf("exit_drv(%d) called\n", func); 307 343 … … 311 347 } 312 348 313 for (a = 0; a < ad_info_cnt; a++) { 314 AD_INFO *ai = ad_infos + a; 315 316 for (p = 0; p <= ai->port_max; p++) { 317 for (d = 0; d <= ai->ports[p].dev_max; d++) { 318 if (ai->ports[p].devs[d].present) { 319 ahci_flush_cache(ai, p, d); 320 } 321 } 322 } 323 } 324 349 apm_suspend(); 325 350 return(STDON); 326 351 } … … 575 600 if (!init_complete) { 576 601 dprintf("leaving initialization mode\n"); 577 spin_lock(drv_lock);578 602 for (a = 0; a < ad_info_cnt; a++) { 603 lock_adapter(ad_infos + a); 579 604 ahci_complete_init(ad_infos + a); 580 605 } 581 606 init_complete = 1; 582 spin_unlock(drv_lock); 607 608 /* release all adapters */ 609 for (a = 0; a < ad_info_cnt; a++) { 610 unlock_adapter(ad_infos + a); 611 } 612 613 /* register APM hook */ 614 apm_init(); 583 615 } 584 616 iorb_done(iorb); … … 941 973 942 974 /****************************************************************************** 943 * Add an IORB to the specified queue. 975 * Add an IORB to the specified queue. This function must be called with the 976 * adapter-level spinlock aquired. 944 977 */ 945 978 void iorb_queue_add(IORB_QUEUE _far *queue, IORBH _far *iorb) … … 994 1027 995 1028 /****************************************************************************** 996 * Remove an IORB from the specified queue. 1029 * Remove an IORB from the specified queue. This function must be called with 1030 * the adapter-level spinlock aquired. 997 1031 */ 998 1032 int iorb_queue_del(IORB_QUEUE _far *queue, IORBH _far *iorb) … … 1037 1071 { 1038 1072 iorb->ErrorCode = error_code; 1039 iorb->Status = IORB_ERROR;1073 iorb->Status |= IORB_ERROR; 1040 1074 } 1041 1075 … … 1078 1112 * Requeue the specified IORB such that it will be sent downstream for 1079 1113 * processing again. This includes freeing all resources currently allocated 1080 * (timer, buffer, ...) and resetting the flags to 0. 1114 * (timer, buffer, ...) and resetting the flags to 0. The driver-level 1115 * spinlock must be aquired when calling this function. 1081 1116 * 1082 1117 * The following flags are preserved: … … 1091 1126 memset(aws, 0x00, sizeof(*aws)); 1092 1127 aws->no_ncq = no_ncq; 1128 } 1129 1130 /****************************************************************************** 1131 * Lock the adapter, waiting for availability if necessary. This is expected 1132 * to be called without the driver-level spinlock aquired. 1133 */ 1134 void lock_adapter(AD_INFO *ai) 1135 { 1136 spin_lock(drv_lock); 1137 while (ai->busy) { 1138 spin_unlock(drv_lock); 1139 msleep(250); 1140 spin_lock(drv_lock); 1141 } 1142 ai->busy = 1; 1143 spin_unlock(drv_lock); 1144 } 1145 1146 /****************************************************************************** 1147 * Unlock adapter (i.e. reset busy flag) 1148 */ 1149 void unlock_adapter(AD_INFO *ai) 1150 { 1151 ai->busy = 0; 1093 1152 } 1094 1153 -
trunk/src/os2ahci/os2ahci.def
r75 r76 1 1 library os2ahci 2 Description '$@#thi.guten (www.thiguten.de):1.00.2011021 6#@OS/2 AHCI Adapter Device Driver'2 Description '$@#thi.guten (www.thiguten.de):1.00.20110218#@OS/2 AHCI Adapter Device Driver' 3 3 protmode 4 4 -
trunk/src/os2ahci/os2ahci.h
r75 r76 122 122 /* SMP spinlock compatibility macros for older DDKs using CLI/STI */ 123 123 #ifndef OS2AHCI_SMP 124 #define DevHelp_CreateSpinLock( sph) *(sph) = 0124 #define DevHelp_CreateSpinLock(p_sph) *(p_sph) = 0 125 125 #define DevHelp_FreeSpinLock(sph) 0 126 126 … … 379 379 /* os2ahci.c */ 380 380 extern USHORT init_drv (RPINITIN _far *req); 381 extern USHORT gen_ioctl (RP_GENIOCTL _far *ioctl); 381 382 extern USHORT exit_drv (int func); 382 383 extern void _cdecl _far _loadds add_entry (IORBH _far *iorb); … … 397 398 extern void iorb_done (IORBH _far *iorb); 398 399 extern void iorb_requeue (IORBH _far *iorb); 400 extern void lock_adapter (AD_INFO *ai); 401 extern void unlock_adapter (AD_INFO *ai); 399 402 extern void _cdecl _far timeout_callback (ULONG timer_handle, ULONG p1, ULONG p2); 400 403 … … 416 419 extern int ahci_stop_fis_rx (AD_INFO *ai, int p); 417 420 extern int ahci_stop_engine (AD_INFO *ai, int p); 421 extern int ahci_port_busy (AD_INFO *ai, int p); 418 422 extern void ahci_exec_iorb (IORBH _far *iorb, int ncq_capable, 419 423 int (*func)(IORBH _far *, int)); … … 474 478 extern void _cdecl engine_ctxhook (ULONG parm); 475 479 480 /* apm.c */ 481 extern void apm_init (void); 482 extern void apm_suspend (void); 483 extern void apm_resume (void); 484 485 /* ioctl.c */ 486 extern USHORT ioctl_get_devlist (RP_GENIOCTL _far *ioctl); 487 extern USHORT ioctl_passthrough (RP_GENIOCTL _far *ioctl); 488 476 489 /* ---------------------------- global variables --------------------------- */ 477 490 … … 492 505 extern AD_INFO ad_infos[]; /* adapter information list */ 493 506 extern int ad_info_cnt; /* number of entries in ad_infos[] */ 507 extern u16 ad_ignore; /* bitmap with adapters to be ignored */ 494 508 extern int init_complete; /* if != 0, initialization has completed */ 495 509 -
trunk/src/os2ahci/pci.c
r48 r76 409 409 UCHAR index; 410 410 UCHAR rc; 411 int ad_indx = 0; 411 412 int i; 412 413 … … 460 461 if (rc == OH_SUCCESS) { 461 462 /* found a device */ 463 if (ad_ignore & (1U << ad_indx++)) { 464 /* ignore this adapter */ 465 continue; 466 } 462 467 add_pci_device(pci_ids + i, &data); 463 468 if (++index > 180) { -
trunk/src/os2ahci/version.h
r75 r76 6 6 7 7 8 #define VERSION 10 2/* driver version (2 implied decimals) */8 #define VERSION 103 /* driver version (2 implied decimals) */ 9 9 10 10 /* BLDLEVEL information (in C source modules added via macro
Note:
See TracChangeset
for help on using the changeset viewer.