Colour targets: Revert an optimisation from almost 18 months ago that actually turned...
[Rockbox.git] / rbutil / ipodpatcher / ipodio-posix.c
blob6dfb09ed33fff3301cb5aee7ee43bfedfe740065
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2006-2007 Dave Chapman
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <sys/ioctl.h>
30 #include <errno.h>
32 #include "ipodio.h"
34 #if defined(linux) || defined (__linux)
35 #include <sys/mount.h>
36 #include <linux/hdreg.h>
37 #define IPOD_SECTORSIZE_IOCTL BLKSSZGET
39 static void get_geometry(struct ipod_t* ipod)
41 struct hd_geometry geometry;
43 if (!ioctl(ipod->dh, HDIO_GETGEO, &geometry)) {
44 /* never use geometry.cylinders - it is truncated */
45 ipod->num_heads = geometry.heads;
46 ipod->sectors_per_track = geometry.sectors;
47 } else {
48 ipod->num_heads = 0;
49 ipod->sectors_per_track = 0;
53 #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
54 || defined(__bsdi__) || defined(__DragonFly__)
55 #include <sys/disk.h>
56 #define IPOD_SECTORSIZE_IOCTL DIOCGSECTORSIZE
58 /* TODO: Implement this function for BSD */
59 static void get_geometry(struct ipod_t* ipod)
61 /* Are these universal for all ipods? */
62 ipod->num_heads = 255;
63 ipod->sectors_per_track = 63;
66 #elif defined(__APPLE__) && defined(__MACH__)
67 #include <sys/disk.h>
68 #define IPOD_SECTORSIZE_IOCTL DKIOCGETBLOCKSIZE
70 /* TODO: Implement this function for Mac OS X */
71 static void get_geometry(struct ipod_t* ipod)
73 /* Are these universal for all ipods? */
74 ipod->num_heads = 255;
75 ipod->sectors_per_track = 63;
78 #else
79 #error No sector-size detection implemented for this platform
80 #endif
82 #if defined(__APPLE__) && defined(__MACH__)
83 static int ipod_unmount(struct ipod_t* ipod)
85 char cmd[4096];
86 int res;
88 sprintf(cmd, "/usr/sbin/diskutil unmount \"%ss2\"",ipod->diskname);
89 fprintf(stderr,"[INFO] ");
90 res = system(cmd);
92 if (res==0) {
93 return 0;
94 } else {
95 perror("Unmount failed");
96 return -1;
99 #endif
101 void print_error(char* msg)
103 perror(msg);
106 int ipod_open(struct ipod_t* ipod, int silent)
108 ipod->dh=open(ipod->diskname,O_RDONLY);
109 if (ipod->dh < 0) {
110 if (!silent) perror(ipod->diskname);
111 if(errno == EACCES) return -2;
112 else return -1;
115 /* Read information about the disk */
117 if(ioctl(ipod->dh,IPOD_SECTORSIZE_IOCTL,&ipod->sector_size) < 0) {
118 ipod->sector_size=512;
119 if (!silent) {
120 fprintf(stderr,"[ERR] ioctl() call to get sector size failed, defaulting to %d\n"
121 ,ipod->sector_size);
125 get_geometry(ipod);
127 return 0;
131 int ipod_reopen_rw(struct ipod_t* ipod)
133 #if defined(__APPLE__) && defined(__MACH__)
134 if (ipod_unmount(ipod) < 0)
135 return -1;
136 #endif
138 close(ipod->dh);
139 ipod->dh=open(ipod->diskname,O_RDWR);
140 if (ipod->dh < 0) {
141 perror(ipod->diskname);
142 return -1;
144 return 0;
147 int ipod_close(struct ipod_t* ipod)
149 close(ipod->dh);
150 return 0;
153 int ipod_alloc_buffer(unsigned char** sectorbuf, int bufsize)
155 *sectorbuf=malloc(bufsize);
156 if (*sectorbuf == NULL) {
157 return -1;
159 return 0;
162 int ipod_seek(struct ipod_t* ipod, unsigned long pos)
164 off_t res;
166 res = lseek(ipod->dh, pos, SEEK_SET);
168 if (res == -1) {
169 return -1;
171 return 0;
174 ssize_t ipod_read(struct ipod_t* ipod, unsigned char* buf, int nbytes)
176 return read(ipod->dh, buf, nbytes);
179 ssize_t ipod_write(struct ipod_t* ipod, unsigned char* buf, int nbytes)
181 return write(ipod->dh, buf, nbytes);