[CRYPTO] tcrypt: Add test vectors of AES_XCBC
[safe/jmp/linux-2.6] / drivers / scsi / scsi_transport_spi.c
index 0b29ee9..3fded48 100644 (file)
@@ -18,7 +18,6 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include <linux/config.h>
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -48,6 +47,7 @@
 
 /* Private data accessors (keep these out of the header file) */
 #define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending)
+#define spi_dv_in_progress(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_in_progress)
 #define spi_dv_mutex(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_mutex)
 
 struct spi_internal {
@@ -146,7 +146,7 @@ static inline const char *spi_signal_to_string(enum spi_signal_type type)
 {
        int i;
 
-       for (i = 0; i < sizeof(signal_types)/sizeof(signal_types[0]); i++) {
+       for (i = 0; i < ARRAY_SIZE(signal_types); i++) {
                if (type == signal_types[i].value)
                        return signal_types[i].name;
        }
@@ -156,7 +156,7 @@ static inline enum spi_signal_type spi_signal_to_value(const char *name)
 {
        int i, len;
 
-       for (i = 0; i < sizeof(signal_types)/sizeof(signal_types[0]); i++) {
+       for (i = 0; i < ARRAY_SIZE(signal_types); i++) {
                len =  strlen(signal_types[i].name);
                if (strncmp(name, signal_types[i].name, len) == 0 &&
                    (name[len] == '\n' || name[len] == '\0'))
@@ -241,6 +241,7 @@ static int spi_setup_transport_attrs(struct transport_container *tc,
        spi_pcomp_en(starget) = 0;
        spi_hold_mcs(starget) = 0;
        spi_dv_pending(starget) = 0;
+       spi_dv_in_progress(starget) = 0;
        spi_initial_dv(starget) = 0;
        mutex_init(&spi_dv_mutex(starget));
 
@@ -785,6 +786,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
 {
        struct spi_internal *i = to_spi_internal(sdev->host->transportt);
        struct scsi_target *starget = sdev->sdev_target;
+       struct Scsi_Host *shost = sdev->host;
        int len = sdev->inquiry_len;
        /* first set us up for narrow async */
        DV_SET(offset, 0);
@@ -830,19 +832,36 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
        DV_SET(period, spi_min_period(starget));
        /* try QAS requests; this should be harmless to set if the
         * target supports it */
-       if (scsi_device_qas(sdev))
+       if (scsi_device_qas(sdev)) {
                DV_SET(qas, 1);
-       /* Also try IU transfers */
-       if (scsi_device_ius(sdev))
+       } else {
+               DV_SET(qas, 0);
+       }
+
+       if (scsi_device_ius(sdev) && spi_min_period(starget) < 9) {
+               /* This u320 (or u640). Set IU transfers */
                DV_SET(iu, 1);
-       if (spi_min_period(starget) < 9) {
-               /* This u320 (or u640). Ignore the coupled parameters
-                * like DT and IU, but set the optional ones */
+               /* Then set the optional parameters */
                DV_SET(rd_strm, 1);
                DV_SET(wr_flow, 1);
                DV_SET(rti, 1);
                if (spi_min_period(starget) == 8)
                        DV_SET(pcomp_en, 1);
+       } else {
+               DV_SET(iu, 0);
+       }
+
+       /* now that we've done all this, actually check the bus
+        * signal type (if known).  Some devices are stupid on
+        * a SE bus and still claim they can try LVD only settings */
+       if (i->f->get_signalling)
+               i->f->get_signalling(shost);
+       if (spi_signalling(shost) == SPI_SIGNAL_SE ||
+           spi_signalling(shost) == SPI_SIGNAL_HVD ||
+           !scsi_device_dt(sdev)) {
+               DV_SET(dt, 0);
+       } else {
+               DV_SET(dt, 1);
        }
        /* Do the read only INQUIRY tests */
        spi_dv_retrain(sdev, buffer, buffer + sdev->inquiry_len,
@@ -899,6 +918,10 @@ spi_dv_device(struct scsi_device *sdev)
        if (unlikely(scsi_device_get(sdev)))
                return;
 
+       if (unlikely(spi_dv_in_progress(starget)))
+               return;
+       spi_dv_in_progress(starget) = 1;
+
        buffer = kzalloc(len, GFP_KERNEL);
 
        if (unlikely(!buffer))
@@ -930,6 +953,7 @@ spi_dv_device(struct scsi_device *sdev)
  out_free:
        kfree(buffer);
  out_put:
+       spi_dv_in_progress(starget) = 0;
        scsi_device_put(sdev);
 }
 EXPORT_SYMBOL(spi_dv_device);
@@ -940,9 +964,10 @@ struct work_queue_wrapper {
 };
 
 static void
-spi_dv_device_work_wrapper(void *data)
+spi_dv_device_work_wrapper(struct work_struct *work)
 {
-       struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data;
+       struct work_queue_wrapper *wqw =
+               container_of(work, struct work_queue_wrapper, work);
        struct scsi_device *sdev = wqw->sdev;
 
        kfree(wqw);
@@ -982,7 +1007,7 @@ spi_schedule_dv_device(struct scsi_device *sdev)
                return;
        }
 
-       INIT_WORK(&wqw->work, spi_dv_device_work_wrapper, wqw);
+       INIT_WORK(&wqw->work, spi_dv_device_work_wrapper);
        wqw->sdev = sdev;
 
        schedule_work(&wqw->work);
@@ -1089,17 +1114,19 @@ EXPORT_SYMBOL_GPL(spi_populate_ppr_msg);
 
 #ifdef CONFIG_SCSI_CONSTANTS
 static const char * const one_byte_msgs[] = {
-/* 0x00 */ "Command Complete", NULL, "Save Pointers",
+/* 0x00 */ "Task Complete", NULL /* Extended Message */, "Save Pointers",
 /* 0x03 */ "Restore Pointers", "Disconnect", "Initiator Error", 
-/* 0x06 */ "Abort", "Message Reject", "Nop", "Message Parity Error",
+/* 0x06 */ "Abort Task Set", "Message Reject", "Nop", "Message Parity Error",
 /* 0x0a */ "Linked Command Complete", "Linked Command Complete w/flag",
-/* 0x0c */ "Bus device reset", "Abort Tag", "Clear Queue", 
-/* 0x0f */ "Initiate Recovery", "Release Recovery"
+/* 0x0c */ "Target Reset", "Abort Task", "Clear Task Set", 
+/* 0x0f */ "Initiate Recovery", "Release Recovery",
+/* 0x11 */ "Terminate Process", "Continue Task", "Target Transfer Disable",
+/* 0x14 */ NULL, NULL, "Clear ACA", "LUN Reset"
 };
 
 static const char * const two_byte_msgs[] = {
 /* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag",
-/* 0x23 */ "Ignore Wide Residue"
+/* 0x23 */ "Ignore Wide Residue", "ACA"
 };
 
 static const char * const extended_msgs[] = {
@@ -1131,7 +1158,7 @@ static void print_ptr(const unsigned char *msg, int msb, const char *desc)
 
 int spi_print_msg(const unsigned char *msg)
 {
-       int len = 0, i;
+       int len = 1, i;
        if (msg[0] == EXTENDED_MESSAGE) {
                len = 2 + msg[1];
                if (len == 2)
@@ -1168,14 +1195,14 @@ int spi_print_msg(const unsigned char *msg)
                        (msg[0] & 0x40) ? "" : "not ",
                        (msg[0] & 0x20) ? "target routine" : "lun",
                        msg[0] & 0x7);
-               len = 1;
        /* Normal One byte */
        } else if (msg[0] < 0x1f) {
-               if (msg[0] < ARRAY_SIZE(one_byte_msgs))
+               if (msg[0] < ARRAY_SIZE(one_byte_msgs) && one_byte_msgs[msg[0]])
                        printk("%s ", one_byte_msgs[msg[0]]);
                else
                        printk("reserved (%02x) ", msg[0]);
-               len = 1;
+       } else if (msg[0] == 0x55) {
+               printk("QAS Request ");
        /* Two byte */
        } else if (msg[0] <= 0x2f) {
                if ((msg[0] - 0x20) < ARRAY_SIZE(two_byte_msgs))
@@ -1195,7 +1222,7 @@ EXPORT_SYMBOL(spi_print_msg);
 
 int spi_print_msg(const unsigned char *msg)
 {
-       int len = 0, i;
+       int len = 1, i;
 
        if (msg[0] == EXTENDED_MESSAGE) {
                len = 2 + msg[1];
@@ -1206,11 +1233,9 @@ int spi_print_msg(const unsigned char *msg)
        /* Identify */
        } else if (msg[0] & 0x80) {
                printk("%02x ", msg[0]);
-               len = 1;
        /* Normal One byte */
-       } else if (msg[0] < 0x1f) {
+       } else if ((msg[0] < 0x1f) || (msg[0] == 0x55)) {
                printk("%02x ", msg[0]);
-               len = 1;
        /* Two byte */
        } else if (msg[0] <= 0x2f) {
                printk("%02x %02x", msg[0], msg[1]);