xref: /haiku/src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp (revision cda5b8808fd0262f0fac472f6cfa809f846a83cf)
1 /*
2  * Copyright 2008, Marcus Overhagen. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include "sata_request.h"
7 #include <string.h>
8 
9 sata_request::sata_request()
10  :	fCcb(NULL)
11  ,	fCompletionSem(create_sem(0, "sata completion"))
12  ,	fCompletionStatus(0)
13  ,	fData(NULL)
14  ,	fDataSize(0)
15 {
16 }
17 
18 
19 sata_request::sata_request(scsi_ccb *ccb)
20  :	fCcb(ccb)
21  ,	fCompletionSem(-1)
22  ,	fCompletionStatus(0)
23  ,	fData(NULL)
24  ,	fDataSize(0)
25 {
26 }
27 
28 
29 sata_request::~sata_request()
30 {
31 	if (fCompletionSem >= 0)
32 		delete_sem(fCompletionSem);
33 }
34 
35 
36 void
37 sata_request::set_data(void *data, size_t dataSize)
38 {
39 	if (fCcb) panic("wrong usage");
40  	fData = data;
41  	fDataSize = dataSize;
42 }
43 
44 
45 void
46 sata_request::set_ata_cmd(uint8 command)
47 {
48 	memset(fFis, 0, sizeof(fFis));
49 	fFis[0] = 0x27;
50 	fFis[1] = 0x80;
51 	fFis[2] = command;
52 }
53 
54 
55 void
56 sata_request::set_ata28_cmd(uint8 command, uint32 lba, uint8 sectorCount)
57 {
58 	set_ata_cmd(command);
59 	fFis[4] = lba & 0xff;
60 	fFis[5] = (lba >> 8) & 0xff;
61 	fFis[6] = (lba >> 16) & 0xff;
62 	fFis[7] = 0x40 | ((lba >> 24) & 0x0f);
63 	fFis[12] = sectorCount & 0xff;
64 }
65 
66 
67 void
68 sata_request::set_ata48_cmd(uint8 command, uint64 lba, uint16 sectorCount)
69 {
70 	set_ata_cmd(command);
71 	fFis[4] = lba & 0xff;
72 	fFis[5] = (lba >> 8) & 0xff;
73 	fFis[6] = (lba >> 16) & 0xff;
74 	fFis[7] = 0x40;
75 	fFis[8] = (lba >> 24) & 0xff;
76 	fFis[9] = (lba >> 32) & 0xff;
77 	fFis[10] = (lba >> 40) & 0xff;
78 	fFis[12] = sectorCount & 0xff;
79 	fFis[13] = (sectorCount >> 8) & 0xff;
80 }
81 
82 
83 void
84 sata_request::finish(int tfd, size_t bytesTransfered)
85 {
86 	if (tfd & ATA_ERR)
87 		dprintf("ahci: sata_request::finish ATA_ERR set for command 0x%02x\n", fFis[2]);
88 	if (fCcb) {
89 		fCcb->data_resid = fCcb->data_length - bytesTransfered;
90 		fCcb->subsys_status = (tfd & ATA_ERR) ? SCSI_REQ_CMP_ERR : SCSI_REQ_CMP;
91 		gSCSI->finished(fCcb, 1);
92 		delete this;
93 	} else {
94 		fCompletionStatus = tfd;
95 		release_sem(fCompletionSem);
96 	}
97 }
98 
99 
100 void
101 sata_request::abort()
102 {
103 	dprintf("ahci: sata_request::abort called for command 0x%02x\n", fFis[2]);
104 	if (fCcb) {
105 		fCcb->subsys_status = SCSI_REQ_ABORTED;
106 		gSCSI->finished(fCcb, 1);
107 		delete this;
108 	} else {
109 		fCompletionStatus = -1;
110 		release_sem(fCompletionSem);
111 	}
112 }
113 
114 
115 void
116 sata_request::wait_for_completition()
117 {
118 	if (fCcb) panic("wrong usage");
119 	acquire_sem(fCompletionSem);
120 }
121 
122 
123 int
124 sata_request::completition_status()
125 {
126 	if (fCcb) panic("wrong usage");
127 	return fCompletionStatus;
128 }
129 
130 
131 
132 
133 
134 
135