1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Björn Stenberg
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
25 #include "dir.h" /* for release_dirs() */
26 #include "file.h" /* for release_files() */
30 /* Partition table entry layout:
31 -----------------------
40 8-11: starting sector (LBA)
41 12-15: nr of sectors in partition
44 #define BYTES2INT32(array,pos) \
45 ((long)array[pos] | ((long)array[pos+1] << 8 ) | \
46 ((long)array[pos+2] << 16 ) | ((long)array[pos+3] << 24 ))
48 static struct partinfo part
[8]; /* space for 4 partitions on 2 drives */
49 static int vol_drive
[NUM_VOLUMES
]; /* mounted to which drive (-1 if none) */
51 #ifdef MAX_LOG_SECTOR_SIZE
52 int disk_sector_multiplier
= 1;
54 struct partinfo
* disk_init(IF_MV_NONVOID(int drive
))
57 unsigned char sector
[512];
58 #ifdef HAVE_MULTIVOLUME
59 /* For each drive, start at a different position, in order not to destroy
60 the first entry of drive 0.
61 That one is needed to calculate config sector position. */
62 struct partinfo
* pinfo
= &part
[drive
*4];
63 if ((size_t)drive
>= sizeof(part
)/sizeof(*part
)/4)
64 return NULL
; /* out of space in table */
66 struct partinfo
* pinfo
= part
;
69 ata_read_sectors(IF_MV2(drive
,) 0,1,§or
);
71 /* check that the boot sector is initialized */
72 if ( (sector
[510] != 0x55) ||
73 (sector
[511] != 0xaa)) {
74 DEBUGF("Bad boot sector signature\n");
78 /* parse partitions */
79 for ( i
=0; i
<4; i
++ ) {
80 unsigned char* ptr
= sector
+ 0x1be + 16*i
;
81 pinfo
[i
].type
= ptr
[4];
82 pinfo
[i
].start
= BYTES2INT32(ptr
, 8);
83 pinfo
[i
].size
= BYTES2INT32(ptr
, 12);
85 DEBUGF("Part%d: Type %02x, start: %08lx size: %08lx\n",
86 i
,pinfo
[i
].type
,pinfo
[i
].start
,pinfo
[i
].size
);
89 if ( pinfo
[i
].type
== 5 ) {
97 struct partinfo
* disk_partinfo(int partition
)
99 return &part
[partition
];
102 int disk_mount_all(void)
108 card_enable_monitoring(false);
111 fat_init(); /* reset all mounted partitions */
112 for (i
=0; i
<NUM_VOLUMES
; i
++)
113 vol_drive
[i
] = -1; /* mark all as unassigned */
115 mounted
= disk_mount(0);
119 mounted
+= disk_mount(1); /* try 2nd "drive", too */
122 card_enable_monitoring(true);
128 static int get_free_volume(void)
131 for (i
=0; i
<NUM_VOLUMES
; i
++)
133 if (vol_drive
[i
] == -1) /* unassigned? */
137 return -1; /* none found */
140 int disk_mount(int drive
)
142 int mounted
= 0; /* reset partition-on-drive flag */
143 int volume
= get_free_volume();
144 struct partinfo
* pinfo
= disk_init(IF_MV(drive
));
150 #ifdef TOSHIBA_GIGABEAT_S
151 int i
= 1; /* For the Gigabeat S, we mount the second partition */
155 for (; volume
!= -1 && i
<4; i
++)
157 #ifdef MAX_LOG_SECTOR_SIZE
160 for (j
= 1; j
<= (MAX_LOG_SECTOR_SIZE
/SECTOR_SIZE
); j
<<= 1)
162 if (!fat_mount(IF_MV2(volume
,) IF_MV2(drive
,) pinfo
[i
].start
* j
))
167 vol_drive
[volume
] = drive
; /* remember the drive for this volume */
168 volume
= get_free_volume(); /* prepare next entry */
170 disk_sector_multiplier
= j
;
175 if (!fat_mount(IF_MV2(volume
,) IF_MV2(drive
,) pinfo
[i
].start
))
178 vol_drive
[volume
] = drive
; /* remember the drive for this volume */
179 volume
= get_free_volume(); /* prepare next entry */
184 if (mounted
== 0 && volume
!= -1) /* none of the 4 entries worked? */
185 { /* try "superfloppy" mode */
186 DEBUGF("No partition found, trying to mount sector 0.\n");
187 if (!fat_mount(IF_MV2(volume
,) IF_MV2(drive
,) 0))
190 vol_drive
[volume
] = drive
; /* remember the drive for this volume */
197 int disk_unmount(int drive
)
201 for (i
=0; i
<NUM_VOLUMES
; i
++)
203 if (vol_drive
[i
] == drive
)
204 { /* force releasing resources */
205 vol_drive
[i
] = -1; /* mark unused */
209 fat_unmount(i
, false);
215 #endif /* #ifdef HAVE_HOTSWAP */