- Timestamp:
- May 28, 2021 3:44:38 PM (3 years ago)
- Location:
- trunk/src/VBox/Devices/PC/BIOS
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/BIOS/ahci.c
r82968 r89364 107 107 /** Current PRD index (for pre/post skip). */ 108 108 uint8_t cur_prd; 109 /** Physical address of the sink buffer (for pre/post skip). */110 uint32_t sink_buf_phys;111 109 /** Saved high bits of EAX. */ 112 110 uint16_t saved_eax_hi; … … 368 366 /* Lock memory needed for DMA. */ 369 367 ahci->edds.num_avail = NUM_EDDS_SG; 370 DBG_AHCI("AHCI: S/G list for %lu bytes (skip %u)\n", 371 (uint32_t)n_sect * sectsz, bios_dsk->drqp.skip_a); 368 DBG_AHCI("AHCI: S/G list for %lu bytes\n", (uint32_t)n_sect * sectsz); 372 369 vds_build_sg_list(&ahci->edds, bios_dsk->drqp.buffer, (uint32_t)n_sect * sectsz); 373 370 … … 376 373 ahci->aPrdt[ahci->cur_prd].phys_addr = ahci->edds.u.sg[0].phys_addr; 377 374 ++ahci->cur_prd; 378 379 if (bios_dsk->drqp.skip_a) {380 ahci->aPrdt[ahci->cur_prd].len = bios_dsk->drqp.skip_a - 1;381 ahci->aPrdt[ahci->cur_prd].phys_addr = ahci->sink_buf_phys;382 ++ahci->cur_prd;383 }384 375 385 376 #if DEBUG_AHCI … … 575 566 576 567 uint16_t ahci_cmd_packet(uint16_t device_id, uint8_t cmdlen, char __far *cmdbuf, 577 uint 16_t skip_b, uint32_t length, uint8_t inout, char __far *buffer)568 uint32_t length, uint8_t inout, char __far *buffer) 578 569 { 579 570 bio_dsk_t __far *bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk; … … 586 577 } 587 578 588 /* The skip length must be even. */589 if (skip_b & 1) {590 DBG_AHCI("%s: skip must be even (%04x)\n", __func__, skip_b);591 return 1;592 }593 594 579 /* Convert to AHCI specific device number. */ 595 580 device_id = VBOX_GET_AHCI_DEVICE(device_id); 596 581 597 DBG_AHCI("%s: reading %lu bytes, skip %u/%u, device %d, port %d\n", __func__, 598 length, bios_dsk->drqp.skip_b, bios_dsk->drqp.skip_a, 599 device_id, bios_dsk->ahcidev[device_id].port); 582 DBG_AHCI("%s: reading %lu bytes, device %d, port %d\n", __func__, 583 length, device_id, bios_dsk->ahcidev[device_id].port); 600 584 DBG_AHCI("%s: reading %u %u-byte sectors\n", __func__, 601 585 bios_dsk->drqp.nsect, bios_dsk->drqp.sect_sz); … … 618 602 bios_dsk->drqp.trsfsectors = 0; 619 603 bios_dsk->drqp.trsfbytes = 0; 620 621 /* Set up a PRD entry to throw away the beginning of the transfer. */622 if (bios_dsk->drqp.skip_b) {623 ahci->aPrdt[0].len = bios_dsk->drqp.skip_b - 1;624 ahci->aPrdt[0].phys_addr = ahci->sink_buf_phys;625 ahci->cur_prd++;626 }627 604 628 605 ahci_cmd_data(bios_dsk, ATA_CMD_PACKET); … … 899 876 ahci->iobase = io_base; 900 877 901 /* Physical address of memory used for throwing away ATAPI data when reading 512-byte902 * blocks from 2048-byte CD sectors.903 */904 ahci->sink_buf_phys = 0xCC000; /// @todo find some better place!905 906 878 /* Reset the controller. */ 907 879 ahci_ctrl_set_bits(io_base, AHCI_REG_GHC, AHCI_GHC_HR); -
trunk/src/VBox/Devices/PC/BIOS/ata.c
r82968 r89364 74 74 // --------------------------------------------------------------------------- 75 75 76 void insw_discard(unsigned nwords, unsigned port);77 #pragma aux insw_discard = \78 ".286" \79 "again:" \80 "in ax,dx" \81 "loop again" \82 parm [cx] [dx] modify exact [cx ax] nomemory;83 84 void insd_discard(unsigned ndwords, unsigned port);85 #if VBOX_BIOS_CPU >= 8038686 # pragma aux insd_discard = \87 ".386" \88 "push eax" \89 "again:" \90 "in eax,dx" \91 "loop again" \92 "pop eax" \93 parm [cx] [dx] modify exact [cx] nomemory;94 #endif95 96 76 // --------------------------------------------------------------------------- 97 77 // ATA/ATAPI driver : initialization … … 1015 995 // 4 : not ready 1016 996 uint16_t ata_cmd_packet(uint16_t device, uint8_t cmdlen, char __far *cmdbuf, 1017 uint 16_t header, uint32_t length, uint8_t inout, char __far *buffer)997 uint32_t length, uint8_t inout, char __far *buffer) 1018 998 { 1019 999 uint16_t iobase1, iobase2; 1020 uint16_t lcount, lbefore, lafter,count;1000 uint16_t lcount, count; 1021 1001 uint8_t channel, slave; 1022 1002 uint8_t status, mode, lmode; … … 1032 1012 if (inout == ATA_DATA_OUT) { 1033 1013 BX_INFO("%s: DATA_OUT not supported yet\n", __func__); 1034 return 1;1035 }1036 1037 // The header length must be even1038 if (header & 1) {1039 BX_DEBUG_ATA("%s: header must be even (%04x)\n", __func__, header);1040 1014 return 1; 1041 1015 } … … 1140 1114 lcount = ((uint16_t)(inb(iobase1 + ATA_CB_CH))<<8)+inb(iobase1 + ATA_CB_CL); 1141 1115 1142 // adjust to read what we want1143 if (header>lcount) {1144 lbefore = lcount;1145 header -= lcount;1146 lcount = 0;1147 }1148 else {1149 lbefore = header;1150 header = 0;1151 lcount -= lbefore;1152 }1153 1154 if (lcount>length) {1155 lafter = lcount - length;1156 lcount = length;1157 length = 0;1158 }1159 else {1160 lafter = 0;1161 length -= lcount;1162 }1163 1164 1116 // Save byte count 1165 1117 count = lcount; 1166 1118 1167 BX_DEBUG_ATA("Trying to read %04x bytes (%04x %04x %04x) ",lbefore+lcount+lafter,lbefore,lcount,lafter);1119 BX_DEBUG_ATA("Trying to read %04x bytes ",lcount); 1168 1120 BX_DEBUG_ATA("to 0x%04x:0x%04x\n",FP_SEG(buffer),FP_OFF(buffer)); 1169 1121 1170 1122 // If counts not dividable by 4, use 16bits mode 1171 1123 lmode = mode; 1172 if (lbefore & 0x03)1173 lmode = ATA_MODE_PIO16;1174 1124 if (lcount & 0x03) 1175 lmode = ATA_MODE_PIO16;1176 if (lafter & 0x03)1177 1125 lmode = ATA_MODE_PIO16; 1178 1126 … … 1180 1128 if (lcount & 0x01) { 1181 1129 lcount += 1; 1182 if ((lafter > 0) && (lafter & 0x01)) {1183 lafter -= 1;1184 }1185 1130 } 1186 1131 … … 1188 1133 if (lmode == ATA_MODE_PIO32) { 1189 1134 lcount >>= 2; 1190 lbefore >>= 2;1191 lafter >>= 2;1192 1135 } else 1193 1136 #endif 1194 1137 { 1195 1138 lcount >>= 1; 1196 lbefore >>= 1;1197 lafter >>= 1;1198 1139 } 1199 1140 1200 1141 #if VBOX_BIOS_CPU >= 80386 1201 1142 if (lmode == ATA_MODE_PIO32) { 1202 if (lbefore)1203 insd_discard(lbefore, iobase1);1204 1143 rep_insd(buffer, lcount, iobase1); 1205 if (lafter)1206 insd_discard(lafter, iobase1);1207 1144 } else 1208 1145 #endif 1209 1146 { 1210 if (lbefore)1211 insw_discard(lbefore, iobase1);1212 1147 rep_insw(buffer, lcount, iobase1); 1213 if (lafter)1214 insw_discard(lafter, iobase1);1215 1148 } 1216 1149 -
trunk/src/VBox/Devices/PC/BIOS/buslogic.c
r89272 r89364 100 100 /** I/O base of device. */ 101 101 uint16_t u16IoBase; 102 /** The sink buf. */103 void __far *pvSinkBuf;104 /** Size of the sink buffer in bytes. */105 uint16_t cbSinkBuf;106 102 } buslogic_t; 107 103 … … 172 168 173 169 int buslogic_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB, 174 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b, 175 uint16_t skip_a) 170 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length) 176 171 { 177 172 buslogic_t __far *buslogic = (buslogic_t __far *)pvHba; … … 182 177 DBG_BUSLOGIC("buslogic_scsi_cmd_data_in:\n"); 183 178 184 if ( ( skip_b185 || skip_a)186 && skip_b + length + skip_a > buslogic->cbSinkBuf) /* Sink buffer is only 16KB at the moment. */187 return 1;188 189 179 _fmemset(&buslogic->EsCmd, 0, sizeof(buslogic->EsCmd)); 190 180 _fmemset(abReply, 0, sizeof(abReply)); 191 181 192 if (!skip_b && !skip_a) 193 { 194 buslogic->EsCmd.cbData = length; 195 buslogic->EsCmd.u32PhysAddrData = buslogic_addr_to_phys(buffer); 196 } 197 else 198 { 199 buslogic->EsCmd.cbData = length + skip_b + skip_a; 200 buslogic->EsCmd.u32PhysAddrData = buslogic_addr_to_phys(buslogic->pvSinkBuf); /* Requires the sink buffer because there is no S/G variant. */ 201 } 182 buslogic->EsCmd.cbData = length; 183 buslogic->EsCmd.u32PhysAddrData = buslogic_addr_to_phys(buffer); 202 184 buslogic->EsCmd.uTargetId = idTgt; 203 185 buslogic->EsCmd.uLogicalUnit = 0; … … 211 193 sizeof(buslogic->EsCmd) - sizeof(buslogic->EsCmd.abCDB) + cbCDB, &abReply[0], sizeof(abReply)); 212 194 if (!rc) 213 { 214 /* Copy the data over from the sink buffer. */ 215 if (abReply[2] == 0) 216 { 217 if (skip_b || skip_a) 218 _fmemcpy(buffer, (const uint8_t __far *)buslogic->pvSinkBuf + skip_b, length); 219 } 220 else 221 rc = abReply[2]; 222 } 195 rc = abReply[2]; 223 196 224 197 return rc; … … 240 213 * Init the BusLogic SCSI driver and detect attached disks. 241 214 */ 242 int buslogic_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint16_t cbSinkBuf,uint8_t u8Bus, uint8_t u8DevFn)215 int buslogic_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn) 243 216 { 244 217 buslogic_t __far *buslogic = (buslogic_t __far *)pvHba; … … 260 233 DBG_BUSLOGIC("I/O base: 0x%x\n", u16IoBase); 261 234 buslogic->u16IoBase = u16IoBase; 262 buslogic->pvSinkBuf = pvSinkBuf;263 buslogic->cbSinkBuf = cbSinkBuf;264 235 return buslogic_scsi_hba_init(buslogic); 265 236 } -
trunk/src/VBox/Devices/PC/BIOS/ebda.h
r89363 r89364 242 242 uint16_t trsfsectors; /* Actual sectors transferred. */ 243 243 uint32_t trsfbytes; /* Actual bytes transferred. */ 244 uint16_t skip_b; /* Bytes to skip before transfer. */245 uint16_t skip_a; /* Bytes to skip after transfer. */246 244 } disk_req_t; 247 245 248 246 extern uint16_t ahci_cmd_packet(uint16_t device_id, uint8_t cmdlen, char __far *cmdbuf, 249 uint 16_t header, uint32_t length, uint8_t inout, char __far *buffer);247 uint32_t length, uint8_t inout, char __far *buffer); 250 248 extern uint16_t scsi_cmd_packet(uint16_t device, uint8_t cmdlen, char __far *cmdbuf, 251 uint 16_t header, uint32_t length, uint8_t inout, char __far *buffer);249 uint32_t length, uint8_t inout, char __far *buffer); 252 250 extern uint16_t ata_cmd_packet(uint16_t device, uint8_t cmdlen, char __far *cmdbuf, 253 uint 16_t header, uint32_t length, uint8_t inout, char __far *buffer);251 uint32_t length, uint8_t inout, char __far *buffer); 254 252 255 253 extern uint16_t ata_soft_reset(uint16_t device); -
trunk/src/VBox/Devices/PC/BIOS/eltorito.c
r89363 r89364 111 111 /* Generic ATAPI/SCSI CD-ROM access routine signature. */ 112 112 typedef uint16_t (* cd_pkt_func)(uint16_t device_id, uint8_t cmdlen, char __far *cmdbuf, 113 uint 16_t header, uint32_t length, uint8_t inout, char __far *buffer);113 uint32_t length, uint8_t inout, char __far *buffer); 114 114 115 115 /* Pointers to HW specific CD-ROM access routines. */ … … 307 307 bios_dsk->drqp.nsect = nbsectors; 308 308 bios_dsk->drqp.sect_sz = 2048L; 309 bios_dsk->drqp.skip_b = 0; 310 bios_dsk->drqp.skip_a = 0; 311 312 return pktacc[bios_dsk->devices[device].type](device, 12, (char __far *)&atapicmd, 0, nbsectors*2048L, ATA_DATA_IN, buf); 309 310 return pktacc[bios_dsk->devices[device].type](device, 12, (char __far *)&atapicmd, nbsectors*2048L, ATA_DATA_IN, buf); 313 311 } 314 312 -
trunk/src/VBox/Devices/PC/BIOS/lsilogic.c
r89267 r89364 284 284 MptSCSIIORequest ScsiIoReq; 285 285 /** S/G elements being used, must come after the I/O request structure. */ 286 MptSGEntrySimple32 aSge[3];286 MptSGEntrySimple32 Sge; 287 287 /** The reply frame used for address replies. */ 288 288 uint8_t abReply[128]; 289 289 /** I/O base of device. */ 290 290 uint16_t u16IoBase; 291 /** The sink buf. */292 void __far *pvSinkBuf;293 291 } lsilogic_t; 294 292 … … 412 410 lsilogic->ScsiIoReq.au8CDB[i] = aCDB[i]; 413 411 414 lsilogic-> aSge[0].u24Length = length;415 lsilogic-> aSge[0].fEndOfList = 1;416 lsilogic-> aSge[0].f64BitAddress = 0;417 lsilogic-> aSge[0].fBufferContainsData = 0;418 lsilogic-> aSge[0].fLocalAddress = 0;419 lsilogic-> aSge[0].u2ElementType = 0x01; /* Simple type */420 lsilogic-> aSge[0].fEndOfBuffer = 1;421 lsilogic-> aSge[0].fLastElement = 1;422 lsilogic-> aSge[0].u32DataBufferAddressLow = lsilogic_addr_to_phys(buffer);412 lsilogic->Sge.u24Length = length; 413 lsilogic->Sge.fEndOfList = 1; 414 lsilogic->Sge.f64BitAddress = 0; 415 lsilogic->Sge.fBufferContainsData = 0; 416 lsilogic->Sge.fLocalAddress = 0; 417 lsilogic->Sge.u2ElementType = 0x01; /* Simple type */ 418 lsilogic->Sge.fEndOfBuffer = 1; 419 lsilogic->Sge.fLastElement = 1; 420 lsilogic->Sge.u32DataBufferAddressLow = lsilogic_addr_to_phys(buffer); 423 421 424 422 return lsilogic_scsi_cmd_exec(lsilogic); … … 426 424 427 425 int lsilogic_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB, 428 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b, 429 uint16_t skip_a) 426 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length) 430 427 { 431 428 lsilogic_t __far *lsilogic = (lsilogic_t __far *)pvHba; 432 429 int i; 433 uint8_t idxSge = 0;434 430 435 431 _fmemset(&lsilogic->ScsiIoReq, 0, sizeof(lsilogic->ScsiIoReq)); … … 443 439 lsilogic->ScsiIoReq.u32MessageContext = 0xcafe; 444 440 lsilogic->ScsiIoReq.u32Control = MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ << 24; 441 lsilogic->ScsiIoReq.u32DataLength = length; 445 442 for (i = 0; i < cbCDB; i++) 446 443 lsilogic->ScsiIoReq.au8CDB[i] = aCDB[i]; 447 444 448 lsilogic->ScsiIoReq.u32DataLength = skip_a + length + skip_b; 449 450 /* Prepend a sinkhole if data is skipped upfront. */ 451 if (skip_b) 452 { 453 lsilogic->aSge[idxSge].u24Length = skip_b; 454 lsilogic->aSge[idxSge].fEndOfList = 0; 455 lsilogic->aSge[idxSge].f64BitAddress = 0; 456 lsilogic->aSge[idxSge].fBufferContainsData = 0; 457 lsilogic->aSge[idxSge].fLocalAddress = 0; 458 lsilogic->aSge[idxSge].u2ElementType = 0x01; /* Simple type */ 459 lsilogic->aSge[idxSge].fEndOfBuffer = 0; 460 lsilogic->aSge[idxSge].fLastElement = 0; 461 lsilogic->aSge[idxSge].u32DataBufferAddressLow = lsilogic_addr_to_phys(lsilogic->pvSinkBuf); 462 463 idxSge++; 464 } 465 466 lsilogic->aSge[idxSge].u24Length = length; 467 lsilogic->aSge[idxSge].fEndOfList = skip_a ? 0 : 1; 468 lsilogic->aSge[idxSge].f64BitAddress = 0; 469 lsilogic->aSge[idxSge].fBufferContainsData = 0; 470 lsilogic->aSge[idxSge].fLocalAddress = 0; 471 lsilogic->aSge[idxSge].u2ElementType = 0x01; /* Simple type */ 472 lsilogic->aSge[idxSge].fEndOfBuffer = skip_a ? 0 : 1; 473 lsilogic->aSge[idxSge].fLastElement = skip_a ? 0 : 1; 474 lsilogic->aSge[idxSge].u32DataBufferAddressLow = lsilogic_addr_to_phys(buffer); 475 476 idxSge++; 477 478 /* Append a sinkhole if data is skipped at the end. */ 479 if (skip_a) 480 { 481 lsilogic->aSge[idxSge].u24Length = skip_a; 482 lsilogic->aSge[idxSge].fEndOfList = 1; 483 lsilogic->aSge[idxSge].f64BitAddress = 0; 484 lsilogic->aSge[idxSge].fBufferContainsData = 0; 485 lsilogic->aSge[idxSge].fLocalAddress = 0; 486 lsilogic->aSge[idxSge].u2ElementType = 0x01; /* Simple type */ 487 lsilogic->aSge[idxSge].fEndOfBuffer = 1; 488 lsilogic->aSge[idxSge].fLastElement = 1; 489 lsilogic->aSge[idxSge].u32DataBufferAddressLow = lsilogic_addr_to_phys(lsilogic->pvSinkBuf); 490 idxSge++; 491 } 445 lsilogic->Sge.u24Length = length; 446 lsilogic->Sge.fEndOfList = 1; 447 lsilogic->Sge.f64BitAddress = 0; 448 lsilogic->Sge.fBufferContainsData = 0; 449 lsilogic->Sge.fLocalAddress = 0; 450 lsilogic->Sge.u2ElementType = 0x01; /* Simple type */ 451 lsilogic->Sge.fEndOfBuffer = 1; 452 lsilogic->Sge.fLastElement = 1; 453 lsilogic->Sge.u32DataBufferAddressLow = lsilogic_addr_to_phys(buffer); 492 454 493 455 return lsilogic_scsi_cmd_exec(lsilogic); … … 536 498 * Init the LsiLogic SCSI driver and detect attached disks. 537 499 */ 538 int lsilogic_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint16_t cbSinkBuf,uint8_t u8Bus, uint8_t u8DevFn)500 int lsilogic_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn) 539 501 { 540 502 lsilogic_t __far *lsilogic = (lsilogic_t __far *)pvHba; … … 556 518 DBG_LSILOGIC("I/O base: 0x%x\n", u16IoBase); 557 519 lsilogic->u16IoBase = u16IoBase; 558 lsilogic->pvSinkBuf = pvSinkBuf;559 520 return lsilogic_scsi_hba_init(lsilogic); 560 521 } -
trunk/src/VBox/Devices/PC/BIOS/scsi.c
r89267 r89364 35 35 #define VBOX_SCSI_NO_HBA 0xffff 36 36 37 #define VBOX_SCSI_SINK_BUF_KB 16 38 39 typedef int (* scsi_hba_init)(void __far *pvHba, void __far *pvSinkBuf, uint16_t cbSinkBuf, uint8_t u8Bus, uint8_t u8DevFn); 37 typedef int (* scsi_hba_init)(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn); 40 38 typedef int (* scsi_hba_cmd_data_out)(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB, 41 39 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length); 42 40 typedef int (* scsi_hba_cmd_data_in)(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB, 43 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_a, 44 uint16_t skip_b); 41 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length); 45 42 46 43 typedef struct … … 114 111 115 112 return hba_seg; 116 }117 118 /**119 * Allocates 1K of conventional memory.120 */121 static uint16_t scsi_sink_buf_alloc(void)122 {123 uint16_t base_mem_kb;124 uint16_t sink_seg;125 126 base_mem_kb = read_word(0x00, 0x0413);127 128 DBG_SCSI("SCSI: %dK of base mem\n", base_mem_kb);129 130 if (base_mem_kb == 0)131 return 0;132 133 base_mem_kb -= VBOX_SCSI_SINK_BUF_KB;134 sink_seg = (((uint32_t)base_mem_kb * 1024) >> 4); /* Calculate start segment. */135 136 write_word(0x00, 0x0413, base_mem_kb);137 138 return sink_seg;139 113 } 140 114 … … 181 155 182 156 rc = hbaacc[idx_hba].cmd_data_in(hba_seg :> 0, target_id, (void __far *)&cdb, 16, 183 bios_dsk->drqp.buffer, (count * 512L) , 0, 0);157 bios_dsk->drqp.buffer, (count * 512L)); 184 158 if (!rc) 185 159 { … … 259 233 * @param cmdlen Length of the CDB. 260 234 * @param cmdbuf The CDB buffer. 261 * @param skip_b How much to skip before reading into the provided data buffer.262 235 * @param length How much to transfer. 263 236 * @param inout Read/Write direction indicator. … … 265 238 */ 266 239 uint16_t scsi_cmd_packet(uint16_t device_id, uint8_t cmdlen, char __far *cmdbuf, 267 uint 16_t skip_b, uint32_t length, uint8_t inout, char __far *buffer)240 uint32_t length, uint8_t inout, char __far *buffer) 268 241 { 269 242 bio_dsk_t __far *bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk; … … 280 253 } 281 254 282 /* The skip length must be even. */283 if (skip_b & 1) {284 DBG_SCSI("%s: skip must be even (%04x)\n", __func__, skip_b);285 return 1;286 }287 288 255 /* Convert to SCSI specific device number. */ 289 256 device_id = VBOX_GET_SCSI_DEVICE(device_id); 290 257 291 DBG_SCSI("%s: reading %lu bytes, skip %u/%u, device %d, target %d\n", __func__, 292 length, bios_dsk->drqp.skip_b, bios_dsk->drqp.skip_a, 293 device_id, bios_dsk->scsidev[device_id].target_id); 258 DBG_SCSI("%s: reading %lu bytes, device %d, target %d\n", __func__, 259 length, device_id, bios_dsk->scsidev[device_id].target_id); 294 260 DBG_SCSI("%s: reading %u %u-byte sectors\n", __func__, 295 261 bios_dsk->drqp.nsect, bios_dsk->drqp.sect_sz); … … 308 274 309 275 rc = hbaacc[idx_hba].cmd_data_in(hba_seg :> 0, target_id, (void __far *)cmdbuf, cmdlen, 310 bios_dsk->drqp.buffer, length , skip_b, bios_dsk->drqp.skip_a);276 bios_dsk->drqp.buffer, length); 311 277 if (!rc) 312 278 bios_dsk->drqp.trsfbytes = length; … … 347 313 aCDB[5] = 0; 348 314 349 rc = hbaacc[idx_hba].cmd_data_in(hba_seg :> 0, i, aCDB, 6, buffer, 5 , 0, 0);315 rc = hbaacc[idx_hba].cmd_data_in(hba_seg :> 0, i, aCDB, 6, buffer, 5); 350 316 if (rc != 0) 351 317 { … … 377 343 aCDB[13] = 32; /* Allocation length. */ 378 344 379 rc = hbaacc[idx_hba].cmd_data_in(hba_seg :> 0, i, aCDB, 16, buffer, 32 , 0, 0);345 rc = hbaacc[idx_hba].cmd_data_in(hba_seg :> 0, i, aCDB, 16, buffer, 32); 380 346 if (rc != 0) 381 347 BX_PANIC("%s: SCSI_READ_CAPACITY failed\n", __func__); … … 546 512 { 547 513 int i; 548 uint16_t sink_seg = 0;549 514 bio_dsk_t __far *bios_dsk; 550 515 … … 564 529 break; 565 530 566 if (!sink_seg) /* Allocate a sink buffer for throwing away data when accessing CD/DVD drives. */567 {568 sink_seg = scsi_sink_buf_alloc();569 if (!sink_seg)570 break;571 }572 573 531 u8Bus = (busdevfn & 0xff00) >> 8; 574 532 u8DevFn = busdevfn & 0x00ff; 575 533 576 534 DBG_SCSI("SCSI HBA at Bus %u DevFn 0x%x (raw 0x%x)\n", u8Bus, u8DevFn, busdevfn); 577 rc = hbaacc[i].init(hba_seg :> 0, sink_seg :> 0, VBOX_SCSI_SINK_BUF_KB * 1024,u8Bus, u8DevFn);535 rc = hbaacc[i].init(hba_seg :> 0, u8Bus, u8DevFn); 578 536 if (!rc) 579 537 scsi_enumerate_attached_devices(hba_seg, i); -
trunk/src/VBox/Devices/PC/BIOS/scsi.h
r89267 r89364 57 57 ct_assert(sizeof(cdb_rw16) == 16); 58 58 59 extern int lsilogic_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint16_t cbSinkBuf,uint8_t u8Bus, uint8_t u8DevFn);59 extern int lsilogic_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn); 60 60 extern int lsilogic_scsi_cmd_data_out(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB, 61 61 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length); 62 62 extern int lsilogic_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB, 63 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b, 64 uint16_t skip_a); 63 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length); 65 64 66 extern int buslogic_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint16_t cbSinkBuf,uint8_t u8Bus, uint8_t u8DevFn);65 extern int buslogic_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn); 67 66 extern int buslogic_scsi_cmd_data_out(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB, 68 67 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length); 69 68 extern int buslogic_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB, 70 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b, 71 uint16_t skip_a); 69 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length); 72 70 73 extern int virtio_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint16_t cbSinkBuf,uint8_t u8Bus, uint8_t u8DevFn);71 extern int virtio_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn); 74 72 extern int virtio_scsi_cmd_data_out(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB, 75 73 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length); 76 74 extern int virtio_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB, 77 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b, 78 uint16_t skip_a); 75 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length); 79 76 80 77 #endif /* !VBOX_INCLUDED_SRC_PC_BIOS_scsi_h */ -
trunk/src/VBox/Devices/PC/BIOS/virtio.c
r89267 r89364 103 103 typedef struct 104 104 { 105 /** The descriptor table, using 5max. */106 virtio_q_desc_t aDescTbl[ 5];105 /** The descriptor table, using 3 max. */ 106 virtio_q_desc_t aDescTbl[3]; 107 107 /** Available ring. */ 108 108 virtio_q_avail_t AvailRing; … … 209 209 /** Device/Function number. */ 210 210 uint8_t u8DevFn; 211 /** The sink buf. */212 void __far *pvSinkBuf;213 211 /** The current executed command structure. */ 214 212 virtio_scsi_req_hdr_t ScsiReqHdr; … … 435 433 436 434 int virtio_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB, 437 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b, 438 uint16_t skip_a) 435 uint8_t cbCDB, uint8_t __far *buffer, uint32_t length) 439 436 { 440 437 virtio_t __far *virtio = (virtio_t __far *)pvHba; 441 438 uint16_t idxUsedOld = virtio->Queue.UsedRing.idxNextUsed; 442 uint8_t idxDesc = 0;443 439 444 440 _fmemset(&virtio->ScsiReqHdr, 0, sizeof(virtio->ScsiReqHdr)); … … 452 448 453 449 /* Fill in the descriptors. */ 454 virtio->Queue.aDescTbl[idxDesc].GCPhysBufLow = virtio_addr_to_phys(&virtio->ScsiReqHdr); 455 virtio->Queue.aDescTbl[idxDesc].GCPhysBufHigh = 0; 456 virtio->Queue.aDescTbl[idxDesc].cbBuf = sizeof(virtio->ScsiReqHdr); 457 virtio->Queue.aDescTbl[idxDesc].fFlags = VIRTIO_Q_DESC_F_NEXT; 458 virtio->Queue.aDescTbl[idxDesc].idxNext = 1; 459 idxDesc++; 450 virtio->Queue.aDescTbl[0].GCPhysBufLow = virtio_addr_to_phys(&virtio->ScsiReqHdr); 451 virtio->Queue.aDescTbl[0].GCPhysBufHigh = 0; 452 virtio->Queue.aDescTbl[0].cbBuf = sizeof(virtio->ScsiReqHdr); 453 virtio->Queue.aDescTbl[0].fFlags = VIRTIO_Q_DESC_F_NEXT; 454 virtio->Queue.aDescTbl[0].idxNext = 1; 460 455 461 456 /* No data out buffer, the status comes right after this in the next descriptor. */ 462 virtio->Queue.aDescTbl[idxDesc].GCPhysBufLow = virtio_addr_to_phys(&virtio->ScsiReqSts); 463 virtio->Queue.aDescTbl[idxDesc].GCPhysBufHigh = 0; 464 virtio->Queue.aDescTbl[idxDesc].cbBuf = sizeof(virtio->ScsiReqSts); 465 virtio->Queue.aDescTbl[idxDesc].fFlags = VIRTIO_Q_DESC_F_WRITE | VIRTIO_Q_DESC_F_NEXT; 466 virtio->Queue.aDescTbl[idxDesc].idxNext = 2; 467 idxDesc++; 468 469 /* Prepend a sinkhole if data is skipped upfront. */ 470 if (skip_b) 471 { 472 virtio->Queue.aDescTbl[idxDesc].GCPhysBufLow = virtio_addr_to_phys(virtio->pvSinkBuf); 473 virtio->Queue.aDescTbl[idxDesc].GCPhysBufHigh = 0; 474 virtio->Queue.aDescTbl[idxDesc].cbBuf = skip_b; 475 virtio->Queue.aDescTbl[idxDesc].fFlags = VIRTIO_Q_DESC_F_WRITE | VIRTIO_Q_DESC_F_NEXT; 476 virtio->Queue.aDescTbl[idxDesc].idxNext = idxDesc + 1; 477 idxDesc++; 478 } 479 480 virtio->Queue.aDescTbl[idxDesc].GCPhysBufLow = virtio_addr_to_phys(buffer); 481 virtio->Queue.aDescTbl[idxDesc].GCPhysBufHigh = 0; 482 virtio->Queue.aDescTbl[idxDesc].cbBuf = length; 483 virtio->Queue.aDescTbl[idxDesc].fFlags = VIRTIO_Q_DESC_F_WRITE; /* End of chain. */ 484 virtio->Queue.aDescTbl[idxDesc].idxNext = skip_a ? idxDesc + 1 : 0; 485 idxDesc++; 486 487 /* Append a sinkhole if data is skipped at the end. */ 488 if (skip_a) 489 { 490 virtio->Queue.aDescTbl[idxDesc - 1].fFlags |= VIRTIO_Q_DESC_F_NEXT; 491 virtio->Queue.aDescTbl[idxDesc - 1].idxNext = idxDesc; 492 493 virtio->Queue.aDescTbl[idxDesc].GCPhysBufLow = virtio_addr_to_phys(virtio->pvSinkBuf); 494 virtio->Queue.aDescTbl[idxDesc].GCPhysBufHigh = 0; 495 virtio->Queue.aDescTbl[idxDesc].cbBuf = skip_a; 496 virtio->Queue.aDescTbl[idxDesc].fFlags = VIRTIO_Q_DESC_F_WRITE; /* End of chain. */ 497 virtio->Queue.aDescTbl[idxDesc].idxNext = 0; 498 } 457 virtio->Queue.aDescTbl[1].GCPhysBufLow = virtio_addr_to_phys(&virtio->ScsiReqSts); 458 virtio->Queue.aDescTbl[1].GCPhysBufHigh = 0; 459 virtio->Queue.aDescTbl[1].cbBuf = sizeof(virtio->ScsiReqSts); 460 virtio->Queue.aDescTbl[1].fFlags = VIRTIO_Q_DESC_F_WRITE | VIRTIO_Q_DESC_F_NEXT; 461 virtio->Queue.aDescTbl[1].idxNext = 2; 462 463 virtio->Queue.aDescTbl[2].GCPhysBufLow = virtio_addr_to_phys(buffer); 464 virtio->Queue.aDescTbl[2].GCPhysBufHigh = 0; 465 virtio->Queue.aDescTbl[2].cbBuf = length; 466 virtio->Queue.aDescTbl[2].fFlags = VIRTIO_Q_DESC_F_WRITE; /* End of chain. */ 467 virtio->Queue.aDescTbl[2].idxNext = 0; 499 468 500 469 /* Put it into the queue, the index is supposed to be free-running and clipped to the ring size … … 662 631 * Init the VirtIO SCSI driver and detect attached disks. 663 632 */ 664 int virtio_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint16_t cbSinkBuf,uint8_t u8Bus, uint8_t u8DevFn)633 int virtio_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn) 665 634 { 666 635 virtio_t __far *virtio = (virtio_t __far *)pvHba; … … 714 683 /* Enable PCI memory, I/O, bus mastering access in command register. */ 715 684 pci_write_config_word(u8Bus, u8DevFn, 4, 0x7); 716 717 virtio->pvSinkBuf = pvSinkBuf;718 685 return virtio_scsi_hba_init(virtio, u8Bus, u8DevFn, u8PciCapOffVirtIo); 719 686 }
Note:
See TracChangeset
for help on using the changeset viewer.

