blob: 44c4dcc95c647fefc7641e30accd9255346ae9d3 [file] [log] [blame]
Dave Chapmane17043e2007-03-15 22:55:36 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
Dave Chapman4a812912007-03-15 23:02:37 +00008 * $Id$
Dave Chapmane17043e2007-03-15 22:55:36 +00009 *
10 * Copyright (C) 2006-2007 Dave Chapman
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * 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.
Dave Chapmane17043e2007-03-15 22:55:36 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
Dominik Riebeling38890ac2011-12-04 19:40:35 +000022#if !defined(_WIN32) /* all non-Windows platforms supported are POSIX. */
Dave Chapmane17043e2007-03-15 22:55:36 +000023#include <stdio.h>
24#include <unistd.h>
25#include <fcntl.h>
26#include <string.h>
27#include <stdlib.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <sys/ioctl.h>
Dominik Riebeling850c4f92008-05-11 16:58:02 +000031#include <errno.h>
Dave Chapmane17043e2007-03-15 22:55:36 +000032
33#if defined(linux) || defined (__linux)
34#include <sys/mount.h>
35#define SANSA_SECTORSIZE_IOCTL BLKSSZGET
36#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
37 || defined(__bsdi__) || defined(__DragonFly__)
38#include <sys/disk.h>
39#define SANSA_SECTORSIZE_IOCTL DIOCGSECTORSIZE
40#elif defined(__APPLE__) && defined(__MACH__)
41#include <sys/disk.h>
42#define SANSA_SECTORSIZE_IOCTL DKIOCGETBLOCKSIZE
43#else
44 #error No sector-size detection implemented for this platform
45#endif
46
47#include "sansaio.h"
48
Dave Chapmanad4b8862007-09-02 19:20:59 +000049#if defined(__APPLE__) && defined(__MACH__)
50static int sansa_unmount(struct sansa_t* sansa)
51{
52 char cmd[4096];
53 int res;
54
55 sprintf(cmd, "/usr/sbin/diskutil unmount \"%ss1\"",sansa->diskname);
56 fprintf(stderr,"[INFO] ");
57 res = system(cmd);
58
59 if (res==0) {
60 return 0;
61 } else {
62 perror("Unmount failed");
63 return -1;
64 }
65}
66#endif
67
68
Dominik Riebeling3e489c12009-11-08 13:38:10 +000069void sansa_print_error(char* msg)
Dave Chapmane17043e2007-03-15 22:55:36 +000070{
71 perror(msg);
72}
Dave Chapmane17043e2007-03-15 22:55:36 +000073
74int sansa_open(struct sansa_t* sansa, int silent)
75{
76 sansa->dh=open(sansa->diskname,O_RDONLY);
77 if (sansa->dh < 0) {
78 if (!silent) perror(sansa->diskname);
Dominik Riebeling850c4f92008-05-11 16:58:02 +000079 if(errno == EACCES) return -2;
80 else return -1;
Dave Chapmane17043e2007-03-15 22:55:36 +000081 }
82
83 if(ioctl(sansa->dh,SANSA_SECTORSIZE_IOCTL,&sansa->sector_size) < 0) {
84 sansa->sector_size=512;
85 if (!silent) {
86 fprintf(stderr,"[ERR] ioctl() call to get sector size failed, defaulting to %d\n"
87 ,sansa->sector_size);
Bertrik Sikkenb7219b72008-08-31 09:44:45 +000088 }
Dave Chapmane17043e2007-03-15 22:55:36 +000089 }
90 return 0;
91}
92
93
94int sansa_reopen_rw(struct sansa_t* sansa)
95{
Dave Chapmanad4b8862007-09-02 19:20:59 +000096#if defined(__APPLE__) && defined(__MACH__)
97 if (sansa_unmount(sansa) < 0)
98 return -1;
99#endif
100
Dave Chapmane17043e2007-03-15 22:55:36 +0000101 close(sansa->dh);
102 sansa->dh=open(sansa->diskname,O_RDWR);
103 if (sansa->dh < 0) {
104 perror(sansa->diskname);
105 return -1;
106 }
107 return 0;
108}
109
110int sansa_close(struct sansa_t* sansa)
111{
112 close(sansa->dh);
113 return 0;
114}
115
Dominik Riebeling9c1ed842012-12-23 23:36:00 +0100116int sansa_alloc_buffer(struct sansa_t *sansa, int bufsize)
Dave Chapmane17043e2007-03-15 22:55:36 +0000117{
Dominik Riebeling9c1ed842012-12-23 23:36:00 +0100118 sansa->sectorbuf=malloc(bufsize);
119 if (sansa->sectorbuf == NULL) {
Dave Chapmane17043e2007-03-15 22:55:36 +0000120 return -1;
121 }
122 return 0;
123}
124
Dominik Riebeling163ab462013-01-01 13:23:47 +0100125int sansa_dealloc_buffer(struct sansa_t* sansa)
126{
127 if (sansa->sectorbuf == NULL) {
128 return -1;
129 }
130 free(sansa->sectorbuf);
131 sansa->sectorbuf = NULL;
132 return 0;
133}
134
Dave Chapmane17043e2007-03-15 22:55:36 +0000135int sansa_seek(struct sansa_t* sansa, loff_t pos)
136{
137 off_t res;
138
139 res = lseek64(sansa->dh, pos, SEEK_SET);
140
141 if (res == -1) {
142 return -1;
143 }
144 return 0;
145}
146
147int sansa_read(struct sansa_t* sansa, unsigned char* buf, int nbytes)
148{
149 return read(sansa->dh, buf, nbytes);
150}
151
Dominik Riebeling9c1ed842012-12-23 23:36:00 +0100152int sansa_write(struct sansa_t* sansa, int nbytes)
Dave Chapmane17043e2007-03-15 22:55:36 +0000153{
Dominik Riebeling9c1ed842012-12-23 23:36:00 +0100154 return write(sansa->dh, sansa->sectorbuf, nbytes);
Dave Chapmane17043e2007-03-15 22:55:36 +0000155}
Dominik Riebeling38890ac2011-12-04 19:40:35 +0000156#endif
157