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

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

Add 64/48 bit LBA support.

File size: 46.5 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
433/* Adjust the cylinder count in the physical
434 * geometry to the last full cylinder.
435 */
436int adjust_cylinders(GEOMETRY64 *geometry, ULONG TotalSectors)
437{
438 USHORT SecPerCyl;
439 int rc = FALSE;
440
441 geometry->TotalSectors = TotalSectors;
442 SecPerCyl = geometry->SectorsPerTrack * geometry->NumHeads;
443 if (SecPerCyl > 0)
444 {
445 ULONG TotalCylinders = TotalSectors / SecPerCyl;
446
447 geometry->TotalSectors = TotalCylinders * SecPerCyl;
448 geometry->TotalCylinders = TotalCylinders;
449 if (TotalCylinders >> 16)
450 {
451 geometry->TotalCylinders = 65535;
452 rc = TRUE;
453 }
454 }
455 return (rc);
456}
457
458/* Calculate the logical geometry based on the input physcial geometry
459 * using the LBA Assist Translation algorithm.
460 */
461#define BIOS_MAX_CYLINDERS 1024l
462#define BIOS_MAX_NUMHEADS 255
463#define BIOS_MAX_SECTORSPERTRACK 63
464void log_geom_calculate_LBA_assist(GEOMETRY64 *geometry, ULONG TotalSectors)
465{
466 UCHAR numSpT = BIOS_MAX_SECTORSPERTRACK;
467 UCHAR numHeads = BIOS_MAX_NUMHEADS;
468 ULONG Cylinders;
469
470 if (TotalSectors <= (BIOS_MAX_CYLINDERS * 128 * BIOS_MAX_SECTORSPERTRACK))
471 {
472 USHORT temp = (TotalSectors - 1) / (BIOS_MAX_CYLINDERS * BIOS_MAX_SECTORSPERTRACK);
473
474 if (temp < 16) numHeads = 16;
475 else if (temp < 32) numHeads = 32;
476 else if (temp < 64) numHeads = 64;
477 else numHeads = 128;
478 }
479
480 do
481 {
482 Cylinders = TotalSectors / (USHORT)(numHeads * numSpT);
483 if (Cylinders >> 16)
484 {
485 if (numSpT < 128)
486 numSpT = (numSpT << 1) | 1;
487 else
488 Cylinders = 65535; // overflow !
489 }
490 } while (Cylinders >> 16);
491
492 geometry->TotalCylinders = Cylinders;
493 geometry->NumHeads = numHeads;
494 geometry->SectorsPerTrack = numSpT;
495}
496
497int check_lvm(IORBH *pIorb, ULONG sector)
498{
499 DLA_Table_Sector *pDLA = (DLA_Table_Sector*)add_workspace(pIorb)->buf;
500 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
501 GEOMETRY64 *geometry = (GEOMETRY64*)((IORB_GEOMETRY*)pIorb)->f16Geometry;
502 int p = iorb_unit_port(pIorb);
503 int rc;
504
505 rc = ahci_exec_polled_cmd(ai, p, 0, 500, ATA_CMD_READ,
506 AP_SECTOR_28, sector-1,
507 AP_COUNT, 1,
508 AP_VADDR, (void *)pDLA, 512,
509 AP_DEVICE, 0x40,
510 AP_END);
511 if (rc) return 0;
512
513 DHEXDUMP(5,pDLA, sizeof(DLA_Table_Sector), "DLA sector %d:\n", sector-1);
514
515 if ((pDLA->DLA_Signature1 == DLA_TABLE_SIGNATURE1) && (pDLA->DLA_Signature2 == DLA_TABLE_SIGNATURE2))
516 {
517 DPRINTF(3,__func__": DLA found at sector %d\n", sector-1);
518 geometry->TotalCylinders = pDLA->Cylinders;
519 geometry->NumHeads = pDLA->Heads_Per_Cylinder;
520 geometry->SectorsPerTrack = pDLA->Sectors_Per_Track;
521 if (add_workspace(pIorb)->fIs64bit)
522 geometry->ullTotalSectors = pDLA->Cylinders * pDLA->Heads_Per_Cylinder * pDLA->Sectors_Per_Track;
523 else
524 geometry->TotalSectors = pDLA->Cylinders * pDLA->Heads_Per_Cylinder * pDLA->Sectors_Per_Track;
525 return 1;
526 }
527
528 return 0;
529}
530
531/******************************************************************************
532 * Try to read LVM information from the disk. If found, use the LVM geometry.
533 * This function will only work at init time. A better strategy would be to
534 * calculate the geometry during ahci_scan_ports and save it away and then just
535 * return the saved values when ata_get_geometry() is called.
536 */
537int is_lvm_geometry(IORBH *pIorb)
538{
539 GEOMETRY *geometry = ((IORB_GEOMETRY*)pIorb)->f16Geometry;
540 ULONG sector;
541
542 if (init_complete) return 0; /* We cannot use ahci_exec_polled_cmd() after init_complete */
543
544 #ifdef DEBUG
545 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
546 int p = iorb_unit_port(pIorb);
547 int d = iorb_unit_device(pIorb);
548 DPRINTF(3,__func__" (%d.%d.%d)\n", ad_no(ai), p, d);
549 #endif
550
551 /* First check the sector reported by the hardware */
552 if (check_lvm(pIorb, geometry->SectorsPerTrack)) return 1;
553
554 for (sector = 255; sector >= 63; sector >>= 1)
555 {
556 if (sector == geometry->SectorsPerTrack) continue;
557 if (check_lvm(pIorb, sector)) return 1;
558 }
559
560 return 0;
561}
562
563/******************************************************************************
564 * Post processing function for ata_get_geometry(): convert the ATA identify
565 * information to OS/2 IOCC_GEOMETRY information.
566 */
567void ata_get_geometry_pp(IORBH FAR16DATA *vIorb, IORBH *pIorb)
568{
569 GEOMETRY64 *geometry = (GEOMETRY64*)((IORB_GEOMETRY*)pIorb)->f16Geometry;
570 USHORT geometry_len = ((IORB_GEOMETRY *)pIorb)->GeometryLen;
571 ULONGLONG ullTotalSectors;
572 u16 *id_buf = add_workspace(pIorb)->buf;
573 int a = iorb_unit_adapter(pIorb);
574 int p = iorb_unit_port(pIorb);
575 char *Method;
576
577 /* Fill-in geometry information; the ATA-8 spec declares the geometry
578 * fields in the ATA ID buffer as obsolete but it's still the best
579 * guess in most cases. If the information stored in the geometry
580 * fields is apparently incorrect, we'll use the algorithm typically
581 * used by SCSI adapters and modern PC BIOS versions:
582 *
583 * - 512 bytes per sector
584 * - 255 heads
585 * - 63 sectors per track (or 56 with the parameter "/4")
586 * - x cylinders (calculated)
587 *
588 * Please note that os2ahci currently does not natively support ATA sectors
589 * larger than 512 bytes, therefore relies on the translation logic built
590 * into the corresponding ATA disks. In order to prevent file systems that
591 * use block sizes larger than 512 bytes (FAT, JFS, ...) from ending up on
592 * incorrectly aligned physical sector accesses, hence using more physical
593 * I/Os than necessary, the command line parameter "/4" can be used to force
594 * a track size of 56 sectors. This way, partitions will start on 4K
595 * boundaries.
596 *
597 * Another limitation is that OS/2 has a 32-bit variable for the total number
598 * of sectors, limiting the maximum capacity to roughly 2TB. This is another
599 * issue that needs to be addressed sooner or later; large sectors could
600 * raise this limit to something like 8TB but this is not really much of a
601 * difference. Maybe there's something in later DDKs that allows more than
602 * 32 bits?
603 *
604 * Warning: Do not change the algorithm for calculating disk geometry without
605 * fully understaing the consequences. Side effects of even slight changes
606 * can be unexpected and catastrophic.
607 */
608 memset(geometry, 0, geometry_len);
609 geometry->BytesPerSector = ATA_SECTOR_SIZE;
610
611 /* extract total number of sectors */
612 if (id_buf[ATA_ID_CFS_ENABLE_2] & 0x400)
613 {
614 /* 48-bit LBA supported */
615 if ((ATA_CAPACITY48_H(id_buf) != 0) && !add_workspace(pIorb)->fIs64bit)
616 {
617 /* more than 32 bits for number of sectors */
618 dprintf(0,"warning: limiting disk %d.%d.%d to 2TB\n",
619 iorb_unit_adapter(pIorb), iorb_unit_port(pIorb),
620 iorb_unit_device(pIorb));
621 ullTotalSectors = 0xffffffff;
622 }
623 else
624 {
625 ullTotalSectors = MAKEULL(ATA_CAPACITY48_H(id_buf), ATA_CAPACITY48_L(id_buf));
626 }
627 }
628 else
629 {
630 /* 28-bit LBA */
631 ullTotalSectors = ATA_CAPACITY(id_buf) & 0x0fffffff;
632 }
633
634 Method = "None";
635 /* fabricate the remaining geometry fields */
636 if (track_size[a][p] != 0)
637 {
638 /* A specific track size has been requested for this port; this is
639 * typically done for disks with 4K sectors to make sure partitions
640 * start on 8-sector boundaries (parameter "/4").
641 */
642 geometry->NumHeads = 255;
643 geometry->SectorsPerTrack = track_size[a][p];
644 geometry->TotalCylinders = ullTotalSectors / ((u32)geometry->NumHeads * (u32)geometry->SectorsPerTrack);
645 Method = "Custom";
646 }
647 else if (CUR_HEADS(id_buf) > 0 && CUR_CYLS(id_buf) > 0 && CUR_SECTORS(id_buf) > 0 &&
648 CUR_CAPACITY(id_buf) == (u32) CUR_HEADS(id_buf) * (u32) CUR_CYLS(id_buf) * (u32) CUR_SECTORS(id_buf))
649 {
650 /* BIOS-supplied (aka "current") geometry values look valid */
651 geometry->NumHeads = CUR_HEADS(id_buf);
652 geometry->SectorsPerTrack = CUR_SECTORS(id_buf);
653 geometry->TotalCylinders = CUR_CYLS(id_buf);
654 Method = "BIOS";
655 }
656 else if (ATA_HEADS(id_buf) > 0 && ATA_CYLS(id_buf) > 0 && ATA_SECTORS(id_buf) > 0)
657 {
658 /* ATA-supplied values for geometry look valid */
659 geometry->NumHeads = ATA_HEADS(id_buf);
660 geometry->SectorsPerTrack = ATA_SECTORS(id_buf);
661 geometry->TotalCylinders = ATA_CYLS(id_buf);
662 Method = "ATA";
663 }
664 else
665 {
666 /* use typical SCSI geometry */
667 geometry->NumHeads = 255;
668 geometry->SectorsPerTrack = 63;
669 geometry->TotalCylinders = ullTotalSectors / ((u32)geometry->NumHeads * (u32)geometry->SectorsPerTrack);
670 Method = "SCSI";
671 }
672
673 DPRINTF(2,"Physical geometry: %d cylinders, %d heads, %d sectors per track (%dMB) (%s)\n",
674 geometry->TotalCylinders, geometry->NumHeads, geometry->SectorsPerTrack,
675 (ULONG)(ullTotalSectors / 2048), Method);
676
677 if (is_lvm_geometry(pIorb)) Method = "LVM"; /* Writes TotalSectors/ullTotalSectors */
678 else
679 {
680 if (add_workspace(pIorb)->fIs64bit)
681 {
682 geometry->NumHeads = 255;
683 geometry->SectorsPerTrack = 255;
684 geometry->TotalCylinders = ullTotalSectors / (255*255);
685 geometry->ullTotalSectors = ullTotalSectors;
686 }
687 else
688 {
689 /* Fixup the geometry in case the geometry reported by the BIOS is bad */
690 if (adjust_cylinders(geometry, ullTotalSectors)) /* Writes TotalSectors */
691 { // cylinder overflow
692 log_geom_calculate_LBA_assist(geometry, ullTotalSectors); /* Does not write TotalSectors */
693 ullTotalSectors = (USHORT)(geometry->NumHeads * geometry->SectorsPerTrack) * (ULONG)geometry->TotalCylinders;
694 }
695 adjust_cylinders(geometry, ullTotalSectors); /* Writes TotalSectors */
696 }
697 }
698 if (add_workspace(pIorb)->fIs64bit) ullTotalSectors = geometry->ullTotalSectors;
699 else ullTotalSectors = geometry->TotalSectors;
700
701 ad_infos[a].ports[p].devs[0].dev_info.Cylinders = geometry->TotalCylinders;
702 ad_infos[a].ports[p].devs[0].dev_info.HeadsPerCylinder = geometry->NumHeads;
703 ad_infos[a].ports[p].devs[0].dev_info.SectorsPerTrack = geometry->SectorsPerTrack;
704 ad_infos[a].ports[p].devs[0].dev_info.TotalSectors = ullTotalSectors;
705 ad_infos[a].ports[p].devs[0].dev_info.Method = Method;
706
707 //DAZ DPRINTF(2,"Reported geometry: %d cylinders, %d heads, %d sectors per track (%dMB) (%s)\n",
708 DPRINTF(0,"Reported geometry: %d cylinders, %d heads, %d sectors per track (%dMB) (%s)\n",
709 geometry->TotalCylinders, geometry->NumHeads, geometry->SectorsPerTrack,
710 (ULONG)(ullTotalSectors / 2048), Method);
711
712 /* tell interrupt handler that this IORB is complete */
713 add_workspace(pIorb)->complete = 1;
714}
715
716/******************************************************************************
717 * Test whether unit is ready.
718 */
719int ata_unit_ready(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
720{
721 /* This is a NOP for ATA devices (at least right now); returning an error
722 * without setting an error code means ahci_exec_iorb() will not queue any
723 * HW command and the IORB will complete successfully.
724 */
725 ((IORB_UNIT_STATUS *)pIorb)->UnitStatus = US_READY | US_POWER;
726 return(-1);
727}
728
729/******************************************************************************
730 * Fabricate ATA READ command based on the capabilities of the corresponding
731 * device and the paramters set from above (NCQ, etc).
732 */
733static int ata_cmd_read(IORBH *pIorb, AD_INFO *ai, int p, int d, int slot,
734 ULONGLONG ullLba, ULONG count, SCATGATENTRY *sg_list,
735 ULONG sg_cnt)
736{
737 int rc;
738
739 if (ullLba >= (1UL << 28) || count > 256 || add_workspace(pIorb)->is_ncq)
740 {
741 /* need LBA48 for this command */
742 if (!ai->ports[p].devs[d].lba48)
743 {
744 iorb_seterr(pIorb, IOERR_RBA_LIMIT);
745 return(-1);
746 }
747 if (add_workspace(pIorb)->is_ncq)
748 {
749 /* use NCQ read; count goes into feature register, tag into count! */
750 rc = ata_cmd(ai, p, d, slot, ATA_CMD_FPDMA_READ,
751 AP_SECTOR_48, ullLba,
752 AP_FEATURES, count,
753 AP_COUNT, (slot << 3), /* tag == slot */
754 AP_SGLIST, sg_list, sg_cnt,
755 AP_DEVICE, 0x40,
756 AP_END);
757 }
758 else
759 {
760 rc = ata_cmd(ai, p, d, slot, ATA_CMD_READ_EXT,
761 AP_SECTOR_48, ullLba,
762 AP_COUNT, count,
763 AP_SGLIST, sg_list, sg_cnt,
764 AP_DEVICE, 0x40,
765 AP_END);
766 }
767
768 }
769 else
770 {
771 rc = ata_cmd(ai, p, d, slot, ATA_CMD_READ,
772 AP_SECTOR_28, (ULONG)ullLba,
773 AP_COUNT, count & 0xffU,
774 AP_SGLIST, sg_list, sg_cnt,
775 AP_DEVICE, 0x40,
776 AP_END);
777 }
778
779 return(rc);
780}
781
782/******************************************************************************
783 * Read sectors from AHCI device.
784 */
785int ata_read(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
786{
787 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
788 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(io->f16SGList);
789 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
790 ULONGLONG ullLba = io->RBA + io->BlocksXferred;
791 USHORT count = io->BlockCount - io->BlocksXferred;
792 USHORT sg_indx;
793 USHORT sg_cnt;
794 int p = iorb_unit_port(pIorb);
795 int d = iorb_unit_device(pIorb);
796 int rc;
797
798 if (io->BlockCount == 0)
799 {
800 /* NOP; return -1 without error in IORB to indicate success */
801 return(-1);
802 }
803
804 if (add_workspace(pIorb)->unaligned)
805 {
806 /* unaligned S/G addresses present; need to use double buffers */
807 return(ata_read_unaligned(pIorb, slot));
808 }
809
810 if (add_workspace(pIorb)->fIs64bit)
811 {
812 ullLba = ((IORB_EXECUTEIO64*)pIorb)->ullRBA + io->BlocksXferred;
813 }
814
815 /* Kludge: some I/O commands during boot use excessive S/G buffer lengths
816 * which cause NCQ commands to lock up. If there's only one S/G element
817 * and this element is already larger than what we can derive from the sector
818 * count, we'll adjust that element.
819 */
820 if (io->BlocksXferred == 0 && io->cSGList == 1 &&
821 pSGList[0].XferBufLen > (ULONG) io->BlockCount * io->BlockSize)
822 {
823 pSGList[0].XferBufLen = (ULONG) io->BlockCount * io->BlockSize;
824 }
825
826 /* prepare read command while keeping an eye on S/G count limitations */
827 do
828 {
829 sg_indx = SgIndexFromOffset(pSGList, io->cSGList, io->BlocksXferred * io->BlockSize);
830 sg_cnt = io->cSGList - sg_indx;
831 rc = ata_cmd_read(pIorb, ai, p, d, slot, ullLba, count, pSGList + sg_indx, sg_cnt);
832 if (rc > 0)
833 {
834 /* couldn't map all S/G elements */
835 ata_max_sg_cnt(io, sg_indx, rc, &sg_cnt, &count);
836 }
837 } while (rc > 0 && sg_cnt > 0);
838
839 if (rc == 0)
840 {
841 add_workspace(pIorb)->blocks = count;
842 add_workspace(pIorb)->ppfunc = ata_read_pp;
843 }
844 else if (rc > 0)
845 {
846 iorb_seterr(pIorb, IOERR_CMD_SGLIST_BAD);
847 }
848 else if (rc == ATA_CMD_UNALIGNED_ADDR)
849 {
850 /* unaligned S/G addresses detected; need to use double buffers */
851 add_workspace(pIorb)->unaligned = 1;
852 return(ata_read_unaligned(pIorb, slot));
853 }
854 else
855 {
856 iorb_seterr(pIorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
857 }
858
859 return(rc);
860}
861
862/******************************************************************************
863 * Read sectors from AHCI device with unaligned S/G element addresses. AHCI
864 * only allows aligned S/G addresses while OS/2 doesn't have these kind of
865 * restrictions. This doesn't happen very often but when it does, we need to
866 * use a transfer buffer and copy the data manually.
867 */
868int ata_read_unaligned(IORBH *pIorb, int slot)
869{
870 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
871 ADD_WORKSPACE *aws = add_workspace(pIorb);
872 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
873 ULONGLONG ullLba = io->RBA + io->BlocksXferred;
874 SCATGATENTRY sg_single;
875 int p = iorb_unit_port(pIorb);
876 int d = iorb_unit_device(pIorb);
877 int rc;
878
879 if (add_workspace(pIorb)->fIs64bit)
880 {
881 ullLba = ((IORB_EXECUTEIO64*)pIorb)->ullRBA + io->BlocksXferred;
882 }
883
884 DPRINTF(7,"ata_read_unaligned(%d.%d.%d, %lld)\n", ad_no(ai), p, d, ullLba);
885 ai->ports[p].unaligned_read_count++;
886
887 /* allocate transfer buffer */
888 if ((aws->buf = MemAlloc(io->BlockSize)) == NULL)
889 {
890 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE);
891 return(-1);
892 }
893
894 /* prepare read command using transfer buffer */
895 sg_single.ppXferBuf = MemPhysAdr(aws->buf);
896 sg_single.XferBufLen = io->BlockSize;
897 rc = ata_cmd_read(pIorb, ai, p, d, slot, ullLba, 1, &sg_single, 1);
898
899 if (rc == 0) {
900 add_workspace(pIorb)->blocks = 1;
901 add_workspace(pIorb)->ppfunc = ata_read_pp;
902
903 } else if (rc > 0) {
904 iorb_seterr(pIorb, IOERR_CMD_SGLIST_BAD);
905
906 } else {
907 iorb_seterr(pIorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
908 }
909
910 return(rc);
911}
912
913/******************************************************************************
914 * Post processing function for ata_read(); this function updates the
915 * BlocksXferred counter in the IORB and, if not all blocks have been
916 * transferred, requeues the IORB to process the remaining sectors. It also
917 * takes care of copying data from the transfer buffer for unaligned reads.
918 */
919void ata_read_pp(IORBH FAR16DATA *vIorb, IORBH *pIorb)
920{
921 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
922 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(io->f16SGList);
923 ADD_WORKSPACE *aws = add_workspace(pIorb);
924
925 if (aws->unaligned)
926 {
927 /* copy transfer buffer to corresponding physical address in S/G list */
928 CopySgBuf(pSGList, io->cSGList, (ULONG)io->BlocksXferred * (ULONG)io->BlockSize,
929 aws->buf, io->BlockSize, BUF_TO_SGL);
930 }
931
932 io->BlocksXferred += add_workspace(pIorb)->blocks;
933 DPRINTF(7,__func__": blocks transferred = %d\n", io->BlocksXferred);
934
935 if (io->BlocksXferred >= io->BlockCount)
936 {
937 /* we're done; tell IRQ handler the IORB is complete */
938 add_workspace(pIorb)->complete = 1;
939 }
940 else
941 {
942 /* requeue this IORB for next iteration */
943 iorb_requeue(pIorb);
944 }
945}
946
947/******************************************************************************
948 * Verify readability of sectors on ATA device.
949 */
950int ata_verify(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
951{
952 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
953 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
954 int p = iorb_unit_port(pIorb);
955 int d = iorb_unit_device(pIorb);
956 ULONGLONG ullLba = io->RBA;
957 int rc;
958
959 if (io->BlockCount == 0)
960 {
961 /* NOP; return -1 without error in IORB to indicate success */
962 return(-1);
963 }
964
965 if (add_workspace(pIorb)->fIs64bit)
966 {
967 ullLba = ((IORB_EXECUTEIO64*)pIorb)->ullRBA;
968 }
969
970 /* prepare verify command */
971 if (ullLba >= (1UL << 28) || io->BlockCount > 256)
972 {
973 /* need LBA48 for this command */
974 if (!ai->ports[p].devs[d].lba48) {
975 iorb_seterr(pIorb, IOERR_RBA_LIMIT);
976 return(-1);
977 }
978 rc = ata_cmd(ai, p, d, slot, ATA_CMD_VERIFY_EXT,
979 AP_SECTOR_48, ullLba,
980 AP_COUNT, io->BlockCount,
981 AP_DEVICE, 0x40,
982 AP_END);
983 } else {
984 rc = ata_cmd(ai, p, d, slot, ATA_CMD_VERIFY,
985 AP_SECTOR_28, (ULONG)ullLba,
986 AP_COUNT, io->BlockCount & 0xffU,
987 AP_DEVICE, 0x40,
988 AP_END);
989 }
990
991 return(rc);
992}
993
994/******************************************************************************
995 * Fabricate ATA WRITE command based on the capabilities of the corresponding
996 * device and the paramters set from above (NCQ, etc)
997 */
998static int ata_cmd_write(IORBH *pIorb, AD_INFO *ai, int p, int d, int slot,
999 ULONGLONG ullLba, ULONG count, SCATGATENTRY *sg_list,
1000 ULONG sg_cnt, int write_through)
1001{
1002 int rc;
1003
1004 if (ullLba >= (1UL << 28) || count > 256 || add_workspace(pIorb)->is_ncq)
1005 {
1006 /* need LBA48 for this command */
1007 if (!ai->ports[p].devs[d].lba48)
1008 {
1009 iorb_seterr(pIorb, IOERR_RBA_LIMIT);
1010 return(-1);
1011 }
1012 if (add_workspace(pIorb)->is_ncq)
1013 {
1014 /* use NCQ write; count goes into feature register, tag into count! */
1015 rc = ata_cmd(ai, p, d, slot, ATA_CMD_FPDMA_WRITE,
1016 AP_SECTOR_48, ullLba,
1017 AP_FEATURES, count,
1018 /* tag = slot */
1019 AP_COUNT, (slot << 3),
1020 AP_SGLIST, sg_list, sg_cnt,
1021 AP_DEVICE, 0x40,
1022 /* force unit access */
1023 AP_DEVICE, (write_through && !force_write_cache) ? 0x80 : 0,
1024 AP_WRITE, 1,
1025 AP_END);
1026 }
1027 else
1028 {
1029 rc = ata_cmd(ai, p, d, slot, ATA_CMD_WRITE_EXT,
1030 AP_SECTOR_48, ullLba,
1031 AP_COUNT, count,
1032 AP_SGLIST, sg_list, sg_cnt,
1033 AP_DEVICE, 0x40,
1034 AP_WRITE, 1,
1035 AP_END);
1036 }
1037 }
1038 else
1039 {
1040 rc = ata_cmd(ai, p, d, slot, ATA_CMD_WRITE,
1041 AP_SECTOR_28, (ULONG)ullLba,
1042 AP_COUNT, count & 0xffU,
1043 AP_SGLIST, sg_list, sg_cnt,
1044 AP_DEVICE, 0x40,
1045 AP_WRITE, 1,
1046 AP_END);
1047 }
1048
1049 return(rc);
1050}
1051
1052/******************************************************************************
1053 * Write sectors to AHCI device.
1054 */
1055int ata_write(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
1056{
1057 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
1058 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(io->f16SGList);
1059 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
1060 ULONGLONG ullLba = io->RBA + io->BlocksXferred;
1061 USHORT count = io->BlockCount - io->BlocksXferred;
1062 USHORT sg_indx;
1063 USHORT sg_cnt;
1064 int p = iorb_unit_port(pIorb);
1065 int d = iorb_unit_device(pIorb);
1066 int rc;
1067
1068 if (io->BlockCount == 0)
1069 {
1070 /* NOP; return -1 without error in IORB to indicate success */
1071 return(-1);
1072 }
1073
1074 if (add_workspace(pIorb)->unaligned)
1075 {
1076 /* unaligned S/G addresses present; need to use double buffers */
1077 return(ata_write_unaligned(pIorb, slot));
1078 }
1079
1080 if (add_workspace(pIorb)->fIs64bit)
1081 {
1082 ullLba = ((IORB_EXECUTEIO64*)pIorb)->ullRBA + io->BlocksXferred;
1083 }
1084
1085 /* prepare write command while keeping an eye on S/G count limitations */
1086 do {
1087 sg_indx = SgIndexFromOffset(pSGList, io->cSGList, io->BlocksXferred * io->BlockSize);
1088 sg_cnt = io->cSGList - sg_indx;
1089 if ((rc = ata_cmd_write(pIorb, ai, p, d, slot, ullLba, count,
1090 pSGList + sg_indx, sg_cnt,
1091 io->Flags & XIO_DISABLE_HW_WRITE_CACHE)) > 0)
1092 {
1093 /* couldn't map all S/G elements */
1094 ata_max_sg_cnt(io, sg_indx, (USHORT)rc, &sg_cnt, &count);
1095 }
1096 } while (rc > 0 && sg_cnt > 0);
1097
1098 if (rc == 0)
1099 {
1100 add_workspace(pIorb)->blocks = count;
1101 add_workspace(pIorb)->ppfunc = ata_write_pp;
1102 }
1103 else if (rc > 0)
1104 {
1105 iorb_seterr(pIorb, IOERR_CMD_SGLIST_BAD);
1106 }
1107 else if (rc == ATA_CMD_UNALIGNED_ADDR)
1108 {
1109 /* unaligned S/G addresses detected; need to use double buffers */
1110 add_workspace(pIorb)->unaligned = 1;
1111 return(ata_write_unaligned(pIorb, slot));
1112 }
1113 else
1114 {
1115 iorb_seterr(pIorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
1116 }
1117
1118 return(rc);
1119}
1120
1121/******************************************************************************
1122 * Write sectors from AHCI device with unaligned S/G element addresses. AHCI
1123 * only allows aligned S/G addresses while OS/2 doesn't have these kind of
1124 * restrictions. This doesn't happen very often but when it does, we need to
1125 * use a transfer buffer and copy the data manually.
1126 */
1127int ata_write_unaligned(IORBH *pIorb, int slot)
1128{
1129 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
1130 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(io->f16SGList);
1131 ADD_WORKSPACE *aws = add_workspace(pIorb);
1132 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
1133 ULONGLONG ullLba = io->RBA + io->BlocksXferred;
1134 SCATGATENTRY sg_single;
1135 int p = iorb_unit_port(pIorb);
1136 int d = iorb_unit_device(pIorb);
1137 int rc;
1138
1139 if (add_workspace(pIorb)->fIs64bit)
1140 {
1141 ullLba = ((IORB_EXECUTEIO64*)pIorb)->ullRBA + io->BlocksXferred;
1142 }
1143
1144 DPRINTF(7,"ata_write_unaligned(%d.%d.%d, %lld)\n", ad_no(ai), p, d, ullLba);
1145
1146 /* allocate transfer buffer */
1147 if ((aws->buf = MemAlloc(io->BlockSize)) == NULL)
1148 {
1149 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE);
1150 return(-1);
1151 }
1152
1153 /* copy next sector from S/G list to transfer buffer */
1154 CopySgBuf(pSGList, io->cSGList, (ULONG)io->BlocksXferred * (ULONG)io->BlockSize,
1155 aws->buf, io->BlockSize, SGL_TO_BUF);
1156
1157 /* prepare write command using transfer buffer */
1158 sg_single.ppXferBuf = MemPhysAdr(aws->buf);
1159 sg_single.XferBufLen = io->BlockSize;
1160 rc = ata_cmd_write(pIorb, ai, p, d, slot, ullLba, 1, &sg_single, 1,
1161 io->Flags & XIO_DISABLE_HW_WRITE_CACHE);
1162
1163 if (rc == 0)
1164 {
1165 add_workspace(pIorb)->blocks = 1;
1166 add_workspace(pIorb)->ppfunc = ata_write_pp;
1167 }
1168 else if (rc > 0)
1169 {
1170 iorb_seterr(pIorb, IOERR_CMD_SGLIST_BAD);
1171 }
1172 else
1173 {
1174 iorb_seterr(pIorb, IOERR_CMD_ADD_SOFTWARE_FAILURE);
1175 }
1176
1177 return(rc);
1178}
1179
1180
1181/******************************************************************************
1182 * Post processing function for ata_write(); this function updates the
1183 * BlocksXferred counter in the IORB and, if not all blocks have been
1184 * transferred, requeues the IORB to process the remaining sectors.
1185 */
1186void ata_write_pp(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1187{
1188 IORB_EXECUTEIO *io = (IORB_EXECUTEIO *)pIorb;
1189
1190 io->BlocksXferred += add_workspace(pIorb)->blocks;
1191 DPRINTF(7,"ata_write_pp(): blocks transferred = %d\n", io->BlocksXferred);
1192
1193 if (io->BlocksXferred >= io->BlockCount)
1194 {
1195 /* we're done; tell IRQ handler the IORB is complete */
1196 add_workspace(pIorb)->complete = 1;
1197 }
1198 else
1199 {
1200 /* requeue this IORB for next iteration */
1201 iorb_requeue(pIorb);
1202 }
1203}
1204
1205/******************************************************************************
1206 * Execute ATA command.
1207 */
1208int ata_execute_ata(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
1209{
1210 IORB_ADAPTER_PASSTHRU *apt = (IORB_ADAPTER_PASSTHRU *)pIorb;
1211 SCATGATENTRY *pSGList = (SCATGATENTRY*)Far16ToFlat(apt->f16SGList);
1212 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
1213 int p = iorb_unit_port(pIorb);
1214 int d = iorb_unit_device(pIorb);
1215 int rc;
1216
1217 if (apt->ControllerCmdLen != sizeof(ATA_CMD))
1218 {
1219 iorb_seterr(pIorb, IOERR_CMD_SYNTAX);
1220 return(-1);
1221 }
1222
1223 rc = ata_cmd(ai, p, d, slot, 0,
1224 AP_SGLIST, pSGList, apt->cSGList,
1225 AP_ATA_CMD, Far16ToFlat(apt->f16ControllerCmd),
1226 AP_WRITE, !(apt->Flags & PT_DIRECTION_IN),
1227 AP_END);
1228
1229 if (rc == 0)
1230 {
1231 add_workspace(pIorb)->ppfunc = ata_execute_ata_pp;
1232 }
1233
1234 return(rc);
1235}
1236
1237/******************************************************************************
1238 * Post processing function for ata_execute_ata(); the main purpose of this
1239 * function is to copy the received D2H FIS (i.e. the device registers after
1240 * command completion) back to the ATA command structure.
1241 *
1242 * See ata_cmd_to_fis() for an explanation of the mapping.
1243 */
1244void ata_execute_ata_pp(IORBH FAR16DATA *vIorb, IORBH *pIorb)
1245{
1246 AHCI_PORT_DMA *dma_base;
1247 ATA_CMD *cmd;
1248 AD_INFO *ai;
1249 u8 *fis;
1250 int p;
1251
1252 /* get address of D2H FIS */
1253 ai = ad_infos + iorb_unit_adapter(pIorb);
1254 p = iorb_unit_port(pIorb);
1255 dma_base = port_dma_base(ai, p);
1256 fis = dma_base->rx_fis + 0x40;
1257
1258 if (fis[0] != 0x34)
1259 {
1260 /* this is not a D2H FIS - give up silently */
1261 DPRINTF(3,"ata_execute_ata_pp(): D2H FIS type incorrect: %d\n", fis[0]);
1262 add_workspace(pIorb)->complete = 1;
1263 return;
1264 }
1265
1266 /* map D2H FIS to the original ATA controller command structure */
1267 cmd = (ATA_CMD *)Far16ToFlat(((IORB_ADAPTER_PASSTHRU*)pIorb)->f16ControllerCmd);
1268
1269 cmd->cmd = fis[2];
1270 cmd->device = fis[7];
1271 cmd->features = ((u16) fis[3])
1272 | ((u16) fis[11]);
1273 cmd->lba_l = ((u32) fis[4])
1274 | ((u32) fis[5] << 8)
1275 | ((u32) fis[6] << 16)
1276 | ((u32) fis[8] << 24);
1277 cmd->lba_h = ((u16) fis[9])
1278 | ((u16) fis[10] << 8);
1279 cmd->count = ((u16) fis[12])
1280 | ((u16) fis[13] << 8);
1281
1282 DHEXDUMP(5,cmd, sizeof(*cmd), "ahci_execute_ata_pp(): cmd after completion:\n");
1283
1284 /* signal completion to interrupt handler */
1285 add_workspace(pIorb)->complete = 1;
1286}
1287
1288/******************************************************************************
1289 * Request sense information for a failed command. Since there is no "request
1290 * sense" command for ATA devices, we need to read the current error code from
1291 * the AHCI task file register and fabricate the sense information.
1292 *
1293 * NOTES:
1294 *
1295 * - This function must be called right after an ATA command has failed and
1296 * before any other commands are queued on the corresponding port. This
1297 * function is typically called in the port restart context hook which is
1298 * triggered by an AHCI error interrupt.
1299 *
1300 * - The ATA error bits are a complete mess. We'll try and catch the most
1301 * interesting error codes (such as medium errors) and report everything
1302 * else with a generic error code.
1303 */
1304int ata_req_sense(IORBH FAR16DATA *vIorb, IORBH *pIorb, int slot)
1305{
1306 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb);
1307 u8 *port_mmio = port_base(ai, iorb_unit_port(pIorb));
1308 u32 tf_data = readl(port_mmio + PORT_TFDATA);
1309 u8 err = (tf_data >> 8);
1310 u8 sts = (tf_data);
1311
1312 if (sts & ATA_ERR)
1313 {
1314 if (sts & ATA_DF)
1315 {
1316 /* there is a device-specific error condition */
1317 if (err & ATA_ICRC)
1318 {
1319 iorb_seterr(pIorb, IOERR_ADAPTER_DEVICEBUSCHECK);
1320 }
1321 else if (err & ATA_UNC)
1322 {
1323 iorb_seterr(pIorb, IOERR_MEDIA);
1324 }
1325 else if (err & ATA_IDNF)
1326 {
1327 iorb_seterr(pIorb, IOERR_RBA_ADDRESSING_ERROR);
1328 }
1329 else
1330 {
1331 iorb_seterr(pIorb, IOERR_DEVICE_NONSPECIFIC);
1332 }
1333
1334 }
1335 else
1336 {
1337 iorb_seterr(pIorb, IOERR_DEVICE_NONSPECIFIC);
1338 }
1339 }
1340 else
1341 {
1342 /* this function only gets called when we received an error interrupt */
1343 iorb_seterr(pIorb, IOERR_DEVICE_NONSPECIFIC);
1344 }
1345
1346 /* Return an error to indicate there's no HW command to be submitted and
1347 * that the IORB can be completed "as is" (the upstream code expects the
1348 * IORB error code, if any, to be set when this happens and this is exactly
1349 * what this function is all about).
1350 */
1351 return(-1);
1352}
1353
1354/******************************************************************************
1355 * Extract vendor and device name from an ATA INDENTIFY buffer. Since strings
1356 * in the indentify buffer are byte-swapped, we need to swap them back.
1357 */
1358char *ata_dev_name(u16 *id_buf)
1359{
1360 static char dev_name[ATA_ID_PROD_LEN + 1];
1361 char *t = dev_name;
1362 char *s = (char *) (id_buf + ATA_ID_PROD);
1363 int i;
1364
1365 dev_name[sizeof(dev_name)-1] = '\0';
1366
1367 for (i = 0; i < ATA_ID_PROD_LEN / 2; i++) {
1368 *(t++) = s[1];
1369 *(t++) = s[0];
1370 s += 2;
1371 }
1372
1373 return(dev_name);
1374}
1375
1376/******************************************************************************
1377 * Halt processing by submitting an internal error. This is a last resort and
1378 * should only be called when the system state is corrupt.
1379 */
1380void panic(char *msg)
1381{
1382 Dev32Help_InternalError(msg, strlen(msg));
1383}
1384
Note: See TracBrowser for help on using the repository browser.