Subversion Repositories freemyipod

Rev

Rev 951 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 951 Rev 953
Line 125... Line 125...
125
        """ Writes the data in 'data' to the location 'addr'
125
        """ Writes the data in 'data' to the location 'addr'
126
            in the memory of the device. Can handle up to 0xff0 bytes.
126
            in the memory of the device. Can handle up to 0xff0 bytes.
127
        """
127
        """
128
        return self.lib.monitorcommand(struct.pack("<IIII%ds" % len(data), 5, addr, len(data), 0, data), "III", (None, None, None))
128
        return self.lib.monitorcommand(struct.pack("<IIII%ds" % len(data), 5, addr, len(data), 0, data), "III", (None, None, None))
129
    
129
    
130
    @command()
130
    @command(timeout = 10000)
131
    def _readmem_bulk(self, addr, size):
131
    def _readmem_bulk(self, addr, size):
132
        """ Reads the memory from location 'addr' with size 'size'
132
        """ Reads the memory from location 'addr' with size 'size'
133
            from the device. Can handle unlimited amounts of bytes,
133
            from the device. Can handle unlimited amounts of bytes,
134
            however the address and size should be cacheline aligned.
134
            however the address and size should be cacheline aligned.
135
        """
135
        """
136
        return self.lib.recvbulk(struct.pack("<III", 1, addr, size), size)
136
        return self.lib.recvbulk(struct.pack("<III", 1, addr, size), size)
137
    
137
    
138
    @command()
138
    @command(timeout = 10000)
139
    def _writemem_bulk(self, addr, data):
139
    def _writemem_bulk(self, addr, data):
140
        """ Writes the data in 'data' to the location 'addr'
140
        """ Writes the data in 'data' to the location 'addr'
141
            in the memory of the device. Can handle unlimited amounts of bytes,
141
            in the memory of the device. Can handle unlimited amounts of bytes,
142
            however the address and size should be cacheline aligned.
142
            however the address and size should be cacheline aligned.
143
 
143
 
Line 197... Line 197...
197
                    data += self._readmem(addr, align)
197
                    data += self._readmem(addr, align)
198
                    addr += align
198
                    addr += align
199
                    size -= align
199
                    size -= align
200
                align = size & 63
200
                align = size & 63
201
                size -= align
201
                size -= align
-
 
202
                if size:
202
                data += self._readmem_bulk(addr, size)
203
                    data += self._readmem_bulk(addr, size)
203
                addr += size
204
                    addr += size
204
                size = align
205
                size = align
205
        except: self.logger.warn("Bulk read interface failed, falling back to slow reads\n")
206
        except: raise#self.logger.warn("Bulk read interface failed, falling back to slow reads\n")
206
        while size > 0:
207
        while size > 0:
207
            readsize = min(size, 0xf00)
208
            readsize = min(size, 0xf00)
208
            data += self._readmem(addr, readsize)
209
            data += self._readmem(addr, readsize)
209
            addr += readsize
210
            addr += readsize
210
            size -= readsize
211
            size -= readsize
Line 226... Line 227...
226
                    offset += align
227
                    offset += align
227
                    addr += align
228
                    addr += align
228
                    size -= align
229
                    size -= align
229
                align = size & 63
230
                align = size & 63
230
                size -= align
231
                size -= align
-
 
232
                if size:
231
                self._writemem_bulk(addr, data[offset:offset+size])
233
                    self._writemem_bulk(addr, data[offset:offset+size])
232
                offset += size
234
                    offset += size
233
                addr += size
235
                    addr += size
234
                size = align
236
                size = align
235
        except: self.logger.warn("Bulk write interface failed, falling back to slow writes\n")
237
        except: self.logger.warn("Bulk write interface failed, falling back to slow writes\n")
236
        while size > 0:
238
        while size > 0:
237
            writesize = min(size, 0xf00)
239
            writesize = min(size, 0xf00)
238
            self._writemem(addr, data[offset:offset+writesize])
240
            self._writemem(addr, data[offset:offset+writesize])
Line 1102... Line 1104...
1102
                raise DeviceError("Device busy")
1104
                raise DeviceError("Device busy")
1103
        else:
1105
        else:
1104
            return writelen
1106
            return writelen
1105
            
1107
            
1106
    def sendbulk(self, cmd, data):
1108
    def sendbulk(self, cmd, data):
1107
        self.logger.debug("Sending bulk command [0x%s]\n" % base64.b16encode(cmd[3::-1]).decode("ascii"))
1109
        self.logger.debug("Sending bulk command [0x%s] with %d bytes\n" % (base64.b16encode(cmd[3::-1]).decode("ascii"), len(data)))
1108
        return self.dev.sendbulk(cmd, data)
1110
        return self.dev.sendbulk(cmd, data)
1109
            
1111
            
1110
    def recvbulk(self, cmd, size):
1112
    def recvbulk(self, cmd, size):
1111
        self.logger.debug("Receiving bulk command [0x%s]\n" % base64.b16encode(cmd[3::-1]).decode("ascii"))
1113
        self.logger.debug("Receiving bulk command [0x%s] with %d bytes\n" % (base64.b16encode(cmd[3::-1]).decode("ascii"), size))
1112
        return self.dev.recvbulk(cmd, size)
1114
        return self.dev.recvbulk(cmd, size)
1113
 
1115
 
1114
 
1116
 
1115
class Dev(object):
1117
class Dev(object):
1116
    def __init__(self, idVendor, idProduct, idProductMask, logger):
1118
    def __init__(self, idVendor, idProduct, idProductMask, logger):
Line 1196... Line 1198...
1196
        data = self.dev.ctrl_transfer(0xc1, 0x00, 0, self.interface, size, self.timeout)
1198
        data = self.dev.ctrl_transfer(0xc1, 0x00, 0, self.interface, size, self.timeout)
1197
        if len(data) != size: raise ReceiveError("Requested size and read size don't match!")
1199
        if len(data) != size: raise ReceiveError("Requested size and read size don't match!")
1198
        return data
1200
        return data
1199
    
1201
    
1200
    def sendbulk(self, cmd, data):
1202
    def sendbulk(self, cmd, data):
1201
        size = self.dev.ctrl_transfer(0x42, 0x00, 0, self.bulkout.bEndpointAddress, cmd, self.timeout)
1203
        cmdsize = self.dev.ctrl_transfer(0x42, 0x00, 0, self.bulkout.bEndpointAddress, cmd, self.timeout)
1202
        if size != len(cmd):
1204
        if cmdsize != len(cmd):
1203
            raise SendError("Bulk send command could not be fully sent (%d of %d)!" % (size, len(cmd)))
1205
            raise SendError("Bulk send command could not be fully sent (%d of %d)!" % (cmdsize, len(cmd)))
1204
        size = self.bulkout.write(data, self.timeout)
1206
        size = self.bulkout.write(data, self.timeout)
1205
        if size != len(data):
1207
        if size != len(data):
1206
            raise SendError("Bulk data could not be fully sent (%d of %d)!" % (size, len(data)))
1208
            raise SendError("Bulk data could not be fully sent (%d of %d)!" % (size, len(data)))
1207
        return size
1209
        return size
1208
    
1210
    
1209
    def recvbulk(self, cmd, size):
1211
    def recvbulk(self, cmd, size):
1210
        size = self.dev.ctrl_transfer(0x42, 0x00, 0, self.bulkin.bEndpointAddress, cmd, self.timeout)
1212
        cmdsize = self.dev.ctrl_transfer(0x42, 0x00, 0, self.bulkin.bEndpointAddress, cmd, self.timeout)
1211
        if size != len(cmd):
1213
        if cmdsize != len(cmd):
1212
            raise ReceiveError("Bulk receive command could not be fully sent (%d of %d)!" % (size, len(cmd)))
1214
            raise ReceiveError("Bulk receive command could not be fully sent (%d of %d)!" % (cmdsize, len(cmd)))
1213
        data = self.bulkin.read(size, self.timeout)
1215
        data = self.bulkin.read(size, self.timeout)
1214
        if len(data) != size:
1216
        if len(data) != size:
1215
            raise SendError("Bulk data could not be fully received (%d of %d)!" % (len(cmd), size))
1217
            raise SendError("Bulk data could not be fully received (%d of %d)!" % (len(data), size))
1216
        return data
1218
        return data
1217
    
1219
    
1218
 
1220
 
1219
if __name__ == "__main__":
1221
if __name__ == "__main__":
1220
    from misc import Logger
1222
    from misc import Logger