firewire: missing newline in printk
[safe/jmp/linux-2.6] / drivers / firewire / fw-sbp2.c
index c6fd7d3..16e942f 100644 (file)
@@ -207,7 +207,6 @@ struct sbp2_command_orb {
 
        struct sbp2_pointer page_table[SG_ALL];
        dma_addr_t page_table_bus;
-       dma_addr_t request_buffer_bus;
 };
 
 /*
@@ -279,7 +278,7 @@ sbp2_status_write(struct fw_card *card, struct fw_request *request,
        unsigned long flags;
 
        if (tcode != TCODE_WRITE_BLOCK_REQUEST ||
-           length == 0 || length > sizeof status) {
+           length == 0 || length > sizeof(status)) {
                fw_send_response(card, request, RCODE_TYPE_ERROR);
                return;
        }
@@ -340,7 +339,7 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit,
 
        orb->pointer.high = 0;
        orb->pointer.low = orb->request_bus;
-       fw_memcpy_to_be32(&orb->pointer, &orb->pointer, sizeof orb->pointer);
+       fw_memcpy_to_be32(&orb->pointer, &orb->pointer, sizeof(orb->pointer));
 
        spin_lock_irqsave(&device->card->lock, flags);
        list_add_tail(&orb->link, &sd->orb_list);
@@ -349,7 +348,7 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit,
        fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST,
                        node_id, generation,
                        device->node->max_speed, offset,
-                       &orb->pointer, sizeof orb->pointer,
+                       &orb->pointer, sizeof(orb->pointer),
                        complete_transaction, orb);
 }
 
@@ -386,7 +385,7 @@ complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
            (struct sbp2_management_orb *)base_orb;
 
        if (status)
-               memcpy(&orb->status, status, sizeof *status);
+               memcpy(&orb->status, status, sizeof(*status));
        complete(&orb->done);
 }
 
@@ -399,7 +398,7 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
        struct sbp2_management_orb *orb;
        int retval = -ENOMEM;
 
-       orb = kzalloc(sizeof *orb, GFP_ATOMIC);
+       orb = kzalloc(sizeof(*orb), GFP_ATOMIC);
        if (orb == NULL)
                return -ENOMEM;
 
@@ -409,13 +408,13 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
         */
        orb->base.request_bus =
                dma_map_single(device->card->device, &orb->request,
-                              sizeof orb->request, DMA_TO_DEVICE);
+                              sizeof(orb->request), DMA_TO_DEVICE);
        if (dma_mapping_error(orb->base.request_bus))
                goto out;
 
        orb->response_bus =
                dma_map_single(device->card->device, &orb->response,
-                              sizeof orb->response, DMA_FROM_DEVICE);
+                              sizeof(orb->response), DMA_FROM_DEVICE);
        if (dma_mapping_error(orb->response_bus))
                goto out;
 
@@ -427,7 +426,7 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
                MANAGEMENT_ORB_FUNCTION(function) |
                MANAGEMENT_ORB_LUN(lun);
        orb->request.length =
-               MANAGEMENT_ORB_RESPONSE_LENGTH(sizeof orb->response);
+               MANAGEMENT_ORB_RESPONSE_LENGTH(sizeof(orb->response));
 
        orb->request.status_fifo.high = sd->address_handler.offset >> 32;
        orb->request.status_fifo.low  = sd->address_handler.offset;
@@ -443,7 +442,7 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
                        MANAGEMENT_ORB_RECONNECT(0);
        }
 
-       fw_memcpy_to_be32(&orb->request, &orb->request, sizeof orb->request);
+       fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request));
 
        init_completion(&orb->done);
        orb->base.callback = complete_management_orb;
@@ -478,13 +477,13 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
        retval = 0;
  out:
        dma_unmap_single(device->card->device, orb->base.request_bus,
-                        sizeof orb->request, DMA_TO_DEVICE);
+                        sizeof(orb->request), DMA_TO_DEVICE);
        dma_unmap_single(device->card->device, orb->response_bus,
-                        sizeof orb->response, DMA_FROM_DEVICE);
+                        sizeof(orb->response), DMA_FROM_DEVICE);
 
        if (response)
                fw_memcpy_from_be32(response,
-                                   orb->response, sizeof orb->response);
+                                   orb->response, sizeof(orb->response));
        kfree(orb);
 
        return retval;
@@ -506,14 +505,14 @@ static int sbp2_agent_reset(struct fw_unit *unit)
        struct fw_transaction *t;
        static u32 zero;
 
-       t = kzalloc(sizeof *t, GFP_ATOMIC);
+       t = kzalloc(sizeof(*t), GFP_ATOMIC);
        if (t == NULL)
                return -ENOMEM;
 
        fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
                        sd->node_id, sd->generation, SCODE_400,
                        sd->command_block_agent_address + SBP2_AGENT_RESET,
-                       &zero, sizeof zero, complete_agent_reset_write, t);
+                       &zero, sizeof(zero), complete_agent_reset_write, t);
 
        return 0;
 }
@@ -870,7 +869,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
        }
 
        dma_unmap_single(device->card->device, orb->base.request_bus,
-                        sizeof orb->request, DMA_TO_DEVICE);
+                        sizeof(orb->request), DMA_TO_DEVICE);
 
        if (orb->cmd->use_sg > 0) {
                sg = (struct scatterlist *)orb->cmd->request_buffer;
@@ -880,19 +879,14 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
 
        if (orb->page_table_bus != 0)
                dma_unmap_single(device->card->device, orb->page_table_bus,
-                                sizeof orb->page_table_bus, DMA_TO_DEVICE);
-
-       if (orb->request_buffer_bus != 0)
-               dma_unmap_single(device->card->device, orb->request_buffer_bus,
-                                sizeof orb->request_buffer_bus,
-                                DMA_FROM_DEVICE);
+                                sizeof(orb->page_table_bus), DMA_TO_DEVICE);
 
        orb->cmd->result = result;
        orb->done(orb->cmd);
        kfree(orb);
 }
 
-static void sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
+static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
 {
        struct sbp2_device *sd =
                (struct sbp2_device *)orb->cmd->device->host->hostdata;
@@ -906,6 +900,8 @@ static void sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
        sg = (struct scatterlist *)orb->cmd->request_buffer;
        count = dma_map_sg(device->card->device, sg, orb->cmd->use_sg,
                           orb->cmd->sc_data_direction);
+       if (count == 0)
+               goto fail;
 
        /*
         * Handle the special case where there is only one element in
@@ -919,12 +915,15 @@ static void sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
                orb->request.data_descriptor.low  = sg_dma_address(sg);
                orb->request.misc |=
                        COMMAND_ORB_DATA_SIZE(sg_dma_len(sg));
-               return;
+               return 0;
        }
 
        /*
         * Convert the scatterlist to an sbp2 page table.  If any
-        * scatterlist entries are too big for sbp2 we split the as we go.
+        * scatterlist entries are too big for sbp2, we split them as we
+        * go.  Even if we ask the block I/O layer to not give us sg
+        * elements larger than 65535 bytes, some IOMMUs may merge sg elements
+        * during DMA mapping, and Linux currently doesn't prevent this.
         */
        for (i = 0, j = 0; i < count; i++) {
                sg_len = sg_dma_len(sg + i);
@@ -939,7 +938,7 @@ static void sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
                }
        }
 
-       size = sizeof orb->page_table[0] * j;
+       size = sizeof(orb->page_table[0]) * j;
 
        /*
         * The data_descriptor pointer is the one case where we need
@@ -952,6 +951,8 @@ static void sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
        orb->page_table_bus =
                dma_map_single(device->card->device, orb->page_table,
                               size, DMA_TO_DEVICE);
+       if (dma_mapping_error(orb->page_table_bus))
+               goto fail_page_table;
        orb->request.data_descriptor.high = sd->address_high;
        orb->request.data_descriptor.low  = orb->page_table_bus;
        orb->request.misc |=
@@ -959,29 +960,14 @@ static void sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
                COMMAND_ORB_DATA_SIZE(j);
 
        fw_memcpy_to_be32(orb->page_table, orb->page_table, size);
-}
 
-static void sbp2_command_orb_map_buffer(struct sbp2_command_orb *orb)
-{
-       struct sbp2_device *sd =
-               (struct sbp2_device *)orb->cmd->device->host->hostdata;
-       struct fw_unit *unit = sd->unit;
-       struct fw_device *device = fw_device(unit->device.parent);
-
-       /*
-        * As for map_scatterlist, we need to fill in the high bits of
-        * the data_descriptor pointer.
-        */
+       return 0;
 
-       orb->request_buffer_bus =
-               dma_map_single(device->card->device,
-                              orb->cmd->request_buffer,
-                              orb->cmd->request_bufflen,
-                              orb->cmd->sc_data_direction);
-       orb->request.data_descriptor.high = sd->address_high;
-       orb->request.data_descriptor.low  = orb->request_buffer_bus;
-       orb->request.misc |=
-               COMMAND_ORB_DATA_SIZE(orb->cmd->request_bufflen);
+ fail_page_table:
+       dma_unmap_sg(device->card->device, sg, orb->cmd->use_sg,
+                    orb->cmd->sc_data_direction);
+ fail:
+       return -ENOMEM;
 }
 
 /* SCSI stack integration */
@@ -999,11 +985,13 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
         * transfer direction not handled.
         */
        if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) {
-               fw_error("Cannot handle DMA_BIDIRECTIONAL - rejecting command");
-               goto fail_alloc;
+               fw_error("Can't handle DMA_BIDIRECTIONAL, rejecting command\n");
+               cmd->result = DID_ERROR << 16;
+               done(cmd);
+               return 0;
        }
 
-       orb = kzalloc(sizeof *orb, GFP_ATOMIC);
+       orb = kzalloc(sizeof(*orb), GFP_ATOMIC);
        if (orb == NULL) {
                fw_notify("failed to alloc orb\n");
                goto fail_alloc;
@@ -1013,7 +1001,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
        orb->base.rcode = -1;
        orb->base.request_bus =
                dma_map_single(device->card->device, &orb->request,
-                              sizeof orb->request, DMA_TO_DEVICE);
+                              sizeof(orb->request), DMA_TO_DEVICE);
        if (dma_mapping_error(orb->base.request_bus))
                goto fail_mapping;
 
@@ -1041,24 +1029,13 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
                orb->request.misc |=
                        COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA);
 
-       if (cmd->use_sg) {
-               sbp2_command_orb_map_scatterlist(orb);
-       } else if (cmd->request_bufflen > SBP2_MAX_SG_ELEMENT_LENGTH) {
-               /*
-                * FIXME: Need to split this into a sg list... but
-                * could we get the scsi or blk layer to do that by
-                * reporting our max supported block size?
-                */
-               fw_error("command > 64k\n");
-               goto fail_bufflen;
-       } else if (cmd->request_bufflen > 0) {
-               sbp2_command_orb_map_buffer(orb);
-       }
+       if (cmd->use_sg && sbp2_command_orb_map_scatterlist(orb) < 0)
+               goto fail_map_payload;
 
-       fw_memcpy_to_be32(&orb->request, &orb->request, sizeof orb->request);
+       fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request));
 
        memset(orb->request.command_block,
-              0, sizeof orb->request.command_block);
+              0, sizeof(orb->request.command_block));
        memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd));
 
        orb->base.callback = complete_command_orb;
@@ -1068,15 +1045,13 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
 
        return 0;
 
- fail_bufflen:
+ fail_map_payload:
        dma_unmap_single(device->card->device, orb->base.request_bus,
-                        sizeof orb->request, DMA_TO_DEVICE);
+                        sizeof(orb->request), DMA_TO_DEVICE);
  fail_mapping:
        kfree(orb);
  fail_alloc:
-       cmd->result = DID_ERROR << 16;
-       done(cmd);
-       return 0;
+       return SCSI_MLQUEUE_HOST_BUSY;
 }
 
 static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
@@ -1127,6 +1102,58 @@ static int sbp2_scsi_abort(struct scsi_cmnd *cmd)
        return SUCCESS;
 }
 
+/*
+ * Format of /sys/bus/scsi/devices/.../ieee1394_id:
+ * u64 EUI-64 : u24 directory_ID : u16 LUN  (all printed in hexadecimal)
+ *
+ * This is the concatenation of target port identifier and logical unit
+ * identifier as per SAM-2...SAM-4 annex A.
+ */
+static ssize_t
+sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr,
+                           char *buf)
+{
+       struct scsi_device *sdev = to_scsi_device(dev);
+       struct sbp2_device *sd;
+       struct fw_unit *unit;
+       struct fw_device *device;
+       u32 directory_id;
+       struct fw_csr_iterator ci;
+       int key, value, lun;
+
+       if (!sdev)
+               return 0;
+       sd = (struct sbp2_device *)sdev->host->hostdata;
+       unit = sd->unit;
+       device = fw_device(unit->device.parent);
+
+       /* implicit directory ID */
+       directory_id = ((unit->directory - device->config_rom) * 4
+                       + CSR_CONFIG_ROM) & 0xffffff;
+
+       /* explicit directory ID, overrides implicit ID if present */
+       fw_csr_iterator_init(&ci, unit->directory);
+       while (fw_csr_iterator_next(&ci, &key, &value))
+               if (key == CSR_DIRECTORY_ID) {
+                       directory_id = value;
+                       break;
+               }
+
+       /* FIXME: Make this work for multi-lun devices. */
+       lun = 0;
+
+       return sprintf(buf, "%08x%08x:%06x:%04x\n",
+                       device->config_rom[3], device->config_rom[4],
+                       directory_id, lun);
+}
+
+static DEVICE_ATTR(ieee1394_id, S_IRUGO, sbp2_sysfs_ieee1394_id_show, NULL);
+
+static struct device_attribute *sbp2_scsi_sysfs_attrs[] = {
+       &dev_attr_ieee1394_id,
+       NULL
+};
+
 static struct scsi_host_template scsi_driver_template = {
        .module                 = THIS_MODULE,
        .name                   = "SBP-2 IEEE-1394",
@@ -1140,6 +1167,7 @@ static struct scsi_host_template scsi_driver_template = {
        .use_clustering         = ENABLE_CLUSTERING,
        .cmd_per_lun            = 1,
        .can_queue              = 1,
+       .sdev_attrs             = sbp2_scsi_sysfs_attrs,
 };
 
 MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");