› Foros › PlayStation 3 › Modchips y Softmods
nickieto escribió:Si se lo que has querido decir, pero lo que quiero saber yo, de dond epuedo bajar la version del port PSP que Deviante ha sacado pa testearla. Gracias
agalardi escribió:CaptainCPS-X escribió:He adjuntado un programa que escribí hace un rato (PSP FILE IO) para demostrar de manera simple como Abrir un archivo para escritura o lectura. Esto nos servirá para llevar un LOG de lo que ocurre mientras corre el PSPGroove.
Aqui tienen el código del main.c:
EDIT: Si se desea escribir en un archivo existente al final del mismo sin sobre-escribirlo se debe utilizar este flag "PSP_O_APPEND".
EDIT 2: He adjuntado la Revision 2 del "PSP FILE IO" y ahora maneja el inicio y salida mediante botones . Ademas le añadi mas informacion, etc.
EDIT 3: Revision 3 adjuntada. (Corregida la detección de fallos al abrir / escribir el archivo)
REV 3:/*
PSP FILE IO (REV 3)
Descripcion: Ejemplo de entrada y salida de archivos utilizando el PSPSDK
Por: CaptainCPS-X (2010)
Rev 1: No tiene manejo de salida.
Rev 2: Agregado el manejo de Inicio y de Salida usando botones (entre otros detalles).
Rev 3: Corregida la deteccion de fallos al abrir / escribir el archivo.
Tome de referencia esta pagina: http://www.psp-programming.com/forums/index.php?topic=68
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspiofilemgr.h>
#include <pspctrl.h>
#define printf pspDebugScreenPrintf
PSP_MODULE_INFO("pspfileio", 0x1000, 1, 1);
int flags = PSP_O_RDWR | PSP_O_CREAT ; // Flag de Lectura / Escritura y Crear archivo de no Existir.
SceMode mode = 0777; // Permiso CHMOD para todo tipo de accion.
const char file[] = "ms0:\\pspfile.txt"; // Archivo a escribir / leer
char fbuffer[256]; // Buffer que se usara para rellenar de texto.
void PSPFileIO(); // Prototipo de la funcion principal.
int bFinished = 0; // Variable para saber si se ha realizado la funcion principal.
int main(int argc, char *argv[]) {
// Iniciamos la pantalla para debug / depurar
pspDebugScreenInit();
// debug
printf("PSP FILE IO (REV. 3) - por CaptainCPS-X (2010) \n\n");
// debug
printf("Este programa abrira el archivo [ %s ] y si no existe lo creara en la Memory Stick del PSP. Luego escribira varias cadenas de texto como forma de prueba.\n\n", file);
printf("PRECIONA \"X\" PARA CONTINUAR...\n\n");
// Buffer data de botones
SceCtrlData pad_data;
// Loop atento a botones
for(;;) {
// Leemos el buffer de botones, por si acaso se ha precionado alguno
sceCtrlReadBufferPositive(&pad_data, 1);
// Si se ha precionado "X" realicamos la funcion principal
if(pad_data.Buttons & PSP_CTRL_CROSS)
{
// Si ya se realizo todo, continua el Loop
if(bFinished) continue;
// debug
printf("Iniciando funcion principal...\n\n");
// Funcion principal
PSPFileIO();
// debug
printf("PRECIONA \"O\" PARA VOLVER AL XBM...\n");
}
// Si se ha precionado "O" salimos del programa
if(pad_data.Buttons & PSP_CTRL_CIRCLE)
{
// debug
printf("Saliendo del programa...\n");
// Salir del programa
sceKernelExitGame();
}
}
return 0;
}
void PSPFileIO() {
// Abrimos el archivo y nos devuelve el ID
SceUID fp = sceIoOpen(file, flags, mode);
if(fp < 0) {
// Error al abrir / crear el archivo.
printf("Error al abrir / crear [ %s ].\n\n", file);
bFinished = 1;
return;
}
// debug
printf("[ %s ] abierto / creado correctamente.\n\n", file);
// Llenamos el buffer con una cadena de texto.
sprintf(fbuffer, "Hola Mundo!.\n");
// Escribimos el buffer al archivo y nos devuelve la cantidad de bytes escritos.
// debug
printf("Escribiendo: %s", fbuffer);
int flen = sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Llenamos el buffer con una cadena de texto nuevamente.
sprintf(fbuffer, "%d bytes escritos.\n", flen);
// Escribimos por ultima vez el buffer al archivo.
// debug
printf("Escribiendo: %s", fbuffer);
sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Cerramos el archivo
// debug
printf("\nCerrando archivo.\n\n");
sceIoClose(fp);
bFinished = 1;
}
REV 2:
[spoiler]/*
PSP FILE IO (REV 2)
Descripcion: Ejemplo de entrada y salida de archivos utilizando el PSPSDK
Por: CaptainCPS-X (13-sep-2010)
Rev 1: No tiene manejo de salida.
Rev 2: Agregado el manejo de Inicio y de Salida usando botones (entre otros detalles).
Tome de referencia esta pagina: http://www.psp-programming.com/forums/index.php?topic=68
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspiofilemgr.h>
#include <pspctrl.h>
#define printf pspDebugScreenPrintf
PSP_MODULE_INFO("pspfileio", 0x1000, 1, 1);
int flags = PSP_O_RDWR | PSP_O_CREAT ; // Flag de Lectura / Escritura y Crear archivo de no Existir.
SceMode mode = 0777; // Permiso CHMOD para todo tipo de accion.
const char file[] = "ms0:\\pspfile.txt"; // Archivo a escribir / leer
char fbuffer[256]; // Buffer que se usara para rellenar de texto.
void PSPFileIO(); // Prototipo de la funcion principal.
int bFinished = 0; // Variable para saber si se ha realizado la funcion principal.
int main(int argc, char *argv[]) {
// Iniciamos la pantalla para debug / depurar
pspDebugScreenInit();
// debug
printf("PSP FILE IO (REV. 2) - por CaptainCPS-X (2010) \n\n");
// debug
printf("Este programa abrira el archivo [ %s ] y si no existe lo creara en la Memory Stick del PSP. Luego escribira varias cadenas de texto como forma de prueba.\n\n", file);
printf("PRECIONA \"X\" PARA CONTINUAR...\n\n");
// Buffer data de botones
SceCtrlData pad_data;
// Loop atento a botones
for(;;) {
// Leemos el buffer de botones, por si acaso se ha precionado alguno
sceCtrlReadBufferPositive(&pad_data, 1);
// Si se ha precionado "X" realicamos la funcion principal
if(pad_data.Buttons & PSP_CTRL_CROSS)
{
// Si ya se realizo todo, continua el Loop
if(bFinished) continue;
// debug
printf("Iniciando funcion principal...\n\n");
// Funcion principal
PSPFileIO();
// debug
printf("Listo!...(PRECIONA \"O\" PARA VOLVER AL XBM.)\n");
}
// Si se ha precionado "O" salimos del programa
if(pad_data.Buttons & PSP_CTRL_CIRCLE)
{
// debug
printf("Saliendo del programa...\n");
// Salir del programa
sceKernelExitGame();
}
}
return 0;
}
void PSPFileIO() {
// Abrimos el archivo y nos devuelve el ID
SceUID fp = sceIoOpen(file, flags, mode);
if(!fp) {
// Error al abrir / crear el archivo.
printf("Error al abrir / crear [ %s ]\n", file);
bFinished = 1;
return;
}
// debug
printf("[ %s ] abierto / creado correctamente.\n\n", file);
// Llenamos el buffer con una cadena de texto.
sprintf(fbuffer, "Hola Mundo!.\n");
// Escribimos el buffer al archivo y nos devuelve la cantidad de bytes escritos.
// debug
printf("Escribiendo: %s", fbuffer);
int flen = sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Llenamos el buffer con una cadena de texto nuevamente.
sprintf(fbuffer, "%d bytes escritos.\n", flen);
// Escribimos por ultima vez el buffer al archivo.
// debug
printf("Escribiendo: %s", fbuffer);
sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Cerramos el archivo
// debug
printf("\nCerrando archivo.\n\n");
sceIoClose(fp);
bFinished = 1;
}
REV 1:/*
PSP FILE IO
Descripcion: Ejemplo de entrada y salida de archivos utilizando el PSPSDK
Por: CaptainCPS-X (13-sep-2010)
Nota: Luego de hacer todo el PSP no responde y hay que darle un hard reset. No se por que razon.
Tome de referencia esta pagina: http://www.psp-programming.com/forums/index.php?topic=68
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspiofilemgr.h>
#define printf pspDebugScreenPrintf
PSP_MODULE_INFO("pspfileio", 0x1000, 1, 1);
int flags = PSP_O_RDWR | PSP_O_CREAT ; // Flag de Lectura / Escritura y Crear archivo de no Existir.
SceMode mode = 0777; // Permiso CHMOD para todo tipo de accion.
char fbuffer[256]; // Buffer que se usara para rellenar de texto.
int main(int argc, char *argv[]) {
// Iniciamos la pantalla para debug / depurar
pspDebugScreenInit();
// Abrimos el archivo y nos devuelve el ID
SceUID fp = sceIoOpen("ms0:\\pspfile.txt", flags, mode);
if(!fp) {
// Error al abrir / crear el archivo.
printf("Error al abrir / crear el archivo.\n");
return 0;
}
// debug
printf("Archivo abierto / creado correctamente.\n\n");
// Llenamos el buffer con una cadena de texto.
sprintf(fbuffer, "Hola Mundo!.\n");
// Escribimos el buffer al archivo y nos devuelve la cantidad de bytes escritos.
// debug
printf("Escribiendo: %s", fbuffer);
int flen = sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Llenamos el buffer con una cadena de texto nuevamente.
sprintf(fbuffer, "%d bytes escritos.\n", flen);
// Escribimos por ultima vez el buffer al archivo.
// debug
printf("Escribiendo: %s", fbuffer);
sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Cerramos el archivo
// debug
printf("Cerrando archivo.\n\n");
sceIoClose(fp);
// debug
printf("Listo!.");
return 0;
}
Dentro del ZIP esta el binario PBP y el código fuente. Comente casi todas las lineas detalladamente y espero les sirva.
*CORREGIDO* - El único problema con mi programa es que se queda congelado al finalizar todo, no se por que y hay que hacerle reset al PSP para salir.
Saludos.
CaptainCPS-X, yo he creado una pequeña funcion para realizar los logs. No está muy depurada, ni tiene mucho control de errores, pero como es solamente para debugear un poco no importa demasiado. tiene cojones lo que me ha costado hacerla con lo poca cosa que es.#include <pspiofilemgr.h>
void milog(const char *cbuffer)
{
char buffer[64];
SceUID fd = sceIoOpen("ms0:/psg.log", PSP_O_WRONLY | PSP_O_CREAT, 0777);
sprintf(buffer, cbuffer);
sceIoWrite(fd, buffer, strlen(buffer));
sceIoClose(fd);
}
despues la estoy usando dentro de cada funcion para que en el fichero me quede una secuencia real y entender un poco mas como funciona todo esto.
creo que es muy sencillo cambiarla un poco para que añada la hora, etc.
de momento sigo tratando de entender la version r37, pero no estaría mal tener la ultima version ya que no lo veo actualizado en http://code.google.com/p/eol-psgroove/
por cierto, ¿a los maestros no os vendría bien poner algo así? seguro que a vosotros no os cuenta nada hacer algo 100 veces mejor que lo mio.
void milog(const char *cbuffer)
{
char buffer[64];
SceUID fd = sceIoOpen("ms0:/psg.log", PSP_O_WRONLY | PSP_O_APPEND | PSP_O_CREAT, 0777);
sprintf(buffer, cbuffer);
sceIoWrite(fd, buffer, strlen(buffer));
sceIoClose(fd);
}
start_hub
start_func
usb_thread
usb_configure
usb_send_request
hub_connect_port
usb_send_request
usb_send_request
usb_send_request
usb_send_request
usb_send_request
usb_send_request
usb_send_request
usb_send_request
usb_send_request
agalardi escribió:agalardi escribió:CaptainCPS-X escribió:He adjuntado un programa que escribí hace un rato (PSP FILE IO) para demostrar de manera simple como Abrir un archivo para escritura o lectura. Esto nos servirá para llevar un LOG de lo que ocurre mientras corre el PSPGroove.
Aqui tienen el código del main.c:
EDIT: Si se desea escribir en un archivo existente al final del mismo sin sobre-escribirlo se debe utilizar este flag "PSP_O_APPEND".
EDIT 2: He adjuntado la Revision 2 del "PSP FILE IO" y ahora maneja el inicio y salida mediante botones . Ademas le añadi mas informacion, etc.
EDIT 3: Revision 3 adjuntada. (Corregida la detección de fallos al abrir / escribir el archivo)
REV 3:/*
PSP FILE IO (REV 3)
Descripcion: Ejemplo de entrada y salida de archivos utilizando el PSPSDK
Por: CaptainCPS-X (2010)
Rev 1: No tiene manejo de salida.
Rev 2: Agregado el manejo de Inicio y de Salida usando botones (entre otros detalles).
Rev 3: Corregida la deteccion de fallos al abrir / escribir el archivo.
Tome de referencia esta pagina: http://www.psp-programming.com/forums/index.php?topic=68
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspiofilemgr.h>
#include <pspctrl.h>
#define printf pspDebugScreenPrintf
PSP_MODULE_INFO("pspfileio", 0x1000, 1, 1);
int flags = PSP_O_RDWR | PSP_O_CREAT ; // Flag de Lectura / Escritura y Crear archivo de no Existir.
SceMode mode = 0777; // Permiso CHMOD para todo tipo de accion.
const char file[] = "ms0:\\pspfile.txt"; // Archivo a escribir / leer
char fbuffer[256]; // Buffer que se usara para rellenar de texto.
void PSPFileIO(); // Prototipo de la funcion principal.
int bFinished = 0; // Variable para saber si se ha realizado la funcion principal.
int main(int argc, char *argv[]) {
// Iniciamos la pantalla para debug / depurar
pspDebugScreenInit();
// debug
printf("PSP FILE IO (REV. 3) - por CaptainCPS-X (2010) \n\n");
// debug
printf("Este programa abrira el archivo [ %s ] y si no existe lo creara en la Memory Stick del PSP. Luego escribira varias cadenas de texto como forma de prueba.\n\n", file);
printf("PRECIONA \"X\" PARA CONTINUAR...\n\n");
// Buffer data de botones
SceCtrlData pad_data;
// Loop atento a botones
for(;;) {
// Leemos el buffer de botones, por si acaso se ha precionado alguno
sceCtrlReadBufferPositive(&pad_data, 1);
// Si se ha precionado "X" realicamos la funcion principal
if(pad_data.Buttons & PSP_CTRL_CROSS)
{
// Si ya se realizo todo, continua el Loop
if(bFinished) continue;
// debug
printf("Iniciando funcion principal...\n\n");
// Funcion principal
PSPFileIO();
// debug
printf("PRECIONA \"O\" PARA VOLVER AL XBM...\n");
}
// Si se ha precionado "O" salimos del programa
if(pad_data.Buttons & PSP_CTRL_CIRCLE)
{
// debug
printf("Saliendo del programa...\n");
// Salir del programa
sceKernelExitGame();
}
}
return 0;
}
void PSPFileIO() {
// Abrimos el archivo y nos devuelve el ID
SceUID fp = sceIoOpen(file, flags, mode);
if(fp < 0) {
// Error al abrir / crear el archivo.
printf("Error al abrir / crear [ %s ].\n\n", file);
bFinished = 1;
return;
}
// debug
printf("[ %s ] abierto / creado correctamente.\n\n", file);
// Llenamos el buffer con una cadena de texto.
sprintf(fbuffer, "Hola Mundo!.\n");
// Escribimos el buffer al archivo y nos devuelve la cantidad de bytes escritos.
// debug
printf("Escribiendo: %s", fbuffer);
int flen = sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Llenamos el buffer con una cadena de texto nuevamente.
sprintf(fbuffer, "%d bytes escritos.\n", flen);
// Escribimos por ultima vez el buffer al archivo.
// debug
printf("Escribiendo: %s", fbuffer);
sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Cerramos el archivo
// debug
printf("\nCerrando archivo.\n\n");
sceIoClose(fp);
bFinished = 1;
}
REV 2:
[spoiler]/*
PSP FILE IO (REV 2)
Descripcion: Ejemplo de entrada y salida de archivos utilizando el PSPSDK
Por: CaptainCPS-X (13-sep-2010)
Rev 1: No tiene manejo de salida.
Rev 2: Agregado el manejo de Inicio y de Salida usando botones (entre otros detalles).
Tome de referencia esta pagina: http://www.psp-programming.com/forums/index.php?topic=68
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspiofilemgr.h>
#include <pspctrl.h>
#define printf pspDebugScreenPrintf
PSP_MODULE_INFO("pspfileio", 0x1000, 1, 1);
int flags = PSP_O_RDWR | PSP_O_CREAT ; // Flag de Lectura / Escritura y Crear archivo de no Existir.
SceMode mode = 0777; // Permiso CHMOD para todo tipo de accion.
const char file[] = "ms0:\\pspfile.txt"; // Archivo a escribir / leer
char fbuffer[256]; // Buffer que se usara para rellenar de texto.
void PSPFileIO(); // Prototipo de la funcion principal.
int bFinished = 0; // Variable para saber si se ha realizado la funcion principal.
int main(int argc, char *argv[]) {
// Iniciamos la pantalla para debug / depurar
pspDebugScreenInit();
// debug
printf("PSP FILE IO (REV. 2) - por CaptainCPS-X (2010) \n\n");
// debug
printf("Este programa abrira el archivo [ %s ] y si no existe lo creara en la Memory Stick del PSP. Luego escribira varias cadenas de texto como forma de prueba.\n\n", file);
printf("PRECIONA \"X\" PARA CONTINUAR...\n\n");
// Buffer data de botones
SceCtrlData pad_data;
// Loop atento a botones
for(;;) {
// Leemos el buffer de botones, por si acaso se ha precionado alguno
sceCtrlReadBufferPositive(&pad_data, 1);
// Si se ha precionado "X" realicamos la funcion principal
if(pad_data.Buttons & PSP_CTRL_CROSS)
{
// Si ya se realizo todo, continua el Loop
if(bFinished) continue;
// debug
printf("Iniciando funcion principal...\n\n");
// Funcion principal
PSPFileIO();
// debug
printf("Listo!...(PRECIONA \"O\" PARA VOLVER AL XBM.)\n");
}
// Si se ha precionado "O" salimos del programa
if(pad_data.Buttons & PSP_CTRL_CIRCLE)
{
// debug
printf("Saliendo del programa...\n");
// Salir del programa
sceKernelExitGame();
}
}
return 0;
}
void PSPFileIO() {
// Abrimos el archivo y nos devuelve el ID
SceUID fp = sceIoOpen(file, flags, mode);
if(!fp) {
// Error al abrir / crear el archivo.
printf("Error al abrir / crear [ %s ]\n", file);
bFinished = 1;
return;
}
// debug
printf("[ %s ] abierto / creado correctamente.\n\n", file);
// Llenamos el buffer con una cadena de texto.
sprintf(fbuffer, "Hola Mundo!.\n");
// Escribimos el buffer al archivo y nos devuelve la cantidad de bytes escritos.
// debug
printf("Escribiendo: %s", fbuffer);
int flen = sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Llenamos el buffer con una cadena de texto nuevamente.
sprintf(fbuffer, "%d bytes escritos.\n", flen);
// Escribimos por ultima vez el buffer al archivo.
// debug
printf("Escribiendo: %s", fbuffer);
sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Cerramos el archivo
// debug
printf("\nCerrando archivo.\n\n");
sceIoClose(fp);
bFinished = 1;
}
REV 1:/*
PSP FILE IO
Descripcion: Ejemplo de entrada y salida de archivos utilizando el PSPSDK
Por: CaptainCPS-X (13-sep-2010)
Nota: Luego de hacer todo el PSP no responde y hay que darle un hard reset. No se por que razon.
Tome de referencia esta pagina: http://www.psp-programming.com/forums/index.php?topic=68
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspiofilemgr.h>
#define printf pspDebugScreenPrintf
PSP_MODULE_INFO("pspfileio", 0x1000, 1, 1);
int flags = PSP_O_RDWR | PSP_O_CREAT ; // Flag de Lectura / Escritura y Crear archivo de no Existir.
SceMode mode = 0777; // Permiso CHMOD para todo tipo de accion.
char fbuffer[256]; // Buffer que se usara para rellenar de texto.
int main(int argc, char *argv[]) {
// Iniciamos la pantalla para debug / depurar
pspDebugScreenInit();
// Abrimos el archivo y nos devuelve el ID
SceUID fp = sceIoOpen("ms0:\\pspfile.txt", flags, mode);
if(!fp) {
// Error al abrir / crear el archivo.
printf("Error al abrir / crear el archivo.\n");
return 0;
}
// debug
printf("Archivo abierto / creado correctamente.\n\n");
// Llenamos el buffer con una cadena de texto.
sprintf(fbuffer, "Hola Mundo!.\n");
// Escribimos el buffer al archivo y nos devuelve la cantidad de bytes escritos.
// debug
printf("Escribiendo: %s", fbuffer);
int flen = sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Llenamos el buffer con una cadena de texto nuevamente.
sprintf(fbuffer, "%d bytes escritos.\n", flen);
// Escribimos por ultima vez el buffer al archivo.
// debug
printf("Escribiendo: %s", fbuffer);
sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Cerramos el archivo
// debug
printf("Cerrando archivo.\n\n");
sceIoClose(fp);
// debug
printf("Listo!.");
return 0;
}
Dentro del ZIP esta el binario PBP y el código fuente. Comente casi todas las lineas detalladamente y espero les sirva.
*CORREGIDO* - El único problema con mi programa es que se queda congelado al finalizar todo, no se por que y hay que hacerle reset al PSP para salir.
Saludos.
CaptainCPS-X, yo he creado una pequeña funcion para realizar los logs. No está muy depurada, ni tiene mucho control de errores, pero como es solamente para debugear un poco no importa demasiado. tiene cojones lo que me ha costado hacerla con lo poca cosa que es.#include <pspiofilemgr.h>
void milog(const char *cbuffer)
{
char buffer[64];
SceUID fd = sceIoOpen("ms0:/psg.log", PSP_O_WRONLY | PSP_O_CREAT, 0777);
sprintf(buffer, cbuffer);
sceIoWrite(fd, buffer, strlen(buffer));
sceIoClose(fd);
}
despues la estoy usando dentro de cada funcion para que en el fichero me quede una secuencia real y entender un poco mas como funciona todo esto.
creo que es muy sencillo cambiarla un poco para que añada la hora, etc.
de momento sigo tratando de entender la version r37, pero no estaría mal tener la ultima version ya que no lo veo actualizado en http://code.google.com/p/eol-psgroove/
por cierto, ¿a los maestros no os vendría bien poner algo así? seguro que a vosotros no os cuenta nada hacer algo 100 veces mejor que lo mio.
[/spoiler]
Entre lo oxidado que estoy (que es mucho) y el poco tiempo que puedo invertirle no consigo avanzar casi nada.
Como comente anteriormente trato de crear un log, al principio muy muy basico y luego ya ire detallando más, para entender el funcionamiento (aunque poco a poco ya me voy enterando).
la funcion es la siguiente y la he llamado al comienzo de cada funcion o procedimiento definido en hub.c para ver la secuencia:void milog(const char *cbuffer)
{
char buffer[64];
SceUID fd = sceIoOpen("ms0:/psg.log", PSP_O_WRONLY | PSP_O_APPEND | PSP_O_CREAT, 0777);
sprintf(buffer, cbuffer);
sceIoWrite(fd, buffer, strlen(buffer));
sceIoClose(fd);
}
me encuentro con algo completamente inesperado: las funciones callback no aparecen en el log.
de momento solo lo estaba probando conectando la psp al PC y registrando la secuencia y he obtenido:start_hub
start_func
usb_thread
usb_configure
usb_send_request
hub_connect_port
usb_send_request
usb_send_request
usb_send_request
usb_send_request
usb_send_request
usb_send_request
usb_send_request
usb_send_request
usb_send_request
pero como es obvio faltan todas las callback.
alguno teneis idea de porque no aparecen?
agalardi escribió:[spoiler]agalardi escribió:CaptainCPS-X escribió:He adjuntado un programa que escribí hace un rato (PSP FILE IO) para demostrar de manera simple como Abrir un archivo para escritura o lectura. Esto nos servirá para llevar un LOG de lo que ocurre mientras corre el PSPGroove.
Aqui tienen el código del main.c:
EDIT: Si se desea escribir en un archivo existente al final del mismo sin sobre-escribirlo se debe utilizar este flag "PSP_O_APPEND".
EDIT 2: He adjuntado la Revision 2 del "PSP FILE IO" y ahora maneja el inicio y salida mediante botones . Ademas le añadi mas informacion, etc.
EDIT 3: Revision 3 adjuntada. (Corregida la detección de fallos al abrir / escribir el archivo)
REV 3:/*
PSP FILE IO (REV 3)
Descripcion: Ejemplo de entrada y salida de archivos utilizando el PSPSDK
Por: CaptainCPS-X (2010)
Rev 1: No tiene manejo de salida.
Rev 2: Agregado el manejo de Inicio y de Salida usando botones (entre otros detalles).
Rev 3: Corregida la deteccion de fallos al abrir / escribir el archivo.
Tome de referencia esta pagina: http://www.psp-programming.com/forums/index.php?topic=68
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspiofilemgr.h>
#include <pspctrl.h>
#define printf pspDebugScreenPrintf
PSP_MODULE_INFO("pspfileio", 0x1000, 1, 1);
int flags = PSP_O_RDWR | PSP_O_CREAT ; // Flag de Lectura / Escritura y Crear archivo de no Existir.
SceMode mode = 0777; // Permiso CHMOD para todo tipo de accion.
const char file[] = "ms0:\\pspfile.txt"; // Archivo a escribir / leer
char fbuffer[256]; // Buffer que se usara para rellenar de texto.
void PSPFileIO(); // Prototipo de la funcion principal.
int bFinished = 0; // Variable para saber si se ha realizado la funcion principal.
int main(int argc, char *argv[]) {
// Iniciamos la pantalla para debug / depurar
pspDebugScreenInit();
// debug
printf("PSP FILE IO (REV. 3) - por CaptainCPS-X (2010) \n\n");
// debug
printf("Este programa abrira el archivo [ %s ] y si no existe lo creara en la Memory Stick del PSP. Luego escribira varias cadenas de texto como forma de prueba.\n\n", file);
printf("PRECIONA \"X\" PARA CONTINUAR...\n\n");
// Buffer data de botones
SceCtrlData pad_data;
// Loop atento a botones
for(;;) {
// Leemos el buffer de botones, por si acaso se ha precionado alguno
sceCtrlReadBufferPositive(&pad_data, 1);
// Si se ha precionado "X" realicamos la funcion principal
if(pad_data.Buttons & PSP_CTRL_CROSS)
{
// Si ya se realizo todo, continua el Loop
if(bFinished) continue;
// debug
printf("Iniciando funcion principal...\n\n");
// Funcion principal
PSPFileIO();
// debug
printf("PRECIONA \"O\" PARA VOLVER AL XBM...\n");
}
// Si se ha precionado "O" salimos del programa
if(pad_data.Buttons & PSP_CTRL_CIRCLE)
{
// debug
printf("Saliendo del programa...\n");
// Salir del programa
sceKernelExitGame();
}
}
return 0;
}
void PSPFileIO() {
// Abrimos el archivo y nos devuelve el ID
SceUID fp = sceIoOpen(file, flags, mode);
if(fp < 0) {
// Error al abrir / crear el archivo.
printf("Error al abrir / crear [ %s ].\n\n", file);
bFinished = 1;
return;
}
// debug
printf("[ %s ] abierto / creado correctamente.\n\n", file);
// Llenamos el buffer con una cadena de texto.
sprintf(fbuffer, "Hola Mundo!.\n");
// Escribimos el buffer al archivo y nos devuelve la cantidad de bytes escritos.
// debug
printf("Escribiendo: %s", fbuffer);
int flen = sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Llenamos el buffer con una cadena de texto nuevamente.
sprintf(fbuffer, "%d bytes escritos.\n", flen);
// Escribimos por ultima vez el buffer al archivo.
// debug
printf("Escribiendo: %s", fbuffer);
sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Cerramos el archivo
// debug
printf("\nCerrando archivo.\n\n");
sceIoClose(fp);
bFinished = 1;
}
REV 2:
[spoiler]/*
PSP FILE IO (REV 2)
Descripcion: Ejemplo de entrada y salida de archivos utilizando el PSPSDK
Por: CaptainCPS-X (13-sep-2010)
Rev 1: No tiene manejo de salida.
Rev 2: Agregado el manejo de Inicio y de Salida usando botones (entre otros detalles).
Tome de referencia esta pagina: http://www.psp-programming.com/forums/index.php?topic=68
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspiofilemgr.h>
#include <pspctrl.h>
#define printf pspDebugScreenPrintf
PSP_MODULE_INFO("pspfileio", 0x1000, 1, 1);
int flags = PSP_O_RDWR | PSP_O_CREAT ; // Flag de Lectura / Escritura y Crear archivo de no Existir.
SceMode mode = 0777; // Permiso CHMOD para todo tipo de accion.
const char file[] = "ms0:\\pspfile.txt"; // Archivo a escribir / leer
char fbuffer[256]; // Buffer que se usara para rellenar de texto.
void PSPFileIO(); // Prototipo de la funcion principal.
int bFinished = 0; // Variable para saber si se ha realizado la funcion principal.
int main(int argc, char *argv[]) {
// Iniciamos la pantalla para debug / depurar
pspDebugScreenInit();
// debug
printf("PSP FILE IO (REV. 2) - por CaptainCPS-X (2010) \n\n");
// debug
printf("Este programa abrira el archivo [ %s ] y si no existe lo creara en la Memory Stick del PSP. Luego escribira varias cadenas de texto como forma de prueba.\n\n", file);
printf("PRECIONA \"X\" PARA CONTINUAR...\n\n");
// Buffer data de botones
SceCtrlData pad_data;
// Loop atento a botones
for(;;) {
// Leemos el buffer de botones, por si acaso se ha precionado alguno
sceCtrlReadBufferPositive(&pad_data, 1);
// Si se ha precionado "X" realicamos la funcion principal
if(pad_data.Buttons & PSP_CTRL_CROSS)
{
// Si ya se realizo todo, continua el Loop
if(bFinished) continue;
// debug
printf("Iniciando funcion principal...\n\n");
// Funcion principal
PSPFileIO();
// debug
printf("Listo!...(PRECIONA \"O\" PARA VOLVER AL XBM.)\n");
}
// Si se ha precionado "O" salimos del programa
if(pad_data.Buttons & PSP_CTRL_CIRCLE)
{
// debug
printf("Saliendo del programa...\n");
// Salir del programa
sceKernelExitGame();
}
}
return 0;
}
void PSPFileIO() {
// Abrimos el archivo y nos devuelve el ID
SceUID fp = sceIoOpen(file, flags, mode);
if(!fp) {
// Error al abrir / crear el archivo.
printf("Error al abrir / crear [ %s ]\n", file);
bFinished = 1;
return;
}
// debug
printf("[ %s ] abierto / creado correctamente.\n\n", file);
// Llenamos el buffer con una cadena de texto.
sprintf(fbuffer, "Hola Mundo!.\n");
// Escribimos el buffer al archivo y nos devuelve la cantidad de bytes escritos.
// debug
printf("Escribiendo: %s", fbuffer);
int flen = sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Llenamos el buffer con una cadena de texto nuevamente.
sprintf(fbuffer, "%d bytes escritos.\n", flen);
// Escribimos por ultima vez el buffer al archivo.
// debug
printf("Escribiendo: %s", fbuffer);
sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Cerramos el archivo
// debug
printf("\nCerrando archivo.\n\n");
sceIoClose(fp);
bFinished = 1;
}
REV 1:/*
PSP FILE IO
Descripcion: Ejemplo de entrada y salida de archivos utilizando el PSPSDK
Por: CaptainCPS-X (13-sep-2010)
Nota: Luego de hacer todo el PSP no responde y hay que darle un hard reset. No se por que razon.
Tome de referencia esta pagina: http://www.psp-programming.com/forums/index.php?topic=68
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspiofilemgr.h>
#define printf pspDebugScreenPrintf
PSP_MODULE_INFO("pspfileio", 0x1000, 1, 1);
int flags = PSP_O_RDWR | PSP_O_CREAT ; // Flag de Lectura / Escritura y Crear archivo de no Existir.
SceMode mode = 0777; // Permiso CHMOD para todo tipo de accion.
char fbuffer[256]; // Buffer que se usara para rellenar de texto.
int main(int argc, char *argv[]) {
// Iniciamos la pantalla para debug / depurar
pspDebugScreenInit();
// Abrimos el archivo y nos devuelve el ID
SceUID fp = sceIoOpen("ms0:\\pspfile.txt", flags, mode);
if(!fp) {
// Error al abrir / crear el archivo.
printf("Error al abrir / crear el archivo.\n");
return 0;
}
// debug
printf("Archivo abierto / creado correctamente.\n\n");
// Llenamos el buffer con una cadena de texto.
sprintf(fbuffer, "Hola Mundo!.\n");
// Escribimos el buffer al archivo y nos devuelve la cantidad de bytes escritos.
// debug
printf("Escribiendo: %s", fbuffer);
int flen = sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Llenamos el buffer con una cadena de texto nuevamente.
sprintf(fbuffer, "%d bytes escritos.\n", flen);
// Escribimos por ultima vez el buffer al archivo.
// debug
printf("Escribiendo: %s", fbuffer);
sceIoWrite(fp, fbuffer, strlen(fbuffer));
// Cerramos el archivo
// debug
printf("Cerrando archivo.\n\n");
sceIoClose(fp);
// debug
printf("Listo!.");
return 0;
}
Dentro del ZIP esta el binario PBP y el código fuente. Comente casi todas las lineas detalladamente y espero les sirva.
*CORREGIDO* - El único problema con mi programa es que se queda congelado al finalizar todo, no se por que y hay que hacerle reset al PSP para salir.
Saludos.
CaptainCPS-X, yo he creado una pequeña funcion para realizar los logs. No está muy depurada, ni tiene mucho control de errores, pero como es solamente para debugear un poco no importa demasiado. tiene cojones lo que me ha costado hacerla con lo poca cosa que es.#include <pspiofilemgr.h>
void milog(const char *cbuffer)
{
char buffer[64];
SceUID fd = sceIoOpen("ms0:/psg.log", PSP_O_WRONLY | PSP_O_CREAT, 0777);
sprintf(buffer, cbuffer);
sceIoWrite(fd, buffer, strlen(buffer));
sceIoClose(fd);
}
despues la estoy usando dentro de cada funcion para que en el fichero me quede una secuencia real y entender un poco mas como funciona todo esto.
creo que es muy sencillo cambiarla un poco para que añada la hora, etc.
de momento sigo tratando de entender la version r37, pero no estaría mal tener la ultima version ya que no lo veo actualizado en http://code.google.com/p/eol-psgroove/
por cierto, ¿a los maestros no os vendría bien poner algo así? seguro que a vosotros no os cuenta nada hacer algo 100 veces mejor que lo mio.
Entre lo oxidado que estoy (que es mucho) y el poco tiempo que puedo invertirle no consigo avanzar casi nada.
Como comente anteriormente trato de crear un log, al principio muy muy basico y luego ya ire detallando más, para entender el funcionamiento (aunque poco a poco ya me voy enterando).
la funcion es la siguiente y la he llamado al comienzo de cada funcion o procedimiento definido en hub.c para ver la secuencia:void milog(const char *cbuffer)
{
char buffer[64];
SceUID fd = sceIoOpen("ms0:/psg.log", PSP_O_WRONLY | PSP_O_APPEND | PSP_O_CREAT, 0777);
sprintf(buffer, cbuffer);
sceIoWrite(fd, buffer, strlen(buffer));
sceIoClose(fd);
}
me encuentro con algo completamente inesperado: las funciones callback no aparecen en el log.
de momento solo lo estaba probando conectando la psp al PC y registrando la secuencia y he obtenido:start_hub
start_func
usb_thread
usb_configure
usb_send_request
hub_connect_port
usb_send_request
usb_send_request
usb_send_request
usb_send_request
usb_send_request
usb_send_request
usb_send_request
usb_send_request
usb_send_request
pero como es obvio faltan todas las callback.
alguno teneis idea de porque no aparecen?
SceUID fd = sceIoOpen("ms0:/psg.log", PSP_O_WRONLY | PSP_O_APPEND | PSP_O_CREAT, 0777);
void milog(const char *cbuffer)
{
char buffer[64];
sprintf(buffer, cbuffer);
sceIoWrite(fd, buffer, strlen(buffer));
}
sceIoClose(fd);
/* States for the state machine */
enum PsfreedomState {
INIT,
HUB_READY,
DEVICE1_WAIT_READY,
DEVICE1_READY,
DEVICE1_WAIT_DISCONNECT,
DEVICE1_DISCONNECTED,
DEVICE2_WAIT_READY,
DEVICE2_READY,
DEVICE2_WAIT_DISCONNECT,
DEVICE2_DISCONNECTED,
DEVICE3_WAIT_READY,
DEVICE3_READY,
DEVICE3_WAIT_DISCONNECT,
DEVICE3_DISCONNECTED,
DEVICE4_WAIT_READY,
DEVICE4_READY,
DEVICE4_WAIT_DISCONNECT,
DEVICE4_DISCONNECTED,
DEVICE5_WAIT_READY,
DEVICE5_CHALLENGED,
DEVICE5_READY,
DEVICE5_WAIT_DISCONNECT,
DEVICE5_DISCONNECTED,
DEVICE6_WAIT_READY,
DEVICE6_READY,
DONE,
};
#define STATUS_STR(s) ( \
s==INIT?"INIT": \
s==HUB_READY?"HUB_READY": \
s==DEVICE1_WAIT_READY?"DEVICE1_WAIT_READY": \
s==DEVICE1_READY?"DEVICE1_READY": \
s==DEVICE1_WAIT_DISCONNECT?"DEVICE1_WAIT_DISCONNECT": \
s==DEVICE1_DISCONNECTED?"DEVICE1_DISCONNECTED": \
s==DEVICE2_WAIT_READY?"DEVICE2_WAIT_READY": \
s==DEVICE2_READY?"DEVICE2_READY": \
s==DEVICE2_WAIT_DISCONNECT?"DEVICE2_WAIT_DISCONNECT": \
s==DEVICE2_DISCONNECTED?"DEVICE2_DISCONNECTED": \
s==DEVICE3_WAIT_READY?"DEVICE3_WAIT_READY": \
s==DEVICE3_READY?"DEVICE3_READY": \
s==DEVICE3_WAIT_DISCONNECT?"DEVICE3_WAIT_DISCONNECT": \
s==DEVICE3_DISCONNECTED?"DEVICE3_DISCONNECTED": \
s==DEVICE4_WAIT_READY?"DEVICE4_WAIT_READY": \
s==DEVICE4_READY?"DEVICE4_READY": \
s==DEVICE4_WAIT_DISCONNECT?"DEVICE4_WAIT_DISCONNECT": \
s==DEVICE4_DISCONNECTED?"DEVICE4_DISCONNECTED": \
s==DEVICE5_WAIT_READY?"DEVICE5_WAIT_READY": \
s==DEVICE5_CHALLENGED?"DEVICE5_CHALLENGED": \
s==DEVICE5_READY?"DEVICE5_READY": \
s==DEVICE5_WAIT_DISCONNECT?"DEVICE5_WAIT_DISCONNECT": \
s==DEVICE5_DISCONNECTED?"DEVICE5_DISCONNECTED": \
s==DEVICE6_WAIT_READY?"DEVICE6_WAIT_READY": \
s==DEVICE6_READY?"DEVICE6_READY": \
s==DONE?"DONE": \
"UNKNOWN_STATE")
/* User-friendly string for the request */
#define REQUEST_STR(r) ( \
r==0x8006?"GET_DESCRIPTOR": \
r==0xa006?"GET_HUB_DESCRIPTOR": \
r==0x0009?"SET_CONFIGURATION": \
r==0x2303?"SET_PORT_FEATURE": \
r==0xa300?"GET_PORT_STATUS": \
r==0x2301?"CLEAR_PORT_FEATURE": \
r==0x010B?"SET_INTERFACE": \
r==0x21AA?"FREEDOM": \
"UNKNOWN")
#include "hub.h"
#include "psfreedom_machine.c"
/* Out device structure */
struct psfreedom_device {
spinlock_t lock;
struct usb_gadget *gadget;
/* for control responses */
struct usb_request *req;
/* for hub interrupts */
struct usb_request *hub_req;
/* The hub uses a non standard ep2in */
struct usb_ep *hub_ep;
/* BULK IN for the JIG */
struct usb_ep *in_ep;
/* BULK OUT for the JIG */
struct usb_ep *out_ep;
/* status of the state machine */
enum PsfreedomState status;
/* The port to switch to after a delay */
int switch_to_port_delayed;
/* Received length of the JIG challenge */
int challenge_len;
/* Sent length of the JIG response */
int response_len;
/* Hub port status/change */
struct hub_port hub_ports[6];
/* Currently enabled port on the hub (0 == hub) */
unsigned int current_port;
/* The address of all ports (0 == hub) */
u8 port_address[7];
/* The port1 configuration descriptor. dynamically loaded from procfs */
u8 *port1_config_desc;
unsigned int port1_config_desc_size;
/* /proc FS data */
struct proc_dir_entry *proc_dir;
struct proc_dir_entry *proc_status_entry;
struct proc_dir_entry *proc_version_entry;
struct proc_dir_entry *proc_payload_entry;
struct proc_dir_entry *proc_shellcode_entry;
};
/* Undef these if it gets defined by the controller's include in
psfreedom_machine.c */
#ifdef DBG
# undef DBG
#endif
#ifdef VDBG
# undef VDBG
#endif
#ifdef INFO
# undef INFO
#endif
#ifdef ERROR
# undef ERROR
#endif
#define INFO(d, fmt, args...) \
dev_info(&(d)->gadget->dev , fmt , ## args)
#define ERROR(d, fmt, args...) \
dev_err(&(d)->gadget->dev , fmt , ## args)
#define DBG(d, fmt, args...) \
dev_dbg(&(d)->gadget->dev , fmt , ## args)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
#define VDBG(d, fmt, args...) \
dev_vdbg(&(d)->gadget->dev , fmt , ## args)
#else
#define VDBG DBG
#endif
static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length);
static void free_ep_req(struct usb_ep *ep, struct usb_request *req);
/* Timer functions and macro to run the state machine */
static int timer_added = 0;
static struct timer_list psfreedom_state_machine_timer;
#define SET_TIMER(ms) DBG (dev, "Setting timer to %dms\n", ms); \
mod_timer (&psfreedom_state_machine_timer, jiffies + msecs_to_jiffies(ms))
#include "hub.c"
#include "psfreedom_devices.c"
static void psfreedom_state_machine_timeout(unsigned long data)
{
struct usb_gadget *gadget = (struct usb_gadget *)data;
struct psfreedom_device *dev = get_gadget_data (gadget);
unsigned long flags;
spin_lock_irqsave (&dev->lock, flags);
DBG (dev, "Timer fired, status is %s\n", STATUS_STR (dev->status));
/* We need to delay switching the address because otherwise we will respond
to the request (that triggered the port switch) with address 0. So we need
to reply with the hub's address, THEN switch to 0.
*/
if (dev->switch_to_port_delayed >= 0)
switch_to_port (dev, dev->switch_to_port_delayed);
dev->switch_to_port_delayed = -1;
switch (dev->status) {
case HUB_READY:
dev->status = DEVICE1_WAIT_READY;
hub_connect_port (dev, 1);
break;
case DEVICE1_READY:
dev->status = DEVICE2_WAIT_READY;
hub_connect_port (dev, 2);
break;
case DEVICE2_READY:
dev->status = DEVICE3_WAIT_READY;
hub_connect_port (dev, 3);
break;
case DEVICE3_READY:
dev->status = DEVICE2_WAIT_DISCONNECT;
hub_disconnect_port (dev, 2);
break;
case DEVICE2_DISCONNECTED:
dev->status = DEVICE4_WAIT_READY;
hub_connect_port (dev, 4);
break;
case DEVICE4_READY:
dev->status = DEVICE5_WAIT_READY;
hub_connect_port (dev, 5);
break;
case DEVICE5_CHALLENGED:
jig_response_send (dev, NULL);
break;
case DEVICE5_READY:
dev->status = DEVICE3_WAIT_DISCONNECT;
hub_disconnect_port (dev, 3);
break;
case DEVICE3_DISCONNECTED:
dev->status = DEVICE5_WAIT_DISCONNECT;
hub_disconnect_port (dev, 5);
break;
case DEVICE5_DISCONNECTED:
dev->status = DEVICE4_WAIT_DISCONNECT;
hub_disconnect_port (dev, 4);
break;
case DEVICE4_DISCONNECTED:
dev->status = DEVICE1_WAIT_DISCONNECT;
hub_disconnect_port (dev, 1);
break;
case DEVICE1_DISCONNECTED:
dev->status = DEVICE6_WAIT_READY;
hub_connect_port (dev, 6);
break;
case DEVICE6_READY:
dev->status = DONE;
INFO (dev, "Congratulations, worked!");
del_timer (&psfreedom_state_machine_timer);
timer_added = 0;
break;
default:
break;
}
spin_unlock_irqrestore (&dev->lock, flags);
}
static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length)
{
struct usb_request *req;
req = usb_ep_alloc_request(ep, GFP_ATOMIC);
if (req) {
req->length = length;
req->buf = kmalloc(length, GFP_ATOMIC);
if (!req->buf) {
usb_ep_free_request(ep, req);
req = NULL;
}
}
return req;
}
static void free_ep_req(struct usb_ep *ep, struct usb_request *req)
{
kfree(req->buf);
usb_ep_free_request(ep, req);
}
static void psfreedom_disconnect (struct usb_gadget *gadget)
{
struct psfreedom_device *dev = get_gadget_data (gadget);
unsigned long flags;
int i;
spin_lock_irqsave (&dev->lock, flags);
INFO (dev, "Got disconnected\n");
/* Reinitialize all device variables*/
dev->challenge_len = 0;
dev->response_len = 0;
dev->current_port = 0;
for (i = 0; i < 6; i++)
dev->hub_ports[i].status = dev->hub_ports[i].change = 0;
for (i = 0; i < 7; i++)
dev->port_address[i] = 0;
hub_disconnect (gadget);
devices_disconnect (gadget);
if (timer_added)
del_timer (&psfreedom_state_machine_timer);
timer_added = 0;
dev->switch_to_port_delayed = -1;
dev->status = INIT;
spin_unlock_irqrestore (&dev->lock, flags);
}
static void psfreedom_setup_complete(struct usb_ep *ep, struct usb_request *req)
{
struct psfreedom_device *dev = ep->driver_data;
unsigned long flags;
spin_lock_irqsave (&dev->lock, flags);
if (req->status || req->actual != req->length) {
struct psfreedom_device * dev = (struct psfreedom_device *) ep->driver_data;
DBG(dev, "%s setup complete FAIL --> %d, %d/%d\n",
STATUS_STR (dev->status), req->status, req->actual, req->length);
} else {
VDBG(dev, "%s setup complete SUCCESS --> %d, %d/%d\n",
STATUS_STR (dev->status), req->status, req->actual, req->length);
}
spin_unlock_irqrestore (&dev->lock, flags);
}
/*
* The setup() callback implements all the ep0 functionality that's
* not handled lower down, in hardware or the hardware driver (like
* device and endpoint feature flags, and their status). It's all
* housekeeping for the gadget function we're implementing. Most of
* the work is in config-specific setup.
*/
static int psfreedom_setup(struct usb_gadget *gadget,
const struct usb_ctrlrequest *ctrl)
{
struct psfreedom_device *dev = get_gadget_data(gadget);
struct usb_request *req = dev->req;
int value = -EOPNOTSUPP;
u16 w_index = le16_to_cpu(ctrl->wIndex);
u16 w_value = le16_to_cpu(ctrl->wValue);
u16 w_length = le16_to_cpu(ctrl->wLength);
u8 address = psfreedom_get_address (dev->gadget);
unsigned long flags;
u16 request = (ctrl->bRequestType << 8) | ctrl->bRequest;
spin_lock_irqsave (&dev->lock, flags);
VDBG (dev, "Setup called %d (%d) -- %d -- %d. Myaddr :%d\n", ctrl->bRequest,
ctrl->bRequestType, w_value, w_index, address);
req->zero = 0;
/* Enable the timer if it's not already enabled */
if (timer_added == 0)
add_timer (&psfreedom_state_machine_timer);
timer_added = 1;
/* Set the address of the port */
if (address)
dev->port_address[dev->current_port] = address;
/* Setup the hub or the devices */
if (dev->current_port == 0)
value = hub_setup (gadget, ctrl, request, w_index, w_value, w_length);
else
value = devices_setup (gadget, ctrl, request, w_index, w_value, w_length);
DBG (dev, "%s Setup called %s (%d - %d) -> %d (w_length=%d)\n",
STATUS_STR (dev->status), REQUEST_STR (request), w_value, w_index,
value, w_length);
/* respond with data transfer before status phase? */
if (value >= 0) {
req->length = value;
req->zero = value < w_length;
value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
if (value < 0) {
DBG(dev, "ep_queue --> %d\n", value);
req->status = 0;
spin_unlock_irqrestore (&dev->lock, flags);
psfreedom_setup_complete(gadget->ep0, req);
return value;
}
}
spin_unlock_irqrestore (&dev->lock, flags);
/* device either stalls (value < 0) or reports success */
return value;
}
int proc_shellcode_read(char *buffer, char **start, off_t offset, int count,
int *eof, void *user_data)
{
struct psfreedom_device *dev = user_data;
unsigned long flags;
INFO (dev, "proc_shellcode_read (/proc/%s/%s) called. count %d."
"Offset 0x%p - 0x%p\n",
PROC_DIR_NAME, PROC_PAYLOAD_NAME, count,
(void *)offset, (void *)(offset + count));
spin_lock_irqsave (&dev->lock, flags);
if (offset < 40) {
/* fill the buffer, return the buffer size */
memcpy(buffer, jig_response + 24 + offset, 40 - offset);
}
*eof = 1;
spin_unlock_irqrestore (&dev->lock, flags);
return offset < 40 ? 40 - offset: 0;
}
int proc_shellcode_write(struct file *file, const char *buffer,
unsigned long count, void *user_data)
{
struct psfreedom_device *dev = user_data;
unsigned long flags;
INFO (dev, "proc_shellcode_write (/proc/%s/%s) called. count %lu\n",
PROC_DIR_NAME, PROC_SHELLCODE_NAME, count);
if (count != 40) {
ERROR (dev, "Shellcode must be 40 bytes long! Received %lu bytes\n", count);
return -EFAULT;
}
spin_lock_irqsave (&dev->lock, flags);
DBG (dev, "Loading shellcode. Size 40\n");
if (copy_from_user(jig_response + 24, buffer, count)) {
spin_unlock_irqrestore (&dev->lock, flags);
return -EFAULT;
}
spin_unlock_irqrestore (&dev->lock, flags);
return count;
}
int proc_payload_read(char *buffer, char **start, off_t offset, int count,
int *eof, void *user_data)
{
struct psfreedom_device *dev = user_data;
unsigned int len;
unsigned long flags;
spin_lock_irqsave (&dev->lock, flags);
INFO (dev, "proc_payload_read (/proc/%s/%s) called. count %d."
"Offset 0x%p - 0x%p\n",
PROC_DIR_NAME, PROC_PAYLOAD_NAME, count,
(void *)offset, (void *)(offset + count));
len = dev->port1_config_desc_size - sizeof(port1_config_desc_prefix);
if (len > offset)
count = min ((int) (len - offset), count);
else
count = 0;
DBG (dev, "Length is %d. Sending %d\n", len, count);
/* fill the buffer, return the buffer size */
if (count)
memcpy(buffer, dev->port1_config_desc + offset + \
sizeof(port1_config_desc_prefix), count);
else
*eof = 1;
*start = buffer;
spin_unlock_irqrestore (&dev->lock, flags);
return count;
}
int proc_payload_write(struct file *file, const char *buffer,
unsigned long count, void *user_data)
{
struct psfreedom_device *dev = user_data;
u8 *new_config = NULL;
unsigned int new_size = 0;
unsigned int prefix_size = sizeof(port1_config_desc_prefix);
unsigned long flags;
INFO (dev, "proc_payload_write (/proc/%s/%s) called. count %lu\n",
PROC_DIR_NAME, PROC_PAYLOAD_NAME, count);
new_size = count + prefix_size;
new_config = kmalloc(new_size, GFP_KERNEL);
memcpy(new_config, port1_config_desc_prefix, prefix_size);
if (copy_from_user(new_config + prefix_size, buffer, count)) {
kfree (new_config);
return -EFAULT;
}
spin_lock_irqsave (&dev->lock, flags);
if (dev->port1_config_desc)
kfree(dev->port1_config_desc);
dev->port1_config_desc = new_config;
dev->port1_config_desc_size = new_size;
spin_unlock_irqrestore (&dev->lock, flags);
return count;
}
int proc_version_read(char *buffer, char **start, off_t offset, int count,
int *eof, void *user_data)
{
struct psfreedom_device *dev = user_data;
VDBG (dev, "proc_version_read (/proc/%s/%s) called. count %d\n",
PROC_DIR_NAME, PROC_VERSION_NAME, count);
*eof = 1;
/* fill the buffer, return the buffer size */
return sprintf (buffer + offset, "%s\n", PSFREEDOM_VERSION);
}
int proc_status_read(char *buffer, char **start, off_t offset, int count,
int *eof, void *user_data)
{
struct psfreedom_device *dev = user_data;
unsigned int len;
unsigned long flags;
spin_lock_irqsave (&dev->lock, flags);
VDBG (dev, "proc_status_read (/proc/%s/%s) called. count %d\n",
PROC_DIR_NAME, PROC_STATUS_NAME, count);
*eof = 1;
/* fill the buffer, return the buffer size */
len = sprintf (buffer + offset, "%s\n", STATUS_STR (dev->status));
spin_unlock_irqrestore (&dev->lock, flags);
return len;
}
static void create_proc_fs (struct psfreedom_device *dev,
struct proc_dir_entry **entry, char *procfs_filename,
read_proc_t read_proc, write_proc_t write_proc)
{
/* create the /proc file */
*entry = create_proc_entry(procfs_filename, 0666, dev->proc_dir);
if (*entry == NULL) {
ERROR (dev, "Error: Could not initialize /proc/%s/%s\n",
PROC_DIR_NAME, procfs_filename);
} else {
(*entry)->read_proc = read_proc;
(*entry)->write_proc = write_proc;
(*entry)->data = dev;
(*entry)->mode = S_IFREG;
if (read_proc)
(*entry)->mode |= S_IRUGO;
if (write_proc)
(*entry)->mode |= S_IWUGO;
(*entry)->uid = 0;
(*entry)->gid = 0;
(*entry)->size = 0;
INFO (dev, "/proc/%s/%s created\n", PROC_DIR_NAME, procfs_filename);
}
}
static void /* __init_or_exit */ psfreedom_unbind(struct usb_gadget *gadget)
{
struct psfreedom_device *dev = get_gadget_data(gadget);
INFO (dev, "unbind\n");
if (timer_added)
del_timer (&psfreedom_state_machine_timer);
timer_added = 0;
/* we've already been disconnected ... no i/o is active */
if (dev) {
if (dev->port1_config_desc)
kfree(dev->port1_config_desc);
if (dev->req)
free_ep_req(gadget->ep0, dev->req);
if (dev->hub_req)
free_ep_req(dev->hub_ep, dev->hub_req);
if (dev->proc_status_entry)
remove_proc_entry(PROC_STATUS_NAME, dev->proc_dir);
if (dev->proc_version_entry)
remove_proc_entry(PROC_VERSION_NAME, dev->proc_dir);
if (dev->proc_payload_entry)
remove_proc_entry(PROC_PAYLOAD_NAME, dev->proc_dir);
if (dev->proc_shellcode_entry)
remove_proc_entry(PROC_SHELLCODE_NAME, dev->proc_dir);
if (dev->proc_dir)
remove_proc_entry(PROC_DIR_NAME, NULL);
kfree(dev);
set_gadget_data(gadget, NULL);
}
}
static int __init psfreedom_bind(struct usb_gadget *gadget)
{
struct psfreedom_device *dev;
int err = 0;
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) {
return -ENOMEM;
}
spin_lock_init(&dev->lock);
usb_gadget_set_selfpowered (gadget);
dev->gadget = gadget;
set_gadget_data(gadget, dev);
INFO(dev, "%s, version: " PSFREEDOM_VERSION " - " DRIVER_VERSION "\n",
longname);
DBG (dev, "Loading default payload and shellcode\n");
dev->port1_config_desc_size = sizeof(default_payload) + \
sizeof(port1_config_desc_prefix);
dev->port1_config_desc = kmalloc(dev->port1_config_desc_size, GFP_KERNEL);
memcpy(dev->port1_config_desc, port1_config_desc_prefix,
sizeof(port1_config_desc_prefix));
memcpy(dev->port1_config_desc + sizeof(port1_config_desc_prefix),
default_payload, sizeof(default_payload));
memcpy(jig_response + 24, default_shellcode, sizeof(default_shellcode));
/* preallocate control response and buffer */
dev->req = alloc_ep_req(gadget->ep0,
max (sizeof (port3_config_desc), dev->port1_config_desc_size) + USB_BUFSIZ);
if (!dev->req) {
err = -ENOMEM;
goto fail;
}
dev->req->complete = psfreedom_setup_complete;
gadget->ep0->driver_data = dev;
/* Bind the hub and devices */
err = hub_bind (gadget, dev);
if (err < 0)
goto fail;
err = devices_bind (gadget, dev);
if (err < 0)
goto fail;
DBG(dev, "psfreedom_bind finished ok\n");
setup_timer(&psfreedom_state_machine_timer, psfreedom_state_machine_timeout,
(unsigned long) gadget);
psfreedom_disconnect (gadget);
/* Create the /proc filesystem */
dev->proc_dir = proc_mkdir (PROC_DIR_NAME, NULL);
if (dev->proc_dir) {
printk(KERN_INFO "/proc/%s/ created\n", PROC_DIR_NAME);
create_proc_fs (dev, &dev->proc_status_entry, PROC_STATUS_NAME,
proc_status_read, NULL);
create_proc_fs (dev, &dev->proc_version_entry, PROC_VERSION_NAME,
proc_version_read, NULL);
create_proc_fs (dev, &dev->proc_payload_entry, PROC_PAYLOAD_NAME,
proc_payload_read, proc_payload_write);
create_proc_fs (dev, &dev->proc_shellcode_entry, PROC_SHELLCODE_NAME,
proc_shellcode_read, proc_shellcode_write);
/* that's it for now..*/
}
return 0;
fail:
psfreedom_unbind(gadget);
return err;
}
static void psfreedom_suspend(struct usb_gadget *gadget)
{
struct psfreedom_device *dev = get_gadget_data(gadget);
if (gadget->speed == USB_SPEED_UNKNOWN) {
return;
}
INFO (dev, "suspend\n");
}
static void psfreedom_resume(struct usb_gadget *gadget)
{
struct psfreedom_device *dev = get_gadget_data(gadget);
INFO (dev, "resume\n");
}
static struct usb_gadget_driver psfreedom_driver = {
.speed = USB_SPEED_HIGH,
.function = (char *)longname,
.bind = psfreedom_bind,
.unbind = psfreedom_unbind,
.setup = psfreedom_setup,
.disconnect = psfreedom_disconnect,
.suspend = psfreedom_suspend,
.resume = psfreedom_resume,
.driver = {
.name = (char *)shortname,
.owner = THIS_MODULE,
},
};
static int __init psfreedom_init(void)
{
int ret = 0;
printk(KERN_INFO "init\n");
/* Determine what speed the controller supports */
if (psfreedom_is_high_speed ())
psfreedom_driver.speed = USB_SPEED_HIGH;
else if (psfreedom_is_low_speed ())
psfreedom_driver.speed = USB_SPEED_HIGH;
else
psfreedom_driver.speed = USB_SPEED_FULL;
ret = usb_gadget_register_driver(&psfreedom_driver);
printk(KERN_INFO "register driver returned %d\n", ret);
return ret;
}
module_init(psfreedom_init);
static void __exit psfreedom_cleanup(void)
{
usb_gadget_unregister_driver(&psfreedom_driver);
}
module_exit(psfreedom_cleanup);
#include "hub.h"
static int hub_interrupt_queued = 0;
static void hub_interrupt_transmit(struct psfreedom_device *dev);
/* Taking first HUB vendor/product ids from http://www.linux-usb.org/usb.ids
*
* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!!
* Instead: allocate your own, using normal USB-IF procedures.
*/
#define DRIVER_VENDOR_NUM 0xaaaa /* Atmel Corp */
#define DRIVER_PRODUCT_NUM 0xcccc /* 4-Port Hub */
/*
* DESCRIPTORS ...
*/
/* B.1 Device Descriptor */
static struct usb_device_descriptor hub_device_desc = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_HUB,
.bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x01,
.idVendor = cpu_to_le16(DRIVER_VENDOR_NUM),
.idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM),
.bcdDevice = cpu_to_le16(0x0100),
.iManufacturer = 0,
.iProduct = 0,
.bNumConfigurations = 1,
};
/* Hub Configuration Descriptor */
static struct usb_config_descriptor hub_config_desc = {
.bLength = USB_DT_CONFIG_SIZE,
.bDescriptorType = USB_DT_CONFIG,
.wTotalLength = USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + USB_DT_ENDPOINT_SIZE,
.bNumInterfaces = 1,
.bConfigurationValue = 1,
.iConfiguration = 0,
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_WAKEUP | USB_CONFIG_ATT_SELFPOWER,
.bMaxPower = 50,
};
/* Hub Interface Descriptor */
static const struct usb_interface_descriptor hub_interface_desc = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0,
.bNumEndpoints = 1,
.bInterfaceClass = USB_CLASS_HUB,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = 0,
};
/* Hub endpoint Descriptor */
static struct usb_endpoint_descriptor hub_endpoint_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN | 0x02,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = __constant_cpu_to_le16(8),
.bInterval = 12, // frames -> 32 ms
};
/* Hub class specific Descriptor */
static const struct usb_hub_header_descriptor hub_header_desc = {
.bLength = USB_DT_HUB_HEADER_SIZE (6),
.bDescriptorType = USB_DT_CS_HUB,
.bNbrPorts = 6,
.wHubCharacteristics = __constant_cpu_to_le16 (0x00a9),
.bPwrOn2PwrGood = 50,
.bHubContrCurrent = 100,
.DeviceRemovable = 0x00,
.PortPwrCtrlMask = 0xFF,
};
static void hub_port_changed (struct psfreedom_device *dev);
static void
switch_to_port (struct psfreedom_device *dev, unsigned int port)
{
if (dev->current_port == port)
return;
DBG (dev, "Switching to port %d. Address is %d\n", port,
dev->port_address[port]);
dev->current_port = port;
psfreedom_set_address (dev->gadget, dev->port_address[port]);
}
static void
hub_connect_port (struct psfreedom_device *dev, unsigned int port)
{
if (port == 0 || port > 6)
return;
switch_to_port (dev, 0);
/* Here, we must enable the port directly, otherwise we might loose time
with the host asking for the status a few more times, and waiting for it to
be enabled, etc.. and we might miss the 5seconds window in which we need
to connect the JIG */
dev->hub_ports[port-1].status |= PORT_STAT_CONNECTION;
dev->hub_ports[port-1].status |= PORT_STAT_ENABLE;
/* If the speed flag set is not the same as what the device suports, it will
not work */
if (psfreedom_is_high_speed ())
dev->hub_ports[port-1].status |= PORT_STAT_HIGH_SPEED;
else if (psfreedom_is_low_speed ())
dev->hub_ports[port-1].status |= PORT_STAT_HIGH_SPEED;
dev->hub_ports[port-1].change |= PORT_STAT_C_CONNECTION;
hub_port_changed (dev);
}
static void
hub_disconnect_port (struct psfreedom_device *dev, unsigned int port)
{
if (port == 0 || port > 6)
return;
switch_to_port (dev, 0);
dev->hub_ports[port-1].status &= ~PORT_STAT_CONNECTION;
dev->hub_ports[port-1].status &= ~PORT_STAT_ENABLE;
dev->hub_ports[port-1].status &= ~PORT_STAT_HIGH_SPEED;
dev->hub_ports[port-1].status &= ~PORT_STAT_LOW_SPEED;
dev->hub_ports[port-1].change |= PORT_STAT_C_CONNECTION;
hub_port_changed (dev);
}
static void hub_interrupt_complete(struct usb_ep *ep, struct usb_request *req)
{
struct psfreedom_device *dev = ep->driver_data;
int status = req->status;
unsigned long flags;
spin_lock_irqsave (&dev->lock, flags);
DBG (dev, "Hub interrupt complete (status %d)\n", status);
hub_interrupt_queued = 0;
switch (status) {
case 0: /* normal completion */
if (ep == dev->hub_ep) {
/* our transmit completed.
see if there's more to go.
hub_transmit eats req, don't queue it again. */
//hub_interrupt_transmit(dev);
spin_unlock_irqrestore (&dev->lock, flags);
return;
}
break;
/* this endpoint is normally active while we're configured */
case -ECONNABORTED: /* hardware forced ep reset */
case -ESHUTDOWN: /* disconnect from host */
VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status,
req->actual, req->length);
case -ECONNRESET: /* request dequeued */
hub_interrupt_queued = 0;
spin_unlock_irqrestore (&dev->lock, flags);
return;
case -EOVERFLOW: /* buffer overrun on read means that
* we didn't provide a big enough
* buffer.
*/
default:
DBG(dev, "%s complete --> %d, %d/%d\n", ep->name,
status, req->actual, req->length);
break;
case -EREMOTEIO: /* short read */
break;
}
hub_interrupt_queued = 1;
status = usb_ep_queue(ep, req, GFP_ATOMIC);
if (status) {
ERROR(dev, "kill %s: resubmit %d bytes --> %d\n",
ep->name, req->length, status);
usb_ep_set_halt(ep);
hub_interrupt_queued = 0;
/* FIXME recover later ... somehow */
}
spin_unlock_irqrestore (&dev->lock, flags);
}
static void hub_interrupt_transmit (struct psfreedom_device *dev)
{
struct usb_ep *ep = dev->hub_ep;
struct usb_request *req = dev->hub_req;
u8 data = 0;
int i;
if (!ep)
return;
if (!req) {
req = alloc_ep_req(ep, USB_BUFSIZ);
dev->hub_req = req;
}
if (!req) {
ERROR(dev, "hub_interrupt_transmit: alloc_ep_request failed\n");
return;
}
req->complete = hub_interrupt_complete;
for (i = 0; i < 6; i++) {
if (dev->hub_ports[i].change != 0)
data |= 1 << (i+1);
}
if (data != 0) {
int err = 0;
if (hub_interrupt_queued) {
ERROR(dev, "hub_interrupt_transmit: Already queued a request\n");
return;
}
/* Only queue one interrupt, and send it only once... If we don't do that
then it will confuse the ps3, which will try to reset our device a few
times and it will make it take over 15 seconds to get to plugging the JIG
which will not work since it must be plugged in during boot in less
than 5 seconds */
memcpy (req->buf, &data, sizeof(data));
req->length = sizeof(data);
DBG (dev, "transmitting interrupt byte 0x%X\n", data);
hub_interrupt_queued = 1;
err = usb_ep_queue(ep, req, GFP_ATOMIC);
} else {
DBG (dev, "Nothing to report, freeing request, NAK-ing interrupt\n");
if (hub_interrupt_queued)
usb_ep_dequeue(ep, req);
hub_interrupt_queued = 0;
}
}
static void hub_port_changed (struct psfreedom_device *dev)
{
hub_interrupt_transmit (dev);
}
static int set_hub_config(struct psfreedom_device *dev)
{
int err = 0;
hub_interrupt_queued = 0;
err = usb_ep_enable(dev->hub_ep, &hub_endpoint_desc);
if (err) {
ERROR(dev, "can't start %s: %d\n", dev->hub_ep->name, err);
goto fail;
}
dev->hub_ep->driver_data = dev;
fail:
/* caller is responsible for cleanup on error */
return err;
}
static void
hub_reset_config(struct psfreedom_device *dev)
{
DBG(dev, "reset config\n");
usb_ep_disable(dev->hub_ep);
hub_interrupt_queued = 0;
}
/* change our operational config. this code must agree with the code
* that returns config descriptors, and altsetting code.
*
* it's also responsible for power management interactions. some
* configurations might not work with our current power sources.
*
* note that some device controller hardware will constrain what this
* code can do, perhaps by disallowing more than one configuration or
* by limiting configuration choices (like the pxa2xx).
*/
static int
hub_set_config(struct psfreedom_device *dev, unsigned number)
{
int result = 0;
struct usb_gadget *gadget = dev->gadget;
hub_reset_config(dev);
result = set_hub_config(dev);
if (!result && !dev->hub_ep) {
result = -ENODEV;
}
if (result) {
hub_reset_config(dev);
} else {
char *speed;
switch (gadget->speed) {
case USB_SPEED_LOW: speed = "low"; break;
case USB_SPEED_FULL: speed = "full"; break;
case USB_SPEED_HIGH: speed = "high"; break;
default: speed = "?"; break;
}
INFO(dev, "%s speed\n", speed);
}
return result;
}
static void hub_disconnect (struct usb_gadget *gadget)
{
struct psfreedom_device *dev = get_gadget_data (gadget);
hub_reset_config (dev);
}
/*
* The setup() callback implements all the ep0 functionality that's
* not handled lower down, in hardware or the hardware driver (like
* device and endpoint feature flags, and their status). It's all
* housekeeping for the gadget function we're implementing. Most of
* the work is in config-specific setup.
*/
static int hub_setup(struct usb_gadget *gadget,
const struct usb_ctrlrequest *ctrl, u16 request,
u16 w_index, u16 w_value, u16 w_length)
{
struct psfreedom_device *dev = get_gadget_data(gadget);
struct usb_request *req = dev->req;
int value = -EOPNOTSUPP;
/* usually this stores reply data in the pre-allocated ep0 buffer,
* but config change events will reconfigure hardware.
*/
switch (ctrl->bRequest) {
case USB_REQ_GET_DESCRIPTOR:
if ((ctrl->bRequestType & USB_DIR_IN) == 0) {
goto unknown;
}
if ((ctrl->bRequestType & USB_TYPE_CLASS) == USB_TYPE_CLASS) {
/* GET_HUB_DESCRIPTOR Class specific request */
value = min(w_length, (u16) sizeof(hub_header_desc));
memcpy(req->buf, &hub_header_desc, value);
if (value >= 0)
value = min(w_length, (u16)value);
} else {
switch (w_value >> 8) {
case USB_DT_DEVICE:
value = min(w_length, (u16) sizeof(hub_device_desc));
memcpy(req->buf, &hub_device_desc, value);
break;
case USB_DT_CONFIG:
memcpy(req->buf, &hub_config_desc, sizeof(hub_config_desc));
value = sizeof(hub_config_desc);
memcpy (req->buf + value, &hub_interface_desc,
sizeof(hub_interface_desc));
value += sizeof(hub_interface_desc);
memcpy (req->buf + value, &hub_endpoint_desc,
sizeof(hub_endpoint_desc));
value += sizeof(hub_endpoint_desc);
if (value >= 0)
value = min(w_length, (u16)value);
break;
case USB_DT_STRING:
value = 0;
break;
}
}
break;
case USB_REQ_SET_CONFIGURATION:
if (ctrl->bRequestType != 0) {
goto unknown;
}
value = hub_set_config(dev, w_value);
break;
case USB_REQ_GET_CONFIGURATION:
if (ctrl->bRequestType != USB_DIR_IN) {
goto unknown;
}
*(u8 *)req->buf = 0;
value = min(w_length, (u16)1);
break;
case USB_REQ_SET_INTERFACE:
if (ctrl->bRequestType != USB_RECIP_INTERFACE) {
goto unknown;
}
value = 0;
break;
case USB_REQ_GET_INTERFACE:
if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) {
goto unknown;
}
if (w_index >= 1) {
value = -EDOM;
break;
}
*(u8 *)req->buf = 0;
value = min(w_length, (u16)1);
break;
case USB_REQ_SET_FEATURE:
if ((ctrl->bRequestType & USB_TYPE_CLASS) == USB_TYPE_CLASS) {
switch (ctrl->bRequestType & USB_RECIP_MASK) {
/* SET_HUB_FEATURE */
case USB_RECIP_DEVICE:
switch (w_value) {
case 0: /* C_HUB_LOCAL_POWER */
case 1: /* C_HUB_OVER_CURRENT */
VDBG (dev, "SetHubFeature called\n");
value = 0;
break;
default:
value = -EINVAL;
break;
}
break;
case USB_RECIP_OTHER:
/* SET_PORT_FEATURE */
if (w_index == 0 || w_index > 6) {
DBG (dev, "SetPortFeature: invalid port index %d\n", w_index);
value = -EINVAL;
break;
}
switch (w_value) {
case 4: /* PORT_RESET */
DBG (dev, "SetPortFeature PORT_RESET called\n");
dev->hub_ports[w_index-1].change |= PORT_STAT_C_RESET;
hub_port_changed (dev);
value = 0;
break;
case 8: /* PORT_POWER */
DBG (dev, "SetPortFeature PORT_POWER called\n");
dev->hub_ports[w_index-1].status |= PORT_STAT_POWER;
if (dev->status == INIT && w_index == 6) {
dev->status = HUB_READY;
SET_TIMER (150);
}
value = 0;
break;
case 0: /* PORT_CONNECTION */
case 1: /* PORT_ENABLE */
case 2: /* PORT_SUSPEND */
case 3: /* PORT_OVER_CURRENT */
case 9: /* PORT_LOW_SPEED */
case 16: /* C_PORT_CONNECTION */
case 17: /* C_PORT_ENABLE */
case 18: /* C_PORT_SUSPEND */
case 19: /* C_PORT_OVER_CURRENT */
case 20: /* C_PORT_RESET */
case 21: /* PORT_TEST */
case 22: /* PORT_INDICATOR */
DBG (dev, "SetPortFeature called\n");
value = 0;
break;
default:
value = -EINVAL;
break;
}
break;
}
}
break;
case USB_REQ_CLEAR_FEATURE:
if ((ctrl->bRequestType & USB_TYPE_CLASS) == USB_TYPE_CLASS) {
switch (ctrl->bRequestType & USB_RECIP_MASK) {
/* CLEAR_HUB_FEATURE */
case USB_RECIP_DEVICE:
switch (w_value) {
case 0: /* C_HUB_LOCAL_POWER */
case 1: /* C_HUB_OVER_CURRENT */
VDBG (dev, "ClearHubFeature called\n");
value = 0;
break;
default:
value = -EINVAL;
break;
}
break;
case USB_RECIP_OTHER:
/* CLEAR_PORT_FEATURE */
if (w_index == 0 || w_index > 6) {
DBG (dev, "ClearPortFeature: invalid port index %d\n", w_index);
value = -EINVAL;
break;
}
switch (w_value) {
case 0: /* PORT_CONNECTION */
case 1: /* PORT_ENABLE */
case 2: /* PORT_SUSPEND */
case 3: /* PORT_OVER_CURRENT */
case 4: /* PORT_RESET */
case 8: /* PORT_POWER */
case 9: /* PORT_LOW_SPEED */
value = 0;
break;
case 16: /* C_PORT_CONNECTION */
DBG (dev, "ClearPortFeature C_PORT_CONNECTION called\n");
dev->hub_ports[w_index-1].change &= ~PORT_STAT_C_CONNECTION;
switch (dev->status) {
case DEVICE1_WAIT_DISCONNECT:
dev->status = DEVICE1_DISCONNECTED;
SET_TIMER (200);
break;
case DEVICE2_WAIT_DISCONNECT:
dev->status = DEVICE2_DISCONNECTED;
SET_TIMER (170);
break;
case DEVICE3_WAIT_DISCONNECT:
dev->status = DEVICE3_DISCONNECTED;
SET_TIMER (450);
break;
case DEVICE4_WAIT_DISCONNECT:
dev->status = DEVICE4_DISCONNECTED;
SET_TIMER (200);
break;
case DEVICE5_WAIT_DISCONNECT:
dev->status = DEVICE5_DISCONNECTED;
SET_TIMER (200);
break;
default:
break;
}
value = 0;
break;
case 20: /* C_PORT_RESET */
DBG (dev, "ClearPortFeature C_PORT_RESET called\n");
dev->hub_ports[w_index-1].change &= ~PORT_STAT_C_RESET;
switch (dev->status) {
case DEVICE1_WAIT_READY:
if (w_index == 1)
dev->switch_to_port_delayed = w_index;
break;
case DEVICE2_WAIT_READY:
if (w_index == 2)
dev->switch_to_port_delayed = w_index;
break;
case DEVICE3_WAIT_READY:
if (w_index == 3)
dev->switch_to_port_delayed = w_index;
break;
case DEVICE4_WAIT_READY:
if (w_index == 4)
dev->switch_to_port_delayed = w_index;
break;
case DEVICE5_WAIT_READY:
if (w_index == 5)
dev->switch_to_port_delayed = w_index;
break;
case DEVICE6_WAIT_READY:
if (w_index == 6)
dev->switch_to_port_delayed = w_index;
break;
default:
break;
}
/* Delay switching the port because we first need to response
to this request with the proper address */
if (dev->switch_to_port_delayed >= 0)
SET_TIMER (0);
value = 0;
break;
case 17: /* C_PORT_ENABLE */
case 18: /* C_PORT_SUSPEND */
case 19: /* C_PORT_OVER_CURRENT */
case 21: /* PORT_TEST */
case 22: /* PORT_INDICATOR */
DBG (dev, "ClearPortFeature called\n");
value = 0;
break;
default:
value = -EINVAL;
break;
}
break;
}
}
break;
case USB_REQ_GET_STATUS:
if ((ctrl->bRequestType & USB_TYPE_CLASS) == USB_TYPE_CLASS) {
u16 status = 0;
u16 change = 0;
value = 2 * sizeof (u16);
switch (ctrl->bRequestType & USB_RECIP_MASK) {
case USB_RECIP_DEVICE:
/* GET_HUB_STATUS */
status = 0;
change = 0;
break;
case USB_RECIP_OTHER:
/* GET_PORT_STATUS */
if (w_index == 0 || w_index > 6) {
DBG (dev, "GetPortstatus : invalid port index %d\n", w_index);
value = -EINVAL;
break;
}
status = dev->hub_ports[w_index -1].status;
change = dev->hub_ports[w_index -1].change;
break;
default:
goto unknown;
}
if (value > 0) {
DBG (dev, "GetHub/PortStatus: transmtiting status %d change %d\n",
status, change);
status = cpu_to_le16 (status);
change = cpu_to_le16 (change);
memcpy(req->buf, &status, sizeof(u16));
memcpy(req->buf + sizeof(u16), &change, sizeof(u16));
}
}
break;
default:
unknown:
ERROR (dev, "unknown control req%02x.%02x v%04x i%04x l%d\n",
ctrl->bRequestType, ctrl->bRequest,
w_value, w_index, w_length);
}
/* device either stalls (value < 0) or reports success */
return value;
}
static int __init hub_bind(struct usb_gadget *gadget, struct psfreedom_device *dev)
{
struct usb_ep *in_ep;
gadget_for_each_ep (in_ep, gadget) {
if (0 == strcmp (in_ep->name,
psfreedom_get_endpoint_name (&hub_endpoint_desc)))
break;
}
if (!in_ep) {
ERROR (dev, "%s: can't find %s on %s\n",
psfreedom_get_endpoint_name (&hub_endpoint_desc),
shortname, gadget->name);
return -ENODEV;
}
in_ep->driver_data = in_ep; /* claim */
/* ok, we made sense of the hardware ... */
dev->hub_ep = in_ep;
dev->hub_req = alloc_ep_req(in_ep, USB_BUFSIZ);
if (!dev->req) {
ERROR (dev, "Couldn't alloc hub request\n");
return -ENOMEM;
}
/* The device's max packet size MUST be the same as ep0 */
hub_device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
INFO(dev, "using %s, EP IN %s\n", gadget->name, in_ep->name);
VDBG(dev, "hub_bind finished ok\n");
return 0;
}
#ifndef __LINUX_USB_HUB_H
#define __LINUX_USB_HUB_H
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/types.h>
#define USB_DT_CS_HUB 0x29
/* 11.23.2.1 Class-Specific AC Interface Descriptor */
struct usb_hub_header_descriptor {
__u8 bLength; /* 8+n */
__u8 bDescriptorType; /* USB_DT_CS_HUB */
__u8 bNbrPorts; /* n */
__le16 wHubCharacteristics; /* hub characteristics */
__u8 bPwrOn2PwrGood; /* ? */
__u8 bHubContrCurrent; /* ? */
__u8 DeviceRemovable; /* [n/8] */
__u8 PortPwrCtrlMask; /* [n/8] */
} __attribute__ ((packed));
#define USB_DT_HUB_HEADER_SIZE(n) (sizeof(struct usb_hub_header_descriptor))
#define PORT_STAT_CONNECTION 0x0001
#define PORT_STAT_ENABLE 0x0002
#define PORT_STAT_RESET 0x0010
#define PORT_STAT_POWER 0x0100
#define PORT_STAT_LOW_SPEED 0x0200
#define PORT_STAT_HIGH_SPEED 0x0400
#define PORT_STAT_C_CONNECTION 0x0001
#define PORT_STAT_C_RESET 0x0010
struct hub_port {
u16 status;
u16 change;
};
#endif /* __LINUX_USB_HUB_H */
# ifdef ENABLE_MUSB_CONTROLLER
/ * Kernel 2.6.21 (N800/N900) necesita al compilar * /
# Define MUSB_DEBUG 0
# ifdef ENABLE_MUSB_ARCHOS_GEN6_CONTROLLER
# Include ".. / drivers / usb / MUSB / musbdefs.h"
# Else
# Include ".. / drivers / usb / MUSB / musb_core.h"
# endif
# Include ".. / drivers / usb / MUSB / musb_gadget.h"
/ **
* Psfreedom_is_high_speed:
*
* Determine si este controlador soporta alta velocidad o no
* Devuelve: 1 si apoya la alta velocidad, 0 en caso contrario
* /
estática int psfreedom_is_high_speed (vacío)
(
retorno 1;
)
/ **
* Psfreedom_is_low_speed:
*
* Determine si este controlador compatible con baja velocidad o no
* Devuelve: 1 si apoya a baja velocidad, 0 en caso contrario
* /
estática int psfreedom_is_low_speed (vacío)
(
retorno 0;
)
/ **
* Psfreedom_get_endpoint_name:
* Descripción: El criterio de valoración descripción
*
* Una función para ayudar a encontrar el nombre del punto final que estamos buscando.
* Esto debería tener en cuenta la dirección de punto final y la dirección.
* Asegúrese de que cada punto final solicitado (1 IN, 2 IN y OUT 2) tiene diferentes
* Nombre de punto final para evitar un único punto final se utiliza para distintos dispositivos.
*
* Returs: el nombre del punto final
* /
estática char *psfreedom_get_endpoint_name (struct usb_endpoint_descriptor *desc)
(
U8 dirección = desc->bEndpointAddress;
U8 epnum = dirección & 0x0f;
si (epnum == 1 & & (dirección y USB_DIR_IN) == USB_DIR_IN)
retorno "ep1in";
otra cosa si (epnum == 2 & & (dirección y USB_DIR_IN) == USB_DIR_IN)
retorno "ep2in";
otra cosa si (epnum == 2 & & (dirección y USB_DIR_IN) == 0)
retorno "ep2out";
más
retorno NULL;
)
/ **
* Psfreedom_get_address:
* @ G: El usb_gadget
*
* Recuperar la dirección del controlador USB
* Devuelve: la dirección indicada en el controlador
* /
estática U8 psfreedom_get_address (struct usb_gadget *g)
(
struct MUSB *MUSB = gadget_to_musb (g);
U8 dirección = 0;
si (MUSB)
# ifdef ENABLE_MUSB_ARCHOS_GEN6_CONTROLLER
Dirección = musb_readb(MUSB->Pregs, MGC_O_HDRC_FADDR);
# Else
Dirección = musb_readb(MUSB->mregs, MUSB_FADDR);
# endif
volver la dirección;
)
/ **
* Psfreedom_set_address:
* @ G: El usb_gadget
* @ Dirección: La dirección para establecer
*
* Cambiar la dirección del controlador USB
* /
estática vacío psfreedom_set_address (struct usb_gadget *g, U8 dirección)
(
struct MUSB *MUSB = gadget_to_musb (g);
si (MUSB) (
# ifdef ENABLE_MUSB_ARCHOS_GEN6_CONTROLLER
MUSB->bAddress = dirección;
musb_writeb(MUSB->Pregs, MGC_O_HDRC_FADDR, dirección);
# Else
MUSB->dirección = dirección;
musb_writeb(MUSB->mregs, MUSB_FADDR, dirección);
# endif
)
)
# endif / * ENABLE_MUSB_CONTROLLER /
# ifdef ENABLE_MSM72K_CONTROLLER
/ * Hack Alerta: Esto era necesario ya que para algunos
razón desconocida, container_of () devolverá un
interfaz de usuario que contienen diddn't la información de dirección que queríamos.
Esto utiliza el desplazamiento desde el usb_gadget suministrado para encontrar
nuestro valor. Si espera mientras usb_info sigue siendo el mismo.
* /
# Define UI_GADGET_OFFSET 1724
# Define USBDEVADDR (readu ((sin firmar) g - UI_GADGET_OFFSET) + 0x0154)
estática en línea vacío writel(sin firmar a largo l, sin signo largo addr)
(
*(volátiles sin firmar a largo __force *)addr = l;
)
estática en línea sin firmar a largo readl(sin firmar a largo addr)
(
retorno *(volátiles sin firmar a largo __force *)addr;
)
estática en línea sin firmar readu(sin firmar addr)
(
retorno *(volátiles sin firmar __force *)addr;
)
estática int psfreedom_is_high_speed (vacío)
(
retorno 1;
)
estática int psfreedom_is_low_speed (vacío)
(
retorno 0;
)
estática char *psfreedom_get_endpoint_name (struct usb_endpoint_descriptor *desc)
(
U8 dirección = desc->bEndpointAddress;
U8 epnum = dirección & 0x0f;
si (epnum == 1 & & (dirección y USB_DIR_IN) == USB_DIR_IN)
retorno "ep1in";
otra cosa si (epnum == 2 & & (dirección y USB_DIR_IN) == USB_DIR_IN)
retorno "ep2in";
otra cosa si (epnum == 2 & & (dirección y USB_DIR_IN) == 0)
retorno "ep2out";
más
retorno NULL;
)
estática U8 psfreedom_get_address (struct usb_gadget *g)
(
sin signo largo de amortiguamiento = 0;
U8 dirección = 0;
buffer = readl(USBDEVADDR);
/ * La dirección se encuentra en los bits 25-32 * /
dirección = (U8) (buffer >> 25) & 0x7F;
dev_vdbg(&g->dev, "***** Cómo dirección:% d\ n", dirección);
volver la dirección;
)
estática vacío psfreedom_set_address (struct usb_gadget *g, U8 dirección)
(
/ * Enviar la dirección en bits 25-32. No utilice el mismo método que la
SET_ADDRESS controlador de 24 bits, que establece a "1" para indicarle al controlador
para retrasar la operación hasta un EN respuesta se envía (respuesta a la
SET_ADDRESS deberá enviarse con la dirección antigua).
* /
writel((dirección << 25), USBDEVADDR);
dev_vdbg(&g->dev, "***** Configuración de la dirección a% d. Nueva dirección:% d\ n",
dirección, psfreedom_get_address(g));
)
# endif / * ENABLE_MSM72K_CONTROLLER /
# ifdef ENABLE_JZ4740_CONTROLLER
# Include "../drivers/usb/gadget/jz4740_udc.h"
# Define JZ_REG_UDC_FADDR 0x00 / * Dirección * Función bits 8 /
estática en línea uint8_t usb_readb (struct jz4740_udc *udc, size_t reg)
(
volver readb(UDC->base + reg);
)
estática en línea vacío usb_writeb (struct jz4740_udc *udc, size_t reg, uint8_t val)
(
writeb(val, UDC->base + reg);
)
estática en línea vacío usb_change_epnum (struct usb_endpoint_descriptor *desc, uint8_t epnum)
(
desc->bEndpointAddress & = ~0x0f;
desc->bEndpointAddress | = epnum;
)
estática int psfreedom_is_high_speed (vacío)
(
retorno 1;
)
estática int psfreedom_is_low_speed (vacío)
(
retorno 0;
)
estática char *psfreedom_get_endpoint_name (struct usb_endpoint_descriptor *desc)
(
U8 dirección = desc->bEndpointAddress;
U8 epnum = dirección & 0x0f;
si (epnum == 1 & & (dirección y USB_DIR_IN) == USB_DIR_IN)
retorno "ep1in a granel";
otra cosa si (epnum == 2 & & (dirección y USB_DIR_IN) == USB_DIR_IN)
retorno "ep2in-int";
otra cosa si (epnum == 2 & & (dirección y USB_DIR_IN) == 0) (
usb_change_epnum(desc, 1);
retorno "ep1out a granel";
) demás
retorno NULL;
)
estática U8 psfreedom_get_address (struct usb_gadget *g)
(
struct jz4740_udc *dev = container_of(g, struct jz4740_udc, gadget);
U8 dirección = 0;
si (dev)
Dirección = usb_readb(dev, JZ_REG_UDC_FADDR);
volver la dirección;
)
estática vacío psfreedom_set_address (struct usb_gadget *g, U8 dirección)
(
struct jz4740_udc *dev = container_of(g, struct jz4740_udc, gadget);
si (dev) (
dev->usb_address = dirección;
usb_writeb(dev, JZ_REG_UDC_FADDR, dirección);
)
)
# endif / * ENABLE_JZ4740_CONTROLLER /
Corregido algunas definiciones, que erán short en vez de char.
Añadido switch_to_port(0) cuando esta en power los 6 puertos
Corregido sizeof en el procedimiento send, que no mandaba los paquetes con su
tamaño correcto
Cambiado tiempo de envio de respuesta al GET STATE a 0ms, no es necesario
esperar, solo hay que esperar a enviar el value = 4, antes de salir de dicha
funcion, no se puede mandar el paquete que espera.
#include <pspsystimer.h>
#include <psprtc.h>
#ifndef __time_t_defined
typedef unsigned long time_t;
#define __time_t_defined
#endif
int expire=0;
SceSysTimerId timer_main;
int tick_main()
{
if (expire>0){
expire--;
}
return -1;
}
timer_main= sceSTimerAlloc();
sceSTimerStartCount(timer_main);
//The timer cycle in microseconds (???). Maximum: 4194303 which represents ~1/10 seconds
sceSTimerSetHandler(timer_main, 395000, tick_main, 0); // 10ms de repetición
azsxdcf escribió:wuepe no quiro serpesado, pero seria mucho pedir preguntarte como va el port?? a mi me da igual si tarda un dia o dos meses, es solo saber si finalmente habra port.
gracias de antemano y jmucho animo
harmony555 escribió:azsxdcf escribió:wuepe no quiro serpesado, pero seria mucho pedir preguntarte como va el port?? a mi me da igual si tarda un dia o dos meses, es solo saber si finalmente habra port.
gracias de antemano y jmucho animo
No te va a decir nada, lo unico que dira (si responde, que no creo) sera el tipico, queda muy poco.
unsigned short hex = 0x3ff3;
unsigned char *bytes = ((unsigned char*)(&hex));
// ahora puedes accesas los valores asi: //
printf("Valor del primer byte: %X\n", bytes[0]); // Valor del primer byte: 0x3F
printf("Valor del segundo byte: %X\n", bytes[1]); // Valor del segundo byte: 0xF3
// en otras palabras, ahora bytes[0] = 0x3f y bytes[1] = 0xf3 //
jose130 escribió:sabeis si es verdad esta imformacion parece ser q lo han conseguido unos franceses
http://www.youtube.com/watch?v=PE5ZEL6e ... r_embedded
katasuka escribió:si estuviese aqi el mismisimo dark_alex lo abria exo ya con los ojos vendaos pero bueno ay q conformarse y esperar aver q ocurre de verdad espero q se acabe consiguiendo seria un chollo para muchos
katasuka escribió:si estuviese aqi el mismisimo dark_alex lo abria exo ya con los ojos vendaos pero bueno ay q conformarse y esperar aver q ocurre de verdad espero q se acabe consiguiendo seria un chollo para muchos
katasuka escribió:si estuviese aqi el mismisimo dark_alex lo abria exo ya con los ojos vendaos pero bueno ay q conformarse y esperar aver q ocurre de verdad espero q se acabe consiguiendo seria un chollo para muchos
<@BrandonW>You might still have to give up on it, without a way to change the function address.
<04@GhoST>
<instinct> I hope not, I have faith in ya Brandon. I remember when you were dealing with the timing issues in #ps3dev
<@BrandonW> There's the quote from the open source USB driver guy that SET_ADDRESS is being handled in hardware (which I have a really tough time believing), which would make it pretty unlikely.
<04@GhoST> so
<04@GhoST> do u want
<04@GhoST> to talk with pspeol develoers?
<04@GhoST> deviante & wuepe etc.?
<@BrandonW> I've already talked to the first one.
<04@GhoST> aha
<instinct> I thought he already has been in communication with them.
<@BrandonW> He agrees that the address-changing code doesn't work.
<04@GhoST> his own? or wuepes code?
<@BrandonW> It's all the same.
<04@GhoST> ah
<@BrandonW> If you look at it and compare it to what's in the open source USB driver, it couldn't possibly work.
<@BrandonW> The only way you're going to figure out which port/address holds the function address is to 1) disassemble the kernel and find out where, if anywhere (!), it's handling SET_ADDRESS and see what it does, or 2) blindly scan memory for the current address, which I have no idea will even work.
<04@GhoST> hmmm
<04@GhoST> could i quote this on eol forums to get as much help as possible?
<04@GhoST> if u dont want its ok.
<@BrandonW> I don't mind. That last part's total conjecture on my part from someone who knows very little about PSP development.
<@BrandonW> The important thing is that the code that changes the address doesn't work, it matches irrelevant code from the open source USB driver.
Hermes escribió:Bueno chicos,
Hoy he tenido un día muy movido y no he podido contar lo que hice ayer .
Ayer, estuve trabajando un poco en el tema, utilizando parte de lo que se está haciendo aquí (arreglando los envíos, con alineación a 64 bytes, flusheado de memoria y uso de eventos ) y además, fusionando el driver pspusb, para poder tener mejor control de la situación (en un solo módulo, lo tengo todo)
Además, cuento con un HUB, lo cual me permite aparte de mirar un poco el protocolo de datos, poder cambiar la dirección de dispositivo de la PSP, para poder intentar localizar si alguno de los registros que conocemos (por el propio pspusb), la contiene.
1) La función SET_ADDRESS que nos tiene que enviar el host, no produce interrupción alguna: es llevada por hardware, tal y como se indica en el propio driver (y como nos avisó vrquist en su día) , pero quedaba la esperanza de que al menos, pudiese ser tratada o vista de alguna manera si modificábamos el driver USB. Pues bien, no se detecta, ni llevando esa detección al primer peldaño, donde se leen los datos procedentes del FIFO. Incluso los que se tomarían como error, los he muestrado.
2) Si el hardware lo hace todo, eso da muy mala espina, pues tal vez esa dirección se está guardando de forma interna y no es accesible como nos tememos. Pero claro, existe la posibilidad de que al menos, en algún registro se muestra la dirección, si es que los señores de SONY en el fondo, hubiera previsto una posibilidad de darle control al usuario...Pues bien, en ese caso, al enchufar la PSP a través de un HUB, debería reflejar una dirección diferente, como es obvio, y así de esa forma, detectar dicho puerto (podemos no saber cual escribir o como escribirlo, si requiere un flag diferente o algo así, pero al menos, deberíamos ser capaces de apreciar los cambios, en lectura). El resultado, es que no lo he localizado, a pesar de haber hecho un volcado de los registros con ayuda de una función exportada (mostrando 32 registros en pantalla)
3) Por cierto, tambien he tenido curiosidad por si se podía lograr mantener vivo un dispositivo y activar otro, sin desconectar el primero desde el punto de vista del host: no lo he logrado, a pesar de haber utilizado una rutina de desconexión propia, donde iba añadiendo o restando elementos, por si se podía lograr ese truco (no se si hubiera valido para algo, pero al menos, no se pierde nada por intentarlo)
Así que llego a la conclusión de que no es posible recrear el exploit con la PSP: no se si se podría hacer de otra manera, pero desde luego, la que utiliza psgroove y otros, no parece posible. Si intentándolo con los mejores medios posibles, no se logra ... (driver usb a gusto del consumidor, etc)
Oh, eso si: es fácil que Windows XP te reconozca un HUB de 6 puertos conectado e incluso que te reconozca un puerto en uso con un dispositivo desconocido, si haces que se reporte el estado correcto, justo en el momento exacto... pero no parece haber forma humana posible para que a partir de ahí, le lleguen los datos que le deberían llegar (ni siquiera se recibe una petición de descriptores para el nuevo dispositivo: lo tengo hecho de una forma burda, con una variable que cuenta las peticiones, ya que no puedo ver los Kprintf, pero que mas da, si no funciona y es un simple testigo)
Yo por mi parte, considero inútil el esfuerzo y desde luego, si hubiera alguna posibilidad que se me escapase, es obvio que para encontrarla, debería trabajarse desde ese peldaño tan bajo (manipulando pspusb). Pero pensad que no es lo mismo un hardware cerrado como es una PSP, que un hardware mucho mas abierto en posibilidades, que es mucho mas fácil que contemplen lo del registro (joder, si suele ser el primero, en los hardware que he visto )
El caso es que mañana me llega mi AT90USBKEY y por mi parte, se acabaron los problemas: me hubiera gustado poder contribuir aportando buenas noticias, pues pese a mi retiro, si es verdad que me encanta ver a la peña colaborando en EOL por un proyecto común (lo cual mola ) y con la impaciencia de que no me llegaba mi plaquita y tal, me dije: "que menos que mirar a ver si puedo ayudar un poco" (de protocolo USB estoy algo mas pez que algunos, seguramente, pero hay cosas que no se me escapan, estando más que acostumbrado a tocar el hardware en su programación), pero veo que es trabajo baldío.
Saludos
Hermes escribió:Bueno chicos,
Hoy he tenido un día muy movido y no he podido contar lo que hice ayer .
Ayer, estuve trabajando un poco en el tema, utilizando parte de lo que se está haciendo aquí (arreglando los envíos, con alineación a 64 bytes, flusheado de memoria y uso de eventos ) y además, fusionando el driver pspusb, para poder tener mejor control de la situación (en un solo módulo, lo tengo todo)
Además, cuento con un HUB, lo cual me permite aparte de mirar un poco el protocolo de datos, poder cambiar la dirección de dispositivo de la PSP, para poder intentar localizar si alguno de los registros que conocemos (por el propio pspusb), la contiene.
1) La función SET_ADDRESS que nos tiene que enviar el host, no produce interrupción alguna: es llevada por hardware, tal y como se indica en el propio driver (y como nos avisó vrquist en su día) , pero quedaba la esperanza de que al menos, pudiese ser tratada o vista de alguna manera si modificábamos el driver USB. Pues bien, no se detecta, ni llevando esa detección al primer peldaño, donde se leen los datos procedentes del FIFO. Incluso los que se tomarían como error, los he muestrado.
2) Si el hardware lo hace todo, eso da muy mala espina, pues tal vez esa dirección se está guardando de forma interna y no es accesible como nos tememos. Pero claro, existe la posibilidad de que al menos, en algún registro se muestra la dirección, si es que los señores de SONY en el fondo, hubiera previsto una posibilidad de darle control al usuario...Pues bien, en ese caso, al enchufar la PSP a través de un HUB, debería reflejar una dirección diferente, como es obvio, y así de esa forma, detectar dicho puerto (podemos no saber cual escribir o como escribirlo, si requiere un flag diferente o algo así, pero al menos, deberíamos ser capaces de apreciar los cambios, en lectura). El resultado, es que no lo he localizado, a pesar de haber hecho un volcado de los registros con ayuda de una función exportada (mostrando 32 registros en pantalla)
3) Por cierto, tambien he tenido curiosidad por si se podía lograr mantener vivo un dispositivo y activar otro, sin desconectar el primero desde el punto de vista del host: no lo he logrado, a pesar de haber utilizado una rutina de desconexión propia, donde iba añadiendo o restando elementos, por si se podía lograr ese truco (no se si hubiera valido para algo, pero al menos, no se pierde nada por intentarlo)
Así que llego a la conclusión de que no es posible recrear el exploit con la PSP: no se si se podría hacer de otra manera, pero desde luego, la que utiliza psgroove y otros, no parece posible. Si intentándolo con los mejores medios posibles, no se logra ... (driver usb a gusto del consumidor, etc)
Oh, eso si: es fácil que Windows XP te reconozca un HUB de 6 puertos conectado e incluso que te reconozca un puerto en uso con un dispositivo desconocido, si haces que se reporte el estado correcto, justo en el momento exacto... pero no parece haber forma humana posible para que a partir de ahí, le lleguen los datos que le deberían llegar (ni siquiera se recibe una petición de descriptores para el nuevo dispositivo: lo tengo hecho de una forma burda, con una variable que cuenta las peticiones, ya que no puedo ver los Kprintf, pero que mas da, si no funciona y es un simple testigo)
Yo por mi parte, considero inútil el esfuerzo y desde luego, si hubiera alguna posibilidad que se me escapase, es obvio que para encontrarla, debería trabajarse desde ese peldaño tan bajo (manipulando pspusb). Pero pensad que no es lo mismo un hardware cerrado como es una PSP, que un hardware mucho mas abierto en posibilidades, que es mucho mas fácil que contemplen lo del registro (joder, si suele ser el primero, en los hardware que he visto )
El caso es que mañana me llega mi AT90USBKEY y por mi parte, se acabaron los problemas: me hubiera gustado poder contribuir aportando buenas noticias, pues pese a mi retiro, si es verdad que me encanta ver a la peña colaborando en EOL por un proyecto común (lo cual mola ) y con la impaciencia de que no me llegaba mi plaquita y tal, me dije: "que menos que mirar a ver si puedo ayudar un poco" (de protocolo USB estoy algo mas pez que algunos, seguramente, pero hay cosas que no se me escapan, estando más que acostumbrado a tocar el hardware en su programación), pero veo que es trabajo baldío.
Saludos
Hermes escribió:Bueno chicos,
Hoy he tenido un día muy movido y no he podido contar lo que hice ayer .
Ayer, estuve trabajando un poco en el tema, utilizando parte de lo que se está haciendo aquí (arreglando los envíos, con alineación a 64 bytes, flusheado de memoria y uso de eventos ) y además, fusionando el driver pspusb, para poder tener mejor control de la situación (en un solo módulo, lo tengo todo)
Además, cuento con un HUB, lo cual me permite aparte de mirar un poco el protocolo de datos, poder cambiar la dirección de dispositivo de la PSP, para poder intentar localizar si alguno de los registros que conocemos (por el propio pspusb), la contiene.
pupila1992 escribió:bueno y planteo yo desde mi mas desconocimiento:
si en el pc la cosa funciona, no es posible que la psp se conecte al pc y del pc con un cable usb macho-macho realicemos el tema?
Hermes escribió:Bueno chicos,
Hoy he tenido un día muy movido y no he podido contar lo que hice ayer .
Ayer, estuve trabajando un poco en el tema, utilizando parte de lo que se está haciendo aquí (arreglando los envíos, con alineación a 64 bytes, flusheado de memoria y uso de eventos ) y además, fusionando el driver pspusb, para poder tener mejor control de la situación (en un solo módulo, lo tengo todo)
Además, cuento con un HUB, lo cual me permite aparte de mirar un poco el protocolo de datos, poder cambiar la dirección de dispositivo de la PSP, para poder intentar localizar si alguno de los registros que conocemos (por el propio pspusb), la contiene.
1) La función SET_ADDRESS que nos tiene que enviar el host, no produce interrupción alguna: es llevada por hardware, tal y como se indica en el propio driver (y como nos avisó vrquist en su día) , pero quedaba la esperanza de que al menos, pudiese ser tratada o vista de alguna manera si modificábamos el driver USB. Pues bien, no se detecta, ni llevando esa detección al primer peldaño, donde se leen los datos procedentes del FIFO. Incluso los que se tomarían como error, los he muestrado.
2) Si el hardware lo hace todo, eso da muy mala espina, pues tal vez esa dirección se está guardando de forma interna y no es accesible como nos tememos. Pero claro, existe la posibilidad de que al menos, en algún registro se muestra la dirección, si es que los señores de SONY en el fondo, hubiera previsto una posibilidad de darle control al usuario...Pues bien, en ese caso, al enchufar la PSP a través de un HUB, debería reflejar una dirección diferente, como es obvio, y así de esa forma, detectar dicho puerto (podemos no saber cual escribir o como escribirlo, si requiere un flag diferente o algo así, pero al menos, deberíamos ser capaces de apreciar los cambios, en lectura). El resultado, es que no lo he localizado, a pesar de haber hecho un volcado de los registros con ayuda de una función exportada (mostrando 32 registros en pantalla)
3) Por cierto, tambien he tenido curiosidad por si se podía lograr mantener vivo un dispositivo y activar otro, sin desconectar el primero desde el punto de vista del host: no lo he logrado, a pesar de haber utilizado una rutina de desconexión propia, donde iba añadiendo o restando elementos, por si se podía lograr ese truco (no se si hubiera valido para algo, pero al menos, no se pierde nada por intentarlo)
Así que llego a la conclusión de que no es posible recrear el exploit con la PSP: no se si se podría hacer de otra manera, pero desde luego, la que utiliza psgroove y otros, no parece posible. Si intentándolo con los mejores medios posibles, no se logra ... (driver usb a gusto del consumidor, etc)
Oh, eso si: es fácil que Windows XP te reconozca un HUB de 6 puertos conectado e incluso que te reconozca un puerto en uso con un dispositivo desconocido, si haces que se reporte el estado correcto, justo en el momento exacto... pero no parece haber forma humana posible para que a partir de ahí, le lleguen los datos que le deberían llegar (ni siquiera se recibe una petición de descriptores para el nuevo dispositivo: lo tengo hecho de una forma burda, con una variable que cuenta las peticiones, ya que no puedo ver los Kprintf, pero que mas da, si no funciona y es un simple testigo)
Yo por mi parte, considero inútil el esfuerzo y desde luego, si hubiera alguna posibilidad que se me escapase, es obvio que para encontrarla, debería trabajarse desde ese peldaño tan bajo (manipulando pspusb). Pero pensad que no es lo mismo un hardware cerrado como es una PSP, que un hardware mucho mas abierto en posibilidades, que es mucho mas fácil que contemplen lo del registro (joder, si suele ser el primero, en los hardware que he visto )
El caso es que mañana me llega mi AT90USBKEY y por mi parte, se acabaron los problemas: me hubiera gustado poder contribuir aportando buenas noticias, pues pese a mi retiro, si es verdad que me encanta ver a la peña colaborando en EOL por un proyecto común (lo cual mola ) y con la impaciencia de que no me llegaba mi plaquita y tal, me dije: "que menos que mirar a ver si puedo ayudar un poco" (de protocolo USB estoy algo mas pez que algunos, seguramente, pero hay cosas que no se me escapan, estando más que acostumbrado a tocar el hardware en su programación), pero veo que es trabajo baldío.
Saludos
_ChRiS_ escribió:En ningún sitio ha dicho Brandon Wilson que se unía al proyecto, solo comentó que la funcion de cambiar la address no funciona.
azsxdcf escribió:y quien es esta para decir que no se puede??? jajaja yo lo flipo, anda acuestate y deja trabajar a los que de verdad saben
azsxdcf escribió:y quien es esta para decir que no se puede??? jajaja yo lo flipo, anda acuestate y deja trabajar a los que de verdad saben
azsxdcf escribió:y quien es esta para decir que no se puede??? jajaja yo lo flipo, anda acuestate y deja trabajar a los que de verdad saben
azsxdcf escribió:y quien es esta para decir que no se puede??? jajaja yo lo flipo, anda acuestate y deja trabajar a los que de verdad saben
azsxdcf escribió:y quien es esta para decir que no se puede??? jajaja yo lo flipo, anda acuestate y deja trabajar a los que de verdad saben
azsxdcf escribió:y quien es esta para decir que no se puede??? jajaja yo lo flipo, anda acuestate y deja trabajar a los que de verdad saben