Exemple #1
0
void _machine_restart(void)
{
	struct sb_halt_arg arg;

	arg.mode = SB_HALT_MODE_PWROFF;
	sbios(SB_HALT, &arg);
}
Exemple #2
0
int checkboard(void)
{
	struct ps2_bootinfo *info = (void *) CKSEG0ADDR(PS2_BOOTINFO_OLDADDR);
	uint32_t size;
	volatile uint32_t *sbios_magic;
	int sbversion = 0;
	struct ps2_bootinfo bootinfo;

	puts("Board: Sony Playstation 2 MIPS r5900\n");
	memset(&bootinfo, 0, sizeof(bootinfo));
	size = info->size;
	if (size > sizeof(bootinfo)) {
		size = sizeof(bootinfo);
	}
	memcpy(&bootinfo, info, size);

	sbios_magic = (uint32_t *) SBIOS_MAGIC;
	if (*sbios_magic == SBIOS_MAGICVAL) {
		gd->arch._sbios = *(int (**)(int, void *))(SBIOS_BASE);
	}
	else
		gd->arch._sbios = NULL;

	sbversion = sbios(SB_GETVER, NULL);
	printf("SBIOS Version 0x%08x\n", sbversion);

	driver_init();
	return 0;
}
Exemple #3
0
static void check_sif_irq(void)
{
	if (inl(EE_DMAC_SIF0_CHCR) & CHCR_STR) {
		/* DMA not finished, no interrupt. */
		return;
	}

	/* Emulate interrupt. */
	sbios(SB_SIFCMDINTRHDLR, NULL);
}
Exemple #4
0
static void driver_init(void)
{
	int rv;
	int result;

	rv = sbios(SB_SIFINIT, NULL);
	if (rv < 0) {
		error("SB_SIFINIT failed rv = %d\n", rv);
		return;
	}

	rv = sbios(SB_SIFINITCMD, NULL);
	if (rv < 0) {
		error("SB_SIFINITCMD failed rv = %d\n", rv);
		return;
	}

	rv = sbios(SB_SIFINITRPC, NULL);
	if (rv < 0) {
		error("SB_SIFINITRPC failed rv = %d\n", rv);
		return;
	}

	for (;;) {
		debug("Call SBR_IOPH_INIT\n");
		rv = sbios_rpc(SBR_IOPH_INIT, NULL, &result);
		debug("rv = %d\n", rv);
		if (rv < 0) {
			error("SBR_IOPH_INIT failed rv = %d\n", rv);
			return;
		}
		debug("result = %d\n", result);
		if (result == 0) {
			/* Success */
			break;
		}
	}
	debug("SBIOS drivers successfully initialized.\n");
}
Exemple #5
0
static int sbios_rpc(int func, void *arg, int *result)
{
	int ret;
	struct sbr_common_arg carg;
	volatile int woken = 0;

	carg.arg = arg;
	carg.func = rpc_wakeup;
	carg.para = (void *) &woken;
	carg.result = -1;

	do {
		debug("Call SBIOS %d\n", func);
		ret = sbios(func, &carg);
		debug("ret = %d\n", ret);
		switch (ret) {
			case 0:
				break;
			case -SIF_RPCE_SENDP:
				/* resource temporarily unavailable */

				/* Time to check for interrupts. */
				check_sif_irq();
				break;
			default:
				*result = ret;
				error("sbios_rpc: RPC failed, func=%d result=%d\n", func, ret);
				return ret;
		}
	} while (ret < 0);

	while(woken == 0) {
		debug("check_sif_irq\n");

		/* Time to check for interrupts. */
		check_sif_irq();
	}
	debug("carg.result %d\n", carg.result);

	*result = carg.result;

	return 0;
}
Exemple #6
0
static int
ps2cdvd_reset(struct cdrom_device_info *cdi)
{
	unsigned long flags;

	save_flags(flags);
	cli();
	ps2sif_lock(ps2cdvd_lock, "cdvd_reset");
	RESET_TIMER();
#ifdef CONFIG_PS2_SBIOS_VER_CHECK
	if (0x0201 <= sbios(SB_GETVER, NULL))
		ps2cdvdcall_reset();
#else
	ps2cdvdcall_reset();
#endif
	invalidate_discinfo();
	ps2cdvd_state = ps2cdvd_enter(STAT_WAIT_DISC);
	ps2sif_unlock(ps2cdvd_lock);
	restore_flags(flags);
	return 0;
}
Exemple #7
0
static void
ps2cdvd_state_machine(struct ps2cdvd_event* ev)
{
	unsigned long flags;
	int old_state = ps2cdvd_state;
	int new_state = ps2cdvd_state;
	struct sbr_common_arg *carg = ev->arg;

	DPRINT(DBG_STATE, "state: %s event: %s\n",
	       ps2cdvd_getstatestr(old_state),
	       ps2cdvd_geteventstr(ev->type));

	save_flags(flags);
	cli();

	switch (ps2cdvd_state) {
	case STAT_WAIT_DISC:
	  switch (ev->type) {
	  case EV_START:
	  case EV_TIMEOUT:
	    if (ps2cdvd_lowlevel_lock() < 0) {
	      /* waiting for unlock... */
	      RESET_TIMER();
	      SET_TIMER(HZ * ps2cdvd_check_interval);
	    } else {
	      new_state = STAT_INIT_TRAYSTAT;
	    }
	    break;
	  case EV_INTR:
	  }
	  break;
	case STAT_INIT_TRAYSTAT:
	  switch (ev->type) {
	  case EV_START:
	  case EV_TIMEOUT:
	    break;
	  case EV_INTR:
	    {
	      if (carg->result != 0) {
		new_state = STAT_WAIT_DISC;
	      } else {
		new_state = STAT_CHECK_DISCTYPE;
	      }
	    }
	    break;
	  }
	  break;
	case STAT_CHECK_DISCTYPE:
	  switch (ev->type) {
	  case EV_START:
	  case EV_TIMEOUT:
	    break;
	  case EV_INTR:
	    disc_type = carg->result;
	    DPRINT(DBG_INFO, "ps2cdvd_getdisctype()='%s', %d\n",
		   ps2cdvd_getdisctypestr(disc_type), disc_type);
	    switch (disc_type) {
	    case SCECdPS2CDDA:		/* PS2 CD DA */
	    case SCECdPS2CD:		/* PS2 CD */
	    case SCECdPSCDDA:		/* PS CD DA */
	    case SCECdPSCD:		/* PS CD */
	    case SCECdCDDA:		/* CD DA */
	    case SCECdPS2DVD:		/* PS2 DVD */
	    case SCECdDVDV:		/* DVD video */
	      new_state = STAT_INIT_CHECK_READY;
	      break;
	    case SCECdDETCTDVDD:	/* DVD-dual detecting */
	    case SCECdDETCTDVDS:	/* DVD-single detecting */
	    case SCECdDETCTCD:		/* CD detecting */
	    case SCECdDETCT:		/* detecting */
	    case SCECdNODISC:		/* no disc */
	      new_state = disc_locked ? STAT_INVALID_DISC : STAT_WAIT_DISC;
	      break;
	    case SCECdIllgalMedia:	/* illegal media */
	    case SCECdUNKNOWN:		/* unknown */
	      printk(KERN_CRIT "ps2cdvd: illegal media\n");
	      new_state = disc_locked ? STAT_INVALID_DISC : STAT_WAIT_DISC;
	      break;
	    }
	    break;
	  }
	  break;
	case STAT_INIT_CHECK_READY:
	  switch (ev->type) {
	  case EV_START:
	  case EV_TIMEOUT:
	    break;
	  case EV_INTR:
	    prev_read = jiffies;
	    if (carg->result == SCECdComplete) {
	      switch (disc_type) {
	      case SCECdPS2CDDA:	/* PS2 CD DA */
	      case SCECdPS2CD:		/* PS2 CD */
	      case SCECdPSCDDA:		/* PS CD DA */
	      case SCECdPSCD:		/* PS CD */
	      case SCECdCDDA:		/* CD DA */
		new_state = STAT_TOC_READ;
		media_mode = SCECdCD;
		break;
	      case SCECdPS2DVD:		/* PS2 DVD */
	      case SCECdDVDV:		/* DVD video */
		new_state = STAT_SET_MMODE;
		media_mode = SCECdDVD;
		break;
	      default:
		printk(KERN_CRIT "ps2cdvd: internal error at %s(%d)\n",
		       __FILE__, __LINE__);
		new_state = disc_locked ? STAT_INVALID_DISC : STAT_WAIT_DISC;
		break;
	      }
	    } else {
	      new_state = STAT_WAIT_DISC;
	    }
	    break;
	  }
	  break;
	case STAT_TOC_READ:
	  switch (ev->type) {
	  case EV_START:
	  case EV_TIMEOUT:
	    break;
	  case EV_INTR:
	    if (carg->result < 0) {
	      DPRINT(DBG_DIAG, "gettoc() failed\n");
	      new_state = disc_locked ? STAT_INVALID_DISC : STAT_WAIT_DISC;
	    } else {
	      struct ps2cdvd_tocentry *toc;

	      toc_valid = 1;
	      toc = (struct ps2cdvd_tocentry *)tocbuf;
	      leadout_start = msftolba(decode_bcd(toc[2].abs_msf[0]),
				       decode_bcd(toc[2].abs_msf[1]),
				       decode_bcd(toc[2].abs_msf[2]));
#ifdef PS2CDVD_DEBUG
	      if (ps2cdvd_debug & DBG_INFO) {
		struct sbr_cdvd_gettoc_arg *arg = carg->arg;
		if (arg->media == 0) {
		  ps2cdvd_tocdump(DBG_LOG_LEVEL "ps2cdvd: ",
				  (struct ps2cdvd_tocentry *)tocbuf);
		} else {
		  /*
		   * we have no interrest in DVD Physical format information
		   ps2cdvd_hexdump(tocbuf, len);
		  */
		}
	      }
#endif
	      new_state = STAT_SET_MMODE;
	    }
	    break;
	  }
	  break;
	case STAT_SET_MMODE:
	  switch (ev->type) {
	  case EV_START:
	  case EV_TIMEOUT:
	    break;
	  case EV_INTR:
	    if (carg->result == 0) {
	      DPRINT(DBG_DIAG, "set_mmode() failed\n");
	      new_state = disc_locked ? STAT_INVALID_DISC : STAT_WAIT_DISC;
	    } else {
	      switch (disc_type) {
	      case SCECdPS2DVD:		/* PS2 DVD */
	      case SCECdPS2CDDA:		/* PS2 CD DA */
	      case SCECdPS2CD:		/* PS2 CD */
	      case SCECdPSCDDA:		/* PS CD DA */
	      case SCECdPSCD:		/* PS CD */
		new_state = STAT_LABEL_READ;
		break;
	      case SCECdDVDV:		/* DVD video */
	      case SCECdCDDA:		/* CD DA */
		if (disc_locked && disc_lock_key_valid) {
		  new_state = STAT_LABEL_READ;
		} else {
		  disc_changed++;
		  new_state = STAT_READY;
		}
		break;
	      default:
		printk(KERN_CRIT "ps2cdvd: internal error at %s(%d)\n",
		       __FILE__, __LINE__);
		new_state = disc_locked ? STAT_INVALID_DISC : STAT_WAIT_DISC;
		break;
	      }
	      break;
	    }
	  }
	  break;
	case STAT_LABEL_READ:
	  switch (ev->type) {
	  case EV_START:
	  case EV_TIMEOUT:
	    break;
	  case EV_INTR:
	    new_state = STAT_LABEL_READ_ERROR_CHECK;
	    break;
	  }
	  break;
	case STAT_LABEL_READ_ERROR_CHECK:
	  switch (ev->type) {
	  case EV_START:
	  case EV_TIMEOUT:
	    break;
	  case EV_INTR:
	    if (carg->result != SCECdErNO) {
	      DPRINT(DBG_DIAG, "error: %s, code=0x%02x\n",
		     ps2cdvd_geterrorstr(carg->result),
		     carg->result);
	      if (disc_locked && disc_lock_key_valid) {
		printk(KERN_CRIT "ps2cdvd: =============================\n");
		printk(KERN_CRIT "ps2cdvd:          wrong disc.         \n");
		printk(KERN_CRIT "ps2cdvd: =============================\n");
		if (!ps2cdvd_wrong_disc_retry) {
		  INIT_REQUEST;
		  while (CURRENT)
		    end_request(0);
		  disc_changed++;
		}
	      }
	      new_state = disc_locked ? STAT_INVALID_DISC : STAT_WAIT_DISC;
	    } else {
	      unsigned long sum;
#ifdef PS2CDVD_DEBUG
	      struct iso_primary_descriptor *label;
	      label = (struct iso_primary_descriptor*)labelbuf;

	      if (ps2cdvd_debug & DBG_INFO) {
		printk(DBG_LOG_LEVEL "ps2cdvd: ");
		print_isofsstr(label->system_id, sizeof(label->system_id));
		print_isofsstr(label->volume_id, sizeof(label->volume_id));
		print_isofsstr(label->volume_set_id,
			       sizeof(label->volume_set_id));
		print_isofsstr(label->publisher_id,
			       sizeof(label->publisher_id));
		print_isofsstr(label->application_id,
			       sizeof(label->application_id));
		printk("\n");

		/* ps2cdvd_hexdump(DBG_LOG_LEVEL "ps2cdvd: ", labelbuf, 2048);
		 */
	      }
#endif
	      label_valid = 1;
	      DPRINT(DBG_DLOCK, "label is valid\n");
	      sum = checksum((u_long*)labelbuf, 2048/sizeof(u_long));
	      if (disc_lock_key_valid &&
		  disc_locked &&
		  disc_lock_key != sum) {
		printk(KERN_CRIT "ps2cdvd: =============================\n");
		printk(KERN_CRIT "ps2cdvd:          wrong disc.         \n");
		printk(KERN_CRIT "ps2cdvd: =============================\n");
		if (!ps2cdvd_wrong_disc_retry) {
		  INIT_REQUEST;
		  while (CURRENT)
		    end_request(0);
		  disc_changed++;
		}
		new_state = STAT_INVALID_DISC;
	      } else {
		disc_lock_key = sum;
		if (!disc_lock_key_valid && disc_locked) {
		  DPRINT(DBG_DLOCK, "disc lock key=%lX\n", sum);
		}
		disc_lock_key_valid = 1;
		new_state = STAT_READY;
	      }
	    }
	    break;
	  }
	  break;
	case STAT_READY:
	  switch (ev->type) {
	  case EV_TICK:
	    if (CURRENT == NULL || ps2sif_iswaiting(ps2cdvd_lock)) {
	      break;
	    }
	    /* fall through */
	  case EV_START:
	  case EV_TIMEOUT:
	    if (ps2cdvd_lowlevel_lock() < 0) {
	      /* waiting for unlock... */
	      RESET_TIMER();
	      SET_TIMER(HZ * ps2cdvd_check_interval);
	      break;
	    }
	    if (CURRENT == NULL) {
	      if (ps2cdvd_spindown * HZ < jiffies - prev_read) {
		new_state = STAT_SPINDOWN;
	      } else {
		/* nothing to do */
		ps2cdvd_lowlevel_unlock();
		RESET_TIMER();
		SET_TIMER(HZ * ps2cdvd_check_interval);
	      }
	    } else {
	      prev_read = jiffies;
	      if (jiffies - prev_tray_check < HZ/2) {
		new_state = STAT_READ;
	      } else {
		prev_tray_check = jiffies;
		new_state = STAT_CHECK_TRAY;
	      }
	    }
	    break;
	  case EV_INTR:
	    break;
	  }
	  break;
	case STAT_CHECK_TRAY:
	  switch (ev->type) {
	  case EV_START:
	  case EV_TIMEOUT:
	    break;
	  case EV_INTR:
	    if (carg->result < 0) {
	      new_state = STAT_ERROR;
	    } else {
	      struct sbr_cdvd_trayreq_arg *arg = carg->arg;
	      if (arg->traycount != 0) {
		if (disc_locked) {
		  printk(KERN_CRIT"ps2cdvd: =============================\n");
		  printk(KERN_CRIT"ps2cdvd: the disc is currently locked.\n");
		  printk(KERN_CRIT"ps2cdvd: please don't take it away!\n");
		  printk(KERN_CRIT"ps2cdvd: =============================\n");
		}

		invalidate_discinfo();

		new_state = STAT_CHECK_DISCTYPE;
	      } else {
		if (CURRENT) {
		  new_state = STAT_READ;
		} else {
		  new_state = STAT_READY;
		}
	      }
	    }
	    break;
	  }
	  break;
	case STAT_READ:
	  switch (ev->type) {
	  case EV_START:
	  case EV_TIMEOUT:
	    break;
	  case EV_INTR:
	    new_state = STAT_READ_ERROR_CHECK;
	    break;
	  }
	  break;
	case STAT_READ_EOM_RETRY:
	  switch (ev->type) {
	  case EV_START:
	  case EV_TIMEOUT:
	    break;
	  case EV_INTR:
	    new_state = STAT_READ_ERROR_CHECK;
	    break;
	  }
	  break;
	case STAT_READ_ERROR_CHECK:
	  switch (ev->type) {
	  case EV_START:
	  case EV_TIMEOUT:
	    break;
	  case EV_INTR:
	    if (carg->result == SCECdErNO) {
	      /*
	       * succeeded
	       */
	      while (CURRENT != NULL &&
		     ps2cdvd_databuf_addr <= CURRENT->sector/4 &&
		     CURRENT->sector/4 < ps2cdvd_databuf_addr + ps2cdvd_databuf_size) {
		memcpy(CURRENT->buffer,
		       ps2cdvd_databuf + DATA_SECT_SIZE * (CURRENT->sector/4 - ps2cdvd_databuf_addr),
		       DATA_SECT_SIZE);
		end_request(1);
	      }
	      if (!ps2sif_iswaiting(ps2cdvd_lock) && CURRENT != NULL) {
		/* tiny acceleration */
		new_state = STAT_READ;
	      } else {
		new_state = STAT_READY;
	      }
	    } else
	    if (carg->result == 0x38) {
	      /*
	       * sector format error
	       */
	      DPRINT(DBG_DIAG,
		     "error: sector format error, code=0x38 (ignored)\n");
	      memset(CURRENT->buffer, 0, DATA_SECT_SIZE);
	      end_request(1);
	      if (!ps2sif_iswaiting(ps2cdvd_lock) && CURRENT != NULL) {
		/* tiny acceleration */
		new_state = STAT_READ;
	      } else {
		new_state = STAT_READY;
	      }
	    } else
	    if (carg->result == SCECdErEOM &&
		ps2cdvd_databuf_addr != 
			CURRENT->sector/4 - ps2cdvd_databuf_size + 1 &&
		ps2cdvd_databuf_size <= CURRENT->sector/4) {
	      /* you got End Of Media and you have not retried */
	      DPRINT(DBG_DIAG, "error: %s, code=0x%02x (retry...)\n",
		     ps2cdvd_geterrorstr(carg->result),
		     carg->result);
	      new_state = STAT_READ_EOM_RETRY;
	    } else {
	      DPRINT(DBG_DIAG, "error: %s, code=0x%02x\n",
		     ps2cdvd_geterrorstr(carg->result),
		     carg->result);
	      ps2cdvd_databuf_addr = -1;
	      end_request(0);		/* I/O error */
	      new_state = STAT_READY;
	    }
	    break;
	  }
	  break;
	case STAT_INVALID_DISC:
	  switch (ev->type) {
	  case EV_START:
	  case EV_TIMEOUT:
	    if (ps2cdvd_lowlevel_lock() < 0) {
	      /* waiting for unlock... */
	      RESET_TIMER();
	      SET_TIMER(HZ * ps2cdvd_check_interval);
	    } else {
	      new_state = STAT_CHECK_DISCTYPE;
	    }
	    break;
	  case EV_INTR:
	    break;
	  }
	  break;
	case STAT_SPINDOWN:
	  switch (ev->type) {
	  case EV_START:
	  case EV_TIMEOUT:
	    break;
	  case EV_INTR:
	    if (CURRENT == NULL) {
	      new_state = STAT_IDLE;
	    } else {
	      DPRINT(DBG_VERBOSE, "re-spinup...\n");
	      new_state = STAT_CHECK_DISCTYPE;
	    }
	    break;
	  }
	  break;
	case STAT_IDLE:
	  switch (ev->type) {
	  case EV_START:
	  case EV_TIMEOUT:
	    if (ps2cdvd_lowlevel_lock() < 0) {
	      /* waiting for unlock... */
	      RESET_TIMER();
	      SET_TIMER(HZ * ps2cdvd_check_interval);
	    } else {
	      new_state = STAT_CHECK_DISCTYPE;
	    }
	    break;
	  case EV_INTR:
	    break;
	  }
	  break;
	case STAT_ERROR:
	  break;
	default:
	  printk(KERN_ERR "ps2cdvd: invalid state");
	  ps2cdvd_state = STAT_WAIT_DISC;
	  break;
	}

	if (new_state != old_state) {
		struct ps2cdvd_event tick;
		tick.type = EV_TICK;
		ps2cdvd_leave(old_state);
		ps2cdvd_state = ps2cdvd_enter(new_state);
		DPRINT(DBG_STATE, "  -> new state: %s\n",
		       ps2cdvd_getstatestr(ps2cdvd_state));
		if (old_state != ps2cdvd_state &&
		    ps2cdvd_state == STAT_READY) {
			ps2cdvd_state_machine(&tick);
		}
		wake_up_interruptible(&statq);
	}

	restore_flags(flags);
}

__initfunc(int ps2cdvd_init(void))
{
	int res;

	DPRINT(DBG_VERBOSE, "init: get lock\n");
	if ((ps2cdvd_lock = ps2sif_getlock(PS2LOCK_CDVD)) == NULL) {
		printk(KERN_ERR "ps2cdvd: Can't get lock\n");
		ps2cdvd_cleanup();
		return -EINVAL;
	}
	ps2sif_lockqueueinit(&ps2cdvd_lock_qi);
	ps2cdvd_lock_qi.name = "ps2cdvd";

	DPRINT(DBG_VERBOSE, "init: initialize timer\n");
	init_timer(&io_timer);
	io_timer.function = (void(*)(u_long))ps2cdvd_timer;
	ps2cdvd_state = STAT_WAIT_DISC;

	DPRINT(DBG_VERBOSE, "init: allocate diaklabel buffer\n");
	labelbuf = kmalloc(2048, GFP_KERNEL);
	if (labelbuf == NULL) {
		printk(KERN_ERR "ps2cdvd: Can't allocate buffer\n");
		ps2cdvd_cleanup();
		return -ENOMEM;
	}
	initialized |= INIT_LABELBUF;

	DPRINT(DBG_VERBOSE, "allocate buffer\n");
	ps2cdvd_databufx = kmalloc(ps2cdvd_databuf_size * AUDIO_SECT_SIZE +
				   BUFFER_ALIGNMENT, GFP_KERNEL);
	if (ps2cdvd_databufx == NULL) {
		printk(KERN_ERR "ps2cdvd: Can't allocate buffer\n");
		ps2cdvd_cleanup();
		return -ENOMEM;
	}
	ps2cdvd_databuf = ALIGN(ps2cdvd_databufx, BUFFER_ALIGNMENT);
	initialized |= INIT_DATABUF;

	DPRINT(DBG_VERBOSE, "init: call sbios\n");
	if (ps2cdvdcall_init()) {
		printk(KERN_ERR "ps2cdvd: Can't initialize CD/DVD-ROM subsystem\n");
		ps2cdvd_cleanup();
		return -EIO;
	}
#ifdef CONFIG_PS2_SBIOS_VER_CHECK
	if (0x0201 <= sbios(SB_GETVER, NULL))
		ps2cdvdcall_reset();
#else
	ps2cdvdcall_reset();
#endif
	initialized |= INIT_IOPSIDE;

	DPRINT(DBG_VERBOSE, "init: register block device\n");
	if ((res = register_blkdev(MAJOR_NR, "ps2cdvd", &cdrom_fops)) < 0) {
		printk(KERN_ERR "ps2cdvd: Unable to get major %d for PS2 CD/DVD-ROM\n",
		       MAJOR_NR);
		ps2cdvd_cleanup();
                return -EIO;
	}
	if (MAJOR_NR == 0) MAJOR_NR = res;
	initialized |= INIT_BLKDEV;

	blksize_size[MAJOR_NR] = ps2cdvd_blocksizes;
	hardsect_size[MAJOR_NR] = ps2cdvd_hardsectsizes;
	blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
	read_ahead[MAJOR_NR] = ps2cdvd_read_ahead;

	DPRINT(DBG_VERBOSE, "init: register cdrom\n");
	ps2cdvd_info.dev = MKDEV(MAJOR_NR, 0);
        if (register_cdrom(&ps2cdvd_info) != 0) {
		printk(KERN_ERR "ps2cdvd: Cannot register PS2 CD/DVD-ROM\n");
		ps2cdvd_cleanup();
		return -EIO;
        }
	initialized |= INIT_CDROM;

	printk(KERN_INFO "PS2 CD/DVD-ROM driver\n");

	if (ps2cdvd_lowlevel_lock() == 0)
	  ps2cdvd_state = ps2cdvd_enter(STAT_INIT_TRAYSTAT);
	else
	  ps2cdvd_state = ps2cdvd_enter(STAT_WAIT_DISC);

	return 0;
}