2 * Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
3 * Distributed under the terms of the MIT License.
6 #include "ATAPrivate.h"
9 ATARequest::ATARequest(bool hasLock
)
20 mutex_init(&fLock
, "ata request");
26 ATARequest::~ATARequest()
29 mutex_destroy(&fLock
);
34 ATARequest::SetStatus(uint8 status
)
41 ATARequest::SetSense(uint8 key
, uint16 codeQualifier
)
44 fSenseCode
= (uint8
)(codeQualifier
>> 8);
45 fSenseQualifier
= (uint8
)(codeQualifier
& 0xff);
50 ATARequest::ClearSense()
52 fSenseKey
= fSenseCode
= fSenseQualifier
= 0;
57 ATARequest::SetDevice(ATADevice
*device
)
64 ATARequest::SetTimeout(bigtime_t timeout
)
71 ATARequest::SetIsWrite(bool isWrite
)
78 ATARequest::SetUseDMA(bool useDMA
)
85 ATARequest::SetBytesLeft(uint32 bytesLeft
)
87 fBytesLeft
= bytesLeft
;
92 ATARequest::Start(scsi_ccb
*ccb
)
94 if (mutex_trylock(&fLock
) != B_OK
)
98 fStatus
= SCSI_REQ_CMP
;
99 fCCB
->device_status
= SCSI_STATUS_GOOD
;
106 ATARequest::Finish(bool resubmit
)
108 // when the request completed and has set sense
109 // data, report this to the scsi stack by setting
110 // CHECK CONDITION status
111 if (fStatus
== SCSI_REQ_CMP
&& fSenseKey
!= 0) {
112 TRACE("setting check condition\n");
114 fCCB
->subsys_status
= SCSI_REQ_CMP_ERR
;
115 fCCB
->device_status
= SCSI_STATUS_CHECK_CONDITION
;
117 // copy sense data if caller requested it
118 if ((fCCB
->flags
& SCSI_DIS_AUTOSENSE
) == 0) {
119 // we cannot copy sense directly as sense buffer may be too small
123 size_t senseLength
= MIN(sizeof(fCCB
->sense
), sizeof(sense
));
124 memcpy(fCCB
->sense
, &sense
, senseLength
);
125 fCCB
->sense_resid
= SCSI_MAX_SENSE_SIZE
- senseLength
;
126 fCCB
->subsys_status
|= SCSI_AUTOSNS_VALID
;
130 fCCB
->subsys_status
= fStatus
;
132 mutex_unlock(&fLock
);
135 gSCSIModule
->resubmit(fCCB
);
137 gSCSIModule
->finished(fCCB
, 1);
144 ATARequest::RequestSense()
146 // Copy sense data from last request into data buffer of current request.
147 // The sense data of last request is still present in the current request,
148 // as it isn't cleared on SCSI_OP_REQUEST_SENSE.
153 memset(&sense
, 0, sizeof(sense
));
155 scsi_cmd_request_sense
*command
= (scsi_cmd_request_sense
*)fCCB
->cdb
;
156 copy_sg_data(fCCB
, 0, command
->allocation_length
, &sense
, sizeof(sense
),
159 fCCB
->data_resid
= fCCB
->data_length
- MIN(MIN(sizeof(sense
),
160 command
->allocation_length
), fCCB
->data_length
);
166 ATARequest::PrepareSGInfo()
168 fSGElementsLeft
= fCCB
->sg_count
;
169 fCurrentSGElement
= fCCB
->sg_list
;
170 fCurrentSGOffset
= 0;
172 fCCB
->data_resid
= fCCB
->data_length
;
177 ATARequest::AdvanceSG(uint32 bytes
)
179 uint32 bytesLeft
= fCurrentSGElement
->size
- fCurrentSGOffset
;
180 if (bytesLeft
<= bytes
) {
181 fCurrentSGOffset
= 0;
185 fCurrentSGOffset
+= bytes
;
190 ATARequest::SetOddByte(uint8 byte
)
198 ATARequest::GetOddByte(uint8
*byte
)
212 ATARequest::_FillSense(scsi_sense
*sense
)
214 memset(sense
, 0, sizeof(*sense
));
215 sense
->error_code
= SCSIS_CURR_ERROR
;
216 sense
->sense_key
= fSenseKey
;
217 sense
->add_sense_length
= sizeof(*sense
) - 7;
218 sense
->asc
= fSenseCode
;
219 sense
->ascq
= fSenseQualifier
;
220 sense
->sense_key_spec
.raw
.SKSV
= 0; // no additional info