Exemplo n.º 1
0
s32 Partition_GetEntries(u32 device, partitionEntry *outbuf, u32 *outval)
{
	static partitionTable table ATTRIBUTE_ALIGN(32);

	u32 cnt, sector_size;
	s32 ret;

	/* Read from specified device */
	switch (device) {
	case WBFS_DEVICE_USB: {
		/* Get sector size */
		ret = USBStorage_GetCapacity(&sector_size);
		if (ret == 0)
			return -1;

		/* Read partition table */
		u8* table_buf = memalign(32, sector_size);
		ret = USBStorage_ReadSectors(0, 1, table_buf);
		memcpy(&table, table_buf, sizeof(table));
		SAFE_FREE(table_buf);
		if (ret < 0)
			return ret;

		break;
	}

	case WBFS_DEVICE_SDHC: {
		/* SDHC sector size */
		sector_size = SDHC_SECTOR_SIZE;

		/* Read partition table */
		ret = SDHC_ReadSectors(0, 1, &table);
		if (!ret)
			return -1;

		break;
	}

	default:
		return -1;
	}


	/* Swap endianess */
	for (cnt = 0; cnt < 4; cnt++) {
		partitionEntry *entry = &table.entries[cnt];

		entry->sector = swap32(entry->sector);
		entry->size   = swap32(entry->size);
	}

	/* Set partition entries */
	memcpy(outbuf, table.entries, sizeof(table.entries));

	/* Set sector size */
	*outval = sector_size;

	return 0;
}
Exemplo n.º 2
0
s32 WBFS_Init(u32 device, u32 timeout)
{
	u32 cnt;
	s32 ret;

	/* Wrong timeout */
	if (!timeout)
		return -1;

	/* Try to mount device */
	for (cnt = 0; cnt < timeout; cnt++) {
		switch (device) {
		case WBFS_DEVICE_USB: {
			/* Initialize USB storage */
			ret = USBStorage_Init();

			if (ret >= 0) {
				/* Setup callbacks */
				readCallback  = __WBFS_ReadUSB;
				writeCallback = __WBFS_WriteUSB;

				/* Device info */
				nb_sectors = USBStorage_GetCapacity(&sector_size);

				goto out;
			}
		}

		case WBFS_DEVICE_SDHC: {
			/* Initialize SDHC */
			ret = SDHC_Init();

			if (ret) {
				/* Setup callbacks */
				readCallback  = __WBFS_ReadSDHC;
				writeCallback = __WBFS_WriteSDHC;

				/* Device info */
				nb_sectors  = 0;
				sector_size = SDHC_SECTOR_SIZE;

				goto out;
			} else
				ret = -1;
		}

		default:
			return -1;
		}

		/* Sleep 1 second */
		sleep(1);
	}

out:
	return ret;
}
Exemplo n.º 3
0
s32 Partition_GetEntriesEx(u32 device, partitionEntry *outbuf, u32 *psect_size, int *num)
{
	static union {
		u8 buf[4096];
		partitionTable table;
		wbfs_head_t head;
	} tbl ATTRIBUTE_ALIGN(32);
	partitionTable *table = &tbl.table;
	partitionEntry *entry;

	u32 i, sector_size;
	s32 ret;
	int maxpart = *num;
	int is_raw = 0;

	// Get sector size
	switch (device) {
	case WBFS_DEVICE_USB:
		ret = USBStorage_GetCapacity(&sector_size);
		if (ret == 0) return -1;
		break;
	case WBFS_DEVICE_SDHC:
		sector_size = SDHC_SECTOR_SIZE;
		break;
	default:
		return -1;
	}
	/* Set sector size */
	*psect_size = sector_size;

	if (sector_size < 512 || sector_size > 4096) {
		printf("ERROR: sector size: %u\n", sector_size);
		sleep(5);
		return -2;
	}

	u32 ext = 0;
	u32 next = 0;

	// Read partition table
	ret = Device_ReadSectors(device, 0, 1, tbl.buf);
	if (!ret) return -1;
	// Check if it's a RAW FS disc, without partition table
	ret = get_fs_type(table);
	dbg_printf("fstype(%d)=%d\n", device, ret);
	if (ret != PART_FS_UNK) {
		// looks like a raw fs
		if (!is_valid_ptable(table)) {
			// if invalid part. table then yes it's raw
			is_raw = 1;
		} else {
			dbg_printf("WARNING: ambiguous part.table!\n", ret);
			// ambiguous: looks like a raw fs and a valid part. table
			// make a decision based on device type
			// sd: assume raw; usb: assume part. table
			if (device == WBFS_DEVICE_SDHC) {
				is_raw = 1;
			}
		}
	}
	if (is_raw) {
		dbg_printf("RAW\n", ret);
		memset(outbuf, 0, sizeof(table->entries));
		// create a fake partition entry
		if (ret == PART_FS_WBFS) {
			wbfs_head_t *head = &tbl.head;
			outbuf->size = wbfs_ntohl(head->n_hd_sec);
		} else {
			outbuf->size = 1;
		}
		if (ret == PART_FS_NTFS) {
			outbuf->type = 0x07;
		} else {
			outbuf->type = 0x0b;
		}
		*num = 1;
		return 0;
	}
	/* Swap endianess */
	for (i = 0; i < 4; i++) {
		entry = &table->entries[i];
		entry->sector = swap32(entry->sector);
		entry->size   = swap32(entry->size);
		if (!ext && part_is_extended(entry->type)) {
			ext = entry->sector;
		}
	}
	/* Set partition entries */
	memcpy(outbuf, table->entries, sizeof(table->entries));
	// num primary
	*num = 4;

	if (!ext) return 0;

	next = ext;
	// scan extended partition for logical
	for(i=0; i<maxpart-4; i++) {
		ret = Device_ReadSectors(device, next, 1, tbl.buf);
		if (!ret) break;
		if (i == 0) {
			// handle the invalid scenario where wbfs is on an EXTENDED
			// partition instead of on the Logical inside Extended.
			if (get_fs_type(table) == PART_FS_WBFS) break;
		}
		entry = &table->entries[0];
		entry->sector = swap32(entry->sector);
		entry->size   = swap32(entry->size);
		if (entry->type && entry->size && entry->sector) {
			// rebase to abolute address
			entry->sector += next;
			// add logical
			memcpy(&outbuf[*num], entry, sizeof(*entry));
			(*num)++;
			// get next
			entry++;
			if (entry->type && entry->size && entry->sector) {
				next = ext + swap32(entry->sector);
			} else {
				break;
			}
		}
	}

	return 0;
}
Exemplo n.º 4
0
s32 WBFS_Init_Dev(u32 device)
{
	s32 ret = -1;

	if (wbfs_disc_mutex == LWP_MUTEX_NULL) {
		LWP_MutexInit(&wbfs_disc_mutex, true);
	}

	/* Try to mount device */
	switch (device) {
		case WBFS_DEVICE_USB:
			{
				long long t1 = TIME_D(usb_init);
				long long t2;
				get_time(&TIME.usb_retry1);
				/* Initialize USB storage */
				ret = USBStorage_Init();

				if (ret >= 0) {
					/* Setup callbacks */
					readCallback  = __WBFS_ReadUSB;
					writeCallback = __WBFS_WriteUSB;

					/* Device info */
					nb_sectors = USBStorage_GetCapacity(&wbfs_dev_sector_size);

					get_time(&TIME.usb_retry2);
					t2 = TIME_D(usb_init);
					TIME.usb_retry2 -= (t2 - t1);
					goto out;
				}
			}
			break;

		case WBFS_DEVICE_SDHC:
			{
				/* Initialize SDHC */
				ret = SDHC_Init();
				// returns true=ok false=error 
				if (!ret && !sdhc_mode_sd) {
					// try normal SD
					sdhc_mode_sd = 1;
					ret = SDHC_Init();
				}
				if (ret) {
					/* Setup callbacks */
					readCallback  = __WBFS_ReadSDHC;
					writeCallback = __WBFS_WriteSDHC;

					/* Device info */
					nb_sectors  = 0;
					wbfs_dev_sector_size = SDHC_SECTOR_SIZE;

					goto out;
				}

				ret = -1;
			}
			break;

		default:
			return -1;
	}
out:
	return ret;
}