* Grep for inline FIXME comments below.
*/
-#include <linux/blkdev.h>
#include <linux/compiler.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/list.h>
+#include <linux/mm.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/stat.h>
.use_clustering = ENABLE_CLUSTERING,
.cmd_per_lun = SBP2_MAX_CMDS,
.can_queue = SBP2_MAX_CMDS,
- .emulated = 1,
.sdev_attrs = sbp2_sysfs_sdev_attrs,
};
+/* for match-all entries in sbp2_workarounds_table */
+#define SBP2_ROM_VALUE_WILDCARD 0x1000000
/*
* List of devices with known bugs.
},
/* Initio bridges, actually only needed for some older ones */ {
.firmware_revision = 0x000200,
+ .model_id = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_INQUIRY_36,
},
/* Symbios bridge */ {
.firmware_revision = 0xa0b800,
+ .model_id = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
},
- /*
- * Note about the following Apple iPod blacklist entries:
- *
- * There are iPods (2nd gen, 3rd gen) with model_id==0. Since our
- * matching logic treats 0 as a wildcard, we cannot match this ID
- * without rewriting the matching routine. Fortunately these iPods
- * do not feature the read_capacity bug according to one report.
- * Read_capacity behaviour as well as model_id could change due to
- * Apple-supplied firmware updates though.
- */
/* iPod 4th generation */ {
.firmware_revision = 0x0a2700,
.model_id = 0x000021,
static int sbp2util_create_command_orb_pool(struct sbp2_lu *lu)
{
struct sbp2_fwhost_info *hi = lu->hi;
- int i;
- unsigned long flags, orbs;
struct sbp2_command_info *cmd;
+ int i, orbs = sbp2_serialize_io ? 2 : SBP2_MAX_CMDS;
- orbs = sbp2_serialize_io ? 2 : SBP2_MAX_CMDS;
-
- spin_lock_irqsave(&lu->cmd_orb_lock, flags);
for (i = 0; i < orbs; i++) {
- cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
- if (!cmd) {
- spin_unlock_irqrestore(&lu->cmd_orb_lock, flags);
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (!cmd)
return -ENOMEM;
- }
cmd->command_orb_dma = dma_map_single(hi->host->device.parent,
&cmd->command_orb,
sizeof(struct sbp2_command_orb),
cmd->sge_dma = dma_map_single(hi->host->device.parent,
&cmd->scatter_gather_element,
sizeof(cmd->scatter_gather_element),
- DMA_BIDIRECTIONAL);
+ DMA_TO_DEVICE);
INIT_LIST_HEAD(&cmd->list);
list_add_tail(&cmd->list, &lu->cmd_orb_completed);
}
- spin_unlock_irqrestore(&lu->cmd_orb_lock, flags);
return 0;
}
DMA_TO_DEVICE);
dma_unmap_single(host->device.parent, cmd->sge_dma,
sizeof(cmd->scatter_gather_element),
- DMA_BIDIRECTIONAL);
+ DMA_TO_DEVICE);
kfree(cmd);
}
spin_unlock_irqrestore(&lu->cmd_orb_lock, flags);
SBP2_ERR("failed to register lower 4GB address range");
goto failed_alloc;
}
+#else
+ if (dma_set_mask(hi->host->device.parent, DMA_32BIT_MASK)) {
+ SBP2_ERR("failed to set 4GB DMA mask");
+ goto failed_alloc;
+ }
#endif
}
if (!lu->login_orb)
goto alloc_fail;
- if (sbp2util_create_command_orb_pool(lu)) {
- SBP2_ERR("sbp2util_create_command_orb_pool failed!");
- sbp2_remove_device(lu);
- return -ENOMEM;
- }
+ if (sbp2util_create_command_orb_pool(lu))
+ goto alloc_fail;
/* Wait a second before trying to log in. Previously logged in
* initiators need a chance to reconnect. */
if (!(workarounds & SBP2_WORKAROUND_OVERRIDE))
for (i = 0; i < ARRAY_SIZE(sbp2_workarounds_table); i++) {
- if (sbp2_workarounds_table[i].firmware_revision &&
+ if (sbp2_workarounds_table[i].firmware_revision !=
+ SBP2_ROM_VALUE_WILDCARD &&
sbp2_workarounds_table[i].firmware_revision !=
(firmware_revision & 0xffff00))
continue;
- if (sbp2_workarounds_table[i].model_id &&
+ if (sbp2_workarounds_table[i].model_id !=
+ SBP2_ROM_VALUE_WILDCARD &&
sbp2_workarounds_table[i].model_id != ud->model_id)
continue;
workarounds |= sbp2_workarounds_table[i].workarounds;
DMA_TO_DEVICE);
dma_sync_single_for_device(hi->host->device.parent, cmd->sge_dma,
sizeof(cmd->scatter_gather_element),
- DMA_BIDIRECTIONAL);
+ DMA_TO_DEVICE);
/* check to see if there are any previous orbs to use */
spin_lock_irqsave(&lu->cmd_orb_lock, flags);
DMA_TO_DEVICE);
dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma,
sizeof(cmd->scatter_gather_element),
- DMA_BIDIRECTIONAL);
+ DMA_TO_DEVICE);
/* Grab SCSI command pointers and check status. */
/*
* FIXME: If the src field in the status is 1, the ORB DMA must
DMA_TO_DEVICE);
dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma,
sizeof(cmd->scatter_gather_element),
- DMA_BIDIRECTIONAL);
+ DMA_TO_DEVICE);
sbp2util_mark_command_completed(lu, cmd);
if (cmd->Current_SCpnt) {
cmd->Current_SCpnt->result = status << 16;
{
struct sbp2_lu *lu = (struct sbp2_lu *)sdev->host->hostdata[0];
- blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
sdev->use_10_for_rw = 1;
+ if (sdev->type == TYPE_ROM)
+ sdev->use_10_for_ms = 1;
if (sdev->type == TYPE_DISK &&
lu->workarounds & SBP2_WORKAROUND_MODE_SENSE_8)
sdev->skip_ms_page_8 = 1;
dma_sync_single_for_cpu(hi->host->device.parent,
cmd->sge_dma,
sizeof(cmd->scatter_gather_element),
- DMA_BIDIRECTIONAL);
+ DMA_TO_DEVICE);
sbp2util_mark_command_completed(lu, cmd);
if (cmd->Current_SCpnt) {
cmd->Current_SCpnt->result = DID_ABORT << 16;