X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fcdrom%2Fcdu31a.c;h=2157c58755e0a3f0c34c2c66bd8c930e56643ae2;hb=refs%2Fheads%2Fvserver;hp=3a758a020280c7f1ac42990dd36bb45e05d28db8;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c index 3a758a020..2157c5875 100644 --- a/drivers/cdrom/cdu31a.c +++ b/drivers/cdrom/cdu31a.c @@ -65,14 +65,6 @@ * This section describes features beyond the normal audio and CD-ROM * functions of the drive. * - * 2048 byte buffer mode - * - * If a disk is mounted with -o block=2048, data is copied straight - * from the drive data port to the buffer. Otherwise, the readahead - * buffer must be involved to hold the other 1K of data when a 1K - * block operation is done. Note that with 2048 byte blocks you - * cannot execute files from the CD. - * * XA compatibility * * The driver should support XA disks for both the CDU31A and CDU33A. @@ -147,12 +139,19 @@ * Removed init_module & cleanup_module in favor of * module_init & module_exit. * Torben Mathiasen + * + * 22 October 2004 -- Make the driver work in 2.6.X + * Added workaround to fix hard lockups on eject + * Fixed door locking problem after mounting empty drive + * Set double-speed drives to double speed by default + * Removed all readahead things - not needed anymore + * Ondrej Zary */ -#include +#define DEBUG 1 +#include #include - #include #include #include @@ -162,30 +161,25 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include #include -#include #include "cdu31a.h" #define MAJOR_NR CDU31A_CDROM_MAJOR #include -#define CDU31A_READAHEAD 4 /* 128 sector, 64kB, 32 reads read-ahead */ #define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10 -#define DEBUG 0 - -/* Define the following if you have data corruption problems. */ -#undef SONY_POLL_EACH_BYTE +#define PFX "CDU31A: " /* ** Edit the following data to change interrupts, DMA channels, etc. @@ -222,7 +216,7 @@ static unsigned int sony_blocks_left = 0; /* Number of 512 byte blocks left /* The base I/O address of the Sony Interface. This is a variable (not a #define) so it can be easily changed via some future ioctl() */ static unsigned int cdu31a_port = 0; -MODULE_PARM(cdu31a_port, "i"); +module_param(cdu31a_port, uint, 0); /* * The following are I/O addresses of the various registers for the drive. The @@ -238,7 +232,7 @@ static volatile unsigned short sony_cd_read_reg; static volatile unsigned short sony_cd_fifost_reg; static struct request_queue *cdu31a_queue; -static spinlock_t cdu31a_lock = SPIN_LOCK_UNLOCKED; /* queue lock */ +static DEFINE_SPINLOCK(cdu31a_lock); /* queue lock */ static int sony_spun_up = 0; /* Has the drive been spun up? */ @@ -269,17 +263,9 @@ static int sony_toc_read = 0; /* Has the TOC been read for static struct s_sony_subcode last_sony_subcode; /* Points to the last subcode address read */ -static volatile int sony_inuse = 0; /* Is the drive in use? Only one operation - at a time allowed */ - -static DECLARE_WAIT_QUEUE_HEAD(sony_wait); /* Things waiting for the drive */ - -static struct task_struct *has_cd_task = NULL; /* The task that is currently - using the CDROM drive, or - NULL if none. */ +static DECLARE_MUTEX(sony_sem); /* Semaphore for drive hardware access */ static int is_double_speed = 0; /* does the drive support double speed ? */ -static int is_a_cdu31a = 1; /* Is the drive a CDU31A? */ static int is_auto_eject = 1; /* Door has been locked? 1=No/0=Yes */ @@ -301,11 +287,12 @@ static unsigned volatile char final_pos_msf[3] = { 0, 0, 0 }; /* What IRQ is the drive using? 0 if none. */ static int cdu31a_irq = 0; -MODULE_PARM(cdu31a_irq, "i"); +module_param(cdu31a_irq, int, 0); /* The interrupt handler will wake this queue up when it gets an interrupts. */ -DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait); +static DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait); +static int irq_flag = 0; static int curr_control_reg = 0; /* Current value of the control register */ @@ -314,12 +301,8 @@ static int curr_control_reg = 0; /* Current value of the control register */ it will be cleared. */ static char disk_changed; -/* Variable for using the readahead buffer. The readahead buffer - is used for raw sector reads and for blocksizes that are smaller - than 2048 bytes. */ -static char readahead_buffer[CD_FRAMESIZE_RAW]; -static int readahead_dataleft = 0; -static int readahead_bad = 0; +/* This was readahead_buffer once... Now it's used only for audio reads */ +static char audio_buffer[CD_FRAMESIZE_RAW]; /* Used to time a short period to abort an operation after the drive has been idle for a while. This keeps the light on @@ -351,13 +334,16 @@ static int scd_media_changed(struct cdrom_device_info *cdi, int disc_nr) */ static int scd_drive_status(struct cdrom_device_info *cdi, int slot_nr) { - if (CDSL_CURRENT != slot_nr) { + if (CDSL_CURRENT != slot_nr) /* we have no changer support */ return -EINVAL; - } - if (scd_spinup() == 0) { + if (sony_spun_up) + return CDS_DISC_OK; + if (down_interruptible(&sony_sem)) + return -ERESTARTSYS; + if (scd_spinup() == 0) sony_spun_up = 1; - } + up(&sony_sem); return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY; } @@ -383,17 +369,31 @@ static inline void disable_interrupts(void) */ static inline void sony_sleep(void) { - unsigned long flags; - if (cdu31a_irq <= 0) { yield(); } else { /* Interrupt driven */ + DEFINE_WAIT(w); + int first = 1; - save_flags(flags); - cli(); - enable_interrupts(); - interruptible_sleep_on(&cdu31a_irq_wait); - restore_flags(flags); + while (1) { + prepare_to_wait(&cdu31a_irq_wait, &w, + TASK_INTERRUPTIBLE); + if (first) { + enable_interrupts(); + first = 0; + } + + if (irq_flag != 0) + break; + if (!signal_pending(current)) { + schedule(); + continue; + } else + disable_interrupts(); + break; + } + finish_wait(&cdu31a_irq_wait, &w); + irq_flag = 0; } } @@ -404,43 +404,42 @@ static inline void sony_sleep(void) */ static inline int is_attention(void) { - return ((inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0); + return (inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0; } static inline int is_busy(void) { - return ((inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0); + return (inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0; } static inline int is_data_ready(void) { - return ((inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0); + return (inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0; } static inline int is_data_requested(void) { - return ((inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0); + return (inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0; } static inline int is_result_ready(void) { - return ((inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0); + return (inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0; } static inline int is_param_write_rdy(void) { - return ((inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0); + return (inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0; } static inline int is_result_reg_not_empty(void) { - return ((inb(sony_cd_fifost_reg) & SONY_RES_REG_NOT_EMP_BIT) != 0); + return (inb(sony_cd_fifost_reg) & SONY_RES_REG_NOT_EMP_BIT) != 0; } static inline void reset_drive(void) { curr_control_reg = 0; - readahead_dataleft = 0; sony_toc_read = 0; outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg); } @@ -453,6 +452,8 @@ static int scd_reset(struct cdrom_device_info *cdi) { unsigned long retry_count; + if (down_interruptible(&sony_sem)) + return -ERESTARTSYS; reset_drive(); retry_count = jiffies + SONY_RESET_TIMEOUT; @@ -460,6 +461,7 @@ static int scd_reset(struct cdrom_device_info *cdi) sony_sleep(); } + up(&sony_sem); return 0; } @@ -486,17 +488,17 @@ static inline void clear_param_reg(void) static inline unsigned char read_status_register(void) { - return (inb(sony_cd_status_reg)); + return inb(sony_cd_status_reg); } static inline unsigned char read_result_register(void) { - return (inb(sony_cd_result_reg)); + return inb(sony_cd_result_reg); } static inline unsigned char read_data_register(void) { - return (inb(sony_cd_read_reg)); + return inb(sony_cd_read_reg); } static inline void write_param(unsigned char param) @@ -511,7 +513,7 @@ static inline void write_cmd(unsigned char cmd) outb(cmd, sony_cd_cmd_reg); } -static irqreturn_t cdu31a_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t cdu31a_interrupt(int irq, void *dev_id) { unsigned char val; @@ -535,15 +537,17 @@ static irqreturn_t cdu31a_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* If something was waiting, wake it up now. */ if (waitqueue_active(&cdu31a_irq_wait)) { disable_interrupts(); - wake_up(&cdu31a_irq_wait); + irq_flag = 1; + wake_up_interruptible(&cdu31a_irq_wait); } } else if (waitqueue_active(&cdu31a_irq_wait)) { disable_interrupts(); - wake_up(&cdu31a_irq_wait); + irq_flag = 1; + wake_up_interruptible(&cdu31a_irq_wait); } else { disable_interrupts(); - printk - ("CDU31A: Got an interrupt but nothing was waiting\n"); + printk(KERN_NOTICE PFX + "Got an interrupt but nothing was waiting\n"); } return IRQ_HANDLED; } @@ -556,82 +560,47 @@ static unsigned char *translate_error(unsigned char err_code) static unsigned char errbuf[80]; switch (err_code) { - case 0x10: - return "illegal command "; - case 0x11: - return "illegal parameter "; - - case 0x20: - return "not loaded "; - case 0x21: - return "no disc "; - case 0x22: - return "not spinning "; - case 0x23: - return "spinning "; - case 0x25: - return "spindle servo "; - case 0x26: - return "focus servo "; - case 0x29: - return "eject mechanism "; - case 0x2a: - return "audio playing "; - case 0x2c: - return "emergency eject "; - - case 0x30: - return "focus "; - case 0x31: - return "frame sync "; - case 0x32: - return "subcode address "; - case 0x33: - return "block sync "; - case 0x34: - return "header address "; - - case 0x40: - return "illegal track read "; - case 0x41: - return "mode 0 read "; - case 0x42: - return "illegal mode read "; - case 0x43: - return "illegal block size read "; - case 0x44: - return "mode read "; - case 0x45: - return "form read "; - case 0x46: - return "leadout read "; - case 0x47: - return "buffer overrun "; - - case 0x53: - return "unrecoverable CIRC "; - case 0x57: - return "unrecoverable LECC "; - - case 0x60: - return "no TOC "; - case 0x61: - return "invalid subcode data "; - case 0x63: - return "focus on TOC read "; - case 0x64: - return "frame sync on TOC read "; - case 0x65: - return "TOC data "; - - case 0x70: - return "hardware failure "; - case 0x91: - return "leadin "; - case 0x92: - return "leadout "; - case 0x93: - return "data track "; + case 0x10: return "illegal command "; + case 0x11: return "illegal parameter "; + + case 0x20: return "not loaded "; + case 0x21: return "no disc "; + case 0x22: return "not spinning "; + case 0x23: return "spinning "; + case 0x25: return "spindle servo "; + case 0x26: return "focus servo "; + case 0x29: return "eject mechanism "; + case 0x2a: return "audio playing "; + case 0x2c: return "emergency eject "; + + case 0x30: return "focus "; + case 0x31: return "frame sync "; + case 0x32: return "subcode address "; + case 0x33: return "block sync "; + case 0x34: return "header address "; + + case 0x40: return "illegal track read "; + case 0x41: return "mode 0 read "; + case 0x42: return "illegal mode read "; + case 0x43: return "illegal block size read "; + case 0x44: return "mode read "; + case 0x45: return "form read "; + case 0x46: return "leadout read "; + case 0x47: return "buffer overrun "; + + case 0x53: return "unrecoverable CIRC "; + case 0x57: return "unrecoverable LECC "; + + case 0x60: return "no TOC "; + case 0x61: return "invalid subcode data "; + case 0x63: return "focus on TOC read "; + case 0x64: return "frame sync on TOC read "; + case 0x65: return "TOC data "; + + case 0x70: return "hardware failure "; + case 0x91: return "leadin "; + case 0x92: return "leadout "; + case 0x93: return "data track "; } sprintf(errbuf, "unknown 0x%02x ", err_code); return errbuf; @@ -653,8 +622,8 @@ static void set_drive_params(int want_doublespeed) do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD, params, 2, res_reg, &res_size); if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) { - printk(" Unable to set spin-down time: 0x%2.2x\n", - res_reg[1]); + printk(KERN_NOTICE PFX + "Unable to set spin-down time: 0x%2.2x\n", res_reg[1]); } params[0] = SONY_SD_MECH_CONTROL; @@ -670,8 +639,8 @@ static void set_drive_params(int want_doublespeed) do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD, params, 2, res_reg, &res_size); if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) { - printk(" Unable to set mechanical parameters: 0x%2.2x\n", - res_reg[1]); + printk(KERN_NOTICE PFX "Unable to set mechanical " + "parameters: 0x%2.2x\n", res_reg[1]); } } @@ -686,7 +655,10 @@ static int scd_select_speed(struct cdrom_device_info *cdi, int speed) else sony_speed = speed - 1; + if (down_interruptible(&sony_sem)) + return -ERESTARTSYS; set_drive_params(sony_speed); + up(&sony_sem); return 0; } @@ -696,13 +668,15 @@ static int scd_select_speed(struct cdrom_device_info *cdi, int speed) */ static int scd_lock_door(struct cdrom_device_info *cdi, int lock) { - if (lock == 0 && sony_usage == 1) { - /* Unlock the door, only if nobody is using the drive */ + if (lock == 0) { is_auto_eject = 1; } else { is_auto_eject = 0; } + if (down_interruptible(&sony_sem)) + return -ERESTARTSYS; set_drive_params(sony_speed); + up(&sony_sem); return 0; } @@ -716,7 +690,7 @@ static void restart_on_error(void) unsigned long retry_count; - printk("cdu31a: Resetting drive on error\n"); + printk(KERN_NOTICE PFX "Resetting drive on error\n"); reset_drive(); retry_count = jiffies + SONY_RESET_TIMEOUT; while (time_before(jiffies, retry_count) && (!is_attention())) { @@ -725,12 +699,11 @@ static void restart_on_error(void) set_drive_params(sony_speed); do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size); if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) { - printk("cdu31a: Unable to spin up drive: 0x%2.2x\n", + printk(KERN_NOTICE PFX "Unable to spin up drive: 0x%2.2x\n", res_reg[1]); } - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(2 * HZ); + msleep(2000); sony_get_toc(); } @@ -786,9 +759,7 @@ get_result(unsigned char *result_buffer, unsigned int *result_size) while (handle_sony_cd_attention()); } if (is_busy() || (!(is_result_ready()))) { -#if DEBUG - printk("CDU31A timeout out %d\n", __LINE__); -#endif + pr_debug(PFX "timeout out %d\n", __LINE__); result_buffer[0] = 0x20; result_buffer[1] = SONY_TIMEOUT_OP_ERR; *result_size = 2; @@ -839,10 +810,8 @@ get_result(unsigned char *result_buffer, unsigned int *result_size) retry_count--; } if (!is_result_ready()) { -#if DEBUG - printk("CDU31A timeout out %d\n", + pr_debug(PFX "timeout out %d\n", __LINE__); -#endif result_buffer[0] = 0x20; result_buffer[1] = SONY_TIMEOUT_OP_ERR; @@ -868,10 +837,8 @@ get_result(unsigned char *result_buffer, unsigned int *result_size) retry_count--; } if (!is_result_ready()) { -#if DEBUG - printk("CDU31A timeout out %d\n", + pr_debug(PFX "timeout out %d\n", __LINE__); -#endif result_buffer[0] = 0x20; result_buffer[1] = SONY_TIMEOUT_OP_ERR; @@ -902,38 +869,12 @@ do_sony_cd_cmd(unsigned char cmd, unsigned char *result_buffer, unsigned int *result_size) { unsigned long retry_count; - int num_retries; - int recursive_call; - unsigned long flags; - - - save_flags(flags); - cli(); - if (current != has_cd_task) { /* Allow recursive calls to this routine */ - while (sony_inuse) { - interruptible_sleep_on(&sony_wait); - if (signal_pending(current)) { - result_buffer[0] = 0x20; - result_buffer[1] = SONY_SIGNAL_OP_ERR; - *result_size = 2; - restore_flags(flags); - return; - } - } - sony_inuse = 1; - has_cd_task = current; - recursive_call = 0; - } else { - recursive_call = 1; - } + int num_retries = 0; - num_retries = 0; retry_cd_operation: while (handle_sony_cd_attention()); - sti(); - retry_count = jiffies + SONY_JIFFIES_TIMEOUT; while (time_before(jiffies, retry_count) && (is_busy())) { sony_sleep(); @@ -941,9 +882,7 @@ retry_cd_operation: while (handle_sony_cd_attention()); } if (is_busy()) { -#if DEBUG - printk("CDU31A timeout out %d\n", __LINE__); -#endif + pr_debug(PFX "timeout out %d\n", __LINE__); result_buffer[0] = 0x20; result_buffer[1] = SONY_TIMEOUT_OP_ERR; *result_size = 2; @@ -960,18 +899,9 @@ retry_cd_operation: if (((result_buffer[0] & 0xf0) == 0x20) && (num_retries < MAX_CDU31A_RETRIES)) { num_retries++; - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(HZ / 10); /* Wait .1 seconds on retries */ + msleep(100); goto retry_cd_operation; } - - if (!recursive_call) { - has_cd_task = NULL; - sony_inuse = 0; - wake_up_interruptible(&sony_wait); - } - - restore_flags(flags); } @@ -991,21 +921,18 @@ static int handle_sony_cd_attention(void) volatile int val; -#if 0*DEBUG - printk("Entering handle_sony_cd_attention\n"); +#if 0 + pr_debug(PFX "Entering %s\n", __FUNCTION__); #endif if (is_attention()) { if (num_consecutive_attentions > CDU31A_MAX_CONSECUTIVE_ATTENTIONS) { - printk - ("cdu31a: Too many consecutive attentions: %d\n", - num_consecutive_attentions); + printk(KERN_NOTICE PFX "Too many consecutive " + "attentions: %d\n", num_consecutive_attentions); num_consecutive_attentions = 0; -#if DEBUG - printk("Leaving handle_sony_cd_attention at %d\n", + pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); -#endif - return (0); + return 0; } clear_attention(); @@ -1045,11 +972,8 @@ static int handle_sony_cd_attention(void) } num_consecutive_attentions++; -#if DEBUG - printk("Leaving handle_sony_cd_attention at %d\n", - __LINE__); -#endif - return (1); + pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); + return 1; } else if (abort_read_started) { while (is_result_reg_not_empty()) { val = read_result_register(); @@ -1061,18 +985,15 @@ static int handle_sony_cd_attention(void) val = read_data_register(); } abort_read_started = 0; -#if DEBUG - printk("Leaving handle_sony_cd_attention at %d\n", - __LINE__); -#endif - return (1); + pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); + return 1; } num_consecutive_attentions = 0; -#if 0*DEBUG - printk("Leaving handle_sony_cd_attention at %d\n", __LINE__); +#if 0 + pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); #endif - return (0); + return 0; } @@ -1084,14 +1005,14 @@ static inline unsigned int int_to_bcd(unsigned int val) retval = (val / 10) << 4; retval = retval | val % 10; - return (retval); + return retval; } /* Convert from BCD to an integer from 0-99 */ static unsigned int bcd_to_int(unsigned int bcd) { - return ((((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f)); + return (((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f); } @@ -1145,33 +1066,15 @@ static void size_to_buf(unsigned int size, unsigned char *buf) operation if the requested sector is not the next one from the drive. */ static int -start_request(unsigned int sector, unsigned int nsect, int read_nsect_only) +start_request(unsigned int sector, unsigned int nsect) { unsigned char params[6]; - unsigned int read_size; unsigned long retry_count; -#if DEBUG - printk("Entering start_request\n"); -#endif + pr_debug(PFX "Entering %s\n", __FUNCTION__); log_to_msf(sector, params); - /* If requested, read exactly what was asked. */ - if (read_nsect_only) { - read_size = nsect; - } - /* - * If the full read-ahead would go beyond the end of the media, trim - * it back to read just till the end of the media. - */ - else if ((sector + nsect) >= sony_toc.lead_out_start_lba) { - read_size = sony_toc.lead_out_start_lba - sector; - } - /* Read the full readahead amount. */ - else { - read_size = CDU31A_READAHEAD / 4; - } - size_to_buf(read_size, ¶ms[3]); + size_to_buf(nsect, ¶ms[3]); /* * Clear any outstanding attentions and wait for the drive to @@ -1187,11 +1090,10 @@ start_request(unsigned int sector, unsigned int nsect, int read_nsect_only) } if (is_busy()) { - printk("CDU31A: Timeout while waiting to issue command\n"); -#if DEBUG - printk("Leaving start_request at %d\n", __LINE__); -#endif - return (1); + printk(KERN_NOTICE PFX "Timeout while waiting " + "to issue command\n"); + pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); + return 1; } else { /* Issue the command */ clear_result_ready(); @@ -1200,22 +1102,15 @@ start_request(unsigned int sector, unsigned int nsect, int read_nsect_only) write_params(params, 6); write_cmd(SONY_READ_BLKERR_STAT_CMD); - sony_blocks_left = read_size * 4; + sony_blocks_left = nsect * 4; sony_next_block = sector * 4; - readahead_dataleft = 0; - readahead_bad = 0; -#if DEBUG - printk("Leaving start_request at %d\n", __LINE__); -#endif - return (0); + pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); + return 0; } -#if DEBUG - printk("Leaving start_request at %d\n", __LINE__); -#endif + pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); } -/* Abort a pending read operation. Clear all the drive status and - readahead variables. */ +/* Abort a pending read operation. Clear all the drive status variables. */ static void abort_read(void) { unsigned char result_reg[2]; @@ -1225,7 +1120,7 @@ static void abort_read(void) do_sony_cd_cmd(SONY_ABORT_CMD, NULL, 0, result_reg, &result_size); if ((result_reg[0] & 0xf0) == 0x20) { - printk("CDU31A: Error aborting read, %s error\n", + printk(KERN_ERR PFX "Aborting read, %s error\n", translate_error(result_reg[1])); } @@ -1240,23 +1135,15 @@ static void abort_read(void) } sony_blocks_left = 0; - readahead_dataleft = 0; - readahead_bad = 0; } /* Called when the timer times out. This will abort the pending read operation. */ static void handle_abort_timeout(unsigned long data) { - unsigned long flags; - -#if DEBUG - printk("Entering handle_abort_timeout\n"); -#endif - save_flags(flags); - cli(); + pr_debug(PFX "Entering %s\n", __FUNCTION__); /* If it is in use, ignore it. */ - if (!sony_inuse) { + if (down_trylock(&sony_sem) == 0) { /* We can't use abort_read(), because it will sleep or schedule in the timer interrupt. Just start the operation, finish it on the next access to @@ -1266,71 +1153,33 @@ static void handle_abort_timeout(unsigned long data) write_cmd(SONY_ABORT_CMD); sony_blocks_left = 0; - readahead_dataleft = 0; - readahead_bad = 0; abort_read_started = 1; + up(&sony_sem); } - restore_flags(flags); -#if DEBUG - printk("Leaving handle_abort_timeout\n"); -#endif + pr_debug(PFX "Leaving %s\n", __FUNCTION__); } -/* Actually get data and status from the drive. */ +/* Actually get one sector of data from the drive. */ static void -input_data(char *buffer, - unsigned int bytesleft, - unsigned int nblocks, unsigned int offset, unsigned int skip) +input_data_sector(char *buffer) { - int i; - volatile unsigned char val; + pr_debug(PFX "Entering %s\n", __FUNCTION__); - -#if DEBUG - printk("Entering input_data\n"); -#endif /* If an XA disk on a CDU31A, skip the first 12 bytes of data from - the disk. The real data is after that. */ - if (sony_xa_mode) { - for (i = 0; i < CD_XA_HEAD; i++) { - val = read_data_register(); - } - } + the disk. The real data is after that. We can use audio_buffer. */ + if (sony_xa_mode) + insb(sony_cd_read_reg, audio_buffer, CD_XA_HEAD); clear_data_ready(); - if (bytesleft == 2048) { /* 2048 byte direct buffer transfer */ - insb(sony_cd_read_reg, buffer, 2048); - readahead_dataleft = 0; - } else { - /* If the input read did not align with the beginning of the block, - skip the necessary bytes. */ - if (skip != 0) { - insb(sony_cd_read_reg, readahead_buffer, skip); - } - - /* Get the data into the buffer. */ - insb(sony_cd_read_reg, &buffer[offset], bytesleft); - - /* Get the rest of the data into the readahead buffer at the - proper location. */ - readahead_dataleft = (2048 - skip) - bytesleft; - insb(sony_cd_read_reg, - readahead_buffer + bytesleft, readahead_dataleft); - } - sony_blocks_left -= nblocks; - sony_next_block += nblocks; + insb(sony_cd_read_reg, buffer, 2048); /* If an XA disk, we have to clear out the rest of the unused - error correction data. */ - if (sony_xa_mode) { - for (i = 0; i < CD_XA_TAIL; i++) { - val = read_data_register(); - } - } -#if DEBUG - printk("Leaving input_data at %d\n", __LINE__); -#endif + error correction data. We can use audio_buffer for that. */ + if (sony_xa_mode) + insb(sony_cd_read_reg, audio_buffer, CD_XA_TAIL); + + pr_debug(PFX "Leaving %s\n", __FUNCTION__); } /* read data from the drive. Note the nsect must be <= 4. */ @@ -1341,79 +1190,12 @@ read_data_block(char *buffer, unsigned char res_reg[], int *res_size) { unsigned long retry_count; - unsigned int bytesleft; - unsigned int offset; - unsigned int skip; - -#if DEBUG - printk("Entering read_data_block\n"); -#endif + pr_debug(PFX "Entering %s\n", __FUNCTION__); res_reg[0] = 0; res_reg[1] = 0; *res_size = 0; - bytesleft = nblocks * 512; - offset = 0; - - /* If the data in the read-ahead does not match the block offset, - then fix things up. */ - if (((block % 4) * 512) != ((2048 - readahead_dataleft) % 2048)) { - sony_next_block += block % 4; - sony_blocks_left -= block % 4; - skip = (block % 4) * 512; - } else { - skip = 0; - } - - /* We have readahead data in the buffer, get that first before we - decide if a read is necessary. */ - if (readahead_dataleft != 0) { - if (bytesleft > readahead_dataleft) { - /* The readahead will not fill the requested buffer, but - get the data out of the readahead into the buffer. */ - memcpy(buffer, - readahead_buffer + (2048 - - readahead_dataleft), - readahead_dataleft); - bytesleft -= readahead_dataleft; - offset += readahead_dataleft; - readahead_dataleft = 0; - } else { - /* The readahead will fill the whole buffer, get the data - and return. */ - memcpy(buffer, - readahead_buffer + (2048 - - readahead_dataleft), - bytesleft); - readahead_dataleft -= bytesleft; - bytesleft = 0; - sony_blocks_left -= nblocks; - sony_next_block += nblocks; - - /* If the data in the readahead is bad, return an error so the - driver will abort the buffer. */ - if (readahead_bad) { - res_reg[0] = 0x20; - res_reg[1] = SONY_BAD_DATA_ERR; - *res_size = 2; - } - - if (readahead_dataleft == 0) { - readahead_bad = 0; - } - - /* Final transfer is done for read command, get final result. */ - if (sony_blocks_left == 0) { - get_result(res_reg, res_size); - } -#if DEBUG - printk("Leaving read_data_block at %d\n", - __LINE__); -#endif - return; - } - } /* Wait for the drive to tell us we have something */ retry_count = jiffies + SONY_JIFFIES_TIMEOUT; @@ -1426,25 +1208,24 @@ read_data_block(char *buffer, if (is_result_ready()) { get_result(res_reg, res_size); if ((res_reg[0] & 0xf0) != 0x20) { - printk - ("CDU31A: Got result that should have been error: %d\n", - res_reg[0]); + printk(KERN_NOTICE PFX "Got result that should" + " have been error: %d\n", res_reg[0]); res_reg[0] = 0x20; res_reg[1] = SONY_BAD_DATA_ERR; *res_size = 2; } abort_read(); } else { -#if DEBUG - printk("CDU31A timeout out %d\n", __LINE__); -#endif + pr_debug(PFX "timeout out %d\n", __LINE__); res_reg[0] = 0x20; res_reg[1] = SONY_TIMEOUT_OP_ERR; *res_size = 2; abort_read(); } } else { - input_data(buffer, bytesleft, nblocks, offset, skip); + input_data_sector(buffer); + sony_blocks_left -= nblocks; + sony_next_block += nblocks; /* Wait for the status from the drive. */ retry_count = jiffies + SONY_JIFFIES_TIMEOUT; @@ -1456,9 +1237,7 @@ read_data_block(char *buffer, } if (!is_result_ready()) { -#if DEBUG - printk("CDU31A timeout out %d\n", __LINE__); -#endif + pr_debug(PFX "timeout out %d\n", __LINE__); res_reg[0] = 0x20; res_reg[1] = SONY_TIMEOUT_OP_ERR; *res_size = 2; @@ -1475,29 +1254,13 @@ read_data_block(char *buffer, SONY_NO_LECC_ERR_BLK_STAT) || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT)) { - /* The data was successful, but if data was read from - the readahead and it was bad, set the whole - buffer as bad. */ - if (readahead_bad) { - readahead_bad = 0; - res_reg[0] = 0x20; - res_reg[1] = - SONY_BAD_DATA_ERR; - *res_size = 2; - } + /* nothing here */ } else { - printk - ("CDU31A: Data block error: 0x%x\n", - res_reg[0]); + printk(KERN_ERR PFX "Data block " + "error: 0x%x\n", res_reg[0]); res_reg[0] = 0x20; res_reg[1] = SONY_BAD_DATA_ERR; *res_size = 2; - - /* Data is in the readahead buffer but an error was returned. - Make sure future requests don't use the data. */ - if (bytesleft != 2048) { - readahead_bad = 1; - } } /* Final transfer is done for read command, get final result. */ @@ -1507,9 +1270,8 @@ read_data_block(char *buffer, } else if ((res_reg[0] & 0xf0) != 0x20) { /* The drive gave me bad status, I don't know what to do. Reset the driver and return an error. */ - printk - ("CDU31A: Invalid block status: 0x%x\n", - res_reg[0]); + printk(KERN_ERR PFX "Invalid block " + "status: 0x%x\n", res_reg[0]); restart_on_error(); res_reg[0] = 0x20; res_reg[1] = SONY_BAD_DATA_ERR; @@ -1517,9 +1279,7 @@ read_data_block(char *buffer, } } } -#if DEBUG - printk("Leaving read_data_block at %d\n", __LINE__); -#endif + pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); } @@ -1533,37 +1293,17 @@ read_data_block(char *buffer, static void do_cdu31a_request(request_queue_t * q) { struct request *req; - int block; - int nblock; + int block, nblock, num_retries; unsigned char res_reg[12]; unsigned int res_size; - int num_retries; - unsigned long flags; - -#if DEBUG - printk("Entering do_cdu31a_request\n"); -#endif + pr_debug(PFX "Entering %s\n", __FUNCTION__); - /* - * Make sure no one else is using the driver; wait for them - * to finish if it is so. - */ - save_flags(flags); - cli(); - while (sony_inuse) { - interruptible_sleep_on(&sony_wait); - if (signal_pending(current)) { - restore_flags(flags); -#if DEBUG - printk("Leaving do_cdu31a_request at %d\n", - __LINE__); -#endif - return; - } + spin_unlock_irq(q->queue_lock); + if (down_interruptible(&sony_sem)) { + spin_lock_irq(q->queue_lock); + return; } - sony_inuse = 1; - has_cd_task = current; /* Get drive status before doing anything. */ while (handle_sony_cd_attention()); @@ -1571,10 +1311,6 @@ static void do_cdu31a_request(request_queue_t * q) /* Make sure we have a valid TOC. */ sony_get_toc(); - /* - * jens: driver has lots of races - */ - spin_unlock_irq(q->queue_lock); /* Make sure the timer is cancelled. */ del_timer(&cdu31a_abort_timer); @@ -1593,44 +1329,43 @@ static void do_cdu31a_request(request_queue_t * q) block = req->sector; nblock = req->nr_sectors; - + pr_debug(PFX "request at block %d, length %d blocks\n", + block, nblock); if (!sony_toc_read) { - printk("CDU31A: TOC not read\n"); + printk(KERN_NOTICE PFX "TOC not read\n"); end_request(req, 0); continue; } /* WTF??? */ - if (!(req->flags & REQ_CMD)) + if (!blk_fs_request(req)) { + end_request(req, 0); continue; + } if (rq_data_dir(req) == WRITE) { end_request(req, 0); continue; } - if (rq_data_dir(req) != READ) - panic("CDU31A: Unknown cmd"); + /* * If the block address is invalid or the request goes beyond the end of * the media, return an error. */ - if ((block / 4) >= sony_toc.lead_out_start_lba) { - printk("CDU31A: Request past end of media\n"); - end_request(req, 0); - continue; - } if (((block + nblock) / 4) >= sony_toc.lead_out_start_lba) { - printk("CDU31A: Request past end of media\n"); + printk(KERN_NOTICE PFX "Request past end of media\n"); end_request(req, 0); continue; } + if (nblock > 4) + nblock = 4; num_retries = 0; try_read_again: while (handle_sony_cd_attention()); if (!sony_toc_read) { - printk("CDU31A: TOC not read\n"); + printk(KERN_NOTICE PFX "TOC not read\n"); end_request(req, 0); continue; } @@ -1638,7 +1373,7 @@ static void do_cdu31a_request(request_queue_t * q) /* If no data is left to be read from the drive, start the next request. */ if (sony_blocks_left == 0) { - if (start_request(block / 4, CDU31A_READAHEAD / 4, 0)) { + if (start_request(block / 4, nblock / 4)) { end_request(req, 0); continue; } @@ -1647,18 +1382,16 @@ static void do_cdu31a_request(request_queue_t * q) the driver, abort the current operation and start a new one. */ else if (block != sony_next_block) { -#if DEBUG - printk("CDU31A Warning: Read for block %d, expected %d\n", + pr_debug(PFX "Read for block %d, expected %d\n", block, sony_next_block); -#endif abort_read(); if (!sony_toc_read) { - printk("CDU31A: TOC not read\n"); + printk(KERN_NOTICE PFX "TOC not read\n"); end_request(req, 0); continue; } - if (start_request(block / 4, CDU31A_READAHEAD / 4, 0)) { - printk("CDU31a: start request failed\n"); + if (start_request(block / 4, nblock / 4)) { + printk(KERN_NOTICE PFX "start request failed\n"); end_request(req, 0); continue; } @@ -1667,7 +1400,12 @@ static void do_cdu31a_request(request_queue_t * q) read_data_block(req->buffer, block, nblock, res_reg, &res_size); if (res_reg[0] != 0x20) { - end_request(req, 1); + if (!end_that_request_first(req, 1, nblock)) { + spin_lock_irq(q->queue_lock); + blkdev_dequeue_request(req); + end_that_request_last(req, 1); + spin_unlock_irq(q->queue_lock); + } continue; } @@ -1681,13 +1419,12 @@ static void do_cdu31a_request(request_queue_t * q) do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size); } else { - printk("CDU31A: %s error for block %d, nblock %d\n", + printk(KERN_NOTICE PFX "%s error for block %d, nblock %d\n", translate_error(res_reg[1]), block, nblock); } goto try_read_again; } end_do_cdu31a_request: - spin_lock_irq(q->queue_lock); #if 0 /* After finished, cancel any pending operations. */ abort_read(); @@ -1698,13 +1435,9 @@ static void do_cdu31a_request(request_queue_t * q) add_timer(&cdu31a_abort_timer); #endif - has_cd_task = NULL; - sony_inuse = 0; - wake_up_interruptible(&sony_wait); - restore_flags(flags); -#if DEBUG - printk("Leaving do_cdu31a_request at %d\n", __LINE__); -#endif + up(&sony_sem); + spin_lock_irq(q->queue_lock); + pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__); } @@ -1723,9 +1456,7 @@ static void sony_get_toc(void) int mint = 99; int maxt = 0; -#if DEBUG - printk("Entering sony_get_toc\n"); -#endif + pr_debug(PFX "Entering %s\n", __FUNCTION__); num_spin_ups = 0; if (!sony_toc_read) { @@ -1776,16 +1507,12 @@ static void sony_get_toc(void) /* This seems to slow things down enough to make it work. This * appears to be a problem in do_sony_cd_cmd. This printk seems * to address the symptoms... -Erik */ -#if 1 - printk("cdu31a: Trying session %d\n", session); -#endif + pr_debug(PFX "Trying session %d\n", session); parms[0] = session; do_sony_cd_cmd(SONY_READ_TOC_SPEC_CMD, parms, 1, res_reg, &res_size); -#if DEBUG - printk("%2.2x %2.2x\n", res_reg[0], res_reg[1]); -#endif + pr_debug(PFX "%2.2x %2.2x\n", res_reg[0], res_reg[1]); if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) { @@ -1795,9 +1522,7 @@ static void sony_get_toc(void) ("Yikes! Couldn't read any sessions!"); break; } -#if DEBUG - printk("Reading session %d\n", session); -#endif + pr_debug(PFX "Reading session %d\n", session); parms[0] = session; do_sony_cd_cmd(SONY_REQ_TOC_DATA_SPEC_CMD, @@ -1808,8 +1533,8 @@ static void sony_get_toc(void) if ((res_size < 2) || ((single_toc.exec_status[0] & 0xf0) == 0x20)) { - printk - ("cdu31a: Error reading session %d: %x %s\n", + printk(KERN_ERR PFX "Error reading " + "session %d: %x %s\n", session, single_toc.exec_status[0], translate_error(single_toc. exec_status[1])); @@ -1817,29 +1542,27 @@ static void sony_get_toc(void) set. */ return; } -#if DEBUG - printk - ("add0 %01x, con0 %01x, poi0 %02x, 1st trk %d, dsktyp %x, dum0 %x\n", + pr_debug(PFX "add0 %01x, con0 %01x, poi0 %02x, " + "1st trk %d, dsktyp %x, dum0 %x\n", single_toc.address0, single_toc.control0, single_toc.point0, bcd_to_int(single_toc.first_track_num), single_toc.disk_type, single_toc.dummy0); - printk - ("add1 %01x, con1 %01x, poi1 %02x, lst trk %d, dummy1 %x, dum2 %x\n", + pr_debug(PFX "add1 %01x, con1 %01x, poi1 %02x, " + "lst trk %d, dummy1 %x, dum2 %x\n", single_toc.address1, single_toc.control1, single_toc.point1, bcd_to_int(single_toc.last_track_num), single_toc.dummy1, single_toc.dummy2); - printk - ("add2 %01x, con2 %01x, poi2 %02x leadout start min %d, sec %d, frame %d\n", + pr_debug(PFX "add2 %01x, con2 %01x, poi2 %02x " + "leadout start min %d, sec %d, frame %d\n", single_toc.address2, single_toc.control2, single_toc.point2, bcd_to_int(single_toc.lead_out_start_msf[0]), bcd_to_int(single_toc.lead_out_start_msf[1]), bcd_to_int(single_toc.lead_out_start_msf[2])); if (res_size > 18 && single_toc.pointb0 > 0xaf) - printk - ("addb0 %01x, conb0 %01x, poib0 %02x, nextsession min %d, sec %d, frame %d\n" + pr_debug(PFX "addb0 %01x, conb0 %01x, poib0 %02x, nextsession min %d, sec %d, frame %d\n" "#mode5_ptrs %02d, max_start_outer_leadout_msf min %d, sec %d, frame %d\n", single_toc.addressb0, single_toc.controlb0, @@ -1864,8 +1587,7 @@ static void sony_get_toc(void) max_start_outer_leadout_msf [2])); if (res_size > 27 && single_toc.pointb1 > 0xaf) - printk - ("addb1 %01x, conb1 %01x, poib1 %02x, %x %x %x %x #skipint_ptrs %d, #skiptrkassign %d %x\n", + pr_debug(PFX "addb1 %01x, conb1 %01x, poib1 %02x, %x %x %x %x #skipint_ptrs %d, #skiptrkassign %d %x\n", single_toc.addressb1, single_toc.controlb1, single_toc.pointb1, @@ -1877,8 +1599,7 @@ static void sony_get_toc(void) single_toc.num_skip_track_assignments, single_toc.dummyb0_2); if (res_size > 36 && single_toc.pointb2 > 0xaf) - printk - ("addb2 %01x, conb2 %01x, poib2 %02x, %02x %02x %02x %02x %02x %02x %02x\n", + pr_debug(PFX "addb2 %01x, conb2 %01x, poib2 %02x, %02x %02x %02x %02x %02x %02x %02x\n", single_toc.addressb2, single_toc.controlb2, single_toc.pointb2, @@ -1890,8 +1611,7 @@ static void sony_get_toc(void) single_toc.tracksb2[5], single_toc.tracksb2[6]); if (res_size > 45 && single_toc.pointb3 > 0xaf) - printk - ("addb3 %01x, conb3 %01x, poib3 %02x, %02x %02x %02x %02x %02x %02x %02x\n", + pr_debug(PFX "addb3 %01x, conb3 %01x, poib3 %02x, %02x %02x %02x %02x %02x %02x %02x\n", single_toc.addressb3, single_toc.controlb3, single_toc.pointb3, @@ -1903,8 +1623,7 @@ static void sony_get_toc(void) single_toc.tracksb3[5], single_toc.tracksb3[6]); if (res_size > 54 && single_toc.pointb4 > 0xaf) - printk - ("addb4 %01x, conb4 %01x, poib4 %02x, %02x %02x %02x %02x %02x %02x %02x\n", + pr_debug(PFX "addb4 %01x, conb4 %01x, poib4 %02x, %02x %02x %02x %02x %02x %02x %02x\n", single_toc.addressb4, single_toc.controlb4, single_toc.pointb4, @@ -1916,8 +1635,7 @@ static void sony_get_toc(void) single_toc.tracksb4[5], single_toc.tracksb4[6]); if (res_size > 63 && single_toc.pointc0 > 0xaf) - printk - ("addc0 %01x, conc0 %01x, poic0 %02x, %02x %02x %02x %02x %02x %02x %02x\n", + pr_debug(PFX "addc0 %01x, conc0 %01x, poic0 %02x, %02x %02x %02x %02x %02x %02x %02x\n", single_toc.addressc0, single_toc.controlc0, single_toc.pointc0, @@ -1928,7 +1646,6 @@ static void sony_get_toc(void) single_toc.dummyc0[4], single_toc.dummyc0[5], single_toc.dummyc0[6]); -#endif #undef DEBUG #define DEBUG 0 @@ -1997,8 +1714,8 @@ static void sony_get_toc(void) res_size += 9; } #if DEBUG - printk - ("start track lba %u, leadout start lba %u\n", + printk(PRINT_INFO PFX "start track lba %u, " + "leadout start lba %u\n", single_toc.start_track_lba, single_toc.lead_out_start_lba); { @@ -2010,8 +1727,7 @@ static void sony_get_toc(void) - bcd_to_int(single_toc. first_track_num); i++) { - printk - ("trk %02d: add 0x%01x, con 0x%01x, track %02d, start min %02d, sec %02d, frame %02d\n", + printk(KERN_INFO PFX "trk %02d: add 0x%01x, con 0x%01x, track %02d, start min %02d, sec %02d, frame %02d\n", i, single_toc.tracks[i].address, single_toc.tracks[i].control, @@ -2044,8 +1760,8 @@ static void sony_get_toc(void) tracks[i]. track); } - printk - ("min track number %d, max track number %d\n", + printk(KERN_INFO PFX "min track number %d, " + "max track number %d\n", mint, maxt); } #endif @@ -2150,8 +1866,8 @@ static void sony_get_toc(void) /* Let's not get carried away... */ if (session > 40) { - printk("cdu31a: too many sessions: %d\n", - session); + printk(KERN_NOTICE PFX "too many sessions: " + "%d\n", session); break; } session++; @@ -2169,17 +1885,13 @@ static void sony_get_toc(void) sony_toc.lead_out_start_msf[2]; sony_toc_read = 1; -#undef DEBUG -#if DEBUG - printk - ("Disk session %d, start track: %d, stop track: %d\n", + + pr_debug(PFX "Disk session %d, start track: %d, " + "stop track: %d\n", session, single_toc.start_track_lba, single_toc.lead_out_start_lba); -#endif } -#if DEBUG - printk("Leaving sony_get_toc\n"); -#endif + pr_debug(PFX "Leaving %s\n", __FUNCTION__); } @@ -2193,8 +1905,12 @@ static int scd_get_last_session(struct cdrom_device_info *cdi, if (ms_info == NULL) return 1; - if (!sony_toc_read) + if (!sony_toc_read) { + if (down_interruptible(&sony_sem)) + return -ERESTARTSYS; sony_get_toc(); + up(&sony_sem); + } ms_info->addr_format = CDROM_LBA; ms_info->addr.lba = sony_toc.start_track_lba; @@ -2234,7 +1950,7 @@ static int read_subcode(void) 0, (unsigned char *) &last_sony_subcode, &res_size); if ((res_size < 2) || ((last_sony_subcode.exec_status[0] & 0xf0) == 0x20)) { - printk("Sony CDROM error %s (read_subcode)\n", + printk(KERN_ERR PFX "Sony CDROM error %s (read_subcode)\n", translate_error(last_sony_subcode.exec_status[1])); return -EIO; } @@ -2272,8 +1988,11 @@ scd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) unsigned int res_size; memset(mcn->medium_catalog_number, 0, 14); + if (down_interruptible(&sony_sem)) + return -ERESTARTSYS; do_sony_cd_cmd(SONY_REQ_UPC_EAN_CMD, NULL, 0, resbuffer, &res_size); + up(&sony_sem); if ((res_size < 2) || ((resbuffer[0] & 0xf0) == 0x20)); else { /* packed bcd to single ASCII digits */ @@ -2402,8 +2121,8 @@ read_audio_data(char *buffer, unsigned char res_reg[], int *res_size) } /* Invalid data from the drive. Shut down the operation. */ else if ((res_reg[0] & 0xf0) != 0x20) { - printk - ("CDU31A: Got result that should have been error: %d\n", + printk(KERN_WARNING PFX "Got result that " + "should have been error: %d\n", res_reg[0]); res_reg[0] = 0x20; res_reg[1] = SONY_BAD_DATA_ERR; @@ -2411,9 +2130,7 @@ read_audio_data(char *buffer, unsigned char res_reg[], int *res_size) } abort_read(); } else { -#if DEBUG - printk("CDU31A timeout out %d\n", __LINE__); -#endif + pr_debug(PFX "timeout out %d\n", __LINE__); res_reg[0] = 0x20; res_reg[1] = SONY_TIMEOUT_OP_ERR; *res_size = 2; @@ -2443,10 +2160,7 @@ read_audio_data(char *buffer, unsigned char res_reg[], int *res_size) } if (!is_result_ready()) { -#if DEBUG - printk("CDU31A timeout out %d\n", - __LINE__); -#endif + pr_debug(PFX "timeout out %d\n", __LINE__); res_reg[0] = 0x20; res_reg[1] = SONY_TIMEOUT_OP_ERR; *res_size = 2; @@ -2464,7 +2178,7 @@ read_audio_data(char *buffer, unsigned char res_reg[], int *res_size) || (res_reg[0] == SONY_NO_ERR_DETECTION_STAT)) { /* Ok, nothing to do. */ } else { - printk("CDU31A: Data block error: 0x%x\n", + printk(KERN_ERR PFX "Data block error: 0x%x\n", res_reg[0]); res_reg[0] = 0x20; res_reg[1] = SONY_BAD_DATA_ERR; @@ -2473,7 +2187,7 @@ read_audio_data(char *buffer, unsigned char res_reg[], int *res_size) } else if ((res_reg[0] & 0xf0) != 0x20) { /* The drive gave me bad status, I don't know what to do. Reset the driver and return an error. */ - printk("CDU31A: Invalid block status: 0x%x\n", + printk(KERN_NOTICE PFX "Invalid block status: 0x%x\n", res_reg[0]); restart_on_error(); res_reg[0] = 0x20; @@ -2492,28 +2206,11 @@ static int read_audio(struct cdrom_read_audio *ra) unsigned char res_reg[12]; unsigned int res_size; unsigned int cframe; - unsigned long flags; - - /* - * Make sure no one else is using the driver; wait for them - * to finish if it is so. - */ - save_flags(flags); - cli(); - while (sony_inuse) { - interruptible_sleep_on(&sony_wait); - if (signal_pending(current)) { - restore_flags(flags); - return -EAGAIN; - } - } - sony_inuse = 1; - has_cd_task = current; - restore_flags(flags); - if (!sony_spun_up) { + if (down_interruptible(&sony_sem)) + return -ERESTARTSYS; + if (!sony_spun_up) scd_spinup(); - } /* Set the drive to do raw operations. */ params[0] = SONY_SD_DECODE_PARAM; @@ -2521,9 +2218,10 @@ static int read_audio(struct cdrom_read_audio *ra) do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD, params, 2, res_reg, &res_size); if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) { - printk("CDU31A: Unable to set decode params: 0x%2.2x\n", + printk(KERN_ERR PFX "Unable to set decode params: 0x%2.2x\n", res_reg[1]); - return -EIO; + retval = -EIO; + goto out_up; } /* From here down, we have to goto exit_read_audio instead of returning @@ -2531,8 +2229,7 @@ static int read_audio(struct cdrom_read_audio *ra) return. */ retval = 0; - /* start_request clears out any readahead data, so it should be safe. */ - if (start_request(ra->addr.lba, ra->nframes, 1)) { + if (start_request(ra->addr.lba, ra->nframes)) { retval = -EIO; goto exit_read_audio; } @@ -2540,11 +2237,11 @@ static int read_audio(struct cdrom_read_audio *ra) /* For every requested frame. */ cframe = 0; while (cframe < ra->nframes) { - read_audio_data(readahead_buffer, res_reg, &res_size); + read_audio_data(audio_buffer, res_reg, &res_size); if ((res_reg[0] & 0xf0) == 0x20) { if (res_reg[1] == SONY_BAD_DATA_ERR) { - printk - ("CDU31A: Data error on audio sector %d\n", + printk(KERN_ERR PFX "Data error on audio " + "sector %d\n", ra->addr.lba + cframe); } else if (res_reg[1] == SONY_ILL_TRACK_R_ERR) { /* Illegal track type, change track types and start over. */ @@ -2559,8 +2256,8 @@ static int read_audio(struct cdrom_read_audio *ra) 2, res_reg, &res_size); if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) { - printk - ("CDU31A: Unable to set decode params: 0x%2.2x\n", + printk(KERN_ERR PFX "Unable to set " + "decode params: 0x%2.2x\n", res_reg[1]); retval = -EIO; goto exit_read_audio; @@ -2569,7 +2266,7 @@ static int read_audio(struct cdrom_read_audio *ra) /* Restart the request on the current frame. */ if (start_request (ra->addr.lba + cframe, - ra->nframes - cframe, 1)) { + ra->nframes - cframe)) { retval = -EIO; goto exit_read_audio; } @@ -2577,18 +2274,17 @@ static int read_audio(struct cdrom_read_audio *ra) /* Don't go back to the top because don't want to get into and infinite loop. A lot of code gets duplicated, but that's no big deal, I don't guess. */ - read_audio_data(readahead_buffer, res_reg, + read_audio_data(audio_buffer, res_reg, &res_size); if ((res_reg[0] & 0xf0) == 0x20) { if (res_reg[1] == SONY_BAD_DATA_ERR) { - printk - ("CDU31A: Data error on audio sector %d\n", + printk(KERN_ERR PFX "Data error" + " on audio sector %d\n", ra->addr.lba + cframe); } else { - printk - ("CDU31A: Error reading audio data on sector %d: %s\n", + printk(KERN_ERR PFX "Error reading audio data on sector %d: %s\n", ra->addr.lba + cframe, translate_error (res_reg[1])); @@ -2598,21 +2294,21 @@ static int read_audio(struct cdrom_read_audio *ra) } else if (copy_to_user(ra->buf + (CD_FRAMESIZE_RAW * cframe), - readahead_buffer, + audio_buffer, CD_FRAMESIZE_RAW)) { retval = -EFAULT; goto exit_read_audio; } } else { - printk - ("CDU31A: Error reading audio data on sector %d: %s\n", + printk(KERN_ERR PFX "Error reading audio " + "data on sector %d: %s\n", ra->addr.lba + cframe, translate_error(res_reg[1])); retval = -EIO; goto exit_read_audio; } } else if (copy_to_user(ra->buf + (CD_FRAMESIZE_RAW * cframe), - (char *)readahead_buffer, + (char *)audio_buffer, CD_FRAMESIZE_RAW)) { retval = -EFAULT; goto exit_read_audio; @@ -2623,7 +2319,7 @@ static int read_audio(struct cdrom_read_audio *ra) get_result(res_reg, &res_size); if ((res_reg[0] & 0xf0) == 0x20) { - printk("CDU31A: Error return from audio read: %s\n", + printk(KERN_ERR PFX "Error return from audio read: %s\n", translate_error(res_reg[1])); retval = -EIO; goto exit_read_audio; @@ -2641,16 +2337,15 @@ static int read_audio(struct cdrom_read_audio *ra) do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD, params, 2, res_reg, &res_size); if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) { - printk("CDU31A: Unable to reset decode params: 0x%2.2x\n", + printk(KERN_ERR PFX "Unable to reset decode params: 0x%2.2x\n", res_reg[1]); - return -EIO; + retval = -EIO; } - has_cd_task = NULL; - sony_inuse = 0; - wake_up_interruptible(&sony_wait); + out_up: + up(&sony_sem); - return (retval); + return retval; } static int @@ -2663,7 +2358,7 @@ do_sony_cd_cmd_chk(const char *name, do_sony_cd_cmd(cmd, params, num_params, result_buffer, result_size); if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20)) { - printk("Sony CDROM error %s (CDROM%s)\n", + printk(KERN_ERR PFX "Error %s (CDROM%s)\n", translate_error(result_buffer[1]), name); return -EIO; } @@ -2676,6 +2371,10 @@ do_sony_cd_cmd_chk(const char *name, */ static int scd_tray_move(struct cdrom_device_info *cdi, int position) { + int retval; + + if (down_interruptible(&sony_sem)) + return -ERESTARTSYS; if (position == 1 /* open tray */ ) { unsigned char res_reg[12]; unsigned int res_size; @@ -2686,13 +2385,15 @@ static int scd_tray_move(struct cdrom_device_info *cdi, int position) &res_size); sony_audio_status = CDROM_AUDIO_INVALID; - return do_sony_cd_cmd_chk("EJECT", SONY_EJECT_CMD, NULL, 0, + retval = do_sony_cd_cmd_chk("EJECT", SONY_EJECT_CMD, NULL, 0, res_reg, &res_size); } else { if (0 == scd_spinup()) sony_spun_up = 1; - return 0; + retval = 0; } + up(&sony_sem); + return retval; } /* @@ -2704,12 +2405,13 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi, unsigned char res_reg[12]; unsigned int res_size; unsigned char params[7]; - int i; - + int i, retval; + if (down_interruptible(&sony_sem)) + return -ERESTARTSYS; switch (cmd) { case CDROMSTART: /* Spin up the drive */ - return do_sony_cd_cmd_chk("START", SONY_SPIN_UP_CMD, NULL, + retval = do_sony_cd_cmd_chk("START", SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size); break; @@ -2722,28 +2424,33 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi, * already not spinning. */ sony_audio_status = CDROM_AUDIO_NO_STATUS; - return do_sony_cd_cmd_chk("STOP", SONY_SPIN_DOWN_CMD, NULL, + retval = do_sony_cd_cmd_chk("STOP", SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size); + break; case CDROMPAUSE: /* Pause the drive */ if (do_sony_cd_cmd_chk ("PAUSE", SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, - &res_size)) - return -EIO; + &res_size)) { + retval = -EIO; + break; + } /* Get the current position and save it for resuming */ if (read_subcode() < 0) { - return -EIO; + retval = -EIO; + break; } cur_pos_msf[0] = last_sony_subcode.abs_msf[0]; cur_pos_msf[1] = last_sony_subcode.abs_msf[1]; cur_pos_msf[2] = last_sony_subcode.abs_msf[2]; sony_audio_status = CDROM_AUDIO_PAUSED; - return 0; + retval = 0; break; case CDROMRESUME: /* Start the drive after being paused */ if (sony_audio_status != CDROM_AUDIO_PAUSED) { - return -EINVAL; + retval = -EINVAL; + break; } do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, @@ -2759,10 +2466,13 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi, params[0] = 0x03; if (do_sony_cd_cmd_chk ("RESUME", SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, - &res_size) < 0) - return -EIO; + &res_size) < 0) { + retval = -EIO; + break; + } sony_audio_status = CDROM_AUDIO_PLAY; - return 0; + retval = 0; + break; case CDROMPLAYMSF: /* Play starting at the given MSF address. */ do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, @@ -2776,15 +2486,18 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi, params[0] = 0x03; if (do_sony_cd_cmd_chk ("PLAYMSF", SONY_AUDIO_PLAYBACK_CMD, params, 7, - res_reg, &res_size) < 0) - return -EIO; + res_reg, &res_size) < 0) { + retval = -EIO; + break; + } /* Save the final position for pauses and resumes */ final_pos_msf[0] = bcd_to_int(params[4]); final_pos_msf[1] = bcd_to_int(params[5]); final_pos_msf[2] = bcd_to_int(params[6]); sony_audio_status = CDROM_AUDIO_PLAY; - return 0; + retval = 0; + break; case CDROMREADTOCHDR: /* Read the table of contents header */ { @@ -2792,14 +2505,16 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi, sony_get_toc(); if (!sony_toc_read) { - return -EIO; + retval = -EIO; + break; } hdr = (struct cdrom_tochdr *) arg; hdr->cdth_trk0 = sony_toc.first_track_num; hdr->cdth_trk1 = sony_toc.last_track_num; } - return 0; + retval = 0; + break; case CDROMREADTOCENTRY: /* Read a given table of contents entry */ { @@ -2809,14 +2524,16 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi, sony_get_toc(); if (!sony_toc_read) { - return -EIO; + retval = -EIO; + break; } entry = (struct cdrom_tocentry *) arg; track_idx = find_track(entry->cdte_track); if (track_idx < 0) { - return -EINVAL; + retval = -EINVAL; + break; } entry->cdte_adr = @@ -2837,7 +2554,7 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi, *(msf_val + 2); } } - return 0; + retval = 0; break; case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */ @@ -2847,18 +2564,21 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi, sony_get_toc(); if (!sony_toc_read) { - return -EIO; + retval = -EIO; + break; } if ((ti->cdti_trk0 < sony_toc.first_track_num) || (ti->cdti_trk0 > sony_toc.last_track_num) || (ti->cdti_trk1 < ti->cdti_trk0)) { - return -EINVAL; + retval = -EINVAL; + break; } track_idx = find_track(ti->cdti_trk0); if (track_idx < 0) { - return -EINVAL; + retval = -EINVAL; + break; } params[1] = int_to_bcd(sony_toc.tracks[track_idx]. @@ -2880,7 +2600,8 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi, track_idx = find_track(ti->cdti_trk1 + 1); } if (track_idx < 0) { - return -EINVAL; + retval = -EINVAL; + break; } params[4] = int_to_bcd(sony_toc.tracks[track_idx]. @@ -2901,14 +2622,16 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi, if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) { - printk("Params: %x %x %x %x %x %x %x\n", + printk(KERN_ERR PFX + "Params: %x %x %x %x %x %x %x\n", params[0], params[1], params[2], params[3], params[4], params[5], params[6]); - printk - ("Sony CDROM error %s (CDROMPLAYTRKIND)\n", + printk(KERN_ERR PFX + "Error %s (CDROMPLAYTRKIND)\n", translate_error(res_reg[1])); - return -EIO; + retval = -EIO; + break; } /* Save the final position for pauses and resumes */ @@ -2916,7 +2639,8 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi, final_pos_msf[1] = bcd_to_int(params[5]); final_pos_msf[2] = bcd_to_int(params[6]); sony_audio_status = CDROM_AUDIO_PLAY; - return 0; + retval = 0; + break; } case CDROMVOLCTRL: /* Volume control. What volume does this change, anyway? */ @@ -2927,25 +2651,32 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi, params[0] = SONY_SD_AUDIO_VOLUME; params[1] = volctrl->channel0; params[2] = volctrl->channel1; - return do_sony_cd_cmd_chk("VOLCTRL", + retval = do_sony_cd_cmd_chk("VOLCTRL", SONY_SET_DRIVE_PARAM_CMD, params, 3, res_reg, &res_size); + break; } case CDROMSUBCHNL: /* Get subchannel info */ - return sony_get_subchnl_info((struct cdrom_subchnl *) arg); + retval = sony_get_subchnl_info((struct cdrom_subchnl *) arg); + break; default: - return -EINVAL; + retval = -EINVAL; + break; } + up(&sony_sem); + return retval; } -static int scd_dev_ioctl(struct cdrom_device_info *cdi, +static int scd_read_audio(struct cdrom_device_info *cdi, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; - int i; + int retval; + if (down_interruptible(&sony_sem)) + return -ERESTARTSYS; switch (cmd) { case CDROMREADAUDIO: /* Read 2352 byte audio tracks and 2340 byte raw data tracks. */ @@ -2955,33 +2686,38 @@ static int scd_dev_ioctl(struct cdrom_device_info *cdi, sony_get_toc(); if (!sony_toc_read) { - return -EIO; + retval = -EIO; + break; } - if (copy_from_user(&ra, argp, sizeof(ra))) - return -EFAULT; + if (copy_from_user(&ra, argp, sizeof(ra))) { + retval = -EFAULT; + break; + } if (ra.nframes == 0) { - return 0; + retval = 0; + break; } - i = verify_area(VERIFY_WRITE, ra.buf, - CD_FRAMESIZE_RAW * ra.nframes); - if (i < 0) - return i; + if (!access_ok(VERIFY_WRITE, ra.buf, + CD_FRAMESIZE_RAW * ra.nframes)) + return -EFAULT; if (ra.addr_format == CDROM_LBA) { if ((ra.addr.lba >= sony_toc.lead_out_start_lba) || (ra.addr.lba + ra.nframes >= sony_toc.lead_out_start_lba)) { - return -EINVAL; + retval = -EINVAL; + break; } } else if (ra.addr_format == CDROM_MSF) { if ((ra.addr.msf.minute >= 75) || (ra.addr.msf.second >= 60) || (ra.addr.msf.frame >= 75)) { - return -EINVAL; + retval = -EINVAL; + break; } ra.addr.lba = ((ra.addr.msf.minute * 4500) @@ -2991,7 +2727,8 @@ static int scd_dev_ioctl(struct cdrom_device_info *cdi, sony_toc.lead_out_start_lba) || (ra.addr.lba + ra.nframes >= sony_toc.lead_out_start_lba)) { - return -EINVAL; + retval = -EINVAL; + break; } /* I know, this can go negative on an unsigned. However, @@ -2999,17 +2736,21 @@ static int scd_dev_ioctl(struct cdrom_device_info *cdi, so this should compensate and allow direct msf access. */ ra.addr.lba -= LOG_START_OFFSET; } else { - return -EINVAL; + retval = -EINVAL; + break; } - return (read_audio(&ra)); + retval = read_audio(&ra); + break; } - return 0; + retval = 0; break; default: - return -EINVAL; + retval = -EINVAL; } + up(&sony_sem); + return retval; } static int scd_spinup(void) @@ -3026,7 +2767,7 @@ static int scd_spinup(void) /* The drive sometimes returns error 0. I don't know why, but ignore it. It seems to mean the drive has already done the operation. */ if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) { - printk("Sony CDROM %s error (scd_open, spin up)\n", + printk(KERN_ERR PFX "%s error (scd_open, spin up)\n", translate_error(res_reg[1])); return 1; } @@ -3050,7 +2791,7 @@ static int scd_spinup(void) goto respinup_on_open; } - printk("Sony CDROM error %s (scd_open, read toc)\n", + printk(KERN_ERR PFX "Error %s (scd_open, read toc)\n", translate_error(res_reg[1])); do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size); @@ -3063,12 +2804,18 @@ static int scd_spinup(void) * Open the drive for operations. Spin the drive up and read the table of * contents if these have not already been done. */ -static int scd_open(struct cdrom_device_info *cdi, int openmode) +static int scd_open(struct cdrom_device_info *cdi, int purpose) { unsigned char res_reg[12]; unsigned int res_size; unsigned char params[2]; + if (purpose == 1) { + /* Open for IOCTLs only - no media check */ + sony_usage++; + return 0; + } + if (sony_usage == 0) { if (scd_spinup() != 0) return -EIO; @@ -3090,9 +2837,8 @@ static int scd_open(struct cdrom_device_info *cdi, int openmode) params, 2, res_reg, &res_size); if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) { - printk - ("CDU31A: Unable to set XA params: 0x%2.2x\n", - res_reg[1]); + printk(KERN_WARNING PFX "Unable to set " + "XA params: 0x%2.2x\n", res_reg[1]); } sony_xa_mode = 1; } @@ -3104,9 +2850,8 @@ static int scd_open(struct cdrom_device_info *cdi, int openmode) params, 2, res_reg, &res_size); if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) { - printk - ("CDU31A: Unable to reset XA params: 0x%2.2x\n", - res_reg[1]); + printk(KERN_WARNING PFX "Unable to reset " + "XA params: 0x%2.2x\n", res_reg[1]); } sony_xa_mode = 0; } @@ -3150,12 +2895,10 @@ static struct cdrom_device_ops scd_dops = { .get_mcn = scd_get_mcn, .reset = scd_reset, .audio_ioctl = scd_audio_ioctl, - .dev_ioctl = scd_dev_ioctl, .capability = CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_MULTI_SESSION | - CDC_MULTI_SESSION | CDC_MCN | - CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | - CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS, + CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | + CDC_RESET | CDC_DRIVE_STATUS, .n_minors = 1, }; @@ -3179,7 +2922,27 @@ static int scd_block_release(struct inode *inode, struct file *file) static int scd_block_ioctl(struct inode *inode, struct file *file, unsigned cmd, unsigned long arg) { - return cdrom_ioctl(&scd_info, inode, cmd, arg); + int retval; + + /* The eject and close commands should be handled by Uniform CD-ROM + * driver - but I always got hard lockup instead of eject + * until I put this here. + */ + switch (cmd) { + case CDROMEJECT: + scd_lock_door(&scd_info, 0); + retval = scd_tray_move(&scd_info, 1); + break; + case CDROMCLOSETRAY: + retval = scd_tray_move(&scd_info, 0); + break; + case CDROMREADAUDIO: + retval = scd_read_audio(&scd_info, CDROMREADAUDIO, arg); + break; + default: + retval = cdrom_ioctl(file, &scd_info, inode, cmd, arg); + } + return retval; } static int scd_block_media_changed(struct gendisk *disk) @@ -3187,7 +2950,7 @@ static int scd_block_media_changed(struct gendisk *disk) return cdrom_media_changed(&scd_info); } -struct block_device_operations scd_bdops = +static struct block_device_operations scd_bdops = { .owner = THIS_MODULE, .open = scd_block_open, @@ -3272,7 +3035,6 @@ out_err: #ifndef MODULE /* * Set up base I/O and interrupts, called from main.c. - */ static int __init cdu31a_setup(char *strings) @@ -3291,7 +3053,7 @@ static int __init cdu31a_setup(char *strings) if (strcmp(strings, "PAS") == 0) { sony_pas_init = 1; } else { - printk("CDU31A: Unknown interface type: %s\n", + printk(KERN_NOTICE PFX "Unknown interface type: %s\n", strings); } } @@ -3374,17 +3136,17 @@ int __init cdu31a_init(void) tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */ cdu31a_irq = 0; + sony_speed = is_double_speed; /* Set 2X drives to 2X by default */ set_drive_params(sony_speed); cdu31a_irq = tmp_irq; if (cdu31a_irq > 0) { if (request_irq - (cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT, + (cdu31a_irq, cdu31a_interrupt, IRQF_DISABLED, "cdu31a", NULL)) { - printk - ("Unable to grab IRQ%d for the CDU31A driver\n", - cdu31a_irq); + printk(KERN_WARNING PFX "Unable to grab IRQ%d for " + "the CDU31A driver\n", cdu31a_irq); cdu31a_irq = 0; } } @@ -3419,13 +3181,12 @@ int __init cdu31a_init(void) strcat(msg, buf); } strcat(msg, "\n"); - - is_a_cdu31a = - strcmp("CD-ROM CDU31A", drive_config.product_id) == 0; + printk(KERN_INFO PFX "%s",msg); cdu31a_queue = blk_init_queue(do_cdu31a_request, &cdu31a_lock); if (!cdu31a_queue) goto errout0; + blk_queue_hardsect_size(cdu31a_queue, 2048); init_timer(&cdu31a_abort_timer); cdu31a_abort_timer.function = handle_abort_timeout; @@ -3438,18 +3199,18 @@ int __init cdu31a_init(void) add_disk(disk); disk_changed = 1; - return (0); + return 0; err: blk_cleanup_queue(cdu31a_queue); errout0: if (cdu31a_irq) free_irq(cdu31a_irq, NULL); - printk("Unable to register CDU-31a with Uniform cdrom driver\n"); + printk(KERN_ERR PFX "Unable to register with Uniform cdrom driver\n"); put_disk(disk); errout1: if (unregister_blkdev(MAJOR_NR, "cdu31a")) { - printk("Can't unregister block device for cdu31a\n"); + printk(KERN_WARNING PFX "Can't unregister block device\n"); } errout2: release_region(cdu31a_port, 4); @@ -3458,17 +3219,17 @@ errout3: } -void __exit cdu31a_exit(void) +static void __exit cdu31a_exit(void) { del_gendisk(scd_gendisk); put_disk(scd_gendisk); if (unregister_cdrom(&scd_info)) { - printk - ("Can't unregister cdu31a from Uniform cdrom driver\n"); + printk(KERN_WARNING PFX "Can't unregister from Uniform " + "cdrom driver\n"); return; } if ((unregister_blkdev(MAJOR_NR, "cdu31a") == -EINVAL)) { - printk("Can't unregister cdu31a\n"); + printk(KERN_WARNING PFX "Can't unregister\n"); return; } @@ -3478,7 +3239,7 @@ void __exit cdu31a_exit(void) free_irq(cdu31a_irq, NULL); release_region(cdu31a_port, 4); - printk(KERN_INFO "cdu31a module released.\n"); + printk(KERN_INFO PFX "module released.\n"); } #ifdef MODULE