source: trunk/src/os2ahci/ata.c

Last change on this file was 211, checked in by David Azarewicz, 2 years ago

Added workaround to help with VirtualBox issues.
Improved diagnostic messages.
Changed how timeouts are reset and how ctx hooks are triggered.
Added quirk for devices with issues executing some standard commands.
Changed to make /N the default.

File size: 44.2 KB
Line 
1/**
2 * ata.c - ATA command processing
3 *
4 * Copyright (c) 2011 thi.guten Software Development
5 * Copyright (c) 2011 Mensys B.V.
6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net>
7 *
8 * Authors: Christian Mueller, Markus Thielen
9 *
10 * Parts copied from/inspired by the Linux AHCI driver;
11 * those parts are (c) Linux AHCI/ATA maintainers
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
28#define INCL_LONGLONG
29#include "os2ahci.h"
30#include "ata.h"
31
32#define MAKEULL(h,l) (((ULONGLONG)h<<32)|l)
33
34/******************************************************************************
35 * Initialize AHCI command slot, FIS and S/G list for the specified ATA
36 * command. The command parameters are passed as a variable argument list
37 * of type and value(s). The list is terminated by AP_END.
38 *
39 * Notes:
40 *
41 * - The specified command slot is expected to be idle; no checks are
42 * performed to prevent messing with a busy port.
43 *
44 * - Port multipliers are not supported, yet, thus 'd' should always
45 * be 0 for the time being.
46 *
47 * - 'cmd' is passed as 16-bit integer because the compiler would push
48 * a 'u8' as 16-bit value (it's a fixed argument) and the stdarg
49 * macros would screw up the address of the first variable argument
50 * if the size of the last fixed argument wouldn't match what the
51 * compiler pushed on the stack.
52 *
53 * Return values:
54 * 0 : success
55 * > 0 : could not map all S/G entries; the return value is the number of
56 * S/G entries that could be mapped.
57 * < 0 : other error
58 */
59int ata_cmd(AD_INFO *ai, int p, int d, int slot, int cmd, ...)
60{
61 va_list va;
62 va_start(va, cmd);
63 return(v_ata_cmd(ai, p, d, slot, cmd, va));
64}
65
66int v_ata_cmd(AD_INFO *ai, int p, int d, int slot, int cmd, va_list va)
67{
68 AHCI_PORT_DMA *dma_base_virt;
69 AHCI_CMD_HDR *cmd_hdr;
70 AHCI_CMD_TBL *cmd_tbl;
71 SCATGATENTRY *sg_list = NULL;
72 SCATGATENTRY sg_single;
73 ATA_PARM ap;
74 ATA_CMD ata_cmd;
75 void *atapi_cmd = NULL;
76 u32 dma_base_phys;
77 u32 atapi_cmd_len = 0;
78 u32 ahci_flags = 0;
79 u32 sg_cnt = 0;
80 u32 i;
81 u32 n;
82
83 /* --------------------------------------------------------------------------
84 * Initialize ATA command. The ATA command is set up with the main command
85 * value and a variable list of additional parameters such as the sector
86 * address, transfer count, ...
87 */
88 memset(&ata_cmd, 0x00, sizeof(ata_cmd));
89 ata_cmd.cmd = cmd;
90
91 /* parse variable arguments */
92 do
93 {
94 switch ((ap = va_arg(va, ATA_PARM)))
95 {
96
97 case AP_AHCI_FLAGS:
98 ahci_flags |= va_arg(va, u32);
99 break;
100
101 case AP_WRITE:
102 if (va_arg(va, u32) != 0)
103 {
104 ahci_flags |= AHCI_CMD_WRITE;
105 }
106 break;
107
108 case AP_FEATURES:
109 /* ATA features word */
110 ata_cmd.features |= va_arg(va, u32);
111 break;
112
113 case AP_COUNT:
114 /* transfer count */
115 ata_cmd.count = va_arg(va, u32);
116 break;
117
118 case AP_SECTOR_28:
119 /* 28-bit sector address */
120 ata_cmd.lba_l = va_arg(va, u32);
121 if (ata_cmd.lba_l & 0xf0000000UL)
122 {
123 dprintf(0, DBG_PREFIX": error: LBA-28 address %d has more than 28 bits\n", ata_cmd.lba_l);
124 return(ATA_CMD_INVALID_PARM);
125 }
126 /* add upper 4 bits to device field */
127 ata_cmd.device |= (ata_cmd.lba_l >> 24) & 0x0fU;
128 /* only lower 24 bits come into lba_l */
129 ata_cmd.lba_l &= 0x00ffffffUL;
130 break;
131
132 case AP_SECTOR_48:
133 /* 48-bit sector address */
134 ata_cmd.lba_l = va_arg(va, u32);
135 ata_cmd.lba_h = va_arg(va, u32);
136 break;
137
138 case AP_DEVICE:
139 /* ATA device byte; note that this byte contains the highest
140 * 4 bits of LBA-28 address; we have to leave them alone here. */
141 ata_cmd.device |= va_arg(va, u32) & 0xf0;
142 break;
143
144 case AP_SGLIST:
145 /* scatter/gather list in SCATGATENTRY/count format */
146 sg_list = va_arg(va, void *);
147 sg_cnt = va_arg(va, u32);
148 break;
149
150 case AP_VADDR:
151 /* virtual buffer address in addr/len format (up to 4K) */
152 sg_single.ppXferBuf = MemPhysAdr(va_arg(va, void *));
153 sg_single.XferBufLen = va_arg(va, u32);
154 sg_list = &sg_single;
155 sg_cnt = 1;
156 break;
157
158 case AP_ATAPI_CMD:
159 /* ATAPI command */
160 atapi_cmd = va_arg(va, void *);
161 atapi_cmd_len = va_arg(va, u32);
162 ahci_flags |= AHCI_CMD_ATAPI;
163 break;
164
165 case AP_ATA_CMD:
166 /* ATA command "pass-through" */
167 memcpy(&ata_cmd, va_arg(va, void *), sizeof(ATA_CMD));
168 break;
169
170 case AP_END:
171 break;
172
173 default:
174 dprintf(0, DBG_PREFIX": error: called with invalid parameter type (%d)\n", (int) ap);
175 return(ATA_CMD_INVALID_PARM);
176 }
177
178 } while (ap != AP_END);
179
180 /* --------------------------------------------------------------------------
181 * Fill in AHCI ATA command information. This includes the port command slot,
182 * the corresponding command FIS and the S/G list. The layout of the AHCI
183 * port DMA region is based on the Linux AHCI driver and looks like this:
184 *
185 * - 32 AHCI command headers (AHCI_CMD_HDR) with 32 bytes, each
186 * - 1 FIS receive area with 256 bytes (AHCI_RX_FIS_SZ)
187 * - 32 AHCI command tables, each consisting of
188 * - 64 bytes for command FIS
189 * - 16 bytes for ATAPI comands
190 * - 48 bytes reserved
191 * - 48 S/G entries (AHCI_SG) with 32 bytes, each
192 *
193 * Since the whole DMA buffer for all ports is larger than 64KB and we need
194 * multiple segments to address all of them, there are no virtual pointers
195 * to the individual elements in AD_INFO. Instead, we're relying on macros
196 * for getting the base address of a particular port's DMA region, then
197 * map a structure on top of that for convenience (AHCI_PORT_DMA).
198 */
199 dma_base_virt = port_dma_base(ai, p);
200 dma_base_phys = port_dma_base_phys(ai, p);
201
202 /* AHCI command header */
203 cmd_hdr = &dma_base_virt->cmd_hdr[slot];
204 memset(cmd_hdr, 0x00, sizeof(*cmd_hdr));
205 cmd_hdr->options = ((d & 0x0f) << 12);
206 cmd_hdr->options |= ahci_flags; /* AHCI command flags */
207 cmd_hdr->options |= 5; /* length of command FIS in 32-bit words */
208 cmd_hdr->tbl_addr = dma_base_phys + offsetof(AHCI_PORT_DMA, cmd_tbl[slot]);
209 /* DAZ can use MemPhysAdr(&dma_base_virt->cmd_tbl[slot]), but is probably slower. */
210
211 /* AHCI command table */
212 cmd_tbl = &dma_base_virt->cmd_tbl[slot];
213 memset(cmd_tbl, 0x00, sizeof(*cmd_tbl));
214 ata_cmd_to_fis(cmd_tbl->cmd_fis, &ata_cmd, d);
215
216 if (atapi_cmd != NULL)
217 {
218 /* copy ATAPI command */
219 memcpy(cmd_tbl->atapi_cmd, atapi_cmd, atapi_cmd_len);
220 }
221
222 /* PRDT (S/G list)
223 *
224 * - The S/G list for AHCI adapters is limited to 22 bits for the transfer
225 * size of each element, thus we need to split S/G elements larger than
226 * 22 bits into 2 AHCI_SG elements.
227 *
228 * - The S/G element size for AHCI is what the spec calls '0'-based
229 * (i.e. 0 means 1 bytes). On top of that, the spec requires S/G transfer
230 * sizes to be even in the context of 16-bit transfers, thus bit '1'
231 * always needs to be set.
232 *
233 * - AHCI_MAX_SG_ELEMENT_LEN defines the maximum size of an AHCI S/G
234 * element in bytes, ignoring the '0'-based methodology (i.e. 1 << 22).
235 *
236 * - There's a limit on the maximum number of S/G elements in the port DMA
237 * buffer (AHCI_MAX_SG) which is lower than the HW maximum. It's beyond
238 * the control of this function to split commands which require more
239 * than AHCI_MAX_SG entries. In order to help the caller, the return value
240 * of this function will indicate how many OS/2 S/G entries were
241 * successfully mapped.
242 */
243 for (i = n = 0; i < sg_cnt; i++)
244 {
245 u32 sg_addr = sg_list[i].ppXferBuf;
246 u32 sg_size = sg_list[i].XferBufLen;
247
248 do
249 {
250 u32 chunk = (sg_size > AHCI_MAX_SG_ELEMENT_LEN) ? AHCI_MAX_SG_ELEMENT_LEN : sg_size;
251
252 if (n >= AHCI_MAX_SG)
253 {
254 /* couldn't store all S/G elements in our DMA buffer */
255 if (sg_size)
256 {
257 dprintf(0, DBG_PREFIX": unaligned SG element\n");
258 return -1;
259 }
260 dprintf(0, DBG_PREFIX": too many S/G elements\n");
261 return(i - 1);
262 }
263 if ((sg_addr & 1) || (chunk & 1))
264 {
265 DPRINTF(0, DBG_PREFIX": warning: called with unaligned S/G element(s)\n");
266 return(ATA_CMD_UNALIGNED_ADDR);
267 }
268 cmd_tbl->sg_list[n].addr = sg_addr;
269 cmd_tbl->sg_list[n].size = chunk - 1;
270 sg_addr += chunk;
271 sg_size -= chunk;
272 n++;
273 } while (sg_size > 0);
274 }
275
276 /* set final S/G count in AHCI command header */
277 cmd_hdr->options |= n << 16;
278
279 #if DEBUG & DBG_DETAILED
280 dprintf(0, DBG_PREFIX": ATA command for %d.%d.%d, slot %d:\n", ad_no(ai), p, d, slot);
281 dHexDump(0,cmd_hdr, offsetof(AHCI_CMD_HDR, reserved), "cmd_hdr: ");
282 dHexDump(0,&ata_cmd, sizeof(ata_cmd), "ata_cmd: ");
283 if (atapi_cmd != NULL)
284 {
285 dHexDump(0,atapi_cmd, atapi_cmd_len, "atapi_cmd: ");
286 }
287 if (n > 0)
288 {
289 dHexDump(0,cmd_tbl->sg_list, sizeof(*cmd_tbl->sg_list) * n, "sg_list: ");
290 }
291 #endif
292
293 return(ATA_CMD_SUCCESS);
294}
295
296/******************************************************************************
297 * Fill SATA command FIS with values extracted from an ATA command structure.
298 * The command FIS buffer (fis) is expected to be initialized to 0s. The
299 * structure of the FIS maps to the ATA shadow register block, including
300 * registers which can be written twice to store 16 bits (called 'exp').
301 *
302 * The FIS structure looks like this (using LSB notation):
303 *
304 * +----------------+----------------+----------------+----------------+
305 * 00 | FIS type (27h) | C|R|R|R|PMP | Command | Features |
306 * +----------------+----------------+----------------+----------------+
307 * 04 | LBA 7:0 | LBA 15:8 | LBA 23:16 | R|R|R|D|Head |
308 * +----------------+----------------+----------------+----------------+
309 * 08 | LBA 31:24 | LBA 40:32 | LBA 47:40 | Features exp |
310 * +----------------+----------------+----------------+----------------+
311 * 12 | Count 7:0 | Count 15:8 | Reserved | Control |
312 * +----------------+----------------+----------------+----------------+
313 * 16 | Reserved | Reserved | Reserved | Reserved |
314 * +----------------+----------------+----------------+----------------+
315 */
316void ata_cmd_to_fis(u8 *fis, ATA_CMD *ata_cmd, int d)
317{
318 fis[0] = 0x27; /* register - host to device FIS */
319 fis[1] = (u8) (d & 0xf); /* port multiplier number */
320 fis[1] |= 0x80; /* bit 7 indicates Command FIS */
321 fis[2] = (u8) ata_cmd->cmd;
322 fis[3] = (u8) ata_cmd->features;
323
324 fis[4] = (u8) ata_cmd->lba_l;
325 fis[5] = (u8) (ata_cmd->lba_l >> 8);
326 fis[6] = (u8) (ata_cmd->lba_l >> 16);
327 fis[7] = (u8) ata_cmd->device;
328
329 fis[8] = (u8) (ata_cmd->lba_l >> 24);
330 fis[9] = (u8) ata_cmd->lba_h;
331 fis[10] = (u8) (ata_cmd->lba_h >> 8);
332 fis[11] = (u8) (ata_cmd->features >> 8);
333
334 fis[12] = (u8) ata_cmd->count;
335 fis[13] = (u8) (ata_cmd->count >> 8);
336}
337
338/******************************************************************************
339 * Get max S/G count which will fit into our HW S/G buffers. This function is
340 * called when the S/G list is too long and we need to split the IORB into
341 * multiple commands. It returns both the number of sectors and S/G list
342 * elements that we can handle in a single command.
343 *
344 * The parameter 'sg_indx' indicates the current start index in the S/G list
345 * (0 if this is the first command iteration).
346 *
347 * The parameter 'sg_max' is the return value of v_ata_cmd() and indicates
348 * how many S/G elements were successfully mapped. Whatever we return needs to
349 * be less or equal to this value.
350 *
351 * Returning 0 in *sg_cnt indicates an error.
352 *
353 * NOTE: OS/2 makes sure S/G lists are set up such that entries at HW limits
354 * will never cross sector boundaries. This means that splitting S/G
355 * lists into multiple commands can be done without editing S/G list
356 * elements. Since AHCI only allows 22 bits for each S/G element, the
357 * hardware limits are reported as AHCI_MAX_SG / 2 but will vary based
358 * on the actual length of S/G elements. This function looks for the
359 * maximum number of S/G elements that can be mapped on sector
360 * boundaries which will still fit into our HW S/G list.
361 */
362void ata_max_sg_cnt(IORB_EXECUTEIO *io, USHORT sg_indx, USHORT sg_max,
363 USHORT *sg_cnt, USHORT *sector_cnt)
364{
365 ULONG max_sector_cnt = 0;
366 USHORT max_sg_cnt = 0;
367 ULONG offset = 0;
368 USHORT i;
369 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(io->f16SGList);
370
371 for (i = sg_indx; i < io->cSGList; i++)
372 {
373 if (i - sg_indx >= sg_max)
374 {
375 /* we're beyond the number of S/G elements we can map */
376 break;
377 }
378
379 offset += pSGList[i].XferBufLen;
380 if (offset % io->BlockSize == 0)
381 {
382 /* this S/G element ends on a sector boundary */
383 max_sector_cnt = offset / io->BlockSize;
384 max_sg_cnt = i + 1;
385 }
386 }
387
388 /* return the best match we found (0 indicating failure) */
389 *sector_cnt = max_sector_cnt;
390 *sg_cnt = max_sg_cnt;
391}
392
393
394/******************************************************************************
395 * Get device or media geometry. Device and media geometry are expected to be
396 * the same for non-removable devices, which will always be the case for the
397 * ATA devices we're dealing with (hard disks). ATAPI is a different story
398 * and handled by atapi_get_geometry().
399 */
400int ata_get_geometry(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
401{
402 ADD_WORKSPACE *aws = add_workspace(pIorb);
403 int rc;
404
405 /* allocate buffer for ATA identify information */
406 if ((aws->buf = MemAlloc(ATA_ID_WORDS * sizeof(u16))) == NULL)
407 {
408 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE);
409 return(-1);
410 }
411
412 /* request ATA identify information */
413 aws->ppfunc = ata_get_geometry_pp;
414 rc = ata_cmd(ad_infos + iorb_unit_adapter(pIorb),
415 iorb_unit_port(pIorb),
416 iorb_unit_device(pIorb),
417 slot,
418 ATA_CMD_ID_ATA,
419 AP_VADDR, (void *) aws->buf, ATA_ID_WORDS * sizeof(u16),
420 AP_END);
421
422 if (rc != 0)
423 {
424 iorb_seterr(pIorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
425 }
426
427 return(rc);
428}
429
430int check_lvm(IORBH *pIorb, ULONG sector)
431{
432 DLA_Table_Sector *pDLA = (DLA_Table_Sector*)add_workspace(pIorb)->buf;
433 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
434 GEOMETRY64 *geometry = (GEOMETRY64*)((IORB_GEOMETRY*)pIorb)->f16Geometry;
435 int p = iorb_unit_port(pIorb);
436 int rc;
437
438 rc = ahci_exec_polled_cmd(ai, p, 0, 500, ATA_CMD_READ,
439 AP_SECTOR_28, sector-1,
440 AP_COUNT, 1,
441 AP_VADDR, (void *)pDLA, 512,
442 AP_DEVICE, 0x40,
443 AP_END);
444 if (rc) return 0;
445
446 DHEXDUMP(DBG_DETAILED, pDLA, sizeof(DLA_Table_Sector), "DLA sector %d:\n", sector-1);
447
448 if ((pDLA->DLA_Signature1 == DLA_TABLE_SIGNATURE1) && (pDLA->DLA_Signature2 == DLA_TABLE_SIGNATURE2))
449 {
450 DPRINTF(DBG_ATTACH, DBG_PREFIX": DLA found at sector %d\n", sector-1);
451 geometry->TotalCylinders = pDLA->Cylinders;
452 geometry->NumHeads = pDLA->Heads_Per_Cylinder;
453 geometry->SectorsPerTrack = pDLA->Sectors_Per_Track;
454 if (add_workspace(pIorb)->fIs64bit)
455 geometry->ullTotalSectors = pDLA->Cylinders * pDLA->Heads_Per_Cylinder * pDLA->Sectors_Per_Track;
456 else
457 geometry->TotalSectors = pDLA->Cylinders * pDLA->Heads_Per_Cylinder * pDLA->Sectors_Per_Track;
458 return 1;
459 }
460
461 return 0;
462}
463
464/******************************************************************************
465 * Try to read LVM information from the disk. If found, use the LVM geometry.
466 * This function will only work at init time. A better strategy would be to
467 * calculate the geometry during ahci_scan_ports and save it away and then just
468 * return the saved values when ata_get_geometry() is called.
469 */
470int is_lvm_geometry(IORBH *pIorb)
471{
472 GEOMETRY *geometry = ((IORB_GEOMETRY*)pIorb)->f16Geometry;
473 ULONG sector;
474
475 if (init_complete) return 0; /* We cannot use ahci_exec_polled_cmd() after init_complete */
476
477 #ifdef DEBUG
478 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
479 int p = iorb_unit_port(pIorb);
480 int d = iorb_unit_device(pIorb);
481 dprintf(DBG_DETAILED, DBG_PREFIX": (%d.%d.%d)\n", ad_no(ai), p, d);
482 #endif
483
484 /* First check the sector reported by the hardware */
485 if (check_lvm(pIorb, geometry->SectorsPerTrack)) return 1;
486
487 for (sector = 255; sector >= 63; sector >>= 1)
488 {
489 if (sector == geometry->SectorsPerTrack) continue;
490 if (check_lvm(pIorb, sector)) return 1;
491 }
492
493 return 0;
494}
495
496/******************************************************************************
497 * Post processing function for ata_get_geometry(): convert the ATA identify
498 * information to OS/2 IOCC_GEOMETRY information.
499 */
500void ata_get_geometry_pp(IORBH FAR16DATA *vIorb, IORBH *pIorb)
501{
502 GEOMETRY64 *geometry = (GEOMETRY64*)((IORB_GEOMETRY*)pIorb)->f16Geometry;
503 USHORT geometry_len = ((IORB_GEOMETRY *)pIorb)->GeometryLen;
504 ULONGLONG ullTotalSectors;
505 u16 *id_buf = add_workspace(pIorb)->buf;
506 int a = iorb_unit_adapter(pIorb);
507 int p = iorb_unit_port(pIorb);
508 char *Method;
509
510 /* Fill-in geometry information; the ATA-8 spec declares the geometry
511 * fields in the ATA ID buffer as obsolete but it's still the best
512 * guess in most cases. If the information stored in the geometry
513 * fields is apparently incorrect, we'll use the algorithm typically
514 * used by SCSI adapters and modern PC BIOS versions:
515 *
516 * - 512 bytes per sector
517 * - 255 heads
518 * - 63 sectors per track (or 56 with the parameter "/4")
519 * - x cylinders (calculated)
520 *
521 * Please note that os2ahci currently does not natively support ATA sectors
522 * larger than 512 bytes, therefore relies on the translation logic built
523 * into the corresponding ATA disks. In order to prevent file systems that
524 * use block sizes larger than 512 bytes (FAT, JFS, ...) from ending up on
525 * incorrectly aligned physical sector accesses, hence using more physical
526 * I/Os than necessary, the command line parameter "/4" can be used to force
527 * a track size of 56 sectors. This way, partitions will start on 4K
528 * boundaries.
529 *
530 * Another limitation is that OS/2 has a 32-bit variable for the total number
531 * of sectors, limiting the maximum capacity to roughly 2TB. This is another
532 * issue that needs to be addressed sooner or later; large sectors could
533 * raise this limit to something like 8TB but this is not really much of a
534 * difference. Maybe there's something in later DDKs that allows more than
535 * 32 bits?
536 *
537 * Warning: Do not change the algorithm for calculating disk geometry without
538 * fully understaing the consequences. Side effects of even slight changes
539 * can be unexpected and catastrophic.
540 */
541 memset(geometry, 0, geometry_len);
542 geometry->BytesPerSector = ATA_SECTOR_SIZE;
543
544 /* extract total number of sectors */
545 if (id_buf[ATA_ID_CFS_ENABLE_2] & 0x400)
546 {
547 /* 48-bit LBA supported */
548 if ((ATA_CAPACITY48_H(id_buf) != 0) && !add_workspace(pIorb)->fIs64bit)
549 {
550 /* more than 32 bits for number of sectors */
551 dprintf(0, DBG_PREFIX": warning: limiting disk %d.%d.%d to 2TB\n",
552 iorb_unit_adapter(pIorb), iorb_unit_port(pIorb),
553 iorb_unit_device(pIorb));
554 ullTotalSectors = 0xffffffff;
555 }
556 else
557 {
558 ullTotalSectors = MAKEULL(ATA_CAPACITY48_H(id_buf), ATA_CAPACITY48_L(id_buf));
559 }
560 }
561 else
562 {
563 /* 28-bit LBA */
564 ullTotalSectors = ATA_CAPACITY(id_buf) & 0x0fffffff;
565 }
566
567 Method = "None";
568 /* fabricate the remaining geometry fields */
569 if (track_size[a][p] != 0)
570 {
571 /* A specific track size has been requested for this port; this is
572 * typically done for disks with 4K sectors to make sure partitions
573 * start on 8-sector boundaries (parameter "/4").
574 */
575 geometry->NumHeads = 255;
576 geometry->SectorsPerTrack = track_size[a][p];
577 geometry->TotalCylinders = ullTotalSectors / ((u32)geometry->NumHeads * (u32)geometry->SectorsPerTrack);
578 Method = "Custom";
579 }
580 else if (CUR_HEADS(id_buf) > 0 && CUR_CYLS(id_buf) > 0 && CUR_SECTORS(id_buf) > 0 &&
581 CUR_CAPACITY(id_buf) == (u32) CUR_HEADS(id_buf) * (u32) CUR_CYLS(id_buf) * (u32) CUR_SECTORS(id_buf))
582 {
583 /* BIOS-supplied (aka "current") geometry values look valid */
584 geometry->NumHeads = CUR_HEADS(id_buf);
585 geometry->SectorsPerTrack = CUR_SECTORS(id_buf);
586 geometry->TotalCylinders = CUR_CYLS(id_buf);
587 Method = "BIOS";
588 }
589 else if (ATA_HEADS(id_buf) > 0 && ATA_CYLS(id_buf) > 0 && ATA_SECTORS(id_buf) > 0)
590 {
591 /* ATA-supplied values for geometry look valid */
592 geometry->NumHeads = ATA_HEADS(id_buf);
593 geometry->SectorsPerTrack = ATA_SECTORS(id_buf);
594 geometry->TotalCylinders = ATA_CYLS(id_buf);
595 Method = "ATA";
596 }
597 else
598 {
599 /* use typical SCSI geometry */
600 geometry->NumHeads = 255;
601 geometry->SectorsPerTrack = 63;
602 geometry->TotalCylinders = ullTotalSectors / ((u32)geometry->NumHeads * (u32)geometry->SectorsPerTrack);
603 Method = "SCSI";
604 }
605
606 DPRINTF(DBG_ATTACH, DBG_PREFIX": Physical geometry: %d cylinders, %d heads, %d sectors per track (%dMB) (%s)\n",
607 geometry->TotalCylinders, geometry->NumHeads, geometry->SectorsPerTrack,
608 (ULONG)(ullTotalSectors / 2048), Method);
609
610 if (is_lvm_geometry(pIorb)) Method = "LVM"; /* Writes TotalSectors/ullTotalSectors */
611 else CalculateLogicalGeometry(geometry, add_workspace(pIorb)->fIs64bit, ullTotalSectors);
612 if (add_workspace(pIorb)->fIs64bit) ullTotalSectors = geometry->ullTotalSectors;
613 else ullTotalSectors = geometry->TotalSectors;
614
615 ad_infos[a].ports[p].devs[0].dev_info.ulCylinders = geometry->TotalCylinders;
616 ad_infos[a].ports[p].devs[0].dev_info.usHeadsPerCylinder = geometry->NumHeads;
617 ad_infos[a].ports[p].devs[0].dev_info.usSectorsPerTrack = geometry->SectorsPerTrack;
618 ad_infos[a].ports[p].devs[0].dev_info.ullTotalSectors = ullTotalSectors;
619 ad_infos[a].ports[p].devs[0].dev_info.pMethod = Method;
620
621 //DAZ DPRINTF(2,"Reported geometry: %d cylinders, %d heads, %d sectors per track (%dMB) (%s)\n",
622 DPRINTF(DBG_ATTACH, DBG_PREFIX": Reported geometry: %d cylinders, %d heads, %d sectors per track (%dMB) (%s)\n",
623 geometry->TotalCylinders, geometry->NumHeads, geometry->SectorsPerTrack,
624 (ULONG)(ullTotalSectors / 2048), Method);
625
626 /* tell interrupt handler that this IORB is complete */
627 add_workspace(pIorb)->complete = 1;
628}
629
630/******************************************************************************
631 * Test whether unit is ready.
632 */
633int ata_unit_ready(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
634{
635 /* This is a NOP for ATA devices (at least right now); returning an error
636 * without setting an error code means ahci_exec_iorb() will not queue any
637 * HW command and the IORB will complete successfully.
638 */
639 ((IORB_UNIT_STATUS *)pIorb)->UnitStatus = US_READY | US_POWER;
640 return(-1);
641}
642
643/******************************************************************************
644 * Fabricate ATA READ command based on the capabilities of the corresponding
645 * device and the paramters set from above (NCQ, etc).
646 */
647static int ata_cmd_read(IORBH *pIorb, AD_INFO *ai, int p, int d, int slot,
648 ULONGLONG ullLba, ULONG count, SCATGATENTRY *sg_list,
649 ULONG sg_cnt)
650{
651 int rc;
652
653 if (add_workspace(pIorb)->is_ncq || ullLba >= (1 << 28) || count > 256 || (ullLba+count) >= (1 << 28))
654 {
655 /* need LBA48 for this command */
656 if (!ai->ports[p].devs[d].lba48)
657 {
658 iorb_seterr(pIorb, IOERR_RBA_LIMIT);
659 return(-1);
660 }
661 if (add_workspace(pIorb)->is_ncq)
662 {
663 /* use NCQ read; count goes into feature register, tag into count! */
664 rc = ata_cmd(ai, p, d, slot, ATA_CMD_FPDMA_READ,
665 AP_SECTOR_48, ullLba,
666 AP_FEATURES, count,
667 AP_COUNT, (slot << 3), /* tag == slot */
668 AP_SGLIST, sg_list, sg_cnt,
669 AP_DEVICE, 0x40,
670 AP_END);
671 }
672 else
673 {
674 rc = ata_cmd(ai, p, d, slot, ATA_CMD_READ_EXT,
675 AP_SECTOR_48, ullLba,
676 AP_COUNT, count,
677 AP_SGLIST, sg_list, sg_cnt,
678 AP_DEVICE, 0x40,
679 AP_END);
680 }
681
682 }
683 else
684 {
685 rc = ata_cmd(ai, p, d, slot, ATA_CMD_READ,
686 AP_SECTOR_28, (ULONG)ullLba,
687 AP_COUNT, count & 0xffU,
688 AP_SGLIST, sg_list, sg_cnt,
689 AP_DEVICE, 0x40,
690 AP_END);
691 }
692
693 return(rc);
694}
695
696/******************************************************************************
697 * Read sectors from AHCI device.
698 */
699int ata_read(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
700{
701 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
702 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(io->f16SGList);
703 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
704 ULONGLONG ullLba = io->RBA + io->BlocksXferred;
705 USHORT count = io->BlockCount - io->BlocksXferred;
706 USHORT sg_indx;
707 USHORT sg_cnt;
708 int p = iorb_unit_port(pIorb);
709 int d = iorb_unit_device(pIorb);
710 int rc;
711
712 if (io->BlockCount == 0)
713 {
714 /* NOP; return -1 without error in IORB to indicate success */
715 return(-1);
716 }
717
718 if (add_workspace(pIorb)->unaligned)
719 {
720 /* unaligned S/G addresses present; need to use double buffers */
721 return(ata_read_unaligned(pIorb, slot));
722 }
723
724 if (add_workspace(pIorb)->fIs64bit)
725 {
726 ullLba = ((IORB_EXECUTEIO64*)pIorb)->ullRBA + io->BlocksXferred;
727 }
728
729 /* Kludge: some I/O commands during boot use excessive S/G buffer lengths
730 * which cause NCQ commands to lock up. If there's only one S/G element
731 * and this element is already larger than what we can derive from the sector
732 * count, we'll adjust that element.
733 */
734 if (io->BlocksXferred == 0 && io->cSGList == 1 &&
735 pSGList[0].XferBufLen > (ULONG) io->BlockCount * io->BlockSize)
736 {
737 pSGList[0].XferBufLen = (ULONG) io->BlockCount * io->BlockSize;
738 }
739
740 /* prepare read command while keeping an eye on S/G count limitations */
741 do
742 {
743 sg_indx = SgIndexFromOffset(pSGList, io->cSGList, io->BlocksXferred * io->BlockSize);
744 sg_cnt = io->cSGList - sg_indx;
745 rc = ata_cmd_read(pIorb, ai, p, d, slot, ullLba, count, pSGList + sg_indx, sg_cnt);
746 if (rc > 0)
747 {
748 /* couldn't map all S/G elements */
749 ata_max_sg_cnt(io, sg_indx, rc, &sg_cnt, &count);
750 }
751 } while (rc > 0 && sg_cnt > 0);
752
753 if (rc == 0)
754 {
755 add_workspace(pIorb)->blocks = count;
756 add_workspace(pIorb)->ppfunc = ata_read_pp;
757 }
758 else if (rc > 0)
759 {
760 iorb_seterr(pIorb, IOERR_CMD_SGLIST_BAD);
761 }
762 else if (rc == ATA_CMD_UNALIGNED_ADDR)
763 {
764 /* unaligned S/G addresses detected; need to use double buffers */
765 add_workspace(pIorb)->unaligned = 1;
766 return(ata_read_unaligned(pIorb, slot));
767 }
768 else
769 {
770 iorb_seterr(pIorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
771 }
772
773 return(rc);
774}
775
776/******************************************************************************
777 * Read sectors from AHCI device with unaligned S/G element addresses. AHCI
778 * only allows aligned S/G addresses while OS/2 doesn't have these kind of
779 * restrictions. This doesn't happen very often but when it does, we need to
780 * use a transfer buffer and copy the data manually.
781 */
782int ata_read_unaligned(IORBH *pIorb, int slot)
783{
784 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
785 ADD_WORKSPACE *aws = add_workspace(pIorb);
786 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
787 ULONGLONG ullLba = io->RBA + io->BlocksXferred;
788 SCATGATENTRY sg_single;
789 int p = iorb_unit_port(pIorb);
790 int d = iorb_unit_device(pIorb);
791 int rc;
792
793 if (add_workspace(pIorb)->fIs64bit)
794 {
795 ullLba = ((IORB_EXECUTEIO64*)pIorb)->ullRBA + io->BlocksXferred;
796 }
797
798 DPRINTF(DBG_DETAILED, DBG_PREFIX": ata_read_unaligned(%d.%d.%d, %lld)\n", ad_no(ai), p, d, ullLba);
799 ai->ports[p].unaligned_read_count++;
800
801 /* allocate transfer buffer */
802 if ((aws->buf = MemAlloc(io->BlockSize)) == NULL)
803 {
804 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE);
805 return(-1);
806 }
807
808 /* prepare read command using transfer buffer */
809 sg_single.ppXferBuf = MemPhysAdr(aws->buf);
810 sg_single.XferBufLen = io->BlockSize;
811 rc = ata_cmd_read(pIorb, ai, p, d, slot, ullLba, 1, &sg_single, 1);
812
813 if (rc == 0) {
814 add_workspace(pIorb)->blocks = 1;
815 add_workspace(pIorb)->ppfunc = ata_read_pp;
816
817 } else if (rc > 0) {
818 iorb_seterr(pIorb, IOERR_CMD_SGLIST_BAD);
819
820 } else {
821 iorb_seterr(pIorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
822 }
823
824 return(rc);
825}
826
827/******************************************************************************
828 * Post processing function for ata_read(); this function updates the
829 * BlocksXferred counter in the IORB and, if not all blocks have been
830 * transferred, requeues the IORB to process the remaining sectors. It also
831 * takes care of copying data from the transfer buffer for unaligned reads.
832 */
833void ata_read_pp(IORBH FAR16DATA *vIorb, IORBH *pIorb)
834{
835 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
836 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(io->f16SGList);
837 ADD_WORKSPACE *aws = add_workspace(pIorb);
838
839 if (aws->unaligned)
840 {
841 /* copy transfer buffer to corresponding physical address in S/G list */
842 CopySgBuf(pSGList, io->cSGList, (ULONG)io->BlocksXferred * (ULONG)io->BlockSize,
843 aws->buf, io->BlockSize, BUF_TO_SGL);
844 }
845
846 io->BlocksXferred += add_workspace(pIorb)->blocks;
847 DPRINTF(DBG_DETAILED, DBG_PREFIX": blocks transferred = %d\n", io->BlocksXferred);
848
849 if (io->BlocksXferred >= io->BlockCount)
850 {
851 /* we're done; tell IRQ handler the IORB is complete */
852 add_workspace(pIorb)->complete = 1;
853 }
854 else
855 {
856 /* requeue this IORB for next iteration */
857 iorb_requeue(pIorb);
858 }
859}
860
861/******************************************************************************
862 * Verify readability of sectors on ATA device.
863 */
864int ata_verify(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
865{
866 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
867 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
868 int p = iorb_unit_port(pIorb);
869 int d = iorb_unit_device(pIorb);
870 ULONGLONG ullLba = io->RBA;
871 int rc;
872
873 if (io->BlockCount == 0)
874 {
875 /* NOP; return -1 without error in IORB to indicate success */
876 return(-1);
877 }
878
879 if (add_workspace(pIorb)->fIs64bit)
880 {
881 ullLba = ((IORB_EXECUTEIO64*)pIorb)->ullRBA;
882 }
883
884 /* prepare verify command */
885 if (ullLba >= (1UL << 28) || io->BlockCount > 256)
886 {
887 /* need LBA48 for this command */
888 if (!ai->ports[p].devs[d].lba48) {
889 iorb_seterr(pIorb, IOERR_RBA_LIMIT);
890 return(-1);
891 }
892 rc = ata_cmd(ai, p, d, slot, ATA_CMD_VERIFY_EXT,
893 AP_SECTOR_48, ullLba,
894 AP_COUNT, io->BlockCount,
895 AP_DEVICE, 0x40,
896 AP_END);
897 } else {
898 rc = ata_cmd(ai, p, d, slot, ATA_CMD_VERIFY,
899 AP_SECTOR_28, (ULONG)ullLba,
900 AP_COUNT, io->BlockCount & 0xffU,
901 AP_DEVICE, 0x40,
902 AP_END);
903 }
904
905 return(rc);
906}
907
908/******************************************************************************
909 * Fabricate ATA WRITE command based on the capabilities of the corresponding
910 * device and the paramters set from above (NCQ, etc)
911 */
912static int ata_cmd_write(IORBH *pIorb, AD_INFO *ai, int p, int d, int slot,
913 ULONGLONG ullLba, ULONG count, SCATGATENTRY *sg_list,
914 ULONG sg_cnt, int write_through)
915{
916 int rc;
917
918 if (ullLba >= (1UL << 28) || count > 256 || add_workspace(pIorb)->is_ncq)
919 {
920 /* need LBA48 for this command */
921 if (!ai->ports[p].devs[d].lba48)
922 {
923 iorb_seterr(pIorb, IOERR_RBA_LIMIT);
924 return(-1);
925 }
926 if (add_workspace(pIorb)->is_ncq)
927 {
928 /* use NCQ write; count goes into feature register, tag into count! */
929 rc = ata_cmd(ai, p, d, slot, ATA_CMD_FPDMA_WRITE,
930 AP_SECTOR_48, ullLba,
931 AP_FEATURES, count,
932 /* tag = slot */
933 AP_COUNT, (slot << 3),
934 AP_SGLIST, sg_list, sg_cnt,
935 AP_DEVICE, 0x40,
936 /* force unit access */
937 AP_DEVICE, (write_through && !force_write_cache) ? 0x80 : 0,
938 AP_WRITE, 1,
939 AP_END);
940 }
941 else
942 {
943 rc = ata_cmd(ai, p, d, slot, ATA_CMD_WRITE_EXT,
944 AP_SECTOR_48, ullLba,
945 AP_COUNT, count,
946 AP_SGLIST, sg_list, sg_cnt,
947 AP_DEVICE, 0x40,
948 AP_WRITE, 1,
949 AP_END);
950 }
951 }
952 else
953 {
954 rc = ata_cmd(ai, p, d, slot, ATA_CMD_WRITE,
955 AP_SECTOR_28, (ULONG)ullLba,
956 AP_COUNT, count & 0xffU,
957 AP_SGLIST, sg_list, sg_cnt,
958 AP_DEVICE, 0x40,
959 AP_WRITE, 1,
960 AP_END);
961 }
962
963 return(rc);
964}
965
966/******************************************************************************
967 * Write sectors to AHCI device.
968 */
969int ata_write(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
970{
971 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
972 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(io->f16SGList);
973 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
974 ULONGLONG ullLba = io->RBA + io->BlocksXferred;
975 USHORT count = io->BlockCount - io->BlocksXferred;
976 USHORT sg_indx;
977 USHORT sg_cnt;
978 int p = iorb_unit_port(pIorb);
979 int d = iorb_unit_device(pIorb);
980 int rc;
981
982 if (io->BlockCount == 0)
983 {
984 /* NOP; return -1 without error in IORB to indicate success */
985 return(-1);
986 }
987
988 if (add_workspace(pIorb)->unaligned)
989 {
990 /* unaligned S/G addresses present; need to use double buffers */
991 return(ata_write_unaligned(pIorb, slot));
992 }
993
994 if (add_workspace(pIorb)->fIs64bit)
995 {
996 ullLba = ((IORB_EXECUTEIO64*)pIorb)->ullRBA + io->BlocksXferred;
997 }
998
999 /* prepare write command while keeping an eye on S/G count limitations */
1000 do {
1001 sg_indx = SgIndexFromOffset(pSGList, io->cSGList, io->BlocksXferred * io->BlockSize);
1002 sg_cnt = io->cSGList - sg_indx;
1003 if ((rc = ata_cmd_write(pIorb, ai, p, d, slot, ullLba, count,
1004 pSGList + sg_indx, sg_cnt,
1005 io->Flags & XIO_DISABLE_HW_WRITE_CACHE)) > 0)
1006 {
1007 /* couldn't map all S/G elements */
1008 ata_max_sg_cnt(io, sg_indx, (USHORT)rc, &sg_cnt, &count);
1009 }
1010 } while (rc > 0 && sg_cnt > 0);
1011
1012 if (rc == 0)
1013 {
1014 add_workspace(pIorb)->blocks = count;
1015 add_workspace(pIorb)->ppfunc = ata_write_pp;
1016 }
1017 else if (rc > 0)
1018 {
1019 iorb_seterr(pIorb, IOERR_CMD_SGLIST_BAD);
1020 }
1021 else if (rc == ATA_CMD_UNALIGNED_ADDR)
1022 {
1023 /* unaligned S/G addresses detected; need to use double buffers */
1024 add_workspace(pIorb)->unaligned = 1;
1025 return(ata_write_unaligned(pIorb, slot));
1026 }
1027 else
1028 {
1029 iorb_seterr(pIorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
1030 }
1031
1032 return(rc);
1033}
1034
1035/******************************************************************************
1036 * Write sectors from AHCI device with unaligned S/G element addresses. AHCI
1037 * only allows aligned S/G addresses while OS/2 doesn't have these kind of
1038 * restrictions. This doesn't happen very often but when it does, we need to
1039 * use a transfer buffer and copy the data manually.
1040 */
1041int ata_write_unaligned(IORBH *pIorb, int slot)
1042{
1043 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
1044 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(io->f16SGList);
1045 ADD_WORKSPACE *aws = add_workspace(pIorb);
1046 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
1047 ULONGLONG ullLba = io->RBA + io->BlocksXferred;
1048 SCATGATENTRY sg_single;
1049 int p = iorb_unit_port(pIorb);
1050 int d = iorb_unit_device(pIorb);
1051 int rc;
1052
1053 if (add_workspace(pIorb)->fIs64bit)
1054 {
1055 ullLba = ((IORB_EXECUTEIO64*)pIorb)->ullRBA + io->BlocksXferred;
1056 }
1057
1058 DPRINTF(DBG_DETAILED, DBG_PREFIX": ata_write_unaligned(%d.%d.%d, %lld)\n", ad_no(ai), p, d, ullLba);
1059
1060 /* allocate transfer buffer */
1061 if ((aws->buf = MemAlloc(io->BlockSize)) == NULL)
1062 {
1063 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE);
1064 return(-1);
1065 }
1066
1067 /* copy next sector from S/G list to transfer buffer */
1068 CopySgBuf(pSGList, io->cSGList, (ULONG)io->BlocksXferred * (ULONG)io->BlockSize,
1069 aws->buf, io->BlockSize, SGL_TO_BUF);
1070
1071 /* prepare write command using transfer buffer */
1072 sg_single.ppXferBuf = MemPhysAdr(aws->buf);
1073 sg_single.XferBufLen = io->BlockSize;
1074 rc = ata_cmd_write(pIorb, ai, p, d, slot, ullLba, 1, &sg_single, 1,
1075 io->Flags & XIO_DISABLE_HW_WRITE_CACHE);
1076
1077 if (rc == 0)
1078 {
1079 add_workspace(pIorb)->blocks = 1;
1080 add_workspace(pIorb)->ppfunc = ata_write_pp;
1081 }
1082 else if (rc > 0)
1083 {
1084 iorb_seterr(pIorb, IOERR_CMD_SGLIST_BAD);
1085 }
1086 else
1087 {
1088 iorb_seterr(pIorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
1089 }
1090
1091 return(rc);
1092}
1093
1094
1095/******************************************************************************
1096 * Post processing function for ata_write(); this function updates the
1097 * BlocksXferred counter in the IORB and, if not all blocks have been
1098 * transferred, requeues the IORB to process the remaining sectors.
1099 */
1100void ata_write_pp(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1101{
1102 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
1103
1104 io->BlocksXferred += add_workspace(pIorb)->blocks;
1105 DPRINTF(DBG_DETAILED, DBG_PREFIX": ata_write_pp(): blocks transferred = %d\n", io->BlocksXferred);
1106
1107 if (io->BlocksXferred >= io->BlockCount)
1108 {
1109 /* we're done; tell IRQ handler the IORB is complete */
1110 add_workspace(pIorb)->complete = 1;
1111 }
1112 else
1113 {
1114 /* requeue this IORB for next iteration */
1115 iorb_requeue(pIorb);
1116 }
1117}
1118
1119/******************************************************************************
1120 * Execute ATA command.
1121 */
1122int ata_execute_ata(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
1123{
1124 IORB_ADAPTER_PASSTHRU *apt = (IORB_ADAPTER_PASSTHRU *)pIorb;
1125 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(apt->f16SGList);
1126 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
1127 int p = iorb_unit_port(pIorb);
1128 int d = iorb_unit_device(pIorb);
1129 int rc;
1130
1131 if (apt->ControllerCmdLen != sizeof(ATA_CMD))
1132 {
1133 iorb_seterr(pIorb, IOERR_CMD_SYNTAX);
1134 return(-1);
1135 }
1136
1137 rc = ata_cmd(ai, p, d, slot, 0,
1138 AP_SGLIST, pSGList, apt->cSGList,
1139 AP_ATA_CMD, Far16ToFlat(apt->f16ControllerCmd),
1140 AP_WRITE, !(apt->Flags & PT_DIRECTION_IN),
1141 AP_END);
1142
1143 if (rc == 0)
1144 {
1145 add_workspace(pIorb)->ppfunc = ata_execute_ata_pp;
1146 }
1147
1148 return(rc);
1149}
1150
1151/******************************************************************************
1152 * Post processing function for ata_execute_ata(); the main purpose of this
1153 * function is to copy the received D2H FIS (i.e. the device registers after
1154 * command completion) back to the ATA command structure.
1155 *
1156 * See ata_cmd_to_fis() for an explanation of the mapping.
1157 */
1158void ata_execute_ata_pp(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1159{
1160 AHCI_PORT_DMA *dma_base;
1161 ATA_CMD *cmd;
1162 AD_INFO *ai;
1163 u8 *fis;
1164 int p;
1165
1166 /* get address of D2H FIS */
1167 ai = ad_infos + iorb_unit_adapter(pIorb);
1168 p = iorb_unit_port(pIorb);
1169 dma_base = port_dma_base(ai, p);
1170 fis = dma_base->rx_fis + 0x40;
1171
1172 if (fis[0] != 0x34)
1173 {
1174 /* this is not a D2H FIS - give up silently */
1175 DPRINTF(DBG_DETAILED, DBG_PREFIX": ata_execute_ata_pp(): D2H FIS type incorrect: %d\n", fis[0]);
1176 add_workspace(pIorb)->complete = 1;
1177 return;
1178 }
1179
1180 /* map D2H FIS to the original ATA controller command structure */
1181 cmd = (ATA_CMD *)Far16ToFlat(((IORB_ADAPTER_PASSTHRU*)pIorb)->f16ControllerCmd);
1182
1183 cmd->cmd = fis[2];
1184 cmd->device = fis[7];
1185 cmd->features = ((u16) fis[3])
1186 | ((u16) fis[11]);
1187 cmd->lba_l = ((u32) fis[4])
1188 | ((u32) fis[5] << 8)
1189 | ((u32) fis[6] << 16)
1190 | ((u32) fis[8] << 24);
1191 cmd->lba_h = ((u16) fis[9])
1192 | ((u16) fis[10] << 8);
1193 cmd->count = ((u16) fis[12])
1194 | ((u16) fis[13] << 8);
1195
1196 DHEXDUMP(DBG_DETAILED, cmd, sizeof(*cmd), "ahci_execute_ata_pp(): cmd after completion:\n");
1197
1198 /* signal completion to interrupt handler */
1199 add_workspace(pIorb)->complete = 1;
1200}
1201
1202/******************************************************************************
1203 * Request sense information for a failed command. Since there is no "request
1204 * sense" command for ATA devices, we need to read the current error code from
1205 * the AHCI task file register and fabricate the sense information.
1206 *
1207 * NOTES:
1208 *
1209 * - This function must be called right after an ATA command has failed and
1210 * before any other commands are queued on the corresponding port. This
1211 * function is typically called in the port restart context hook which is
1212 * triggered by an AHCI error interrupt.
1213 *
1214 * - The ATA error bits are a complete mess. We'll try and catch the most
1215 * interesting error codes (such as medium errors) and report everything
1216 * else with a generic error code.
1217 */
1218int ata_req_sense(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
1219{
1220 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
1221 u8 *port_mmio = port_base(ai, iorb_unit_port(pIorb));
1222 u32 tf_data = readl(port_mmio + PORT_TFDATA);
1223 u8 err = (tf_data >> 8);
1224 u8 sts = (tf_data);
1225
1226 if (sts & ATA_ERR)
1227 {
1228 if (sts & ATA_DF)
1229 {
1230 /* there is a device-specific error condition */
1231 if (err & ATA_ICRC)
1232 {
1233 iorb_seterr(pIorb, IOERR_ADAPTER_DEVICEBUSCHECK);
1234 }
1235 else if (err & ATA_UNC)
1236 {
1237 iorb_seterr(pIorb, IOERR_MEDIA);
1238 }
1239 else if (err & ATA_IDNF)
1240 {
1241 iorb_seterr(pIorb, IOERR_RBA_ADDRESSING_ERROR);
1242 }
1243 else
1244 {
1245 iorb_seterr(pIorb, IOERR_DEVICE_NONSPECIFIC);
1246 }
1247
1248 }
1249 else
1250 {
1251 iorb_seterr(pIorb, IOERR_DEVICE_NONSPECIFIC);
1252 }
1253 }
1254 else
1255 {
1256 /* this function only gets called when we received an error interrupt */
1257 iorb_seterr(pIorb, IOERR_DEVICE_NONSPECIFIC);
1258 }
1259
1260 /* Return an error to indicate there's no HW command to be submitted and
1261 * that the IORB can be completed "as is" (the upstream code expects the
1262 * IORB error code, if any, to be set when this happens and this is exactly
1263 * what this function is all about).
1264 */
1265 return(-1);
1266}
1267
1268/******************************************************************************
1269 * Extract vendor and device name from an ATA INDENTIFY buffer. Since strings
1270 * in the indentify buffer are byte-swapped, we need to swap them back.
1271 */
1272char *ata_dev_name(u16 *id_buf)
1273{
1274 static char dev_name[ATA_ID_PROD_LEN + 1];
1275 char *t = dev_name;
1276 char *s = (char *) (id_buf + ATA_ID_PROD);
1277 int i;
1278
1279 dev_name[sizeof(dev_name)-1] = '\0';
1280
1281 for (i = 0; i < ATA_ID_PROD_LEN / 2; i++) {
1282 *(t++) = s[1];
1283 *(t++) = s[0];
1284 s += 2;
1285 }
1286
1287 return(dev_name);
1288}
1289
1290/******************************************************************************
1291 * Halt processing by submitting an internal error. This is a last resort and
1292 * should only be called when the system state is corrupt.
1293 */
1294void panic(char *msg)
1295{
1296 Dev32Help_InternalError(msg, strlen(msg));
1297}
1298
Note: See TracBrowser for help on using the repository browser.