]>
glassweightruler.freedombox.rocks Git - Ventoy.git/blob - VBLADE/vblade-master/ata.c
1 // ata.c: ATA simulator for vblade
26 static ushort ident
[256];
29 setfld(ushort
*a
, int idx
, int len
, char *str
) // set field in ident
49 setlba28(ushort
*ident
, vlong lba
)
53 cp
= (uchar
*) &ident
[60];
57 *cp
++ = (lba
>>= 8) & 0xf;
61 setlba48(ushort
*ident
, vlong lba
)
65 cp
= (uchar
*) &ident
[100];
75 setushort(ushort
*a
, int i
, ushort n
)
89 setushort(ident
, 47, 0x8000);
90 setushort(ident
, 49, 0x0200);
91 setushort(ident
, 50, 0x4000);
92 setushort(ident
, 83, 0x5400);
93 setushort(ident
, 84, 0x4000);
94 setushort(ident
, 86, 0x1400);
95 setushort(ident
, 87, 0x4000);
96 setushort(ident
, 93, 0x400b);
97 setfld(ident
, 27, 40, "Coraid EtherDrive vblade");
98 sprintf(buf
, "V%d", VBLADE_VERSION
);
99 setfld(ident
, 23, 8, buf
);
100 setfld(ident
, 10, 20, serial
);
104 /* The ATA spec is weird in that you specify the device size as number
105 * of sectors and then address the sectors with an offset. That means
106 * with LBA 28 you shouldn't see an LBA of all ones. Still, we don't
110 atacmd(Ataregs
*p
, uchar
*dp
, int ndp
, int payload
) // do the ata cmd
115 enum { MAXLBA28SIZE
= 0x0fffffff };
121 p
->status
= DRDY
| ERR
;
124 case 0xe7: // flush cache
126 case 0xec: // identify device
127 if (p
->sectors
!= 1 || ndp
< 512)
129 memmove(dp
, ident
, 512);
131 if (size
& ~MAXLBA28SIZE
)
132 setlba28(ip
, MAXLBA28SIZE
);
140 case 0xe5: // check power mode
142 p
->sectors
= 0xff; // the device is active or idle
145 case 0x20: // read sectors
146 case 0x30: // write sectors
147 lba
= p
->lba
& MAXLBA28SIZE
;
149 case 0x24: // read sectors ext
150 case 0x34: // write sectors ext
151 lba
= p
->lba
& 0x0000ffffffffffffLL
; // full 48
155 // we ought not be here unless we are a read/write
157 if (p
->sectors
> maxscnt
|| p
->sectors
*512 > ndp
)
160 if (lba
+ p
->sectors
> size
) {
162 p
->status
= DRDY
| ERR
;
166 if (p
->cmd
== 0x20 || p
->cmd
== 0x24)
167 n
= getsec(bfd
, dp
, lba
+offset
, p
->sectors
);
169 // packet should be big enough to contain the data
170 if (payload
< 512 * p
->sectors
)
172 n
= putsec(bfd
, dp
, lba
+offset
, p
->sectors
);
175 if (n
!= p
->sectors
) {