Changeset 60 for trunk/src/os2ahci/atapi.c
- Timestamp:
- Dec 16, 2010, 3:54:53 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/os2ahci/atapi.c
r39 r60 23 23 #include "os2ahci.h" 24 24 #include "ata.h" 25 #include "atapi.h" 25 26 26 27 /* -------------------------- macros and constants ------------------------- */ … … 29 30 30 31 /* -------------------------- function prototypes -------------------------- */ 32 33 static void atapi_req_sense_pp (IORBH _far *iorb); 34 static void atapi_execute_cdb_pp (IORBH _far *iorb); 35 31 36 32 37 /* ------------------------ global/static variables ------------------------ */ … … 49 54 int atapi_unit_ready(IORBH _far *iorb, int slot) 50 55 { 56 dprintf("atapi_unit_ready called\n"); 51 57 iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED); 52 58 return(-1); … … 58 64 int atapi_read(IORBH _far *iorb, int slot) 59 65 { 60 iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED); 61 return(-1); 62 } 66 IORB_EXECUTEIO _far *io = (IORB_EXECUTEIO _far *) iorb; 67 ATAPI_CDB_12 cdb; 68 AD_INFO *ai = ad_infos + iorb_unit_adapter(iorb); 69 USHORT count = io->BlockCount - io->BlocksXferred; 70 USHORT sg_indx; 71 USHORT sg_cnt; 72 int p = iorb_unit_port(iorb); 73 int d = iorb_unit_device(iorb); 74 int rc; 75 76 /* translate read command to SCSI/ATAPI READ12 command. 77 * READ12 seems to be the most supported READ variant - according to MMC, 78 * and its enough even for BluRay. 79 */ 80 memset(&cdb, 0x00, sizeof(cdb)); 81 cdb.cmd = ATAPI_CMD_READ_12; 82 SET_CDB_32(cdb.lba, io->RBA + io->BlocksXferred); 83 84 do { 85 /* update sector count (might have been updated due to S/G limitations) */ 86 SET_CDB_32(cdb.trans_len, (u32) count); 87 88 /* update S/G count and index */ 89 sg_indx = ata_get_sg_indx(io); 90 sg_cnt = io->cSGList - sg_indx; 91 92 /* issue command */ 93 rc = ata_cmd(ai, p, d, slot, ATA_CMD_PACKET, 94 AP_ATAPI_CMD, (void _far *) &cdb, sizeof(cdb), 95 AP_SGLIST, io->pSGList + sg_indx, (u16) sg_cnt, 96 AP_DEVICE, 0x4000, 97 AP_END); 98 99 if (rc > 0) { 100 /* couldn't map all S/G elements */ 101 ata_max_sg_cnt(io, sg_indx, (USHORT) rc, &sg_cnt, &count); 102 } 103 } while (rc > 0 && sg_cnt > 0); 104 105 if (rc == 0) { 106 add_workspace(iorb)->blocks = count; 107 add_workspace(iorb)->ppfunc = ata_read_pp; 108 109 } else if (rc > 0) { 110 iorb_seterr(iorb, IOERR_CMD_SGLIST_BAD); 111 112 } else { 113 iorb_seterr(iorb, IOERR_CMD_ADD_SOFTWARE_FAILURE); 114 } 115 116 return(rc); 117 } 63 118 64 119 /****************************************************************************** … … 67 122 int atapi_verify(IORBH _far *iorb, int slot) 68 123 { 124 dprintf("atapi_verify called\n"); 69 125 iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED); 70 126 return(-1); … … 76 132 int atapi_write(IORBH _far *iorb, int slot) 77 133 { 134 dprintf("atapi_write called\n"); 78 135 iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED); 79 136 return(-1); … … 85 142 int atapi_execute_cdb(IORBH _far *iorb, int slot) 86 143 { 87 iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED); 88 return(-1); 144 IORB_ADAPTER_PASSTHRU _far *pt = (IORB_ADAPTER_PASSTHRU _far *) iorb; 145 int rc; 146 147 /* we do not perform the S/G limitation recovery loop here: 148 * "ADDs are not required to iterate commands through the CDB PassThru 149 * mechanism:" -- Storage Device Driver Reference, Scatter/Gather Lists 150 */ 151 rc = ata_cmd(ad_infos + iorb_unit_adapter(iorb), 152 iorb_unit_port(iorb), 153 iorb_unit_device(iorb), 154 slot, ATA_CMD_PACKET, 155 AP_ATAPI_CMD, (void _far *) pt->pControllerCmd, 156 pt->ControllerCmdLen, 157 AP_SGLIST, pt->pSGList, pt->cSGList, 158 AP_END); 159 160 if (rc == 0) { 161 add_workspace(iorb)->blocks = pt->cSGList; 162 add_workspace(iorb)->ppfunc = atapi_execute_cdb_pp; 163 164 } else if (rc > 0) { 165 iorb_seterr(iorb, IOERR_CMD_SGLIST_BAD); 166 167 } else { 168 iorb_seterr(iorb, IOERR_CMD_ADD_SOFTWARE_FAILURE); 169 } 170 171 return(rc); 172 } 173 174 /****************************************************************************** 175 * Post processing function for atapi_execute_cdb(); since we have no 176 * knowledge of the command itself, we just tell the IRQ handler that 177 * we're done. 178 */ 179 static void atapi_execute_cdb_pp(IORBH _far *iorb) 180 { 181 add_workspace(iorb)->complete = 1; 89 182 } 90 183 … … 100 193 int atapi_req_sense(IORBH _far *iorb, int slot) 101 194 { 102 iorb_seterr(iorb, IOERR_CMD_NOT_SUPPORTED); 103 return(-1); 104 } 105 195 ADD_WORKSPACE _far *aws = add_workspace(iorb); 196 ATAPI_CDB_REQ_SENSE cdb; 197 int rc; 198 199 /* allocate sense buffer in ADD workspace */ 200 aws->buf = malloc(ATAPI_SENSE_LEN); 201 if (aws->buf == NULL) { 202 iorb_seterr(iorb, IOERR_CMD_SW_RESOURCE); 203 return(-1); 204 } 205 memset(aws->buf, 0x00, ATAPI_SENSE_LEN); 206 207 /* prepare request sense command */ 208 memset(&cdb, 0x00, sizeof(cdb)); 209 cdb.cmd = ATAPI_CMD_REQUEST_SENSE; 210 aws->ppfunc = atapi_req_sense_pp; 211 rc = ata_cmd(ad_infos + iorb_unit_adapter(iorb), 212 iorb_unit_port(iorb), 213 iorb_unit_device(iorb), 214 slot, 215 ATA_CMD_PACKET, 216 AP_ATAPI_CMD, (void _far*) &cdb, sizeof(cdb), 217 AP_VADDR, (void _far *) aws->buf, ATAPI_SENSE_LEN, 218 AP_END); 219 220 if (rc > 0) { 221 /* should never happen - we got 64 bytes here */ 222 iorb_seterr(iorb, IOERR_CMD_SGLIST_BAD); 223 224 } else { 225 /* we failed to get info about an error -> return 226 * non specific device error 227 */ 228 iorb_seterr(iorb, IOERR_DEVICE_NONSPECIFIC); 229 } 230 231 return(rc); 232 } 233 234 /****************************************************************************** 235 * Post processing function for ATAPI request sense; examines the sense 236 * data returned and maps sense info to IORB error info. 237 */ 238 static void atapi_req_sense_pp(IORBH _far *iorb) 239 { 240 ADD_WORKSPACE _far *aws = add_workspace(iorb); 241 ATAPI_SENSE_DATA *psd = (ATAPI_SENSE_DATA *) aws->buf; 242 243 /* map sense data to some IOERR_ value */ 244 switch (ATAPI_GET_SENSE(psd)) { 245 246 case ASENSE_NO_SENSE: 247 case ASENSE_RECOVERED_ERROR: 248 /* no error */ 249 break; 250 251 case ASENSE_NOT_READY: 252 iorb_seterr(iorb, IOERR_UNIT_NOT_READY); 253 break; 254 255 case ASENSE_UNIT_ATTENTION: 256 iorb_seterr(iorb, IOERR_MEDIA_CHANGED); 257 break; 258 259 case ASENSE_MEDIUM_ERROR: 260 iorb_seterr(iorb, IOERR_MEDIA); 261 break; 262 263 case ASENSE_ILLEGAL_REQUEST: 264 iorb_seterr(iorb, IOERR_CMD_SYNTAX); 265 break; 266 267 case ASENSE_DATA_PROTECT: 268 iorb_seterr(iorb, IOERR_MEDIA_WRITE_PROTECT); 269 break; 270 271 case ASENSE_BLANK_CHECK: 272 iorb_seterr(iorb, IOERR_MEDIA_NOT_FORMATTED); 273 break; 274 275 case ASENSE_ABORTED_COMMAND: 276 case ASENSE_COPY_ABORTED: 277 iorb_seterr(iorb, IOERR_CMD_ABORTED); 278 break; 279 280 default: 281 iorb_seterr(iorb, IOERR_DEVICE_NONSPECIFIC); 282 break; 283 } 284 285 /* free sense buffer */ 286 aws_free(aws); 287 288 }
Note:
See TracChangeset
for help on using the changeset viewer.