- Timestamp:
- Feb 22, 2011, 2:25:44 AM (14 years ago)
- Location:
- trunk/src/os2ahci
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/os2ahci/ahci.c
r76 r77 413 413 int i; 414 414 415 spin_lock(drv_lock); 416 id_buf = malloc(ATA_ID_WORDS * sizeof(u16)); 417 spin_unlock(drv_lock); 418 if (id_buf == NULL) { 415 if ((id_buf = malloc(ATA_ID_WORDS * sizeof(u16))) == NULL) { 419 416 return(-1); 420 417 } … … 499 496 ahci_restore_bios_config(ai); 500 497 } 501 spin_lock(drv_lock);502 498 free(id_buf); 503 spin_unlock(drv_lock);504 499 return(0); 505 500 } … … 613 608 writel(ai->mmio + HOST_IRQ_STAT, 1UL << p); 614 609 615 /* set link speed */ 616 tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x000000f0UL; 617 writel(port_mmio + PORT_SCR_CTL, tmp | (link_speed[ad_no(ai)][p] << 4)); 610 /* set link speed and power management options */ 611 tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x00000ff0UL; 612 tmp |= ((u32) link_speed[ad_no(ai)][p] & 0x0f) << 4; 613 tmp |= ((u32) link_power[ad_no(ai)][p] & 0x0f) << 8; 614 writel(port_mmio + PORT_SCR_CTL, tmp); 618 615 619 616 /* issue COMRESET on the port */ … … 873 870 AD_INFO *ai = ad_infos + iorb_unit_adapter(iorb); 874 871 P_INFO *port = ai->ports + iorb_unit_port(iorb); 875 ULONG timeout = (iorb->Timeout > 0) ? iorb->Timeout * 1000 : DEFAULT_TIMEOUT;872 ULONG timeout; 876 873 u8 _far *port_mmio = port_base(ai, iorb_unit_port(iorb)); 877 874 u16 cmd_max = ai->cmd_max; 878 875 int i; 876 877 /* determine timeout in milliseconds */ 878 switch (iorb->Timeout) { 879 case 0: 880 timeout = DEFAULT_TIMEOUT; 881 break; 882 case 0xffffffffUL: 883 timeout = 0xffffffffUL; 884 break; 885 default: 886 timeout = iorb->Timeout * 1000; 887 break; 888 } 879 889 880 890 /* Enable AHCI mode; apparently, the AHCI mode may end up becoming … … 1296 1306 for (iorb = done_queue.root; iorb != NULL; iorb = next) { 1297 1307 next = iorb->pNxtIORB; 1298 complete_iorb(iorb);1308 iorb_complete(iorb); 1299 1309 } 1300 1310 } … … 1541 1551 1542 1552 /* try to detect virtualbox environment to enable a hack for IRQ routing */ 1543 if (ai == ad_infos && p == 7 && 1544 ai->pci->vendor == 0x8086 && ai->pci->device == 0x2829 && 1553 if (ai == ad_infos && ai->pci->vendor == 0x8086 && ai->pci->device == 0x2829 && 1545 1554 !memcmp(ata_dev_name(id_buf), "VBOX HARDDISK", 13)) { 1546 1555 /* running inside virtualbox */ -
trunk/src/os2ahci/atapi.c
r76 r77 201 201 u8 cdb[ATAPI_MIN_CDB_LEN]; 202 202 ATAPI_CDB_6 _far *pcdb = (ATAPI_CDB_6 _far *) cdb; 203 size_t sense_buf_len = ATAPI_SENSE_LEN; 203 204 204 205 if ((iorb->RequestControl & IORB_REQ_STATUSBLOCK) && … … 211 212 (u16) iorb->pStatusBlock); 212 213 if (ssb->Flags & 0x0008U) { 213 /* set a generic error code and skip automatic sense code handling */214 214 iorb_seterr(iorb, IOERR_DEVICE_NONSPECIFIC); 215 215 return(-1); 216 216 } 217 218 /* if the sense buffer requested is larger than our default, adjust 219 * the length accordingly to satisfy the caller's requirements. */ 220 if (ssb->SenseData != NULL && ssb->ReqSenseLen > sense_buf_len) { 221 sense_buf_len = ssb->ReqSenseLen; 222 } 217 223 } 218 224 219 225 /* allocate sense buffer in ADD workspace */ 220 if ((aws->buf = malloc( ATAPI_SENSE_LEN)) == NULL) {226 if ((aws->buf = malloc(sense_buf_len)) == NULL) { 221 227 iorb_seterr(iorb, IOERR_CMD_SW_RESOURCE); 222 228 return(-1); 223 229 } 224 memset(aws->buf, 0x00, ATAPI_SENSE_LEN);230 memset(aws->buf, 0x00, sense_buf_len); 225 231 226 232 /* prepare request sense command */ 227 233 memset(cdb, 0x00, sizeof(cdb)); 228 234 pcdb->cmd = ATAPI_CMD_REQUEST_SENSE; 229 pcdb->trans_len = (u8) ATAPI_SENSE_LEN;235 pcdb->trans_len = (u8) sense_buf_len; 230 236 231 237 aws->ppfunc = atapi_req_sense_pp; … … 236 242 ATA_CMD_PACKET, 237 243 AP_ATAPI_CMD, (void _far*) cdb, sizeof(cdb), 238 AP_VADDR, (void _far *) aws->buf, ATAPI_SENSE_LEN,244 AP_VADDR, (void _far *) aws->buf, sense_buf_len, 239 245 AP_FEATURES, ATAPI_FEAT_DMA, 240 246 AP_END); … … 277 283 278 284 if (ssb->SenseData != NULL) { 279 memcpy(ssb->SenseData, psd, max(ssb->ReqSenseLen, ATAPI_SENSE_LEN));285 memcpy(ssb->SenseData, psd, ssb->ReqSenseLen); 280 286 ssb->Flags |= STATUS_SENSEDATA_VALID; 281 287 } -
trunk/src/os2ahci/ctxhook.c
r75 r77 224 224 spin_unlock(drv_lock); 225 225 226 complete_iorb(iorb);226 iorb_complete(iorb); 227 227 } 228 228 … … 371 371 spin_unlock(drv_lock); 372 372 373 iorb->Status = IORB_ERROR;374 complete_iorb(iorb);373 iorb->Status |= IORB_ERROR; 374 iorb_complete(iorb); 375 375 } 376 376 -
trunk/src/os2ahci/libc.c
r71 r77 60 60 61 61 static char hex_digits[] = "0123456789abcdef"; 62 static ULONG mem_lock; 62 63 static ULONG com_lock; 63 64 … … 94 95 95 96 /****************************************************************************** 96 * Initialize COM1 to 115200,n,8,1 97 * Initialize libc components 98 */ 99 void init_libc(void) 100 { 101 DevHelp_CreateSpinLock(&mem_lock); 102 DevHelp_CreateSpinLock(&com_lock); 103 } 104 105 /****************************************************************************** 106 * Initialize COM port to 115200,n,8,1 97 107 * 98 108 * NOTE: Something is wrong with this code, or the init sequence, but we never 99 109 * got around to fixing it because it works fine on Virtualbox, and on 100 110 * physical machines we tend to have the kernel debugger running on the 101 * same port simply because serial ports are not that plenty on PCs 102 * these days, thus KDB will set port parameters for us. This is going 111 * same port, thus KDB will set port parameters for us. This is going 103 112 * to be fixed eventually... 104 113 */ 105 void init_com 1(void)114 void init_com(void) 106 115 { 107 116 int i; … … 462 471 * sense buffers, etc. and should be freed as soon as possible, otherwise 463 472 * we'll quickly run out of memory. 464 *465 * NOTE: This function is not reentrant, thus must be called with the driver-466 * level spinlock held. The main reason for this design is that most467 * functions that need dynamic memory are already holding the spinlock.468 473 */ 469 474 void *malloc(size_t len) … … 472 477 u16 i; 473 478 u16 n; 479 480 spin_lock(mem_lock); 474 481 475 482 /* find a sequence of free heap units big enough for the requested length */ … … 486 493 heap_units[i] = (u8) (n - i); 487 494 } 495 spin_unlock(mem_lock); 488 496 return(heap_buf + (n - units) * HEAP_UNIT); 489 497 } … … 498 506 499 507 /* out of memory */ 508 spin_unlock(mem_lock); 500 509 dprintf("malloc(%d): out of memory\n", len); 501 510 return(NULL); … … 524 533 525 534 /* clear unit allocation counters in heap_units[] */ 535 spin_lock(mem_lock); 536 526 537 first_unit = (u16) (p - heap_buf) / HEAP_UNIT; 527 538 units = heap_units[first_unit]; … … 529 540 heap_units[i] = 0; 530 541 } 542 543 spin_unlock(mem_lock); 531 544 } 532 545 -
trunk/src/os2ahci/os2ahci.c
r76 r77 41 41 } 42 42 43 /* set two-dimensional array of port options */ 44 #define set_port_option(opt, val) \ 45 if (adapter_index == -1) { \ 46 /* set option for all adapters and ports */ \ 47 memset(opt, val, sizeof(opt)); \ 48 } else if (port_index == -1) { \ 49 /* set option for all ports on current adapter */ \ 50 memset(opt[adapter_index], val, sizeof(*opt)); \ 51 } else { \ 52 /* set option for specific port */ \ 53 opt[adapter_index][port_index] = val; \ 54 } 55 43 56 /* ------------------------ typedefs and structures ------------------------ */ 44 57 45 58 /* -------------------------- function prototypes -------------------------- */ 46 59 47 void _cdecl small_code_ (void); 60 void _cdecl small_code_ (void); 61 62 static int add_unit_info (IORB_CONFIGURATION _far *iorb_conf, int dt_ai, 63 int a, int p, int d, int scsi_id); 48 64 49 65 /* ------------------------ global/static variables ------------------------ */ 50 66 51 67 int debug = 0; /* if > 0, print debug messages to COM1 */ 52 int thorough_scan ;/* if != 0, perform thorough PCI scan */68 int thorough_scan = 1; /* if != 0, perform thorough PCI scan */ 53 69 int init_reset; /* if != 0, reset ports during init */ 54 70 … … 84 100 85 101 /* apapter/port-specific options saved when parsing the command line */ 102 u8 emulate_scsi[MAX_AD][AHCI_MAX_PORTS]; 103 u8 disable_ncq[MAX_AD][AHCI_MAX_PORTS]; 86 104 u8 link_speed[MAX_AD][AHCI_MAX_PORTS]; 87 u8 disable_ncq[MAX_AD][AHCI_MAX_PORTS];105 u8 link_power[MAX_AD][AHCI_MAX_PORTS]; 88 106 89 107 static char init_msg[] = "OS2AHCI driver version %d.%02d\n"; … … 91 109 static char eval_msg[] = ANSI_CLR_RED ANSI_CLR_BRIGHT "Evaluation version " 92 110 "- not licensed for production use.\n" ANSI_RESET; 93 94 111 95 112 /* ----------------------------- start of code ----------------------------- */ … … 139 156 int adapter_index = -1; 140 157 int port_index = -1; 158 int invert_option; 159 int optval; 141 160 u16 vendor; 142 161 u16 device; … … 148 167 DevHelp_CreateSpinLock(&drv_lock); 149 168 150 if (debug) { 151 /* initialize debug interface (COM1) */ 152 init_com1(); 153 } 169 /* initialize libc code */ 170 init_libc(); 154 171 155 172 /* print initialization message */ … … 167 184 168 185 for (s = cmd_line; *s != 0; s++) { 169 if (*s == '/' && s[1] != '\0') { 186 if (*s == '/') { 187 if ((invert_option = (s[1] == '!')) != 0) { 188 s++; 189 } 170 190 s++; 171 switch(tolower(*s)) { 191 switch (tolower(*s)) { 192 193 case '\0': 194 /* end of command line; can only happen if command line is incorrect */ 195 cprintf("incomplete command line option\n"); 196 goto init_fail; 172 197 173 198 case 'c': … … 178 203 case 'd': 179 204 /* increase debug level */ 180 debug++; 205 if (debug++ == 0) { 206 init_com(); 207 } 181 208 break; 182 209 … … 194 221 case 't': 195 222 /* perform thorough PCI scan (i.e. look for individual supported PCI IDs) */ 196 thorough_scan = 1;223 thorough_scan = !invert_option; 197 224 break; 198 225 … … 200 227 /* reset ports during initialization */ 201 228 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 }209 229 break; 210 230 … … 227 247 break; 228 248 249 case 'i': 250 /* ignore current adapter index */ 251 if (adapter_index >= 0) { 252 ad_ignore |= 1U << adapter_index; 253 } 254 break; 255 229 256 case 's': 230 /* set link speed of current port on current adapter */ 231 drv_parm_int(s, link_speed[adapter_index][port_index], u8, 10); 232 init_reset = 1; 257 /* enable SCSI emulation for ATAPI devices */ 258 set_port_option(emulate_scsi, !invert_option); 233 259 break; 234 260 235 261 case 'n': 236 262 /* disable NCQ */ 237 if (adapter_index == -1) { 238 /* disable NCQ on all adapters and ports */ 239 memset(disable_ncq, 0x01, sizeof(disable_ncq)); 240 } else if (port_index == -1) { 241 /* disable NCQ on all ports of this adapter */ 242 memset(disable_ncq[adapter_index], 0x01, sizeof(*disable_ncq)); 243 } else { 244 /* disable NCQ for this adapter and port */ 245 disable_ncq[adapter_index][port_index] = 1; 246 } 263 set_port_option(disable_ncq, !invert_option); 264 break; 265 266 case 'l': 267 /* set link speed or power savings */ 268 s++; 269 switch (tolower(*s)) { 270 case 's': 271 /* set link speed */ 272 drv_parm_int(s, optval, int, 10); 273 set_port_option(link_speed, optval); 274 break; 275 case 'p': 276 /* set power management */ 277 drv_parm_int(s, optval, int, 10); 278 set_port_option(link_power, optval); 279 break; 280 default: 281 cprintf("invalid link parameter (%c)\n", *s); 282 goto init_fail; 283 } 284 /* need to reset the port in order to establish link settings */ 285 init_reset = 1; 247 286 break; 248 287 … … 402 441 iorb->Status = IORB_ERROR; 403 442 iorb->ErrorCode = IOERR_CMD_SYNTAX; 404 complete_iorb(iorb);443 iorb_complete(iorb); 405 444 continue; 406 445 } … … 744 783 * Scan all ports for AHCI devices and construct a DASD device table. 745 784 * 746 * NOTE: This function may be called multiple times. Only the first invocation 747 * will actually scan for devices; all subsequent calls will merely 748 * return the results of the initial scan, potentially augmented by 749 * modified unit infos after IOCC_CONFIGURATION/IOCM_CHANGE_UNITINFO 750 * requests. 785 * NOTES: This function may be called multiple times. Only the first 786 * invocation will actually scan for devices; all subsequent calls will 787 * merely return the results of the initial scan, potentially augmented 788 * by modified unit infos after IOCC_CONFIGURATION/IOCM_CHANGE_UNITINFO 789 * requests. 790 * 791 * In order to support applications that can't deal with ATAPI devies 792 * (i.e. need a SCSI adapter) os2ahci will optionally report ATAPI 793 * dvices as SCSI devices. The corresponding SCSI adapter doesn't 794 * really exist and is only reported here for the IOCM_GET_DEVICETABLE 795 * request. The units attached to this adapter will use the real HW 796 * unit IDs, thus we'll never receive a command specific to the 797 * emulated SCSI adapter and won't need to set up any sort of entity 798 * for it; the only purpose of the emulated SCSI adapter is to pass the 799 * bus type "AI_DEVBUS_SCSI_2" upstream, and the emulated units, of 800 * course. The emulated SCSI target IDs are allocated as follows: 801 * 802 * 0 the virtual adapter 803 * 1..n emulated devices; SCSI target ID increments sequentially 751 804 */ 752 805 void iocm_device_table(IORBH _far *iorb) … … 755 808 DEVICETABLE _far *dt; 756 809 char _far *pos; 810 int scsi_units = 0; 811 int scsi_id = 1; 757 812 int rc; 813 int dta; 758 814 int a; 759 815 int p; … … 769 825 dt->ADDLevelMinor = ADD_LEVEL_MINOR; 770 826 dt->ADDHandle = add_handle; 771 dt->TotalAdapters = ad_info_cnt; 772 773 /* Initial position of dynamic portion of device table (i.e. behind the 774 * array of ADAPTERINFO pointers, pAdapter, in the device table) 775 */ 776 pos = (char _far *) (dt->pAdapter + ad_info_cnt); 777 778 for (a = 0; a < ad_info_cnt; a++) { 827 dt->TotalAdapters = ad_info_cnt + 1; 828 829 /* set start of adapter and device information tables */ 830 pos = (char _far *) (dt->pAdapter + dt->TotalAdapters); 831 832 /* go through all adapters, including the virtual SCSI adapter */ 833 for (dta = 0; dta < dt->TotalAdapters; dta++) { 779 834 ADAPTERINFO _far *ptr = (ADAPTERINFO _far *) pos; 780 AD_INFO *ad_info = ad_infos + a;781 int units = 0;782 835 783 836 /* sanity check for sufficient space in device table */ … … 788 841 } 789 842 790 /* set ADAPTERINFO offset in device table */ 791 dt->pAdapter[a] = (ADAPTERINFO _near *) ((u32) ptr & 0xffff); 792 793 /* fill in adapter information structure in device table */ 843 dt->pAdapter[dta] = (ADAPTERINFO _near *) ((u32) ptr & 0xffff); 794 844 memset(ptr, 0x00, sizeof(*ptr)); 795 sprintf(ptr->AdapterName, "AHCI_%d", a); 796 ptr->AdapterDevBus = AI_DEVBUS_ST506 | AI_DEVBUS_32BIT; 845 797 846 ptr->AdapterIOAccess = AI_IOACCESS_BUS_MASTER; 798 847 ptr->AdapterHostBus = AI_HOSTBUS_OTHER | AI_BUSWIDTH_32BIT; 799 848 ptr->AdapterFlags = AF_16M | AF_HW_SCATGAT; 800 801 /* AHCI limits S/G elements to 22 bits, thus we'll report only half of 802 * our S/G list buffers to reduce complexity. The command preparation code 803 * will always try to map as many S/G elements as possible so the physical 804 * S/G list capacity is not really wasted except in rare conditions where 805 * we need to split commands with long S/G lists without any suitable split 806 * points except those at the reported MaxHWSGList. 807 */ 808 ptr->MaxHWSGList = AHCI_MAX_SG / 2; 809 810 if (!ad_info->port_scan_done) { 811 /* First call; need to scan AHCI hardware for devices. Since this might 812 * be a lengthy operation, especially when init_reset is set, we'll mark 813 * the adapter as busy (new IORBs will only be queued but not executed) 814 * and release the spinlock while scanning the ports so interrupts will 815 * be processed. 816 */ 817 if (ad_info->busy) { 818 dprintf("error: port scan requested while adapter was busy\n"); 819 iorb_seterr(iorb, IOERR_CMD_SW_RESOURCE); 820 goto iocm_device_table_done; 849 ptr->MaxHWSGList = AHCI_MAX_SG / 2; /* AHCI S/G elements are 22 bits */ 850 851 if (dta < ad_info_cnt) { 852 /* this is a physical AHCI adapter */ 853 AD_INFO *ad_info = ad_infos + dta; 854 855 ptr->AdapterDevBus = AI_DEVBUS_ST506 | AI_DEVBUS_32BIT; 856 sprintf(ptr->AdapterName, "AHCI_%d", dta); 857 858 if (!ad_info->port_scan_done) { 859 /* first call; need to scan AHCI hardware for devices */ 860 if (ad_info->busy) { 861 dprintf("error: port scan requested while adapter was busy\n"); 862 iorb_seterr(iorb, IOERR_CMD_SW_RESOURCE); 863 goto iocm_device_table_done; 864 } 865 ad_info->busy = 1; 866 spin_unlock(drv_lock); 867 rc = ahci_scan_ports(ad_info); 868 spin_lock(drv_lock); 869 ad_info->busy = 0; 870 871 if (rc != 0) { 872 dprintf("error: port scan failed on adapter #%d\n", dta); 873 iorb_seterr(iorb, IOERR_CMD_SW_RESOURCE); 874 goto iocm_device_table_done; 875 } 876 ad_info->port_scan_done = 1; 821 877 } 822 ad_info->busy = 1; 823 spin_unlock(drv_lock); 824 rc = ahci_scan_ports(ad_info); 825 spin_lock(drv_lock); 826 ad_info->busy = 0; 827 828 if (rc != 0) { 829 dprintf("error: port scan failed on adapter #%d\n", a); 830 iorb_seterr(iorb, IOERR_CMD_SW_RESOURCE); 831 goto iocm_device_table_done; 832 } 833 ad_info->port_scan_done = 1; 834 } 835 836 /* insert devices (units) into the device table */ 837 for (p = 0; p <= ad_info->port_max; p++) { 838 for (d = 0; d <= ad_info->ports[p].dev_max; d++) { 839 if (ad_info->ports[p].devs[d].present) { 840 UNITINFO _far *ui = ptr->UnitInfo + units; 841 842 /* sanity check for sufficient space in device table */ 843 if ((u32) (ui + 1) - (u32) dt > iorb_conf->DeviceTableLen) { 844 dprintf("error: device table provided by DASD too small\n"); 845 iorb_seterr(iorb, IOERR_CMD_SW_RESOURCE); 846 goto iocm_device_table_done; 878 879 /* insert physical (i.e. AHCI) devices into the device table */ 880 for (p = 0; p <= ad_info->port_max; p++) { 881 for (d = 0; d <= ad_info->ports[p].dev_max; d++) { 882 if (ad_info->ports[p].devs[d].present) { 883 if (ad_info->ports[p].devs[d].atapi && emulate_scsi[dta][p]) { 884 /* only report this unit as SCSI unit */ 885 scsi_units++; 886 continue; 887 } 888 if (add_unit_info(iorb_conf, dta, dta, p, d, 0)) { 889 goto iocm_device_table_done; 890 } 847 891 } 848 849 if (ad_info->ports[p].devs[d].unit_info == NULL) {850 /* provide initial information about this device (unit) */851 memset(ui, 0x00, sizeof(*ui));852 ui->AdapterIndex = a;853 ui->UnitIndex = units;854 ui->UnitHandle = iorb_unit(a, p, d);855 ui->UnitType = ad_info->ports[p].devs[d].dev_type;856 ui->QueuingCount = ad_info->ports[p].devs[d].ncq_max;;857 if (ad_info->ports[p].devs[d].removable) {858 ui->UnitFlags |= UF_REMOVABLE;859 }860 } else {861 /* copy updated device (unit) information (IOCM_CHANGE_UNITINFO) */862 memcpy(ui, ad_info->ports[p].devs[d].unit_info, sizeof(*ui));863 }864 units++;865 892 } 866 893 } 867 } 868 869 /* set total device (unit) count for this adapter */ 870 ptr->AdapterUnits = units; 894 895 } else { 896 /* this is the virtual SCSI adapter */ 897 if (scsi_units == 0) { 898 /* not a single unit to be emulated via SCSI */ 899 dt->TotalAdapters--; 900 break; 901 } 902 903 /* set adapter name and bus type to mimic a SCSI controller */ 904 ptr->AdapterDevBus = AI_DEVBUS_SCSI_2 | AI_DEVBUS_16BIT; 905 sprintf(ptr->AdapterName, "AHCI_SCSI_0"); 906 907 /* add all ATAPI units to be emulated by this virtual adaper */ 908 for (a = 0; a < ad_info_cnt; a++) { 909 AD_INFO *ad_info = ad_infos + a; 910 911 for (p = 0; p <= ad_info->port_max; p++) { 912 for (d = 0; d <= ad_info->ports[p].dev_max; d++) { 913 if (ad_info->ports[p].devs[d].present && 914 ad_info->ports[p].devs[d].atapi && 915 emulate_scsi[a][p]) { 916 if (add_unit_info(iorb_conf, dta, a, p, d, scsi_id++)) { 917 goto iocm_device_table_done; 918 } 919 } 920 } 921 } 922 } 923 } 871 924 872 925 /* calculate offset for next adapter */ 873 pos = (char _far *) (ptr->UnitInfo + units);926 pos = (char _far *) (ptr->UnitInfo + ptr->AdapterUnits); 874 927 } 875 928 … … 1088 1141 * Due to this logic, this function is only good for simple task-time 1089 1142 * completions. Functions working on lists of IORBs (such as interrupt 1090 * handlers or context hooks) should implement their own logic. See 1091 * abort_ctxhook() for an example. 1143 * handlers or context hooks) should call iorb_complete() directly and 1144 * implement their own logic for removing the IORB from the port queue. 1145 * See abort_ctxhook() for an example. 1092 1146 */ 1093 1147 void iorb_done(IORBH _far *iorb) … … 1106 1160 spin_unlock(drv_lock); 1107 1161 1108 complete_iorb(iorb); 1162 iorb_complete(iorb); 1163 } 1164 1165 /****************************************************************************** 1166 * Complete an IORB. It should be called without the adapter-level spinlock 1167 * to allow the IORB completion routine to perform whatever processing it 1168 * requires. This implies that the IORB should no longer be in any global 1169 * queue because the IORB completion routine may well reuse the IORB and send 1170 * the next request to us before even returning from this function. 1171 */ 1172 void iorb_complete(IORBH _far *iorb) 1173 { 1174 iorb->Status |= IORB_DONE; 1175 1176 dprintf("IORB %Fp complete (status = 0x%04x, error = 0x%04x)\n", 1177 iorb, iorb->Status, iorb->ErrorCode); 1178 1179 if (iorb->RequestControl & IORB_ASYNC_POST) { 1180 iorb->NotifyAddress(iorb); 1181 } 1109 1182 } 1110 1183 … … 1126 1199 memset(aws, 0x00, sizeof(*aws)); 1127 1200 aws->no_ncq = no_ncq; 1201 } 1202 1203 /****************************************************************************** 1204 * Free resources in ADD workspace (timer, buffer, ...). This function should 1205 * be called with the spinlock held to prevent race conditions. 1206 */ 1207 void aws_free(ADD_WORKSPACE _far *aws) 1208 { 1209 if (aws->timer != 0) { 1210 ADD_CancelTimer(aws->timer); 1211 aws->timer = 0; 1212 } 1213 1214 if (aws->buf != NULL) { 1215 free(aws->buf); 1216 aws->buf = NULL; 1217 } 1128 1218 } 1129 1219 … … 1201 1291 { 1202 1292 } 1293 1294 /****************************************************************************** 1295 * Add unit info to ADAPTERINFO array (IOCC_GET_DEVICE_TABLE requests). The 1296 * adapter info array in the device table, dt->pAdapter[], is expected to be 1297 * initialized for the specified index (dt_ai). 1298 * 1299 * Please note that the device table adapter index, dta, is not always equal 1300 * to the physical adapter index, a: if SCSI emulation has been activated, the 1301 * last reported adapter is a virtual SCSI adapter and the physical adapter 1302 * indexes for those units are, of course, different from the device table 1303 * index of the virtual SCSI adapter. 1304 */ 1305 static int add_unit_info(IORB_CONFIGURATION _far *iorb_conf, int dta, 1306 int a, int p, int d, int scsi_id) 1307 { 1308 DEVICETABLE _far *dt = iorb_conf->pDeviceTable; 1309 ADAPTERINFO _far *ptr = (ADAPTERINFO _far *) (((u32) dt & 0xffff0000U) + 1310 (u16) dt->pAdapter[dta]); 1311 UNITINFO _far *ui = ptr->UnitInfo + ptr->AdapterUnits; 1312 AD_INFO *ai = ad_infos + a; 1313 1314 if ((u32) (ui + 1) - (u32) dt > iorb_conf->DeviceTableLen) { 1315 dprintf("error: device table provided by DASD too small\n"); 1316 iorb_seterr(&iorb_conf->iorbh, IOERR_CMD_SW_RESOURCE); 1317 return(-1); 1318 } 1319 1320 if (ai->ports[p].devs[d].unit_info == NULL) { 1321 /* provide original information about this device (unit) */ 1322 memset(ui, 0x00, sizeof(*ui)); 1323 ui->AdapterIndex = dta; /* device table adapter index */ 1324 ui->UnitHandle = iorb_unit(a, p, d); /* physical adapter index */ 1325 ui->UnitIndex = ptr->AdapterUnits; 1326 ui->UnitType = ai->ports[p].devs[d].dev_type; 1327 ui->QueuingCount = ai->ports[p].devs[d].ncq_max;; 1328 if (ai->ports[p].devs[d].removable) { 1329 ui->UnitFlags |= UF_REMOVABLE; 1330 } 1331 if (scsi_id > 0) { 1332 /* set fake SCSI ID for this unit */ 1333 ui->UnitSCSITargetID = scsi_id; 1334 } 1335 } else { 1336 /* copy updated device (unit) information (IOCM_CHANGE_UNITINFO) */ 1337 memcpy(ui, ai->ports[p].devs[d].unit_info, sizeof(*ui)); 1338 } 1339 1340 ptr->AdapterUnits++; 1341 return(0); 1342 } 1343 -
trunk/src/os2ahci/os2ahci.def
r76 r77 1 1 library os2ahci 2 Description '$@#thi.guten (www.thiguten.de):1.00.201102 18#@OS/2 AHCI Adapter Device Driver'2 Description '$@#thi.guten (www.thiguten.de):1.00.20110221#@OS/2 AHCI Adapter Device Driver' 3 3 protmode 4 4 -
trunk/src/os2ahci/os2ahci.h
r76 r77 115 115 /* ctype macros */ 116 116 #define isupper(ch) ((ch) >= 'A' && (ch) <= 'Z') 117 #define tolower(ch) (isupper(ch) ? (ch) -('a' - 'A') : (ch))117 #define tolower(ch) (isupper(ch) ? (ch) + ('a' - 'A') : (ch)) 118 118 119 119 /* stddef macros */ … … 192 192 #define add_workspace(iorb) ((ADD_WORKSPACE _far *) &(iorb)->ADDWorkSpace) 193 193 194 /* free resources in ADD workspace (timer, buffer, ...) */195 #define aws_free(aws) if ((aws)->timer != 0) { \196 ADD_CancelTimer((aws)->timer); \197 (aws)->timer = 0; \198 } \199 if ((aws)->buf != NULL) { \200 free((aws)->buf); \201 (aws)->buf = NULL; \202 }203 204 /* complete IORB */205 #define complete_iorb(iorb) (iorb)->Status |= IORB_DONE; \206 dprintf("IORB %Fp complete " \207 "(status = 0x%04x, error = 0x%04x)\n", \208 (iorb), (iorb)->Status, \209 (iorb)->ErrorCode); \210 if ((iorb)->RequestControl & IORB_ASYNC_POST) { \211 (iorb)->NotifyAddress(iorb); \212 }213 194 214 195 … … 264 245 #define ANSI_CLR_WHITE "\x1b[37m" 265 246 #define ANSI_RESET "\x1b[0m" 266 267 247 268 248 /* ------------------------ typedefs and structures ------------------------ */ … … 397 377 extern void iorb_seterr (IORBH _far *iorb, USHORT error_code); 398 378 extern void iorb_done (IORBH _far *iorb); 379 extern void iorb_complete (IORBH _far *iorb); 399 380 extern void iorb_requeue (IORBH _far *iorb); 381 extern void aws_free (ADD_WORKSPACE _far *aws); 400 382 extern void lock_adapter (AD_INFO *ai); 401 383 extern void unlock_adapter (AD_INFO *ai); … … 443 425 444 426 /* libc.c */ 445 extern void init_com1 (void); 427 extern void init_libc (void); 428 extern void init_com (void); 446 429 extern int vsprintf (char _far *buf, const char *fmt, va_list va); 447 430 extern int sprintf (char _far *buf, const char *fmt, ...); … … 523 506 524 507 /* apapter/port-specific options saved when parsing the command line */ 508 extern u8 emulate_scsi[MAX_AD][AHCI_MAX_PORTS]; 509 extern u8 disable_ncq[MAX_AD][AHCI_MAX_PORTS]; 525 510 extern u8 link_speed[MAX_AD][AHCI_MAX_PORTS]; 526 extern u8 disable_ncq[MAX_AD][AHCI_MAX_PORTS];527 511 extern u8 link_power[MAX_AD][AHCI_MAX_PORTS]; 512 -
trunk/src/os2ahci/pci.c
r76 r77 620 620 * resource is added to the corresponding rc_list.hResource[] slot. 621 621 * rc_list is used further down to associate resources to adapters 622 * whe the adapter itself is registered with the OS/2 resource manager. 622 * when the adapter itself is registered with the OS/2 resource 623 * manager. 623 624 */ 624 625 ad_info = ad_infos + ad_info_cnt; -
trunk/src/os2ahci/version.h
r76 r77 6 6 7 7 8 #define VERSION 10 3/* driver version (2 implied decimals) */8 #define VERSION 104 /* 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.