2 * Copyright (C) 2012, The AROS Development Team. All rights reserved.
3 * Author: Jason S. McMullan <jason.mcmullan@gmail.com>
5 * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1
8 #include <exec/errors.h>
9 #include <devices/scsidisk.h>
10 #include <devices/trackdisk.h>
11 #include <scsi/commands.h>
12 #include <scsi/values.h>
15 #include "ahci_scsi.h"
20 #define offsetof(TYPE, MEMBER) ((IPTR) &((TYPE *)0)->MEMBER)
21 #define container_of(ptr, type, member) ({ \
22 const typeof(((type *)0)->member) *__mptr = (ptr); \
23 (type *)((char *)__mptr - offsetof(type, member)); })
26 static inline UQUAD
scsi_8btou64(UBYTE
*addr
)
31 for (i
= 0; i
< 8; i
++, res
<<= 8, res
|= *(addr
++));
35 static inline ULONG
scsi_4btoul(UBYTE
*addr
)
40 for (i
= 0; i
< 4; i
++, res
<<= 8, res
|= *(addr
++));
44 static inline ULONG
scsi_3btoul(UBYTE
*addr
)
49 for (i
= 0; i
< 3; i
++, res
<<= 8, res
|= *(addr
++));
53 static inline ULONG
scsi_2btoul(UBYTE
*addr
)
58 for (i
= 0; i
< 2; i
++, res
<<= 8, res
|= *(addr
++));
62 static inline void scsi_ulto4b(ULONG val
, UBYTE
*addr
)
65 for (i
= 3; i
>= 0; i
--, val
>>= 8)
70 * Construct dummy sense data for disks, and ATAPI devices
71 * that do not support extended status
73 * In the io_complete, there should a REQUEST SENSE command
76 static void ahci_ata_sense(struct ata_xfer
*xa
,
77 struct scsi_sense_data
*sense_data
)
79 struct ata_fis_d2h
*rfis
= &xa
->rfis
;
80 UBYTE asc
= 0, asq
= 0, key
= 0;
82 if ((rfis
->status
& ATA_D2H_STATUS_BSY
)) {
83 key
= SSD_KEY_ABORTED_COMMAND
;
85 /* Decode error bits */
86 switch (rfis
->error
& 0xff) {
87 case ATA_D2H_ERROR_BBK
|ATA_D2H_ERROR_UNK
|ATA_D2H_ERROR_IDNF
:
88 case ATA_D2H_ERROR_BBK
|ATA_D2H_ERROR_UNK
|ATA_D2H_ERROR_IDNF
|ATA_D2H_ERROR_AMNF
:
89 /* Device busy, aborted command */
90 case ATA_D2H_ERROR_ABRT
:
92 key
= SSD_KEY_ABORTED_COMMAND
;
93 asc
= 0x00; asq
= 0x00; /* no additional sense code */
95 case ATA_D2H_ERROR_UNK
|ATA_D2H_ERROR_MC
|ATA_D2H_ERROR_AMNF
:
97 key
= SSD_KEY_HARDWARE_ERROR
;
98 asc
= 0x44; asq
= 0x00; /* internal target failure */
100 case ATA_D2H_ERROR_BBK
|ATA_D2H_ERROR_ABRT
:
101 /* Data partiy error */
102 key
= SSD_KEY_ABORTED_COMMAND
;
103 asc
= 0x4b; asq
= 0x00; /* data phase error */
105 case ATA_D2H_ERROR_MC
:
107 key
= SSD_KEY_NOT_READY
;
108 asc
= 0x3a; asq
= 0x00; /* medium not present */
110 case ATA_D2H_ERROR_MCR
:
111 /* Media change request */
112 key
= SSD_KEY_NOT_READY
;
113 asc
= 0x04; asq
= 0x03; /* manual intervention required */
115 case ATA_D2H_ERROR_MC
|ATA_D2H_ERROR_IDNF
|ATA_D2H_ERROR_ABRT
|ATA_D2H_ERROR_TK0NF
|ATA_D2H_ERROR_AMNF
:
116 case ATA_D2H_ERROR_MCR
|ATA_D2H_ERROR_AMNF
:
117 /* Unit offline or not ready */
118 key
= SSD_KEY_NOT_READY
;
119 asc
= 0x04; asq
= 0x00; /* unknown reason */
121 case ATA_D2H_ERROR_AMNF
:
122 /* No address mark found */
123 key
= SSD_KEY_MEDIUM_ERROR
;
124 asc
= 0x31; asq
= 0x00; /* medium format corrupted */
126 case ATA_D2H_ERROR_TK0NF
:
127 /* Track 0 not found */
128 key
= SSD_KEY_HARDWARE_ERROR
;
129 asc
= 0x02; asq
= 0x00; /* no seek complete */
131 case ATA_D2H_ERROR_IDNF
:
132 /* Sector not found */
133 key
= SSD_KEY_ILLEGAL_REQUEST
;
134 asc
= 0x21; asq
= 0x00; /* LBA out of range */
136 case ATA_D2H_ERROR_BBK
:
137 /* Bad block (now defined as interface CRC in ATA8-ACS) */
138 key
= SSD_KEY_ABORTED_COMMAND
;
139 asc
= 0x47; asq
= 0x00; /* SCSI partity error */
141 case ATA_D2H_ERROR_UNK
:
143 key
= SSD_KEY_MEDIUM_ERROR
;
144 if ((xa
->fis
->flags
& ATA_H2D_FEATURES_DIR
) == ATA_H2D_FEATURES_DIR_WRITE
) {
145 asc
= 0x10; asq
= 0x00; /* write fault */
147 asc
= 0x11; asq
= 0x00; /* read fault */
151 D(bug("ahci.device: No sense translation for ATA Error 0x%02x\n", rfis
->error
));
152 switch (rfis
->status
) {
153 case ATA_D2H_STATUS_DF
:
154 key
= SSD_KEY_HARDWARE_ERROR
;
155 asc
= 0x44; asq
= 0x00; /* Internal target failure */
157 case ATA_D2H_STATUS_DRQ
:
158 key
= SSD_KEY_ABORTED_COMMAND
;
159 asc
= 0x4B; asq
= 0x00; /* Data phase error */
161 case ATA_D2H_STATUS_CORR
:
162 if ((xa
->fis
->flags
& ATA_H2D_FEATURES_DIR
) == ATA_H2D_FEATURES_DIR_WRITE
) {
163 key
= SSD_KEY_RECOVERED_ERROR
;
164 asc
= 0x0c; asq
= 0x01; /* Recovered write with realloc */
166 key
= SSD_KEY_RECOVERED_ERROR
;
167 asc
= 0x18; asq
= 0x02; /* Recovered read with realloc */
171 D(bug("ahci.device: No sense translation for ATA Status 0x%02x\n", rfis
->status
));
172 key
= SSD_KEY_ABORTED_COMMAND
;
179 memset(sense_data
, 0, sizeof(sense_data
));
181 sense_data
->error_code
= SSD_ERRCODE_VALID
| SSD_CURRENT_ERROR
;
183 sense_data
->flags
= ((rfis
->error
& 0xF0) >> 4) | key
;
184 if (rfis
->error
& ATA_D2H_ERROR_AMNF
)
185 sense_data
->flags
|= SSD_ILI
;
186 sense_data
->add_sense_code
= asc
;
187 sense_data
->add_sense_qual
= asq
;
190 static void ahci_io_complete(struct ata_xfer
*xa
)
192 struct IORequest
*io
= xa
->atascsi_private
;
193 const int sense_length
= offsetof(struct scsi_sense_data
, extra_bytes
[0]);
197 if (io
->io_Command
== HD_SCSICMD
) {
198 struct SCSICmd
*scsi
= IOStdReq(io
)->io_Data
;
199 scsi
->scsi_Status
= SCSI_GOOD
;
200 scsi
->scsi_Actual
= xa
->datalen
;
201 IOStdReq(io
)->io_Actual
= sizeof(*scsi
);
203 IOStdReq(io
)->io_Actual
= xa
->datalen
;
207 if (io
->io_Command
== HD_SCSICMD
) {
208 struct SCSICmd
*scsi
= IOStdReq(io
)->io_Data
;
209 D(bug("Error on HD_SCSICMD\n"));
210 scsi
->scsi_Status
= SCSI_CHECK_CONDITION
;
211 scsi
->scsi_Actual
= 0;
212 IOStdReq(io
)->io_Actual
= sizeof(*scsi
);
213 if (scsi
->scsi_Flags
& (SCSIF_AUTOSENSE
| SCSIF_OLDAUTOSENSE
)) {
214 D(bug("SCSIF_AUTOSENSE desired\n"));
215 if (scsi
->scsi_SenseData
&& scsi
->scsi_SenseLength
>= sense_length
) {
216 ahci_ata_sense(xa
, (void *)scsi
->scsi_SenseData
);
217 scsi
->scsi_SenseActual
= sense_length
;
218 D(bug("SCSI Sense: KCQ = 0x%02x 0x%02x 0x%02x\n",
219 scsi
->scsi_SenseData
[2],
220 scsi
->scsi_SenseData
[12],
221 scsi
->scsi_SenseData
[13]));
225 io
->io_Error
= TDERR_SeekError
;
226 IOStdReq(io
)->io_Actual
= 0;
230 if (io
->io_Command
== HD_SCSICMD
) {
231 struct SCSICmd
*scsi
= IOStdReq(io
)->io_Data
;
232 scsi
->scsi_Status
= SCSI_BUSY
;
233 scsi
->scsi_Actual
= 0;
234 IOStdReq(io
)->io_Actual
= sizeof(*scsi
);
236 io
->io_Error
= IOERR_UNITBUSY
;
237 IOStdReq(io
)->io_Actual
= 0;
241 io
->io_Error
= IOERR_NOCMD
;
245 ahci_ata_put_xfer(xa
);
246 if (!(io
->io_Flags
& IOF_QUICK
)) {
248 Remove(&io
->io_Message
.mn_Node
);
250 ReplyMsg(&io
->io_Message
);
256 * Simulate page inquiries for disk attachments.
258 static BYTE
ahci_scsi_page_inquiry(struct ahci_port
*ap
, struct ata_port
*at
, struct SCSICmd
*scsi
)
261 struct scsi_vpd_supported_page_list list
;
262 struct scsi_vpd_unit_serial_number serno
;
270 cdb
= (APTR
)scsi
->scsi_Command
;
272 switch(cdb
->inquiry
.page_code
) {
273 case SVPD_SUPPORTED_PAGE_LIST
:
275 page
.list
.device
= T_DIRECT
;
276 page
.list
.page_code
= SVPD_SUPPORTED_PAGE_LIST
;
277 page
.list
.list
[i
++] = SVPD_SUPPORTED_PAGE_LIST
;
278 page
.list
.list
[i
++] = SVPD_UNIT_SERIAL_NUMBER
;
279 page
.list
.length
= i
;
280 len
= offsetof(struct scsi_vpd_supported_page_list
, list
[3]);
282 case SVPD_UNIT_SERIAL_NUMBER
:
284 j
= sizeof(at
->at_identify
.serial
);
285 for (i
= 0; i
< j
&& at
->at_identify
.serial
[i
] == ' '; ++i
)
287 while (j
> i
&& at
->at_identify
.serial
[j
-1] == ' ')
289 page
.serno
.device
= T_DIRECT
;
290 page
.serno
.page_code
= SVPD_UNIT_SERIAL_NUMBER
;
291 page
.serno
.length
= j
- i
;
292 CopyMem(at
->at_identify
.serial
+ i
,
293 page
.serno
.serial_num
, j
- i
);
294 len
= offsetof(struct scsi_vpd_unit_serial_number
,
302 if (len
> scsi
->scsi_Length
)
303 return IOERR_BADLENGTH
;
305 memset(scsi
->scsi_Data
+ len
, 0, scsi
->scsi_Length
- len
);
306 CopyMem(&page
, scsi
->scsi_Data
, len
);
307 scsi
->scsi_Actual
= len
;
314 * Convert the SCSI command to an ata_xfer command in xa
315 * for ATA_PORT_T_DISK operations. Set the completion function
316 * to convert the response back, then dispatch to the OpenBSD AHCI
319 * AHCI DISK commands only support a limited command set, and we
320 * fake additional commands to make it play nice.
322 * Return TRUE if no need to wait for a reply
324 BOOL
ahci_scsi_disk_io(struct IORequest
*io
, struct SCSICmd
*scsi
)
326 struct cam_sim
*unit
= (struct cam_sim
*)io
->io_Unit
;
327 struct ahci_port
*ap
= unit
->sim_Port
;
328 struct ata_port
*at
= ap
->ap_ata
[0];
330 struct ata_fis_h2d
*fis
;
332 struct scsi_inquiry_data inquiry_data
;
333 struct scsi_read_capacity_data read_capacity_data
;
334 } *rdata
= (APTR
)scsi
->scsi_Command
;
335 ULONG rdata_len
= scsi
->scsi_CmdLength
;
340 scsi_cdb_t cdb
= (APTR
)scsi
->scsi_Command
;
342 xa
= ahci_ata_get_xfer(ap
, at
);
344 switch(cdb
->generic
.opcode
) {
345 case SCSI_REQUEST_SENSE
:
347 * Auto-sense everything, so explicit sense requests
350 io
->io_Error
= HFERR_BadStatus
;
356 * Inquiry supported features
358 * [opcode, byte2, page_code, length, control]
360 if (cdb
->inquiry
.byte2
& SI_EVPD
) {
361 io
->io_Error
= ahci_scsi_page_inquiry(ap
, at
, scsi
);
363 memset(rdata
, 0, rdata_len
);
364 if (rdata_len
< SHORT_INQUIRY_LENGTH
) {
365 io
->io_Error
= IOERR_BADLENGTH
;
368 if (rdata_len
> sizeof(rdata
->inquiry_data
))
369 rdata_len
= sizeof(rdata
->inquiry_data
);
370 rdata
->inquiry_data
.device
= T_DIRECT
;
371 /* Mark as removable if ATA has the 'removable' tag */
372 rdata
->inquiry_data
.dev_qual2
= (at
->at_identify
.config
? 0x80 : 0);
373 rdata
->inquiry_data
.version
= SCSI_REV_SPC2
;
374 rdata
->inquiry_data
.response_format
= 2;
375 rdata
->inquiry_data
.additional_length
= 32;
376 CopyMem("SATA ", rdata
->inquiry_data
.vendor
, 8);
377 CopyMem(at
->at_identify
.model
,
378 rdata
->inquiry_data
.product
,
379 sizeof(rdata
->inquiry_data
.product
));
380 CopyMem(at
->at_identify
.firmware
,
381 rdata
->inquiry_data
.revision
,
382 sizeof(rdata
->inquiry_data
.revision
));
385 case SCSI_DA_READ_CAPACITY
:
387 if (rdata_len
< sizeof(rdata
->read_capacity_data
)) {
388 io
->io_Error
= IOERR_BADLENGTH
;
392 capacity
= at
->at_capacity
;
394 memset(rdata
, 0, rdata_len
);
395 rdata_len
= sizeof(rdata
->read_capacity_data
);
396 if (capacity
> 0xFFFFFFFFU
)
397 capacity
= 0xFFFFFFFFU
;
398 memset(&rdata
->read_capacity_data
, 0, rdata_len
);
399 scsi_ulto4b((u_int32_t
)capacity
- 1,
400 rdata
->read_capacity_data
.addr
);
401 scsi_ulto4b(512, rdata
->read_capacity_data
.length
);
403 case SCSI_DA_SYNCHRONIZE_CACHE
:
405 * Synchronize cache. Specification says this can take
406 * greater then 30 seconds so give it at least 45.
409 fis
->flags
= ATA_H2D_FLAGS_CMD
;
410 fis
->command
= ATA_C_FLUSH_CACHE
;
412 if (xa
->timeout
< 45000)
416 xa
->complete
= ahci_io_complete
;
418 case SCSI_TEST_UNIT_READY
:
420 * Just silently return success
426 switch(cdb
->generic
.opcode
) {
428 lba
= scsi_3btoul(cdb
->rw_6
.addr
) & 0x1FFFFF;
429 count
= cdb
->rw_6
.length
? cdb
->rw_6
.length
: 0x100;
430 xa
->flags
= ATA_F_READ
;
432 case SCSI_DA_READ_10
:
433 lba
= scsi_4btoul(cdb
->rw_10
.addr
);
434 count
= scsi_2btoul(cdb
->rw_10
.length
);
435 xa
->flags
= ATA_F_READ
;
437 case SCSI_DA_READ_12
:
438 lba
= scsi_4btoul(cdb
->rw_12
.addr
);
439 count
= scsi_4btoul(cdb
->rw_12
.length
);
440 xa
->flags
= ATA_F_READ
;
442 case SCSI_DA_READ_16
:
443 lba
= scsi_8btou64(cdb
->rw_16
.addr
);
444 count
= scsi_4btoul(cdb
->rw_16
.length
);
445 xa
->flags
= ATA_F_READ
;
447 case SCSI_DA_WRITE_6
:
448 lba
= scsi_3btoul(cdb
->rw_6
.addr
) & 0x1FFFFF;
449 count
= cdb
->rw_6
.length
? cdb
->rw_6
.length
: 0x100;
450 xa
->flags
= ATA_F_WRITE
;
452 case SCSI_DA_WRITE_10
:
453 lba
= scsi_4btoul(cdb
->rw_10
.addr
);
454 count
= scsi_2btoul(cdb
->rw_10
.length
);
455 xa
->flags
= ATA_F_WRITE
;
457 case SCSI_DA_WRITE_12
:
458 lba
= scsi_4btoul(cdb
->rw_12
.addr
);
459 count
= scsi_4btoul(cdb
->rw_12
.length
);
460 xa
->flags
= ATA_F_WRITE
;
462 case SCSI_DA_WRITE_16
:
463 lba
= scsi_8btou64(cdb
->rw_16
.addr
);
464 count
= scsi_4btoul(cdb
->rw_16
.length
);
465 xa
->flags
= ATA_F_WRITE
;
468 io
->io_Error
= IOERR_NOCMD
;
476 fis
->flags
= ATA_H2D_FLAGS_CMD
;
477 fis
->lba_low
= (u_int8_t
)lba
;
478 fis
->lba_mid
= (u_int8_t
)(lba
>> 8);
479 fis
->lba_high
= (u_int8_t
)(lba
>> 16);
480 fis
->device
= ATA_H2D_DEVICE_LBA
;
483 * NCQ only for direct-attached disks, do not currently
484 * try to use NCQ with port multipliers.
486 if (at
->at_ncqdepth
> 1 &&
487 ap
->ap_type
== ATA_PORT_T_DISK
&&
488 (ap
->ap_sc
->sc_cap
& AHCI_REG_CAP_SNCQ
) &&
489 (io
->io_Flags
& IOF_QUICK
) == 0) {
491 * Use NCQ - always uses 48 bit addressing
493 xa
->flags
|= ATA_F_NCQ
;
494 fis
->command
= (xa
->flags
& ATA_F_WRITE
) ?
495 ATA_C_WRITE_FPDMA
: ATA_C_READ_FPDMA
;
496 fis
->lba_low_exp
= (u_int8_t
)(lba
>> 24);
497 fis
->lba_mid_exp
= (u_int8_t
)(lba
>> 32);
498 fis
->lba_high_exp
= (u_int8_t
)(lba
>> 40);
499 fis
->sector_count
= xa
->tag
<< 3;
500 fis
->features
= (u_int8_t
)count
;
501 fis
->features_exp
= (u_int8_t
)(count
>> 8);
502 } else if (count
> 0x100 || lba
> 0x0FFFFFFFU
) {
506 fis
->command
= (xa
->flags
& ATA_F_WRITE
) ?
507 ATA_C_WRITEDMA_EXT
: ATA_C_READDMA_EXT
;
508 fis
->lba_low_exp
= (u_int8_t
)(lba
>> 24);
509 fis
->lba_mid_exp
= (u_int8_t
)(lba
>> 32);
510 fis
->lba_high_exp
= (u_int8_t
)(lba
>> 40);
511 fis
->sector_count
= (u_int8_t
)count
;
512 fis
->sector_count_exp
= (u_int8_t
)(count
>> 8);
517 * NOTE: 256 sectors is supported, stored as 0.
519 fis
->command
= (xa
->flags
& ATA_F_WRITE
) ?
520 ATA_C_WRITEDMA
: ATA_C_READDMA
;
521 fis
->device
|= (u_int8_t
)(lba
>> 24) & 0x0F;
522 fis
->sector_count
= (u_int8_t
)count
;
525 xa
->data
= scsi
->scsi_Data
;
526 xa
->datalen
= scsi
->scsi_Length
;
527 xa
->complete
= ahci_io_complete
;
528 xa
->timeout
= 1000; /* milliseconds */
530 if (xa
->timeout
> 10000) /* XXX - debug */
533 if (io
->io_Flags
& IOF_QUICK
)
534 xa
->flags
|= ATA_F_POLL
;
539 * If the request is still in progress the xa and FIS have
540 * been set up (except for the PM target), and must be dispatched.
541 * Otherwise the request was completed.
544 KKASSERT(xa
->complete
!= NULL
);
545 xa
->atascsi_private
= io
;
546 ahci_os_lock_port(ap
);
547 xa
->fis
->flags
|= at
->at_target
;
549 ahci_os_unlock_port(ap
);
551 IOStdReq(io
)->io_Actual
= sizeof(*scsi
);
552 ahci_ata_put_xfer(xa
);
559 * Convert the SCSI command in ccb to an ata_xfer command in xa
560 * for ATA_PORT_T_ATAPI operations. Set the completion function
561 * to convert the response back, then dispatch to the OpenBSD AHCI
564 BOOL
ahci_scsi_atapi_io(struct IORequest
*io
, struct SCSICmd
*scsi
)
566 struct cam_sim
*unit
= (struct cam_sim
*)io
->io_Unit
;
567 struct ahci_port
*ap
= unit
->sim_Port
;
568 struct ata_port
*at
= ap
->ap_ata
[0];
570 struct ata_fis_h2d
*fis
;
575 if (scsi
->scsi_Flags
& SCSIF_READ
) {
576 flags
= ATA_F_PACKET
| ATA_F_READ
;
578 flags
= ATA_F_PACKET
| ATA_F_WRITE
;
582 * Special handling to get the rfis back into host memory while
583 * still allowing the chip to run commands in parallel to
584 * ATAPI devices behind a PM.
586 flags
|= ATA_F_AUTOSENSE
;
589 * The command has to fit in the packet command buffer.
591 if (scsi
->scsi_CmdLength
< 6 || scsi
->scsi_CmdLength
> 16) {
592 io
->io_Error
= IOERR_NOCMD
;
597 * Initialize the XA and FIS. It is unclear how much of
598 * this has to mimic the equivalent ATA command.
600 * XXX not passing NULL at for direct attach!
602 xa
= ahci_ata_get_xfer(ap
, at
);
605 fis
->flags
= ATA_H2D_FLAGS_CMD
| at
->at_target
;
606 fis
->command
= ATA_C_PACKET
;
607 fis
->device
= ATA_H2D_DEVICE_LBA
;
608 fis
->sector_count
= xa
->tag
<< 3;
609 if (flags
& (ATA_F_READ
| ATA_F_WRITE
)) {
610 if (flags
& ATA_F_WRITE
) {
611 fis
->features
= ATA_H2D_FEATURES_DMA
|
612 ATA_H2D_FEATURES_DIR_WRITE
;
614 fis
->features
= ATA_H2D_FEATURES_DMA
|
615 ATA_H2D_FEATURES_DIR_READ
;
621 fis
->control
= ATA_FIS_CONTROL_4BIT
;
624 xa
->data
= scsi
->scsi_Data
;
625 xa
->datalen
= scsi
->scsi_Length
;
626 xa
->timeout
= 1000; /* milliseconds */
628 if (io
->io_Flags
& IOF_QUICK
)
629 xa
->flags
|= ATA_F_POLL
;
632 * Copy the cdb to the packetcmd buffer in the FIS using a
633 * convenient pointer in the xa.
635 * Zero-out any trailing bytes in case the ATAPI device cares.
637 cdbs
= (void *)scsi
->scsi_Command
;
638 CopyMem(cdbs
, xa
->packetcmd
, scsi
->scsi_CmdLength
);
639 if (scsi
->scsi_CmdLength
< 16)
640 memset(xa
->packetcmd
+ scsi
->scsi_CmdLength
, 0, 16 - scsi
->scsi_CmdLength
);
643 kprintf("opcode %d cdb_len %d dxfer_len %d\n",
644 cdbs
->generic
.opcode
,
645 scsi
->scsi_CmdLength
, scsi
->scsi_Length
);
649 * Some ATAPI commands do not actually follow the SCSI standard.
651 cdbd
= (void *)xa
->packetcmd
;
653 switch(cdbd
->generic
.opcode
) {
654 case SCSI_REQUEST_SENSE
:
656 * Force SENSE requests to the ATAPI sense length.
658 * It is unclear if this is needed or not.
660 if (cdbd
->sense
.length
== SSD_FULL_SIZE
) {
662 kprintf("%s: Shortening sense request\n",
665 cdbd
->sense
.length
= offsetof(struct scsi_sense_data
,
671 * Some ATAPI devices can't handle long inquiry lengths,
672 * don't ask me why. Truncate the inquiry length.
674 if (cdbd
->inquiry
.page_code
== 0 &&
675 cdbd
->inquiry
.length
> SHORT_INQUIRY_LENGTH
) {
676 cdbd
->inquiry
.length
= SHORT_INQUIRY_LENGTH
;
680 case SCSI_DA_WRITE_6
:
682 * Convert *_6 to *_10 commands. Most ATAPI devices
683 * cannot handle the SCSI READ_6 and WRITE_6 commands.
685 cdbd
->rw_10
.opcode
|= 0x20;
686 cdbd
->rw_10
.byte2
= 0;
687 cdbd
->rw_10
.addr
[0] = 0;
688 cdbd
->rw_10
.addr
[1] = cdbs
->rw_6
.addr
[0] & 0x1F;
689 cdbd
->rw_10
.addr
[2] = cdbs
->rw_6
.addr
[1];
690 cdbd
->rw_10
.addr
[3] = cdbs
->rw_6
.addr
[2];
691 cdbd
->rw_10
.reserved
= 0;
692 cdbd
->rw_10
.length
[0] = 0;
693 cdbd
->rw_10
.length
[1] = cdbs
->rw_6
.length
;
694 cdbd
->rw_10
.control
= cdbs
->rw_6
.control
;
703 xa
->complete
= ahci_io_complete
;
704 xa
->atascsi_private
= io
;
705 ahci_os_lock_port(ap
);
707 ahci_os_unlock_port(ap
);
709 return (io
->io_Flags
& IOF_QUICK
) ? TRUE
: FALSE
;