]> git.neil.brown.name Git - history.git/commitdiff
Import 2.3.19 2.3.19
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:27:28 +0000 (15:27 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:27:28 +0000 (15:27 -0500)
drivers/scsi/sr.c
drivers/scsi/sr_ioctl.c
include/asm-i386/spinlock.h
include/linux/cdrom.h

index 687b0beee4d851321f2f47e42db46299b66d670b..6ba9a2dd5168368477d3c2720f4827fe47d11c09 100644 (file)
@@ -47,7 +47,9 @@
 #include <scsi/scsi_ioctl.h>   /* For the door lock/unlock commands */
 #include "constants.h"
 
+#ifdef MODULE
 MODULE_PARM(xa_test, "i");     /* see sr_ioctl.c */
+#endif
 
 #define MAX_RETRIES    3
 #define SR_TIMEOUT     (30 * HZ)
@@ -106,9 +108,10 @@ static struct cdrom_device_ops sr_dops =
        sr_audio_ioctl,         /* audio ioctl */
        sr_dev_ioctl,           /* device-specific ioctl */
        CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED |
-       CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
-       CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS | CDC_CD_R | CDC_CD_RW |
-       CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_GENERIC_PACKET,
+       CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED |
+       CDC_PLAY_AUDIO | CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS |
+       CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM |
+       CDC_GENERIC_PACKET,
        0,
        sr_packet
 };
@@ -874,17 +877,9 @@ void get_sectorsize(int i)
                memset(buffer, 0, 8);
 
                /* Do the command and wait.. */
-               {
-                       DECLARE_MUTEX_LOCKED(sem);
-                       SCpnt->request.sem = &sem;
-                       spin_lock_irqsave(&io_request_lock, flags);
-                       scsi_do_cmd(SCpnt,
-                                   (void *) cmd, (void *) buffer,
-                                   512, sr_init_done, SR_TIMEOUT,
-                                   MAX_RETRIES);
-                       spin_unlock_irqrestore(&io_request_lock, flags);
-                       down(&sem);
-               }
+
+               scsi_wait_cmd (SCpnt, (void *) cmd, (void *) buffer,
+                       512, sr_init_done,  SR_TIMEOUT,  MAX_RETRIES);
 
                the_result = SCpnt->result;
                retries--;
@@ -958,7 +953,7 @@ void get_capabilities(int i)
                "pop-up",
                "",
                "changer",
-               "changer",
+               "cartridge changer",
                "",
                ""
        };
@@ -1010,6 +1005,20 @@ void get_capabilities(int i)
        if ((buffer[n + 3] & 0x1) == 0)
                /* can't write CD-R media */
                scsi_CDs[i].cdi.mask |= CDC_CD_R;
+       if ((buffer[n+6] & 0x8) == 0)
+               /* can't eject */
+               scsi_CDs[i].cdi.mask |= CDC_OPEN_TRAY;
+
+       if ((buffer[n+6] >> 5) == mechtype_individual_changer ||
+           (buffer[n+6] >> 5) == mechtype_cartridge_changer)
+               scsi_CDs[i].cdi.capacity = 
+                       cdrom_number_of_slots(&(scsi_CDs[i].cdi));
+       if (scsi_CDs[i].cdi.capacity <= 1)
+                /* not a changer */
+               scsi_CDs[i].cdi.mask |= CDC_SELECT_DISC;
+       /*else    I don't think it can close its tray
+               scsi_CDs[i].cdi.mask |= CDC_CLOSE_TRAY; */
+
 
        scsi_free(buffer, 512);
 }
@@ -1022,7 +1031,6 @@ static int sr_packet(struct cdrom_device_info *cdi, struct cdrom_generic_command
 {
        Scsi_Cmnd *SCpnt;
        Scsi_Device *device = scsi_CDs[MINOR(cdi->dev)].device;
-       DECLARE_MUTEX_LOCKED(sem);
        unsigned long flags;
        int stat;
 
@@ -1036,15 +1044,11 @@ static int sr_packet(struct cdrom_device_info *cdi, struct cdrom_generic_command
 
        /* do the locking and issue the command */
        SCpnt->request.rq_dev = cdi->dev;
-       SCpnt->request.rq_status = RQ_SCSI_BUSY;
        /* scsi_do_cmd sets the command length */
        SCpnt->cmd_len = 0;
-       SCpnt->request.sem = &sem;
-       spin_lock_irqsave(&io_request_lock, flags);
-       scsi_do_cmd(SCpnt, (void *) cgc->cmd, (void *) cgc->buffer, cgc->buflen,
-                   sr_init_done, SR_TIMEOUT, MAX_RETRIES);
-       spin_unlock_irqrestore(&io_request_lock, flags);
-       down(&sem);
+       
+       scsi_wait_cmd (SCpnt, (void *)cgc->cmd, (void *)cgc->buffer, cgc->buflen,
+               sr_init_done, SR_TIMEOUT, MAX_RETRIES);
 
        stat = SCpnt->result;
 
index f8dbc3ce3f2ab1698a06493432a8f1b3e591c553..482a5d14c20b2ea62a3e2a6ca9356adc83a843d0 100644 (file)
@@ -293,16 +293,14 @@ int sr_select_speed(struct cdrom_device_info *cdi, int speed)
 int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void* arg)
 {
     u_char  sr_cmd[10];    
-    int result, target;
-    
-    target = MINOR(cdi->dev);
+    int result, target  = MINOR(cdi->dev);
+    unsigned char buffer[32];
     
     switch (cmd) 
     {
     case CDROMREADTOCHDR:
     {
        struct cdrom_tochdr* tochdr = (struct cdrom_tochdr*)arg;
-       char buffer[32];
        
        sr_cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5);
@@ -323,7 +321,6 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void* arg)
     case CDROMREADTOCENTRY:
     {
        struct cdrom_tocentry* tocentry = (struct cdrom_tocentry*)arg;
-       unsigned char buffer[32];
        
        sr_cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) |
index f8254a4929f742c16ee85727adf6728331b64d2d..a10ed9c5c5d84b26022f8c65dd8c209e85450f57 100644 (file)
@@ -62,10 +62,9 @@ __asm__ __volatile__( \
  */
 typedef struct {
        volatile unsigned int lock;
-       unsigned long previous;
 } rwlock_t;
 
-#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
+#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
 
 /*
  * On x86, we implement read-write locks as a 32-bit counter
index 3cda09828bcb288b7a8bee9fc2fd256c4eae4af1..bf37966920460249792915685dd5e0a96a3fec19 100644 (file)
 /* Address in MSF format */
 struct cdrom_msf0              
 {
-       u_char  minute;
-       u_char  second;
-       u_char  frame;
+       __u8    minute;
+       __u8    second;
+       __u8    frame;
 };
 
 /* Address in either MSF or logical format */
@@ -162,48 +162,48 @@ union cdrom_addr
 /* This struct is used by the CDROMPLAYMSF ioctl */ 
 struct cdrom_msf 
 {
-       u_char  cdmsf_min0;     /* start minute */
-       u_char  cdmsf_sec0;     /* start second */
-       u_char  cdmsf_frame0;   /* start frame */
-       u_char  cdmsf_min1;     /* end minute */
-       u_char  cdmsf_sec1;     /* end second */
-       u_char  cdmsf_frame1;   /* end frame */
+       __u8    cdmsf_min0;     /* start minute */
+       __u8    cdmsf_sec0;     /* start second */
+       __u8    cdmsf_frame0;   /* start frame */
+       __u8    cdmsf_min1;     /* end minute */
+       __u8    cdmsf_sec1;     /* end second */
+       __u8    cdmsf_frame1;   /* end frame */
 };
 
 /* This struct is used by the CDROMPLAYTRKIND ioctl */
 struct cdrom_ti 
 {
-       u_char  cdti_trk0;      /* start track */
-       u_char  cdti_ind0;      /* start index */
-       u_char  cdti_trk1;      /* end track */
-       u_char  cdti_ind1;      /* end index */
+       __u8    cdti_trk0;      /* start track */
+       __u8    cdti_ind0;      /* start index */
+       __u8    cdti_trk1;      /* end track */
+       __u8    cdti_ind1;      /* end index */
 };
 
 /* This struct is used by the CDROMREADTOCHDR ioctl */
 struct cdrom_tochdr    
 {
-       u_char  cdth_trk0;      /* start track */
-       u_char  cdth_trk1;      /* end track */
+       __u8    cdth_trk0;      /* start track */
+       __u8    cdth_trk1;      /* end track */
 };
 
 /* This struct is used by the CDROMVOLCTRL and CDROMVOLREAD ioctls */
 struct cdrom_volctrl
 {
-       u_char  channel0;
-       u_char  channel1;
-       u_char  channel2;
-       u_char  channel3;
+       __u8    channel0;
+       __u8    channel1;
+       __u8    channel2;
+       __u8    channel3;
 };
 
 /* This struct is used by the CDROMSUBCHNL ioctl */
 struct cdrom_subchnl 
 {
-       u_char  cdsc_format;
-       u_char  cdsc_audiostatus;
-       u_char  cdsc_adr:       4;
-       u_char  cdsc_ctrl:      4;
-       u_char  cdsc_trk;
-       u_char  cdsc_ind;
+       __u8    cdsc_format;
+       __u8    cdsc_audiostatus;
+       __u8    cdsc_adr:       4;
+       __u8    cdsc_ctrl:      4;
+       __u8    cdsc_trk;
+       __u8    cdsc_ind;
        union cdrom_addr cdsc_absaddr;
        union cdrom_addr cdsc_reladdr;
 };
@@ -212,12 +212,12 @@ struct cdrom_subchnl
 /* This struct is used by the CDROMREADTOCENTRY ioctl */
 struct cdrom_tocentry 
 {
-       u_char  cdte_track;
-       u_char  cdte_adr        :4;
-       u_char  cdte_ctrl       :4;
-       u_char  cdte_format;
+       __u8    cdte_track;
+       __u8    cdte_adr        :4;
+       __u8    cdte_ctrl       :4;
+       __u8    cdte_format;
        union cdrom_addr cdte_addr;
-       u_char  cdte_datamode;
+       __u8    cdte_datamode;
 };
 
 /* This struct is used by the CDROMREADMODE1, and CDROMREADMODE2 ioctls */
@@ -232,9 +232,9 @@ struct cdrom_read
 struct cdrom_read_audio
 {
        union cdrom_addr addr; /* frame address */
-       u_char addr_format;    /* CDROM_LBA or CDROM_MSF */
+       __u8 addr_format;    /* CDROM_LBA or CDROM_MSF */
        int nframes;           /* number of 2352-byte-frames to read at once */
-       u_char *buf;           /* frame buffer (size: nframes*2352 bytes) */
+       __u8 *buf;           /* frame buffer (size: nframes*2352 bytes) */
 };
 
 /* This struct is used with the CDROMMULTISESSION ioctl */
@@ -243,8 +243,8 @@ struct cdrom_multisession
        union cdrom_addr addr; /* frame address: start-of-last-session 
                                   (not the new "frame 16"!).  Only valid
                                   if the "xa_flag" is true. */
-       u_char xa_flag;        /* 1: "is XA disk" */
-       u_char addr_format;    /* CDROM_LBA or CDROM_MSF */
+       __u8 xa_flag;        /* 1: "is XA disk" */
+       __u8 addr_format;    /* CDROM_LBA or CDROM_MSF */
 };
 
 /* This struct is used with the CDROM_GET_MCN ioctl.  
@@ -254,7 +254,7 @@ struct cdrom_multisession
  */  
 struct cdrom_mcn 
 {
-  u_char medium_catalog_number[14]; /* 13 ASCII digits, null-terminated */
+  __u8 medium_catalog_number[14]; /* 13 ASCII digits, null-terminated */
 };
 
 /* This is used by the CDROMPLAYBLK ioctl */
@@ -400,6 +400,14 @@ struct cdrom_generic_command
 #define CDSL_NONE              ((int) (~0U>>1)-1)
 #define CDSL_CURRENT           ((int) (~0U>>1))
 
+/* For partition based multisession access. IDE can handle 64 partitions
+ * per drive - SCSI CD-ROM's use minors to differentiate between the
+ * various drives, so we can't do multisessions the same way there.
+ * Use the -o session=x option to mount on them.
+ */
+#define CD_PART_MAX            64
+#define CD_PART_MASK           (CD_PART_MAX - 1)
+
 /*********************************************************************
  * Generic Packet commands, MMC commands, and such
  *********************************************************************/
@@ -495,59 +503,59 @@ struct cdrom_generic_command
 #define DVD_STRUCT_MANUFACT    0x04
 
 struct dvd_layer {
-       u_char book_version     : 4;
-       u_char book_type        : 4;
-       u_char min_rate         : 4;
-       u_char disc_size        : 4;
-       u_char layer_type       : 4;
-       u_char track_path       : 1;
-       u_char nlayers          : 2;
-       u_char track_density    : 4;
-       u_char linear_density   : 4;
-       u_char bca              : 1;
-       u_char start_sector;
-       u_char end_sector;
-       u_char end_sector_l0;
+       __u8 book_version       : 4;
+       __u8 book_type  : 4;
+       __u8 min_rate           : 4;
+       __u8 disc_size  : 4;
+       __u8 layer_type : 4;
+       __u8 track_path : 1;
+       __u8 nlayers            : 2;
+       __u8 track_density      : 4;
+       __u8 linear_density     : 4;
+       __u8 bca                : 1;
+       __u8 start_sector;
+       __u8 end_sector;
+       __u8 end_sector_l0;
 };
 
 struct dvd_physical {
-       u_char type;
-       u_char layer_num;
+       __u8 type;
+       __u8 layer_num;
        struct dvd_layer layer[4];
 };
 
 struct dvd_copyright {
-       u_char type;
+       __u8 type;
 
-       u_char layer_num;
-       u_char cpst;
-       u_char rmi;
+       __u8 layer_num;
+       __u8 cpst;
+       __u8 rmi;
 };
 
 struct dvd_disckey {
-       u_char type;
+       __u8 type;
 
        unsigned agid                   : 2;
-       u_char value[2048];
+       __u8 value[2048];
 };
 
 struct dvd_bca {
-       u_char type;
+       __u8 type;
 
        int len;
-       u_char value[188];
+       __u8 value[188];
 };
 
 struct dvd_manufact {
-       u_char type;
+       __u8 type;
 
-       u_char layer_num;
+       __u8 layer_num;
        int len;
-       u_char value[2048];
+       __u8 value[2048];
 };
 
 typedef union {
-       u_char type;
+       __u8 type;
 
        struct dvd_physical     physical;
        struct dvd_copyright    copyright;
@@ -577,30 +585,30 @@ typedef union {
 #define DVD_INVALIDATE_AGID    9
 
 /* State data */
-typedef u_char dvd_key[5];             /* 40-bit value, MSB is first elem. */
-typedef u_char dvd_challenge[10];      /* 80-bit value, MSB is first elem. */
+typedef __u8 dvd_key[5];               /* 40-bit value, MSB is first elem. */
+typedef __u8 dvd_challenge[10];        /* 80-bit value, MSB is first elem. */
 
 struct dvd_lu_send_agid {
-       u_char type;
+       __u8 type;
        unsigned agid           : 2;
 };
 
 struct dvd_host_send_challenge {
-       u_char type;
+       __u8 type;
        unsigned agid           : 2;
 
        dvd_challenge chal;
 };
 
 struct dvd_send_key {
-       u_char type;
+       __u8 type;
        unsigned agid           : 2;
 
        dvd_key key;
 };
 
 struct dvd_lu_send_challenge {
-       u_char type;
+       __u8 type;
        unsigned agid           : 2;
 
        dvd_challenge chal;
@@ -617,7 +625,7 @@ struct dvd_lu_send_challenge {
 #define DVD_CGMS_RESTRICTED    3
 
 struct dvd_lu_send_title_key {
-       u_char type;
+       __u8 type;
        unsigned agid           : 2;
 
        dvd_key title_key;
@@ -628,14 +636,14 @@ struct dvd_lu_send_title_key {
 };
 
 struct dvd_lu_send_asf {
-       u_char type;
+       __u8 type;
        unsigned agid           : 2;
 
        unsigned asf            : 1;
 };
 
 typedef union {
-       u_char type;
+       __u8 type;
 
        struct dvd_lu_send_agid         lsa;
        struct dvd_host_send_challenge  hsc;
@@ -658,11 +666,13 @@ struct cdrom_device_info {
        int speed;                      /* maximum speed for reading data */
        int capacity;                   /* number of discs in jukebox */
 /* device-related storage */
-       int options : 30;               /* options flags */
-       unsigned mc_flags : 2;          /* media change buffer flags */
+       int options             : 30;   /* options flags */
+       unsigned mc_flags       : 2;    /* media change buffer flags */
        int use_count;                  /* number of times device opened */
        char name[20];                  /* name of the device type */
-
+/* per-device flags */
+        __u8 sanyo_slot                : 2;    /* Sanyo 3 CD changer support */
+        __u8 reserved          : 6;    /* not used yet */
 };
 
 struct cdrom_device_ops {
@@ -699,6 +709,7 @@ extern struct file_operations cdrom_fops;
 
 extern int register_cdrom(struct cdrom_device_info *cdi);
 extern int unregister_cdrom(struct cdrom_device_info *cdi);
+
 typedef struct {
     int data;
     int audio;
@@ -706,9 +717,19 @@ typedef struct {
     int xa;
     long error;
 } tracktype;
+
 extern void cdrom_count_tracks(struct cdrom_device_info *cdi,tracktype* tracks);
 extern int cdrom_get_next_writable(kdev_t dev, long *next_writable);
 extern int cdrom_get_last_written(kdev_t dev, long *last_written);
+extern int cdrom_number_of_slots(struct cdrom_device_info *cdi);
+extern int cdrom_select_disc(struct cdrom_device_info *cdi, int slot);
+extern int cdrom_mode_select(struct cdrom_device_info *cdi,
+                            struct cdrom_generic_command *cgc);
+extern int cdrom_mode_sense(struct cdrom_device_info *cdi,
+                           struct cdrom_generic_command *cgc,
+                           int page_code, int page_control);
+extern void init_cdrom_command(struct cdrom_generic_command *cgc,
+                              void *buffer, int len);
 
 typedef struct {
        __u16 disc_information_length;
@@ -796,6 +817,61 @@ typedef struct {
        __u32 last_rec_address;
 } track_information;
 
+/* The SCSI spec says there could be 256 slots. */
+#define CDROM_MAX_SLOTS        256
+
+struct cdrom_mechstat_header {
+#if defined(__BIG_ENDIAN_BITFIELD)
+       __u8 fault         : 1;
+       __u8 changer_state : 2;
+       __u8 curslot       : 5;
+       __u8 mech_state    : 3;
+       __u8 door_open     : 1;
+       __u8 reserved1     : 4;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+       __u8 curslot       : 5;
+       __u8 changer_state : 2;
+       __u8 fault         : 1;
+       __u8 reserved1     : 4;
+       __u8 door_open     : 1;
+       __u8 mech_state    : 3;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+       __u8     curlba[3];
+       __u8     nslots;
+       __u8 short slot_tablelen;
+};
+
+
+struct cdrom_slot {
+#if defined(__BIG_ENDIAN_BITFIELD)
+       __u8 disc_present : 1;
+       __u8 reserved1    : 6;
+       __u8 change       : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+       __u8 change       : 1;
+       __u8 reserved1    : 6;
+       __u8 disc_present : 1;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+       __u8 reserved2[3];
+};
+
+struct cdrom_changer_info {
+       struct cdrom_mechstat_header hdr;
+       struct cdrom_slot slots[CDROM_MAX_SLOTS];
+};
+
+typedef enum {
+       mechtype_caddy = 0,
+       mechtype_tray  = 1,
+       mechtype_popup = 2,
+       mechtype_individual_changer = 4,
+       mechtype_cartridge_changer  = 5
+} mechtype_t;
+
 #endif  /* End of kernel only stuff */ 
 
 #endif  /* _LINUX_CDROM_H */