source: trunk/src/os2ahci/ata.c@ 208

Last change on this file since 208 was 208, checked in by David Azarewicz, 4 years ago

Use standardized routines.

File size: 44.0 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-2021 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,"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,"error: v_ata_cmd() 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, __func__": unaligned SG element\n");
258 return -1;
259 }
260 dprintf(0, __func__": too many S/G elements\n");
261 return(i - 1);
262 }
263 if ((sg_addr & 1) || (chunk & 1))
264 {
265 DPRINTF(0,"warning: ata_cmd() 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 #ifdef DEBUG
280 if ((D32g_DbgLevel >= 5) /*|| (atapi_cmd != NULL)*/)
281 {
282 DPRINTF(0,"ATA command for %d.%d.%d, slot %d:\n", ad_no(ai), p, d, slot);
283 dHexDump(0,cmd_hdr, offsetof(AHCI_CMD_HDR, reserved), "cmd_hdr: ");
284 dHexDump(0,&ata_cmd, sizeof(ata_cmd), "ata_cmd: ");
285 if (atapi_cmd != NULL)
286 {
287 dHexDump(0,atapi_cmd, atapi_cmd_len, "atapi_cmd: ");
288 }
289 if (n > 0)
290 {
291 dHexDump(0,cmd_tbl->sg_list, sizeof(*cmd_tbl->sg_list) * n, "sg_list: ");
292 }
293 }
294 #endif
295
296 return(ATA_CMD_SUCCESS);
297}
298
299/******************************************************************************
300 * Fill SATA command FIS with values extracted from an ATA command structure.
301 * The command FIS buffer (fis) is expected to be initialized to 0s. The
302 * structure of the FIS maps to the ATA shadow register block, including
303 * registers which can be written twice to store 16 bits (called 'exp').
304 *
305 * The FIS structure looks like this (using LSB notation):
306 *
307 * +----------------+----------------+----------------+----------------+
308 * 00 | FIS type (27h) | C|R|R|R|PMP | Command | Features |
309 * +----------------+----------------+----------------+----------------+
310 * 04 | LBA 7:0 | LBA 15:8 | LBA 23:16 | R|R|R|D|Head |
311 * +----------------+----------------+----------------+----------------+
312 * 08 | LBA 31:24 | LBA 40:32 | LBA 47:40 | Features exp |
313 * +----------------+----------------+----------------+----------------+
314 * 12 | Count 7:0 | Count 15:8 | Reserved | Control |
315 * +----------------+----------------+----------------+----------------+
316 * 16 | Reserved | Reserved | Reserved | Reserved |
317 * +----------------+----------------+----------------+----------------+
318 */
319void ata_cmd_to_fis(u8 *fis, ATA_CMD *ata_cmd, int d)
320{
321 fis[0] = 0x27; /* register - host to device FIS */
322 fis[1] = (u8) (d & 0xf); /* port multiplier number */
323 fis[1] |= 0x80; /* bit 7 indicates Command FIS */
324 fis[2] = (u8) ata_cmd->cmd;
325 fis[3] = (u8) ata_cmd->features;
326
327 fis[4] = (u8) ata_cmd->lba_l;
328 fis[5] = (u8) (ata_cmd->lba_l >> 8);
329 fis[6] = (u8) (ata_cmd->lba_l >> 16);
330 fis[7] = (u8) ata_cmd->device;
331
332 fis[8] = (u8) (ata_cmd->lba_l >> 24);
333 fis[9] = (u8) ata_cmd->lba_h;
334 fis[10] = (u8) (ata_cmd->lba_h >> 8);
335 fis[11] = (u8) (ata_cmd->features >> 8);
336
337 fis[12] = (u8) ata_cmd->count;
338 fis[13] = (u8) (ata_cmd->count >> 8);
339}
340
341/******************************************************************************
342 * Get max S/G count which will fit into our HW S/G buffers. This function is
343 * called when the S/G list is too long and we need to split the IORB into
344 * multiple commands. It returns both the number of sectors and S/G list
345 * elements that we can handle in a single command.
346 *
347 * The parameter 'sg_indx' indicates the current start index in the S/G list
348 * (0 if this is the first command iteration).
349 *
350 * The parameter 'sg_max' is the return value of v_ata_cmd() and indicates
351 * how many S/G elements were successfully mapped. Whatever we return needs to
352 * be less or equal to this value.
353 *
354 * Returning 0 in *sg_cnt indicates an error.
355 *
356 * NOTE: OS/2 makes sure S/G lists are set up such that entries at HW limits
357 * will never cross sector boundaries. This means that splitting S/G
358 * lists into multiple commands can be done without editing S/G list
359 * elements. Since AHCI only allows 22 bits for each S/G element, the
360 * hardware limits are reported as AHCI_MAX_SG / 2 but will vary based
361 * on the actual length of S/G elements. This function looks for the
362 * maximum number of S/G elements that can be mapped on sector
363 * boundaries which will still fit into our HW S/G list.
364 */
365void ata_max_sg_cnt(IORB_EXECUTEIO *io, USHORT sg_indx, USHORT sg_max,
366 USHORT *sg_cnt, USHORT *sector_cnt)
367{
368 ULONG max_sector_cnt = 0;
369 USHORT max_sg_cnt = 0;
370 ULONG offset = 0;
371 USHORT i;
372 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(io->f16SGList);
373
374 for (i = sg_indx; i < io->cSGList; i++)
375 {
376 if (i - sg_indx >= sg_max)
377 {
378 /* we're beyond the number of S/G elements we can map */
379 break;
380 }
381
382 offset += pSGList[i].XferBufLen;
383 if (offset % io->BlockSize == 0)
384 {
385 /* this S/G element ends on a sector boundary */
386 max_sector_cnt = offset / io->BlockSize;
387 max_sg_cnt = i + 1;
388 }
389 }
390
391 /* return the best match we found (0 indicating failure) */
392 *sector_cnt = max_sector_cnt;
393 *sg_cnt = max_sg_cnt;
394}
395
396
397/******************************************************************************
398 * Get device or media geometry. Device and media geometry are expected to be
399 * the same for non-removable devices, which will always be the case for the
400 * ATA devices we're dealing with (hard disks). ATAPI is a different story
401 * and handled by atapi_get_geometry().
402 */
403int ata_get_geometry(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
404{
405 ADD_WORKSPACE *aws = add_workspace(pIorb);
406 int rc;
407
408 /* allocate buffer for ATA identify information */
409 if ((aws->buf = MemAlloc(ATA_ID_WORDS * sizeof(u16))) == NULL)
410 {
411 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE);
412 return(-1);
413 }
414
415 /* request ATA identify information */
416 aws->ppfunc = ata_get_geometry_pp;
417 rc = ata_cmd(ad_infos + iorb_unit_adapter(pIorb),
418 iorb_unit_port(pIorb),
419 iorb_unit_device(pIorb),
420 slot,
421 ATA_CMD_ID_ATA,
422 AP_VADDR, (void *) aws->buf, ATA_ID_WORDS * sizeof(u16),
423 AP_END);
424
425 if (rc != 0)
426 {
427 iorb_seterr(pIorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
428 }
429
430 return(rc);
431}
432
433int check_lvm(IORBH *pIorb, ULONG sector)
434{
435 DLA_Table_Sector *pDLA = (DLA_Table_Sector*)add_workspace(pIorb)->buf;
436 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
437 GEOMETRY64 *geometry = (GEOMETRY64*)((IORB_GEOMETRY*)pIorb)->f16Geometry;
438 int p = iorb_unit_port(pIorb);
439 int rc;
440
441 rc = ahci_exec_polled_cmd(ai, p, 0, 500, ATA_CMD_READ,
442 AP_SECTOR_28, sector-1,
443 AP_COUNT, 1,
444 AP_VADDR, (void *)pDLA, 512,
445 AP_DEVICE, 0x40,
446 AP_END);
447 if (rc) return 0;
448
449 DHEXDUMP(5,pDLA, sizeof(DLA_Table_Sector), "DLA sector %d:\n", sector-1);
450
451 if ((pDLA->DLA_Signature1 == DLA_TABLE_SIGNATURE1) && (pDLA->DLA_Signature2 == DLA_TABLE_SIGNATURE2))
452 {
453 DPRINTF(3,__func__": DLA found at sector %d\n", sector-1);
454 geometry->TotalCylinders = pDLA->Cylinders;
455 geometry->NumHeads = pDLA->Heads_Per_Cylinder;
456 geometry->SectorsPerTrack = pDLA->Sectors_Per_Track;
457 if (add_workspace(pIorb)->fIs64bit)
458 geometry->ullTotalSectors = pDLA->Cylinders * pDLA->Heads_Per_Cylinder * pDLA->Sectors_Per_Track;
459 else
460 geometry->TotalSectors = pDLA->Cylinders * pDLA->Heads_Per_Cylinder * pDLA->Sectors_Per_Track;
461 return 1;
462 }
463
464 return 0;
465}
466
467/******************************************************************************
468 * Try to read LVM information from the disk. If found, use the LVM geometry.
469 * This function will only work at init time. A better strategy would be to
470 * calculate the geometry during ahci_scan_ports and save it away and then just
471 * return the saved values when ata_get_geometry() is called.
472 */
473int is_lvm_geometry(IORBH *pIorb)
474{
475 GEOMETRY *geometry = ((IORB_GEOMETRY*)pIorb)->f16Geometry;
476 ULONG sector;
477
478 if (init_complete) return 0; /* We cannot use ahci_exec_polled_cmd() after init_complete */
479
480 #ifdef DEBUG
481 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
482 int p = iorb_unit_port(pIorb);
483 int d = iorb_unit_device(pIorb);
484 DPRINTF(3,__func__" (%d.%d.%d)\n", ad_no(ai), p, d);
485 #endif
486
487 /* First check the sector reported by the hardware */
488 if (check_lvm(pIorb, geometry->SectorsPerTrack)) return 1;
489
490 for (sector = 255; sector >= 63; sector >>= 1)
491 {
492 if (sector == geometry->SectorsPerTrack) continue;
493 if (check_lvm(pIorb, sector)) return 1;
494 }
495
496 return 0;
497}
498
499/******************************************************************************
500 * Post processing function for ata_get_geometry(): convert the ATA identify
501 * information to OS/2 IOCC_GEOMETRY information.
502 */
503void ata_get_geometry_pp(IORBH FAR16DATA *vIorb, IORBH *pIorb)
504{
505 GEOMETRY64 *geometry = (GEOMETRY64*)((IORB_GEOMETRY*)pIorb)->f16Geometry;
506 USHORT geometry_len = ((IORB_GEOMETRY *)pIorb)->GeometryLen;
507 ULONGLONG ullTotalSectors;
508 u16 *id_buf = add_workspace(pIorb)->buf;
509 int a = iorb_unit_adapter(pIorb);
510 int p = iorb_unit_port(pIorb);
511 char *Method;
512
513 /* Fill-in geometry information; the ATA-8 spec declares the geometry
514 * fields in the ATA ID buffer as obsolete but it's still the best
515 * guess in most cases. If the information stored in the geometry
516 * fields is apparently incorrect, we'll use the algorithm typically
517 * used by SCSI adapters and modern PC BIOS versions:
518 *
519 * - 512 bytes per sector
520 * - 255 heads
521 * - 63 sectors per track (or 56 with the parameter "/4")
522 * - x cylinders (calculated)
523 *
524 * Please note that os2ahci currently does not natively support ATA sectors
525 * larger than 512 bytes, therefore relies on the translation logic built
526 * into the corresponding ATA disks. In order to prevent file systems that
527 * use block sizes larger than 512 bytes (FAT, JFS, ...) from ending up on
528 * incorrectly aligned physical sector accesses, hence using more physical
529 * I/Os than necessary, the command line parameter "/4" can be used to force
530 * a track size of 56 sectors. This way, partitions will start on 4K
531 * boundaries.
532 *
533 * Another limitation is that OS/2 has a 32-bit variable for the total number
534 * of sectors, limiting the maximum capacity to roughly 2TB. This is another
535 * issue that needs to be addressed sooner or later; large sectors could
536 * raise this limit to something like 8TB but this is not really much of a
537 * difference. Maybe there's something in later DDKs that allows more than
538 * 32 bits?
539 *
540 * Warning: Do not change the algorithm for calculating disk geometry without
541 * fully understaing the consequences. Side effects of even slight changes
542 * can be unexpected and catastrophic.
543 */
544 memset(geometry, 0, geometry_len);
545 geometry->BytesPerSector = ATA_SECTOR_SIZE;
546
547 /* extract total number of sectors */
548 if (id_buf[ATA_ID_CFS_ENABLE_2] & 0x400)
549 {
550 /* 48-bit LBA supported */
551 if ((ATA_CAPACITY48_H(id_buf) != 0) && !add_workspace(pIorb)->fIs64bit)
552 {
553 /* more than 32 bits for number of sectors */
554 dprintf(0,"warning: limiting disk %d.%d.%d to 2TB\n",
555 iorb_unit_adapter(pIorb), iorb_unit_port(pIorb),
556 iorb_unit_device(pIorb));
557 ullTotalSectors = 0xffffffff;
558 }
559 else
560 {
561 ullTotalSectors = MAKEULL(ATA_CAPACITY48_H(id_buf), ATA_CAPACITY48_L(id_buf));
562 }
563 }
564 else
565 {
566 /* 28-bit LBA */
567 ullTotalSectors = ATA_CAPACITY(id_buf) & 0x0fffffff;
568 }
569
570 Method = "None";
571 /* fabricate the remaining geometry fields */
572 if (track_size[a][p] != 0)
573 {
574 /* A specific track size has been requested for this port; this is
575 * typically done for disks with 4K sectors to make sure partitions
576 * start on 8-sector boundaries (parameter "/4").
577 */
578 geometry->NumHeads = 255;
579 geometry->SectorsPerTrack = track_size[a][p];
580 geometry->TotalCylinders = ullTotalSectors / ((u32)geometry->NumHeads * (u32)geometry->SectorsPerTrack);
581 Method = "Custom";
582 }
583 else if (CUR_HEADS(id_buf) > 0 && CUR_CYLS(id_buf) > 0 && CUR_SECTORS(id_buf) > 0 &&
584 CUR_CAPACITY(id_buf) == (u32) CUR_HEADS(id_buf) * (u32) CUR_CYLS(id_buf) * (u32) CUR_SECTORS(id_buf))
585 {
586 /* BIOS-supplied (aka "current") geometry values look valid */
587 geometry->NumHeads = CUR_HEADS(id_buf);
588 geometry->SectorsPerTrack = CUR_SECTORS(id_buf);
589 geometry->TotalCylinders = CUR_CYLS(id_buf);
590 Method = "BIOS";
591 }
592 else if (ATA_HEADS(id_buf) > 0 && ATA_CYLS(id_buf) > 0 && ATA_SECTORS(id_buf) > 0)
593 {
594 /* ATA-supplied values for geometry look valid */
595 geometry->NumHeads = ATA_HEADS(id_buf);
596 geometry->SectorsPerTrack = ATA_SECTORS(id_buf);
597 geometry->TotalCylinders = ATA_CYLS(id_buf);
598 Method = "ATA";
599 }
600 else
601 {
602 /* use typical SCSI geometry */
603 geometry->NumHeads = 255;
604 geometry->SectorsPerTrack = 63;
605 geometry->TotalCylinders = ullTotalSectors / ((u32)geometry->NumHeads * (u32)geometry->SectorsPerTrack);
606 Method = "SCSI";
607 }
608
609 DPRINTF(2,"Physical geometry: %d cylinders, %d heads, %d sectors per track (%dMB) (%s)\n",
610 geometry->TotalCylinders, geometry->NumHeads, geometry->SectorsPerTrack,
611 (ULONG)(ullTotalSectors / 2048), Method);
612
613 if (is_lvm_geometry(pIorb)) Method = "LVM"; /* Writes TotalSectors/ullTotalSectors */
614 else CalculateLogicalGeometry(geometry, add_workspace(pIorb)->fIs64bit, ullTotalSectors);
615 if (add_workspace(pIorb)->fIs64bit) ullTotalSectors = geometry->ullTotalSectors;
616 else ullTotalSectors = geometry->TotalSectors;
617
618 ad_infos[a].ports[p].devs[0].dev_info.Cylinders = geometry->TotalCylinders;
619 ad_infos[a].ports[p].devs[0].dev_info.HeadsPerCylinder = geometry->NumHeads;
620 ad_infos[a].ports[p].devs[0].dev_info.SectorsPerTrack = geometry->SectorsPerTrack;
621 ad_infos[a].ports[p].devs[0].dev_info.TotalSectors = ullTotalSectors;
622 ad_infos[a].ports[p].devs[0].dev_info.Method = Method;
623
624 //DAZ DPRINTF(2,"Reported geometry: %d cylinders, %d heads, %d sectors per track (%dMB) (%s)\n",
625 DPRINTF(0,"Reported geometry: %d cylinders, %d heads, %d sectors per track (%dMB) (%s)\n",
626 geometry->TotalCylinders, geometry->NumHeads, geometry->SectorsPerTrack,
627 (ULONG)(ullTotalSectors / 2048), Method);
628
629 /* tell interrupt handler that this IORB is complete */
630 add_workspace(pIorb)->complete = 1;
631}
632
633/******************************************************************************
634 * Test whether unit is ready.
635 */
636int ata_unit_ready(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
637{
638 /* This is a NOP for ATA devices (at least right now); returning an error
639 * without setting an error code means ahci_exec_iorb() will not queue any
640 * HW command and the IORB will complete successfully.
641 */
642 ((IORB_UNIT_STATUS *)pIorb)->UnitStatus = US_READY | US_POWER;
643 return(-1);
644}
645
646/******************************************************************************
647 * Fabricate ATA READ command based on the capabilities of the corresponding
648 * device and the paramters set from above (NCQ, etc).
649 */
650static int ata_cmd_read(IORBH *pIorb, AD_INFO *ai, int p, int d, int slot,
651 ULONGLONG ullLba, ULONG count, SCATGATENTRY *sg_list,
652 ULONG sg_cnt)
653{
654 int rc;
655
656 if (ullLba >= (1UL << 28) || count > 256 || add_workspace(pIorb)->is_ncq)
657 {
658 /* need LBA48 for this command */
659 if (!ai->ports[p].devs[d].lba48)
660 {
661 iorb_seterr(pIorb, IOERR_RBA_LIMIT);
662 return(-1);
663 }
664 if (add_workspace(pIorb)->is_ncq)
665 {
666 /* use NCQ read; count goes into feature register, tag into count! */
667 rc = ata_cmd(ai, p, d, slot, ATA_CMD_FPDMA_READ,
668 AP_SECTOR_48, ullLba,
669 AP_FEATURES, count,
670 AP_COUNT, (slot << 3), /* tag == slot */
671 AP_SGLIST, sg_list, sg_cnt,
672 AP_DEVICE, 0x40,
673 AP_END);
674 }
675 else
676 {
677 rc = ata_cmd(ai, p, d, slot, ATA_CMD_READ_EXT,
678 AP_SECTOR_48, ullLba,
679 AP_COUNT, count,
680 AP_SGLIST, sg_list, sg_cnt,
681 AP_DEVICE, 0x40,
682 AP_END);
683 }
684
685 }
686 else
687 {
688 rc = ata_cmd(ai, p, d, slot, ATA_CMD_READ,
689 AP_SECTOR_28, (ULONG)ullLba,
690 AP_COUNT, count & 0xffU,
691 AP_SGLIST, sg_list, sg_cnt,
692 AP_DEVICE, 0x40,
693 AP_END);
694 }
695
696 return(rc);
697}
698
699/******************************************************************************
700 * Read sectors from AHCI device.
701 */
702int ata_read(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
703{
704 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
705 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(io->f16SGList);
706 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
707 ULONGLONG ullLba = io->RBA + io->BlocksXferred;
708 USHORT count = io->BlockCount - io->BlocksXferred;
709 USHORT sg_indx;
710 USHORT sg_cnt;
711 int p = iorb_unit_port(pIorb);
712 int d = iorb_unit_device(pIorb);
713 int rc;
714
715 if (io->BlockCount == 0)
716 {
717 /* NOP; return -1 without error in IORB to indicate success */
718 return(-1);
719 }
720
721 if (add_workspace(pIorb)->unaligned)
722 {
723 /* unaligned S/G addresses present; need to use double buffers */
724 return(ata_read_unaligned(pIorb, slot));
725 }
726
727 if (add_workspace(pIorb)->fIs64bit)
728 {
729 ullLba = ((IORB_EXECUTEIO64*)pIorb)->ullRBA + io->BlocksXferred;
730 }
731
732 /* Kludge: some I/O commands during boot use excessive S/G buffer lengths
733 * which cause NCQ commands to lock up. If there's only one S/G element
734 * and this element is already larger than what we can derive from the sector
735 * count, we'll adjust that element.
736 */
737 if (io->BlocksXferred == 0 && io->cSGList == 1 &&
738 pSGList[0].XferBufLen > (ULONG) io->BlockCount * io->BlockSize)
739 {
740 pSGList[0].XferBufLen = (ULONG) io->BlockCount * io->BlockSize;
741 }
742
743 /* prepare read command while keeping an eye on S/G count limitations */
744 do
745 {
746 sg_indx = SgIndexFromOffset(pSGList, io->cSGList, io->BlocksXferred * io->BlockSize);
747 sg_cnt = io->cSGList - sg_indx;
748 rc = ata_cmd_read(pIorb, ai, p, d, slot, ullLba, count, pSGList + sg_indx, sg_cnt);
749 if (rc > 0)
750 {
751 /* couldn't map all S/G elements */
752 ata_max_sg_cnt(io, sg_indx, rc, &sg_cnt, &count);
753 }
754 } while (rc > 0 && sg_cnt > 0);
755
756 if (rc == 0)
757 {
758 add_workspace(pIorb)->blocks = count;
759 add_workspace(pIorb)->ppfunc = ata_read_pp;
760 }
761 else if (rc > 0)
762 {
763 iorb_seterr(pIorb, IOERR_CMD_SGLIST_BAD);
764 }
765 else if (rc == ATA_CMD_UNALIGNED_ADDR)
766 {
767 /* unaligned S/G addresses detected; need to use double buffers */
768 add_workspace(pIorb)->unaligned = 1;
769 return(ata_read_unaligned(pIorb, slot));
770 }
771 else
772 {
773 iorb_seterr(pIorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
774 }
775
776 return(rc);
777}
778
779/******************************************************************************
780 * Read sectors from AHCI device with unaligned S/G element addresses. AHCI
781 * only allows aligned S/G addresses while OS/2 doesn't have these kind of
782 * restrictions. This doesn't happen very often but when it does, we need to
783 * use a transfer buffer and copy the data manually.
784 */
785int ata_read_unaligned(IORBH *pIorb, int slot)
786{
787 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
788 ADD_WORKSPACE *aws = add_workspace(pIorb);
789 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
790 ULONGLONG ullLba = io->RBA + io->BlocksXferred;
791 SCATGATENTRY sg_single;
792 int p = iorb_unit_port(pIorb);
793 int d = iorb_unit_device(pIorb);
794 int rc;
795
796 if (add_workspace(pIorb)->fIs64bit)
797 {
798 ullLba = ((IORB_EXECUTEIO64*)pIorb)->ullRBA + io->BlocksXferred;
799 }
800
801 DPRINTF(7,"ata_read_unaligned(%d.%d.%d, %lld)\n", ad_no(ai), p, d, ullLba);
802 ai->ports[p].unaligned_read_count++;
803
804 /* allocate transfer buffer */
805 if ((aws->buf = MemAlloc(io->BlockSize)) == NULL)
806 {
807 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE);
808 return(-1);
809 }
810
811 /* prepare read command using transfer buffer */
812 sg_single.ppXferBuf = MemPhysAdr(aws->buf);
813 sg_single.XferBufLen = io->BlockSize;
814 rc = ata_cmd_read(pIorb, ai, p, d, slot, ullLba, 1, &sg_single, 1);
815
816 if (rc == 0) {
817 add_workspace(pIorb)->blocks = 1;
818 add_workspace(pIorb)->ppfunc = ata_read_pp;
819
820 } else if (rc > 0) {
821 iorb_seterr(pIorb, IOERR_CMD_SGLIST_BAD);
822
823 } else {
824 iorb_seterr(pIorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
825 }
826
827 return(rc);
828}
829
830/******************************************************************************
831 * Post processing function for ata_read(); this function updates the
832 * BlocksXferred counter in the IORB and, if not all blocks have been
833 * transferred, requeues the IORB to process the remaining sectors. It also
834 * takes care of copying data from the transfer buffer for unaligned reads.
835 */
836void ata_read_pp(IORBH FAR16DATA *vIorb, IORBH *pIorb)
837{
838 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
839 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(io->f16SGList);
840 ADD_WORKSPACE *aws = add_workspace(pIorb);
841
842 if (aws->unaligned)
843 {
844 /* copy transfer buffer to corresponding physical address in S/G list */
845 CopySgBuf(pSGList, io->cSGList, (ULONG)io->BlocksXferred * (ULONG)io->BlockSize,
846 aws->buf, io->BlockSize, BUF_TO_SGL);
847 }
848
849 io->BlocksXferred += add_workspace(pIorb)->blocks;
850 DPRINTF(7,__func__": blocks transferred = %d\n", io->BlocksXferred);
851
852 if (io->BlocksXferred >= io->BlockCount)
853 {
854 /* we're done; tell IRQ handler the IORB is complete */
855 add_workspace(pIorb)->complete = 1;
856 }
857 else
858 {
859 /* requeue this IORB for next iteration */
860 iorb_requeue(pIorb);
861 }
862}
863
864/******************************************************************************
865 * Verify readability of sectors on ATA device.
866 */
867int ata_verify(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
868{
869 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
870 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
871 int p = iorb_unit_port(pIorb);
872 int d = iorb_unit_device(pIorb);
873 ULONGLONG ullLba = io->RBA;
874 int rc;
875
876 if (io->BlockCount == 0)
877 {
878 /* NOP; return -1 without error in IORB to indicate success */
879 return(-1);
880 }
881
882 if (add_workspace(pIorb)->fIs64bit)
883 {
884 ullLba = ((IORB_EXECUTEIO64*)pIorb)->ullRBA;
885 }
886
887 /* prepare verify command */
888 if (ullLba >= (1UL << 28) || io->BlockCount > 256)
889 {
890 /* need LBA48 for this command */
891 if (!ai->ports[p].devs[d].lba48) {
892 iorb_seterr(pIorb, IOERR_RBA_LIMIT);
893 return(-1);
894 }
895 rc = ata_cmd(ai, p, d, slot, ATA_CMD_VERIFY_EXT,
896 AP_SECTOR_48, ullLba,
897 AP_COUNT, io->BlockCount,
898 AP_DEVICE, 0x40,
899 AP_END);
900 } else {
901 rc = ata_cmd(ai, p, d, slot, ATA_CMD_VERIFY,
902 AP_SECTOR_28, (ULONG)ullLba,
903 AP_COUNT, io->BlockCount & 0xffU,
904 AP_DEVICE, 0x40,
905 AP_END);
906 }
907
908 return(rc);
909}
910
911/******************************************************************************
912 * Fabricate ATA WRITE command based on the capabilities of the corresponding
913 * device and the paramters set from above (NCQ, etc)
914 */
915static int ata_cmd_write(IORBH *pIorb, AD_INFO *ai, int p, int d, int slot,
916 ULONGLONG ullLba, ULONG count, SCATGATENTRY *sg_list,
917 ULONG sg_cnt, int write_through)
918{
919 int rc;
920
921 if (ullLba >= (1UL << 28) || count > 256 || add_workspace(pIorb)->is_ncq)
922 {
923 /* need LBA48 for this command */
924 if (!ai->ports[p].devs[d].lba48)
925 {
926 iorb_seterr(pIorb, IOERR_RBA_LIMIT);
927 return(-1);
928 }
929 if (add_workspace(pIorb)->is_ncq)
930 {
931 /* use NCQ write; count goes into feature register, tag into count! */
932 rc = ata_cmd(ai, p, d, slot, ATA_CMD_FPDMA_WRITE,
933 AP_SECTOR_48, ullLba,
934 AP_FEATURES, count,
935 /* tag = slot */
936 AP_COUNT, (slot << 3),
937 AP_SGLIST, sg_list, sg_cnt,
938 AP_DEVICE, 0x40,
939 /* force unit access */
940 AP_DEVICE, (write_through && !force_write_cache) ? 0x80 : 0,
941 AP_WRITE, 1,
942 AP_END);
943 }
944 else
945 {
946 rc = ata_cmd(ai, p, d, slot, ATA_CMD_WRITE_EXT,
947 AP_SECTOR_48, ullLba,
948 AP_COUNT, count,
949 AP_SGLIST, sg_list, sg_cnt,
950 AP_DEVICE, 0x40,
951 AP_WRITE, 1,
952 AP_END);
953 }
954 }
955 else
956 {
957 rc = ata_cmd(ai, p, d, slot, ATA_CMD_WRITE,
958 AP_SECTOR_28, (ULONG)ullLba,
959 AP_COUNT, count & 0xffU,
960 AP_SGLIST, sg_list, sg_cnt,
961 AP_DEVICE, 0x40,
962 AP_WRITE, 1,
963 AP_END);
964 }
965
966 return(rc);
967}
968
969/******************************************************************************
970 * Write sectors to AHCI device.
971 */
972int ata_write(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
973{
974 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
975 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(io->f16SGList);
976 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
977 ULONGLONG ullLba = io->RBA + io->BlocksXferred;
978 USHORT count = io->BlockCount - io->BlocksXferred;
979 USHORT sg_indx;
980 USHORT sg_cnt;
981 int p = iorb_unit_port(pIorb);
982 int d = iorb_unit_device(pIorb);
983 int rc;
984
985 if (io->BlockCount == 0)
986 {
987 /* NOP; return -1 without error in IORB to indicate success */
988 return(-1);
989 }
990
991 if (add_workspace(pIorb)->unaligned)
992 {
993 /* unaligned S/G addresses present; need to use double buffers */
994 return(ata_write_unaligned(pIorb, slot));
995 }
996
997 if (add_workspace(pIorb)->fIs64bit)
998 {
999 ullLba = ((IORB_EXECUTEIO64*)pIorb)->ullRBA + io->BlocksXferred;
1000 }
1001
1002 /* prepare write command while keeping an eye on S/G count limitations */
1003 do {
1004 sg_indx = SgIndexFromOffset(pSGList, io->cSGList, io->BlocksXferred * io->BlockSize);
1005 sg_cnt = io->cSGList - sg_indx;
1006 if ((rc = ata_cmd_write(pIorb, ai, p, d, slot, ullLba, count,
1007 pSGList + sg_indx, sg_cnt,
1008 io->Flags & XIO_DISABLE_HW_WRITE_CACHE)) > 0)
1009 {
1010 /* couldn't map all S/G elements */
1011 ata_max_sg_cnt(io, sg_indx, (USHORT)rc, &sg_cnt, &count);
1012 }
1013 } while (rc > 0 && sg_cnt > 0);
1014
1015 if (rc == 0)
1016 {
1017 add_workspace(pIorb)->blocks = count;
1018 add_workspace(pIorb)->ppfunc = ata_write_pp;
1019 }
1020 else if (rc > 0)
1021 {
1022 iorb_seterr(pIorb, IOERR_CMD_SGLIST_BAD);
1023 }
1024 else if (rc == ATA_CMD_UNALIGNED_ADDR)
1025 {
1026 /* unaligned S/G addresses detected; need to use double buffers */
1027 add_workspace(pIorb)->unaligned = 1;
1028 return(ata_write_unaligned(pIorb, slot));
1029 }
1030 else
1031 {
1032 iorb_seterr(pIorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
1033 }
1034
1035 return(rc);
1036}
1037
1038/******************************************************************************
1039 * Write sectors from AHCI device with unaligned S/G element addresses. AHCI
1040 * only allows aligned S/G addresses while OS/2 doesn't have these kind of
1041 * restrictions. This doesn't happen very often but when it does, we need to
1042 * use a transfer buffer and copy the data manually.
1043 */
1044int ata_write_unaligned(IORBH *pIorb, int slot)
1045{
1046 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
1047 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(io->f16SGList);
1048 ADD_WORKSPACE *aws = add_workspace(pIorb);
1049 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
1050 ULONGLONG ullLba = io->RBA + io->BlocksXferred;
1051 SCATGATENTRY sg_single;
1052 int p = iorb_unit_port(pIorb);
1053 int d = iorb_unit_device(pIorb);
1054 int rc;
1055
1056 if (add_workspace(pIorb)->fIs64bit)
1057 {
1058 ullLba = ((IORB_EXECUTEIO64*)pIorb)->ullRBA + io->BlocksXferred;
1059 }
1060
1061 DPRINTF(7,"ata_write_unaligned(%d.%d.%d, %lld)\n", ad_no(ai), p, d, ullLba);
1062
1063 /* allocate transfer buffer */
1064 if ((aws->buf = MemAlloc(io->BlockSize)) == NULL)
1065 {
1066 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE);
1067 return(-1);
1068 }
1069
1070 /* copy next sector from S/G list to transfer buffer */
1071 CopySgBuf(pSGList, io->cSGList, (ULONG)io->BlocksXferred * (ULONG)io->BlockSize,
1072 aws->buf, io->BlockSize, SGL_TO_BUF);
1073
1074 /* prepare write command using transfer buffer */
1075 sg_single.ppXferBuf = MemPhysAdr(aws->buf);
1076 sg_single.XferBufLen = io->BlockSize;
1077 rc = ata_cmd_write(pIorb, ai, p, d, slot, ullLba, 1, &sg_single, 1,
1078 io->Flags & XIO_DISABLE_HW_WRITE_CACHE);
1079
1080 if (rc == 0)
1081 {
1082 add_workspace(pIorb)->blocks = 1;
1083 add_workspace(pIorb)->ppfunc = ata_write_pp;
1084 }
1085 else if (rc > 0)
1086 {
1087 iorb_seterr(pIorb, IOERR_CMD_SGLIST_BAD);
1088 }
1089 else
1090 {
1091 iorb_seterr(pIorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
1092 }
1093
1094 return(rc);
1095}
1096
1097
1098/******************************************************************************
1099 * Post processing function for ata_write(); this function updates the
1100 * BlocksXferred counter in the IORB and, if not all blocks have been
1101 * transferred, requeues the IORB to process the remaining sectors.
1102 */
1103void ata_write_pp(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1104{
1105 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
1106
1107 io->BlocksXferred += add_workspace(pIorb)->blocks;
1108 DPRINTF(7,"ata_write_pp(): blocks transferred = %d\n", io->BlocksXferred);
1109
1110 if (io->BlocksXferred >= io->BlockCount)
1111 {
1112 /* we're done; tell IRQ handler the IORB is complete */
1113 add_workspace(pIorb)->complete = 1;
1114 }
1115 else
1116 {
1117 /* requeue this IORB for next iteration */
1118 iorb_requeue(pIorb);
1119 }
1120}
1121
1122/******************************************************************************
1123 * Execute ATA command.
1124 */
1125int ata_execute_ata(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
1126{
1127 IORB_ADAPTER_PASSTHRU *apt = (IORB_ADAPTER_PASSTHRU *)pIorb;
1128 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(apt->f16SGList);
1129 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
1130 int p = iorb_unit_port(pIorb);
1131 int d = iorb_unit_device(pIorb);
1132 int rc;
1133
1134 if (apt->ControllerCmdLen != sizeof(ATA_CMD))
1135 {
1136 iorb_seterr(pIorb, IOERR_CMD_SYNTAX);
1137 return(-1);
1138 }
1139
1140 rc = ata_cmd(ai, p, d, slot, 0,
1141 AP_SGLIST, pSGList, apt->cSGList,
1142 AP_ATA_CMD, Far16ToFlat(apt->f16ControllerCmd),
1143 AP_WRITE, !(apt->Flags & PT_DIRECTION_IN),
1144 AP_END);
1145
1146 if (rc == 0)
1147 {
1148 add_workspace(pIorb)->ppfunc = ata_execute_ata_pp;
1149 }
1150
1151 return(rc);
1152}
1153
1154/******************************************************************************
1155 * Post processing function for ata_execute_ata(); the main purpose of this
1156 * function is to copy the received D2H FIS (i.e. the device registers after
1157 * command completion) back to the ATA command structure.
1158 *
1159 * See ata_cmd_to_fis() for an explanation of the mapping.
1160 */
1161void ata_execute_ata_pp(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1162{
1163 AHCI_PORT_DMA *dma_base;
1164 ATA_CMD *cmd;
1165 AD_INFO *ai;
1166 u8 *fis;
1167 int p;
1168
1169 /* get address of D2H FIS */
1170 ai = ad_infos + iorb_unit_adapter(pIorb);
1171 p = iorb_unit_port(pIorb);
1172 dma_base = port_dma_base(ai, p);
1173 fis = dma_base->rx_fis + 0x40;
1174
1175 if (fis[0] != 0x34)
1176 {
1177 /* this is not a D2H FIS - give up silently */
1178 DPRINTF(3,"ata_execute_ata_pp(): D2H FIS type incorrect: %d\n", fis[0]);
1179 add_workspace(pIorb)->complete = 1;
1180 return;
1181 }
1182
1183 /* map D2H FIS to the original ATA controller command structure */
1184 cmd = (ATA_CMD *)Far16ToFlat(((IORB_ADAPTER_PASSTHRU*)pIorb)->f16ControllerCmd);
1185
1186 cmd->cmd = fis[2];
1187 cmd->device = fis[7];
1188 cmd->features = ((u16) fis[3])
1189 | ((u16) fis[11]);
1190 cmd->lba_l = ((u32) fis[4])
1191 | ((u32) fis[5] << 8)
1192 | ((u32) fis[6] << 16)
1193 | ((u32) fis[8] << 24);
1194 cmd->lba_h = ((u16) fis[9])
1195 | ((u16) fis[10] << 8);
1196 cmd->count = ((u16) fis[12])
1197 | ((u16) fis[13] << 8);
1198
1199 DHEXDUMP(5,cmd, sizeof(*cmd), "ahci_execute_ata_pp(): cmd after completion:\n");
1200
1201 /* signal completion to interrupt handler */
1202 add_workspace(pIorb)->complete = 1;
1203}
1204
1205/******************************************************************************
1206 * Request sense information for a failed command. Since there is no "request
1207 * sense" command for ATA devices, we need to read the current error code from
1208 * the AHCI task file register and fabricate the sense information.
1209 *
1210 * NOTES:
1211 *
1212 * - This function must be called right after an ATA command has failed and
1213 * before any other commands are queued on the corresponding port. This
1214 * function is typically called in the port restart context hook which is
1215 * triggered by an AHCI error interrupt.
1216 *
1217 * - The ATA error bits are a complete mess. We'll try and catch the most
1218 * interesting error codes (such as medium errors) and report everything
1219 * else with a generic error code.
1220 */
1221int ata_req_sense(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
1222{
1223 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
1224 u8 *port_mmio = port_base(ai, iorb_unit_port(pIorb));
1225 u32 tf_data = readl(port_mmio + PORT_TFDATA);
1226 u8 err = (tf_data >> 8);
1227 u8 sts = (tf_data);
1228
1229 if (sts & ATA_ERR)
1230 {
1231 if (sts & ATA_DF)
1232 {
1233 /* there is a device-specific error condition */
1234 if (err & ATA_ICRC)
1235 {
1236 iorb_seterr(pIorb, IOERR_ADAPTER_DEVICEBUSCHECK);
1237 }
1238 else if (err & ATA_UNC)
1239 {
1240 iorb_seterr(pIorb, IOERR_MEDIA);
1241 }
1242 else if (err & ATA_IDNF)
1243 {
1244 iorb_seterr(pIorb, IOERR_RBA_ADDRESSING_ERROR);
1245 }
1246 else
1247 {
1248 iorb_seterr(pIorb, IOERR_DEVICE_NONSPECIFIC);
1249 }
1250
1251 }
1252 else
1253 {
1254 iorb_seterr(pIorb, IOERR_DEVICE_NONSPECIFIC);
1255 }
1256 }
1257 else
1258 {
1259 /* this function only gets called when we received an error interrupt */
1260 iorb_seterr(pIorb, IOERR_DEVICE_NONSPECIFIC);
1261 }
1262
1263 /* Return an error to indicate there's no HW command to be submitted and
1264 * that the IORB can be completed "as is" (the upstream code expects the
1265 * IORB error code, if any, to be set when this happens and this is exactly
1266 * what this function is all about).
1267 */
1268 return(-1);
1269}
1270
1271/******************************************************************************
1272 * Extract vendor and device name from an ATA INDENTIFY buffer. Since strings
1273 * in the indentify buffer are byte-swapped, we need to swap them back.
1274 */
1275char *ata_dev_name(u16 *id_buf)
1276{
1277 static char dev_name[ATA_ID_PROD_LEN + 1];
1278 char *t = dev_name;
1279 char *s = (char *) (id_buf + ATA_ID_PROD);
1280 int i;
1281
1282 dev_name[sizeof(dev_name)-1] = '\0';
1283
1284 for (i = 0; i < ATA_ID_PROD_LEN / 2; i++) {
1285 *(t++) = s[1];
1286 *(t++) = s[0];
1287 s += 2;
1288 }
1289
1290 return(dev_name);
1291}
1292
1293/******************************************************************************
1294 * Halt processing by submitting an internal error. This is a last resort and
1295 * should only be called when the system state is corrupt.
1296 */
1297void panic(char *msg)
1298{
1299 Dev32Help_InternalError(msg, strlen(msg));
1300}
1301
Note: See TracBrowser for help on using the repository browser.