1
1
package msc
2
2
3
- type Disk interface {
4
- Ready () bool
5
- ReadOnly () bool
6
- BlockCount () uint32
7
- BlockSize () uint32
8
- Read (offset uint32 , buffer []byte ) (uint32 , error )
9
- Write (offset uint32 , buffer []byte ) (uint32 , error )
10
- }
3
+ import (
4
+ "encoding/binary"
5
+ "machine"
6
+ )
7
+
8
+ var _ machine.BlockDevice = (* DefaultDisk )(nil )
11
9
12
10
// DefaultDisk is a placeholder disk implementation
13
11
type DefaultDisk struct {
@@ -18,36 +16,58 @@ func NewDefaultDisk() *DefaultDisk {
18
16
return & DefaultDisk {}
19
17
}
20
18
21
- func (d * DefaultDisk ) Ready () bool {
22
- return true
19
+ func (d * DefaultDisk ) Size () int64 {
20
+ return 4096 * int64 ( d . WriteBlockSize ()) // 2MB
23
21
}
24
22
25
- func (d * DefaultDisk ) ReadOnly () bool {
26
- return false
23
+ func (d * DefaultDisk ) WriteBlockSize () int64 {
24
+ return 512 // 512 bytes
27
25
}
28
26
29
- func (d * DefaultDisk ) BlockCount () uint32 {
30
- return 4096 // 2MB
27
+ func (d * DefaultDisk ) EraseBlockSize () int64 {
28
+ return 2048 // 4 blocks of 512 bytes
31
29
}
32
30
33
- func (d * DefaultDisk ) BlockSize () uint32 {
34
- return 512 // 512 bytes
31
+ func (d * DefaultDisk ) EraseBlocks ( startBlock , numBlocks int64 ) error {
32
+ return nil
35
33
}
36
34
37
- func (d * DefaultDisk ) Read ( offset uint32 , buffer []byte ) (uint32 , error ) {
35
+ func (d * DefaultDisk ) ReadAt ( buffer []byte , offset int64 ) (int , error ) {
38
36
n := uint8 (offset )
39
37
for i := range buffer {
40
38
n ++
41
39
buffer [i ] = n
42
40
}
43
- return uint32 ( len (buffer ) ), nil
41
+ return len (buffer ), nil
44
42
}
45
43
46
- func (d * DefaultDisk ) Write ( offset uint32 , buffer []byte ) (uint32 , error ) {
47
- return uint32 ( len (buffer ) ), nil
44
+ func (d * DefaultDisk ) WriteAt ( buffer []byte , offset int64 ) (int , error ) {
45
+ return len (buffer ), nil
48
46
}
49
47
50
- // RegisterDisk registers a disk provider with the MSC driver
51
- func (m * msc ) RegisterDisk (disk Disk ) {
52
- m .disk = disk
48
+ // RegisterBlockDevice registers a BlockDevice provider with the MSC driver
49
+ func (m * msc ) RegisterBlockDevice (dev machine.BlockDevice ) {
50
+ m .dev = dev
51
+
52
+ // Set VPD UNMAP fields
53
+ for i := range vpdPages {
54
+ if vpdPages [i ].PageCode == 0xb0 {
55
+ // 0xb0 - 5.4.5 Block Limits VPD page (B0h)
56
+ if len (vpdPages [i ].Data ) >= 28 {
57
+ // Set the OPTIMAL UNMAP GRANULARITY (write blocks per erase block)
58
+ granularity := uint32 (dev .EraseBlockSize ()) / uint32 (dev .WriteBlockSize ())
59
+ binary .BigEndian .PutUint32 (vpdPages [i ].Data [24 :28 ], granularity )
60
+ }
61
+ /* TODO: Add method for working out the optimal unmap granularity alignment
62
+ if len(vpdPages[i].Data) >= 32 {
63
+ // Set the UNMAP GRANULARITY ALIGNMENT (first sector of first full erase block)
64
+ // The unmap granularity alignment is used to calculate an optimal unmap request starting LBA as follows:
65
+ // optimal unmap request starting LBA = (n * OPTIMAL UNMAP GRANULARITY) + UNMAP GRANULARITY ALIGNMENT
66
+ // where n is zero or any positive integer value
67
+ // https://www.seagate.com/files/staticfiles/support/docs/manual/Interface%20manuals/100293068j.pdf
68
+ }
69
+ */
70
+ break
71
+ }
72
+ }
53
73
}
0 commit comments