[Investigación] PsGroove en PSP

126, 27, 28, 29, 30
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
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

Este hilo es solo de investigacion. Para preguntas y de mas tienes el otro
(mensaje borrado)
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ó:
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?

has probado con el psfreedom de deviante haber que te sale,e leido por aí que ya lo detecta bien en windows y en la ps3 lo detecta como desconocido.
(mensaje borrado)
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?

[/spoiler]

1º Te comento, que no haces bien, lo de tener que abrir el fichero cada vez que vayas a escribir, lo suyo es abrir el fichero inicialmente.
   SceUID fd = sceIoOpen("ms0:/psg.log", PSP_O_WRONLY | PSP_O_APPEND | PSP_O_CREAT, 0777);

por ejemplo en el main.

luego ya defines la funcion.
void milog(const char *cbuffer)
{
   char buffer[64];
   sprintf(buffer, cbuffer);
   sceIoWrite(fd, buffer, strlen(buffer));
}

y por último al cerra la aplicación, cierras el fichero, en el unload module.
sceIoClose(fd);


Seguro que llamas a esta función cuando dices, haber si no la has puesto, si no, prueba con este cambio haber si te mejora.
Voy a repasarme los psgrooves o psfreedoms existentes por si podemos adaptar algo, empezando por este


/* 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 /


Si veo algo interesante lo adapto a la psp y os lo hago saber ;)
wuepe, ya comentaba que la funcion estaba sin optimizar nada de nada. habia pensado en usarla como dices, pero alguna vez se me queda "colgado" el programa y debo apagar la psp, por lo que podrían perderse datos. tampoco gano mucho tiempo porque realmente no es una funcion que sea llamada de forma intensiva.

tambien pense en crear el handle del fichero como static y despues de cada write hacer un flush, asi no haria falta cerrar el fichero, pero no he visto la funcion fflush y me da pereza buscarla para lo que voy a ganar.

podría haberme colado, pero lo he comprobado. llamo a milog() al principio de cada funcion de hub.c (21 veces). no se, no me habia pasado
Si es extraño que no entre en los callback, por lo demás, si se registra, incluso las funciones que se ejecutan desde el callback.

Actualizado la versión de arriba a la r37, con los bugs que comentasteis, sigue estando por separado el envio de la respuesta al GET STATE HUB y GET STATE PORT, para depurar mejor cuando manda uno, o cual mandamos.

Cambios
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.


Aquí pongo una función, para poder hacer un Main, desde un timer, usando la librerías del sdk

includes
#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;


function de repetición main
int tick_main()
{
  if (expire>0){
    expire--;
  }
  return -1;
}


Creación, iría en el int start_hub(SceSize args, void *argp)

 
  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
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
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.
(mensaje borrado)
Animo mucho animo que queda poco para portarlo.
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.



Hombre tal vez tu hubieras hecho esto mas rapido, te haz tardado no? haz tu propio port al psp y dejate de *m**adas
salio algo interesante. espero les ayuda para poder terminar de configurar el PSProve (si le cambie el nombre)

http://ps3wiki.lan.st/index.php/PSJailb ... ngineering
Hola muchachos,

Nada mas les queria preguntar si todavia usan el archivo utils.c?

Si todavia lo usan les recomendaria cambiar las funciones porque la forma en la que combierten un short a bytes es muy lenta, como lo pueden hacer es asi:

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 //


La verdad es que no tengo mucho tiempo como para leer todo el codigo, pero si tienen problemas especificos con el codigo, yo les puedo ayudar a resolverlos.

darionco
Creo que esto puede ser importante:

brandonlwilson

Did some digging into PSP port, I don't think address code floating around is right. Address != endpoint. Maybe still do-able with research.
sabeis si es verdad esta imformacion parece ser q lo han conseguido unos franceses
http://www.youtube.com/watch?v=PE5ZEL6e ... r_embedded
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

ImagenEso es mas falso que una moneda de 3 euros.
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 XD
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 XD


Pues ve a mamarle la ***** y a ver si le convenzes, lo que hay que leer. :o
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 XD


yo no comento nunca pero esto que hacabo de leer... ole tus webos chav@l...
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 XD


ungrateful little kid ...
Learn to respect the people that are working hard so that you have homebrew.
<@BrandonW>You might still have to give up on it, without a way to change the function address.
<04@GhoST> :D

<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.


Un resumen de lo que falta por hacer y de la situación del panorama ;).
y que dice ? xD
o sea, si no me equivoco la función que crearon como hará una semana para cambiar la dirección del puerto no va. y para llegar a hacer eso bien es necesario tocar el kernel
Bueno chicos,

Hoy he tenido un día muy movido y no he podido contar lo que hice ayer XD.

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 XD)

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
Pues nada, por lo menos se intentó. Yo personalmente agradezco el esfuerzo de todo el equipo pero visto lo visto parece improbable que nos encontremos con el port, así que la mejor opción para todos los que estábamos esperando una noticia al respecto (bien fuese buena o mala) no es otra que adquirir alguno de los muchos clones que ya han salido a la luz.

Gracias Eolteam por haberlo intentado
Hermes escribió:Bueno chicos,

Hoy he tenido un día muy movido y no he podido contar lo que hice ayer XD.

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 XD)

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


Pues se acabo lo que se daba, a buscarse otra cosita para nuestras ps3, que no sea la PSP. Gracias a todos por el esfuerzo.

PIC casero voy a por ti!!!!
Hermes escribió:Bueno chicos,

Hoy he tenido un día muy movido y no he podido contar lo que hice ayer XD.

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 XD)

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

Joder Hermes, que vida? soy Tato30 de ps2reality, pues una lastima, yo también al final me he montado una pic y de hay estoy tirando, pero siento mucho decirlo pero si hermes dice que no se puede..... la cosa acabara aquí seguramente. De todas formas ha sido apasionante seguir día a día los progresos del team y ver las ideas y los enfoques nuevos que se iban presentando, como gente nueva se ha unido al proyecto y como se a coordinado todo. Eso demuestra la pasión de mucha gente por superarse y eso tiene un valor impagable aunque no haya ese pequeño premio final.

Saludos y me alegro de verte tio !!
mucisimas gracias a todos, por aver estado dando el callo dia y noce, ha sido realmente apasionante seguir vuestro progreso, os mereciais sacar el port, pero esto demuestr que hay cosas en la vida que no tienen solucion por muy lucador que uno sea, muchas gracias a todos, y ya tengo encrgado mi ps3key, un saludo!!
Uffff, vaya jarro de agua fría.

Me gustaría decir que yo también voy a encargar un Dongle a alguna página web, pero viendo el panorama judicial que está tomando todo esto, la cosa va a estar dificil para conseguir uno.

Nada, a armarme de paciencia e intentar conseguir los componentes para hacerlo casero (suponiendo que tenga "webs" suficientes para poder hacerlo) :(
Gracias, para quitarse el sombrero, esta espera aparte de aprender ha servido para no lanzarnos a comprar cualquier cosa y abaratar gastos. Un abrazo y gracias
playstation_9999 está baneado por "usar clon para saltarse baneo temporal"
Hermes escribió:Bueno chicos,

Hoy he tenido un día muy movido y no he podido contar lo que hice ayer XD.

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.

Hermes aver si te curras un cargador bueno.
Señores muchas gracias por todo, hay veces en la vida que las cosas no salen pero si los has intentado nunca te quedara la duda.
Un abrazo a todo el equipo. Gracias.
http://www.burks.de/grafik2/owned.jpg

Lo siento, pero esque no lo he podido resistir...

[qmparto] [qmparto] [qmparto] [qmparto] [qmparto] [qmparto] [qmparto] [qmparto] [qmparto] [qmparto] [qmparto] [qmparto] [qmparto] [qmparto] [qmparto] [qmparto]
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?
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?


Bajo mi ignorancia, como decian algunos...

Te contesto:

Esto NO se puede, ya que entonces quien tendría que emular sería el PC, y no puede hacer función de concentrador usb.

Saludos.
Hermes escribió:Bueno chicos,

Hoy he tenido un día muy movido y no he podido contar lo que hice ayer XD.

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 XD)

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


es triste ver este tipo de comentarios tan pesimistas justo cuando personas como Brandon Wilson que ya ha creado un port que parecía imposible, se unen al proyecto.
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.
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
_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.


¿esto: http://twitter.com/brandonlwilson/status/24645701421 para ti no es unirse y ayudar al proyecto? ¿o que esperas que venga aquí al foro a decir que se quiere unir?
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

Si no sabes quien es CALLATE, googlea un poco y veras....

Anda que menudos andan sueltos por el mundo.
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

No tienes ni zorra idea de quién estás tu hablando macho xd
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


jeje, se deverian dar clases de historia, pero historia moderna que nos somos tan viejos... [+risas]
tu sigue flipando.
playstation_9999 está baneado por "usar clon para saltarse baneo temporal"
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

Metete en el foro de wii y busca uLoader, [+risas] "paquete" [+risas] si no sabes quien es Hermes cierra el buzón que te canta paquete [+risas].Hermes scener de Wii,no es por nada pero sabe mucho más de los que están haciendo el port así que ZASSSS EN TODA LA BOCA [+risas] [+risas] [+risas] [+risas]
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


jajaja de donde sales? date una vuelta por el foro de wii o ps2 pero en scene, por si nunca los has visitado .
Le habeis contestado ya 300 XD se habrá dado por enterado!!
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


Esto demuestra el interes que tiene la gente en las cosas.... Vaya tela colega!!!
1482 respuestas
Cerrado
126, 27, 28, 29, 30
Volver a Modchips y Softmods