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

Last change on this file since 206 was 205, checked in by David Azarewicz, 5 years ago

Fixed ADD RM id.

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