Merge branch 'for-linus' of git://git.kernel.dk/data/git/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/data/git/linux-2.6-block: (63 commits) Fix memory leak in dm-crypt SPARC64: sg chaining support SPARC: sg chaining support PPC: sg chaining support PS3: sg chaining support IA64: sg chaining support x86-64: enable sg chaining x86-64: update pci-gart iommu to sg helpers x86-64: update nommu to sg helpers x86-64: update calgary iommu to sg helpers swiotlb: sg chaining support i386: enable sg chaining i386 dma_map_sg: convert to using sg helpers mmc: need to zero sglist on init Panic in blk_rq_map_sg() from CCISS driver remove sglist_len remove blk_queue_max_phys_segments in libata revert sg segment size ifdefs Fixup u14-34f ENABLE_SG_CHAINING qla1280: enable use_sg_chaining option ...
This commit is contained in:
@@ -1990,6 +1990,7 @@ static struct scsi_host_template driver_template = {
|
||||
.max_sectors = TW_MAX_SECTORS,
|
||||
.cmd_per_lun = TW_MAX_CMDS_PER_LUN,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.shost_attrs = twa_host_attrs,
|
||||
.emulated = 1
|
||||
};
|
||||
|
@@ -2261,6 +2261,7 @@ static struct scsi_host_template driver_template = {
|
||||
.max_sectors = TW_MAX_SECTORS,
|
||||
.cmd_per_lun = TW_MAX_CMDS_PER_LUN,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.shost_attrs = tw_host_attrs,
|
||||
.emulated = 1
|
||||
};
|
||||
|
@@ -3575,6 +3575,7 @@ static struct scsi_host_template Bus_Logic_template = {
|
||||
.unchecked_isa_dma = 1,
|
||||
.max_sectors = 128,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -1066,7 +1066,8 @@ static struct scsi_host_template driver_template =
|
||||
.sg_tablesize = 32 /*SG_ALL*/ /*SG_NONE*/,
|
||||
.cmd_per_lun = 1 /* commands per lun */,
|
||||
.unchecked_isa_dma = 1 /* unchecked_isa_dma */,
|
||||
.use_clustering = ENABLE_CLUSTERING
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
#include "scsi_module.c"
|
||||
|
@@ -1071,6 +1071,7 @@ static struct scsi_host_template inia100_template = {
|
||||
.sg_tablesize = SG_ALL,
|
||||
.cmd_per_lun = 1,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
static int __devinit inia100_probe_one(struct pci_dev *pdev,
|
||||
|
@@ -944,6 +944,7 @@ static struct scsi_host_template aac_driver_template = {
|
||||
.cmd_per_lun = AAC_NUM_IO_FIB,
|
||||
#endif
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.emulated = 1,
|
||||
};
|
||||
|
||||
|
@@ -61,15 +61,15 @@ static void BAD_DMA(void *address, unsigned int length)
|
||||
}
|
||||
|
||||
static void BAD_SG_DMA(Scsi_Cmnd * SCpnt,
|
||||
struct scatterlist *sgpnt,
|
||||
struct scatterlist *sgp,
|
||||
int nseg,
|
||||
int badseg)
|
||||
{
|
||||
printk(KERN_CRIT "sgpnt[%d:%d] page %p/0x%llx length %u\n",
|
||||
badseg, nseg,
|
||||
page_address(sgpnt[badseg].page) + sgpnt[badseg].offset,
|
||||
(unsigned long long)SCSI_SG_PA(&sgpnt[badseg]),
|
||||
sgpnt[badseg].length);
|
||||
page_address(sgp->page) + sgp->offset,
|
||||
(unsigned long long)SCSI_SG_PA(sgp),
|
||||
sgp->length);
|
||||
|
||||
/*
|
||||
* Not safe to continue.
|
||||
@@ -691,7 +691,7 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
|
||||
memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);
|
||||
|
||||
if (SCpnt->use_sg) {
|
||||
struct scatterlist *sgpnt;
|
||||
struct scatterlist *sg;
|
||||
struct chain *cptr;
|
||||
#ifdef DEBUG
|
||||
unsigned char *ptr;
|
||||
@@ -699,23 +699,21 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
|
||||
int i;
|
||||
ccb[mbo].op = 2; /* SCSI Initiator Command w/scatter-gather */
|
||||
SCpnt->host_scribble = kmalloc(512, GFP_KERNEL | GFP_DMA);
|
||||
sgpnt = (struct scatterlist *) SCpnt->request_buffer;
|
||||
cptr = (struct chain *) SCpnt->host_scribble;
|
||||
if (cptr == NULL) {
|
||||
/* free the claimed mailbox slot */
|
||||
HOSTDATA(SCpnt->device->host)->SCint[mbo] = NULL;
|
||||
return SCSI_MLQUEUE_HOST_BUSY;
|
||||
}
|
||||
for (i = 0; i < SCpnt->use_sg; i++) {
|
||||
if (sgpnt[i].length == 0 || SCpnt->use_sg > 16 ||
|
||||
(((int) sgpnt[i].offset) & 1) || (sgpnt[i].length & 1)) {
|
||||
scsi_for_each_sg(SCpnt, sg, SCpnt->use_sg, i) {
|
||||
if (sg->length == 0 || SCpnt->use_sg > 16 ||
|
||||
(((int) sg->offset) & 1) || (sg->length & 1)) {
|
||||
unsigned char *ptr;
|
||||
printk(KERN_CRIT "Bad segment list supplied to aha1542.c (%d, %d)\n", SCpnt->use_sg, i);
|
||||
for (i = 0; i < SCpnt->use_sg; i++) {
|
||||
scsi_for_each_sg(SCpnt, sg, SCpnt->use_sg, i) {
|
||||
printk(KERN_CRIT "%d: %p %d\n", i,
|
||||
(page_address(sgpnt[i].page) +
|
||||
sgpnt[i].offset),
|
||||
sgpnt[i].length);
|
||||
(page_address(sg->page) +
|
||||
sg->offset), sg->length);
|
||||
};
|
||||
printk(KERN_CRIT "cptr %x: ", (unsigned int) cptr);
|
||||
ptr = (unsigned char *) &cptr[i];
|
||||
@@ -723,10 +721,10 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
|
||||
printk("%02x ", ptr[i]);
|
||||
panic("Foooooooood fight!");
|
||||
};
|
||||
any2scsi(cptr[i].dataptr, SCSI_SG_PA(&sgpnt[i]));
|
||||
if (SCSI_SG_PA(&sgpnt[i]) + sgpnt[i].length - 1 > ISA_DMA_THRESHOLD)
|
||||
BAD_SG_DMA(SCpnt, sgpnt, SCpnt->use_sg, i);
|
||||
any2scsi(cptr[i].datalen, sgpnt[i].length);
|
||||
any2scsi(cptr[i].dataptr, SCSI_SG_PA(sg));
|
||||
if (SCSI_SG_PA(sg) + sg->length - 1 > ISA_DMA_THRESHOLD)
|
||||
BAD_SG_DMA(SCpnt, sg, SCpnt->use_sg, i);
|
||||
any2scsi(cptr[i].datalen, sg->length);
|
||||
};
|
||||
any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain));
|
||||
any2scsi(ccb[mbo].dataptr, SCSI_BUF_PA(cptr));
|
||||
|
@@ -563,6 +563,7 @@ static struct scsi_host_template aha1740_template = {
|
||||
.sg_tablesize = AHA1740_SCATTER,
|
||||
.cmd_per_lun = AHA1740_CMDLUN,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.eh_abort_handler = aha1740_eh_abort_handler,
|
||||
};
|
||||
|
||||
|
@@ -766,6 +766,7 @@ struct scsi_host_template aic79xx_driver_template = {
|
||||
.max_sectors = 8192,
|
||||
.cmd_per_lun = 2,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.slave_alloc = ahd_linux_slave_alloc,
|
||||
.slave_configure = ahd_linux_slave_configure,
|
||||
.target_alloc = ahd_linux_target_alloc,
|
||||
|
@@ -747,6 +747,7 @@ struct scsi_host_template aic7xxx_driver_template = {
|
||||
.max_sectors = 8192,
|
||||
.cmd_per_lun = 2,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.slave_alloc = ahc_linux_slave_alloc,
|
||||
.slave_configure = ahc_linux_slave_configure,
|
||||
.target_alloc = ahc_linux_target_alloc,
|
||||
|
@@ -11142,6 +11142,7 @@ static struct scsi_host_template driver_template = {
|
||||
.max_sectors = 2048,
|
||||
.cmd_per_lun = 3,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
#include "scsi_module.c"
|
||||
|
@@ -94,7 +94,7 @@ static inline int asd_map_scatterlist(struct sas_task *task,
|
||||
res = -ENOMEM;
|
||||
goto err_unmap;
|
||||
}
|
||||
for (sc = task->scatter, i = 0; i < num_sg; i++, sc++) {
|
||||
for_each_sg(task->scatter, sc, num_sg, i) {
|
||||
struct sg_el *sg =
|
||||
&((struct sg_el *)ascb->sg_arr->vaddr)[i];
|
||||
sg->bus_addr = cpu_to_le64((u64)sg_dma_address(sc));
|
||||
@@ -103,7 +103,7 @@ static inline int asd_map_scatterlist(struct sas_task *task,
|
||||
sg->flags |= ASD_SG_EL_LIST_EOL;
|
||||
}
|
||||
|
||||
for (sc = task->scatter, i = 0; i < 2; i++, sc++) {
|
||||
for_each_sg(task->scatter, sc, 2, i) {
|
||||
sg_arr[i].bus_addr =
|
||||
cpu_to_le64((u64)sg_dma_address(sc));
|
||||
sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc));
|
||||
@@ -115,7 +115,7 @@ static inline int asd_map_scatterlist(struct sas_task *task,
|
||||
sg_arr[2].bus_addr=cpu_to_le64((u64)ascb->sg_arr->dma_handle);
|
||||
} else {
|
||||
int i;
|
||||
for (sc = task->scatter, i = 0; i < num_sg; i++, sc++) {
|
||||
for_each_sg(task->scatter, sc, num_sg, i) {
|
||||
sg_arr[i].bus_addr =
|
||||
cpu_to_le64((u64)sg_dma_address(sc));
|
||||
sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc));
|
||||
|
@@ -122,6 +122,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = {
|
||||
.max_sectors = ARCMSR_MAX_XFER_SECTORS,
|
||||
.cmd_per_lun = ARCMSR_MAX_CMD_PERLUN,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.shost_attrs = arcmsr_host_attrs,
|
||||
};
|
||||
#ifdef CONFIG_SCSI_ARCMSR_AER
|
||||
|
@@ -4765,6 +4765,7 @@ static struct scsi_host_template dc395x_driver_template = {
|
||||
.eh_bus_reset_handler = dc395x_eh_bus_reset,
|
||||
.unchecked_isa_dma = 0,
|
||||
.use_clustering = DISABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
|
||||
|
@@ -3295,6 +3295,7 @@ static struct scsi_host_template adpt_template = {
|
||||
.this_id = 7,
|
||||
.cmd_per_lun = 1,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
static s32 adpt_scsi_register(adpt_hba* pHba)
|
||||
|
@@ -523,7 +523,8 @@ static struct scsi_host_template driver_template = {
|
||||
.slave_configure = eata2x_slave_configure,
|
||||
.this_id = 7,
|
||||
.unchecked_isa_dma = 1,
|
||||
.use_clustering = ENABLE_CLUSTERING
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
|
@@ -343,6 +343,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
|
||||
shost->use_clustering = sht->use_clustering;
|
||||
shost->ordered_tag = sht->ordered_tag;
|
||||
shost->active_mode = sht->supported_mode;
|
||||
shost->use_sg_chaining = sht->use_sg_chaining;
|
||||
|
||||
if (sht->max_host_blocked)
|
||||
shost->max_host_blocked = sht->max_host_blocked;
|
||||
|
@@ -655,6 +655,7 @@ static struct scsi_host_template driver_template = {
|
||||
.unchecked_isa_dma = 0,
|
||||
.emulated = 0,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.proc_name = driver_name,
|
||||
.shost_attrs = hptiop_attrs,
|
||||
.this_id = -1,
|
||||
|
@@ -1501,6 +1501,7 @@ static struct scsi_host_template ibmmca_driver_template = {
|
||||
.sg_tablesize = 16,
|
||||
.cmd_per_lun = 1,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
static int ibmmca_probe(struct device *dev)
|
||||
|
@@ -1548,6 +1548,7 @@ static struct scsi_host_template driver_template = {
|
||||
.this_id = -1,
|
||||
.sg_tablesize = SG_ALL,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.shost_attrs = ibmvscsi_attrs,
|
||||
};
|
||||
|
||||
|
@@ -70,6 +70,7 @@ typedef struct idescsi_pc_s {
|
||||
u8 *buffer; /* Data buffer */
|
||||
u8 *current_position; /* Pointer into the above buffer */
|
||||
struct scatterlist *sg; /* Scatter gather table */
|
||||
struct scatterlist *last_sg; /* Last sg element */
|
||||
int b_count; /* Bytes transferred from current entry */
|
||||
struct scsi_cmnd *scsi_cmd; /* SCSI command */
|
||||
void (*done)(struct scsi_cmnd *); /* Scsi completion routine */
|
||||
@@ -173,12 +174,6 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
|
||||
char *buf;
|
||||
|
||||
while (bcount) {
|
||||
if (pc->sg - scsi_sglist(pc->scsi_cmd) >
|
||||
scsi_sg_count(pc->scsi_cmd)) {
|
||||
printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n");
|
||||
idescsi_discard_data (drive, bcount);
|
||||
return;
|
||||
}
|
||||
count = min(pc->sg->length - pc->b_count, bcount);
|
||||
if (PageHighMem(pc->sg->page)) {
|
||||
unsigned long flags;
|
||||
@@ -197,10 +192,17 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
|
||||
}
|
||||
bcount -= count; pc->b_count += count;
|
||||
if (pc->b_count == pc->sg->length) {
|
||||
pc->sg++;
|
||||
if (pc->sg == pc->last_sg)
|
||||
break;
|
||||
pc->sg = sg_next(pc->sg);
|
||||
pc->b_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (bcount) {
|
||||
printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n");
|
||||
idescsi_discard_data (drive, bcount);
|
||||
}
|
||||
}
|
||||
|
||||
static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount)
|
||||
@@ -209,12 +211,6 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
|
||||
char *buf;
|
||||
|
||||
while (bcount) {
|
||||
if (pc->sg - scsi_sglist(pc->scsi_cmd) >
|
||||
scsi_sg_count(pc->scsi_cmd)) {
|
||||
printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n");
|
||||
idescsi_output_zeros (drive, bcount);
|
||||
return;
|
||||
}
|
||||
count = min(pc->sg->length - pc->b_count, bcount);
|
||||
if (PageHighMem(pc->sg->page)) {
|
||||
unsigned long flags;
|
||||
@@ -233,10 +229,17 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
|
||||
}
|
||||
bcount -= count; pc->b_count += count;
|
||||
if (pc->b_count == pc->sg->length) {
|
||||
pc->sg++;
|
||||
if (pc->sg == pc->last_sg)
|
||||
break;
|
||||
pc->sg = sg_next(pc->sg);
|
||||
pc->b_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (bcount) {
|
||||
printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n");
|
||||
idescsi_output_zeros (drive, bcount);
|
||||
}
|
||||
}
|
||||
|
||||
static void hexdump(u8 *x, int len)
|
||||
@@ -804,6 +807,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
|
||||
memcpy (pc->c, cmd->cmnd, cmd->cmd_len);
|
||||
pc->buffer = NULL;
|
||||
pc->sg = scsi_sglist(cmd);
|
||||
pc->last_sg = sg_last(pc->sg, cmd->use_sg);
|
||||
pc->b_count = 0;
|
||||
pc->request_transfer = pc->buffer_size = scsi_bufflen(cmd);
|
||||
pc->scsi_cmd = cmd;
|
||||
|
@@ -2831,6 +2831,7 @@ static struct scsi_host_template initio_template = {
|
||||
.sg_tablesize = SG_ALL,
|
||||
.cmd_per_lun = 1,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
static int initio_probe_one(struct pci_dev *pdev,
|
||||
|
@@ -3252,7 +3252,7 @@ ips_done(ips_ha_t * ha, ips_scb_t * scb)
|
||||
*/
|
||||
if ((scb->breakup) || (scb->sg_break)) {
|
||||
struct scatterlist *sg;
|
||||
int sg_dma_index, ips_sg_index = 0;
|
||||
int i, sg_dma_index, ips_sg_index = 0;
|
||||
|
||||
/* we had a data breakup */
|
||||
scb->data_len = 0;
|
||||
@@ -3261,20 +3261,22 @@ ips_done(ips_ha_t * ha, ips_scb_t * scb)
|
||||
|
||||
/* Spin forward to last dma chunk */
|
||||
sg_dma_index = scb->breakup;
|
||||
for (i = 0; i < scb->breakup; i++)
|
||||
sg = sg_next(sg);
|
||||
|
||||
/* Take care of possible partial on last chunk */
|
||||
ips_fill_scb_sg_single(ha,
|
||||
sg_dma_address(&sg[sg_dma_index]),
|
||||
sg_dma_address(sg),
|
||||
scb, ips_sg_index++,
|
||||
sg_dma_len(&sg[sg_dma_index]));
|
||||
sg_dma_len(sg));
|
||||
|
||||
for (; sg_dma_index < scsi_sg_count(scb->scsi_cmd);
|
||||
sg_dma_index++) {
|
||||
sg_dma_index++, sg = sg_next(sg)) {
|
||||
if (ips_fill_scb_sg_single
|
||||
(ha,
|
||||
sg_dma_address(&sg[sg_dma_index]),
|
||||
sg_dma_address(sg),
|
||||
scb, ips_sg_index++,
|
||||
sg_dma_len(&sg[sg_dma_index])) < 0)
|
||||
sg_dma_len(sg)) < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -1438,6 +1438,7 @@ struct scsi_host_template lpfc_template = {
|
||||
.scan_finished = lpfc_scan_finished,
|
||||
.this_id = -1,
|
||||
.sg_tablesize = LPFC_SG_SEG_CNT,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.cmd_per_lun = LPFC_CMD_PER_LUN,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.shost_attrs = lpfc_hba_attrs,
|
||||
@@ -1460,6 +1461,7 @@ struct scsi_host_template lpfc_vport_template = {
|
||||
.sg_tablesize = LPFC_SG_SEG_CNT,
|
||||
.cmd_per_lun = LPFC_CMD_PER_LUN,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.shost_attrs = lpfc_vport_attrs,
|
||||
.max_sectors = 0xFFFF,
|
||||
};
|
||||
|
@@ -402,6 +402,7 @@ static struct scsi_host_template mac53c94_template = {
|
||||
.sg_tablesize = SG_ALL,
|
||||
.cmd_per_lun = 1,
|
||||
.use_clustering = DISABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *match)
|
||||
|
@@ -4492,6 +4492,7 @@ static struct scsi_host_template megaraid_template = {
|
||||
.sg_tablesize = MAX_SGLIST,
|
||||
.cmd_per_lun = DEF_CMD_PER_LUN,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.eh_abort_handler = megaraid_abort,
|
||||
.eh_device_reset_handler = megaraid_reset,
|
||||
.eh_bus_reset_handler = megaraid_reset,
|
||||
|
@@ -361,6 +361,7 @@ static struct scsi_host_template megaraid_template_g = {
|
||||
.eh_host_reset_handler = megaraid_reset_handler,
|
||||
.change_queue_depth = megaraid_change_queue_depth,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.sdev_attrs = megaraid_sdev_attrs,
|
||||
.shost_attrs = megaraid_shost_attrs,
|
||||
};
|
||||
|
@@ -1110,6 +1110,7 @@ static struct scsi_host_template megasas_template = {
|
||||
.eh_timed_out = megasas_reset_timer,
|
||||
.bios_param = megasas_bios_param,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -1843,6 +1843,7 @@ static struct scsi_host_template mesh_template = {
|
||||
.sg_tablesize = SG_ALL,
|
||||
.cmd_per_lun = 2,
|
||||
.use_clustering = DISABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
|
||||
|
@@ -281,6 +281,7 @@ static struct scsi_host_template nsp32_template = {
|
||||
.cmd_per_lun = 1,
|
||||
.this_id = NSP32_HOST_SCSIID,
|
||||
.use_clustering = DISABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.eh_abort_handler = nsp32_eh_abort,
|
||||
.eh_bus_reset_handler = nsp32_eh_bus_reset,
|
||||
.eh_host_reset_handler = nsp32_eh_host_reset,
|
||||
|
@@ -694,6 +694,7 @@ static struct scsi_host_template sym53c500_driver_template = {
|
||||
.sg_tablesize = 32,
|
||||
.cmd_per_lun = 1,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.shost_attrs = SYM53C500_shost_attrs
|
||||
};
|
||||
|
||||
|
@@ -2775,7 +2775,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
|
||||
struct device_reg __iomem *reg = ha->iobase;
|
||||
struct scsi_cmnd *cmd = sp->cmd;
|
||||
cmd_a64_entry_t *pkt;
|
||||
struct scatterlist *sg = NULL;
|
||||
struct scatterlist *sg = NULL, *s;
|
||||
__le32 *dword_ptr;
|
||||
dma_addr_t dma_handle;
|
||||
int status = 0;
|
||||
@@ -2889,13 +2889,16 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
|
||||
* Load data segments.
|
||||
*/
|
||||
if (seg_cnt) { /* If data transfer. */
|
||||
int remseg = seg_cnt;
|
||||
/* Setup packet address segment pointer. */
|
||||
dword_ptr = (u32 *)&pkt->dseg_0_address;
|
||||
|
||||
if (cmd->use_sg) { /* If scatter gather */
|
||||
/* Load command entry data segments. */
|
||||
for (cnt = 0; cnt < 2 && seg_cnt; cnt++, seg_cnt--) {
|
||||
dma_handle = sg_dma_address(sg);
|
||||
for_each_sg(sg, s, seg_cnt, cnt) {
|
||||
if (cnt == 2)
|
||||
break;
|
||||
dma_handle = sg_dma_address(s);
|
||||
#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
|
||||
if (ha->flags.use_pci_vchannel)
|
||||
sn_pci_set_vchan(ha->pdev,
|
||||
@@ -2906,12 +2909,12 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
|
||||
cpu_to_le32(pci_dma_lo32(dma_handle));
|
||||
*dword_ptr++ =
|
||||
cpu_to_le32(pci_dma_hi32(dma_handle));
|
||||
*dword_ptr++ = cpu_to_le32(sg_dma_len(sg));
|
||||
sg++;
|
||||
*dword_ptr++ = cpu_to_le32(sg_dma_len(s));
|
||||
dprintk(3, "S/G Segment phys_addr=%x %x, len=0x%x\n",
|
||||
cpu_to_le32(pci_dma_hi32(dma_handle)),
|
||||
cpu_to_le32(pci_dma_lo32(dma_handle)),
|
||||
cpu_to_le32(sg_dma_len(sg)));
|
||||
cpu_to_le32(sg_dma_len(sg_next(s))));
|
||||
remseg--;
|
||||
}
|
||||
dprintk(5, "qla1280_64bit_start_scsi: Scatter/gather "
|
||||
"command packet data - b %i, t %i, l %i \n",
|
||||
@@ -2926,7 +2929,9 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
|
||||
dprintk(3, "S/G Building Continuation...seg_cnt=0x%x "
|
||||
"remains\n", seg_cnt);
|
||||
|
||||
while (seg_cnt > 0) {
|
||||
while (remseg > 0) {
|
||||
/* Update sg start */
|
||||
sg = s;
|
||||
/* Adjust ring index. */
|
||||
ha->req_ring_index++;
|
||||
if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
|
||||
@@ -2952,9 +2957,10 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
|
||||
(u32 *)&((struct cont_a64_entry *) pkt)->dseg_0_address;
|
||||
|
||||
/* Load continuation entry data segments. */
|
||||
for (cnt = 0; cnt < 5 && seg_cnt;
|
||||
cnt++, seg_cnt--) {
|
||||
dma_handle = sg_dma_address(sg);
|
||||
for_each_sg(sg, s, remseg, cnt) {
|
||||
if (cnt == 5)
|
||||
break;
|
||||
dma_handle = sg_dma_address(s);
|
||||
#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
|
||||
if (ha->flags.use_pci_vchannel)
|
||||
sn_pci_set_vchan(ha->pdev,
|
||||
@@ -2966,13 +2972,13 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
|
||||
*dword_ptr++ =
|
||||
cpu_to_le32(pci_dma_hi32(dma_handle));
|
||||
*dword_ptr++ =
|
||||
cpu_to_le32(sg_dma_len(sg));
|
||||
cpu_to_le32(sg_dma_len(s));
|
||||
dprintk(3, "S/G Segment Cont. phys_addr=%x %x, len=0x%x\n",
|
||||
cpu_to_le32(pci_dma_hi32(dma_handle)),
|
||||
cpu_to_le32(pci_dma_lo32(dma_handle)),
|
||||
cpu_to_le32(sg_dma_len(sg)));
|
||||
sg++;
|
||||
cpu_to_le32(sg_dma_len(s)));
|
||||
}
|
||||
remseg -= cnt;
|
||||
dprintk(5, "qla1280_64bit_start_scsi: "
|
||||
"continuation packet data - b %i, t "
|
||||
"%i, l %i \n", SCSI_BUS_32(cmd),
|
||||
@@ -3062,7 +3068,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
|
||||
struct device_reg __iomem *reg = ha->iobase;
|
||||
struct scsi_cmnd *cmd = sp->cmd;
|
||||
struct cmd_entry *pkt;
|
||||
struct scatterlist *sg = NULL;
|
||||
struct scatterlist *sg = NULL, *s;
|
||||
__le32 *dword_ptr;
|
||||
int status = 0;
|
||||
int cnt;
|
||||
@@ -3188,6 +3194,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
|
||||
* Load data segments.
|
||||
*/
|
||||
if (seg_cnt) {
|
||||
int remseg = seg_cnt;
|
||||
/* Setup packet address segment pointer. */
|
||||
dword_ptr = &pkt->dseg_0_address;
|
||||
|
||||
@@ -3196,22 +3203,25 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
|
||||
qla1280_dump_buffer(1, (char *)sg, 4 * 16);
|
||||
|
||||
/* Load command entry data segments. */
|
||||
for (cnt = 0; cnt < 4 && seg_cnt; cnt++, seg_cnt--) {
|
||||
for_each_sg(sg, s, seg_cnt, cnt) {
|
||||
if (cnt == 4)
|
||||
break;
|
||||
*dword_ptr++ =
|
||||
cpu_to_le32(pci_dma_lo32(sg_dma_address(sg)));
|
||||
*dword_ptr++ =
|
||||
cpu_to_le32(sg_dma_len(sg));
|
||||
cpu_to_le32(pci_dma_lo32(sg_dma_address(s)));
|
||||
*dword_ptr++ = cpu_to_le32(sg_dma_len(s));
|
||||
dprintk(3, "S/G Segment phys_addr=0x%lx, len=0x%x\n",
|
||||
(pci_dma_lo32(sg_dma_address(sg))),
|
||||
(sg_dma_len(sg)));
|
||||
sg++;
|
||||
(pci_dma_lo32(sg_dma_address(s))),
|
||||
(sg_dma_len(s)));
|
||||
remseg--;
|
||||
}
|
||||
/*
|
||||
* Build continuation packets.
|
||||
*/
|
||||
dprintk(3, "S/G Building Continuation"
|
||||
"...seg_cnt=0x%x remains\n", seg_cnt);
|
||||
while (seg_cnt > 0) {
|
||||
while (remseg > 0) {
|
||||
/* Continue from end point */
|
||||
sg = s;
|
||||
/* Adjust ring index. */
|
||||
ha->req_ring_index++;
|
||||
if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
|
||||
@@ -3239,19 +3249,20 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
|
||||
&((struct cont_entry *) pkt)->dseg_0_address;
|
||||
|
||||
/* Load continuation entry data segments. */
|
||||
for (cnt = 0; cnt < 7 && seg_cnt;
|
||||
cnt++, seg_cnt--) {
|
||||
for_each_sg(sg, s, remseg, cnt) {
|
||||
if (cnt == 7)
|
||||
break;
|
||||
*dword_ptr++ =
|
||||
cpu_to_le32(pci_dma_lo32(sg_dma_address(sg)));
|
||||
cpu_to_le32(pci_dma_lo32(sg_dma_address(s)));
|
||||
*dword_ptr++ =
|
||||
cpu_to_le32(sg_dma_len(sg));
|
||||
cpu_to_le32(sg_dma_len(s));
|
||||
dprintk(1,
|
||||
"S/G Segment Cont. phys_addr=0x%x, "
|
||||
"len=0x%x\n",
|
||||
cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))),
|
||||
cpu_to_le32(sg_dma_len(sg)));
|
||||
sg++;
|
||||
cpu_to_le32(pci_dma_lo32(sg_dma_address(s))),
|
||||
cpu_to_le32(sg_dma_len(s)));
|
||||
}
|
||||
remseg -= cnt;
|
||||
dprintk(5, "qla1280_32bit_start_scsi: "
|
||||
"continuation packet data - "
|
||||
"scsi(%i:%i:%i)\n", SCSI_BUS_32(cmd),
|
||||
@@ -4248,6 +4259,7 @@ static struct scsi_host_template qla1280_driver_template = {
|
||||
.sg_tablesize = SG_ALL,
|
||||
.cmd_per_lun = 1,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
|
||||
|
@@ -132,6 +132,7 @@ struct scsi_host_template qla2x00_driver_template = {
|
||||
.this_id = -1,
|
||||
.cmd_per_lun = 3,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.sg_tablesize = SG_ALL,
|
||||
|
||||
/*
|
||||
@@ -163,6 +164,7 @@ struct scsi_host_template qla24xx_driver_template = {
|
||||
.this_id = -1,
|
||||
.cmd_per_lun = 3,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.sg_tablesize = SG_ALL,
|
||||
|
||||
.max_sectors = 0xFFFF,
|
||||
|
@@ -94,6 +94,7 @@ static struct scsi_host_template qla4xxx_driver_template = {
|
||||
.this_id = -1,
|
||||
.cmd_per_lun = 3,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.sg_tablesize = SG_ALL,
|
||||
|
||||
.max_sectors = 0xFFFF,
|
||||
|
@@ -197,6 +197,7 @@ static struct scsi_host_template qlogicfas_driver_template = {
|
||||
.sg_tablesize = SG_ALL,
|
||||
.cmd_per_lun = 1,
|
||||
.use_clustering = DISABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
static __init int qlogicfas_init(void)
|
||||
|
@@ -868,7 +868,7 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
|
||||
struct qlogicpti *qpti, u_int in_ptr, u_int out_ptr)
|
||||
{
|
||||
struct dataseg *ds;
|
||||
struct scatterlist *sg;
|
||||
struct scatterlist *sg, *s;
|
||||
int i, n;
|
||||
|
||||
if (Cmnd->use_sg) {
|
||||
@@ -884,11 +884,12 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
|
||||
n = sg_count;
|
||||
if (n > 4)
|
||||
n = 4;
|
||||
for (i = 0; i < n; i++, sg++) {
|
||||
ds[i].d_base = sg_dma_address(sg);
|
||||
ds[i].d_count = sg_dma_len(sg);
|
||||
for_each_sg(sg, s, n, i) {
|
||||
ds[i].d_base = sg_dma_address(s);
|
||||
ds[i].d_count = sg_dma_len(s);
|
||||
}
|
||||
sg_count -= 4;
|
||||
sg = s;
|
||||
while (sg_count > 0) {
|
||||
struct Continuation_Entry *cont;
|
||||
|
||||
@@ -907,9 +908,9 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
|
||||
n = sg_count;
|
||||
if (n > 7)
|
||||
n = 7;
|
||||
for (i = 0; i < n; i++, sg++) {
|
||||
ds[i].d_base = sg_dma_address(sg);
|
||||
ds[i].d_count = sg_dma_len(sg);
|
||||
for_each_sg(sg, s, n, i) {
|
||||
ds[i].d_base = sg_dma_address(s);
|
||||
ds[i].d_count = sg_dma_len(s);
|
||||
}
|
||||
sg_count -= n;
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/scatterlist.h>
|
||||
|
||||
#include <linux/blkdev.h>
|
||||
#include "scsi.h"
|
||||
@@ -600,7 +601,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
|
||||
int k, req_len, act_len, len, active;
|
||||
void * kaddr;
|
||||
void * kaddr_off;
|
||||
struct scatterlist * sgpnt;
|
||||
struct scatterlist * sg;
|
||||
|
||||
if (0 == scp->request_bufflen)
|
||||
return 0;
|
||||
@@ -619,16 +620,16 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
|
||||
scp->resid = req_len - act_len;
|
||||
return 0;
|
||||
}
|
||||
sgpnt = (struct scatterlist *)scp->request_buffer;
|
||||
active = 1;
|
||||
for (k = 0, req_len = 0, act_len = 0; k < scp->use_sg; ++k, ++sgpnt) {
|
||||
req_len = act_len = 0;
|
||||
scsi_for_each_sg(scp, sg, scp->use_sg, k) {
|
||||
if (active) {
|
||||
kaddr = (unsigned char *)
|
||||
kmap_atomic(sgpnt->page, KM_USER0);
|
||||
kmap_atomic(sg->page, KM_USER0);
|
||||
if (NULL == kaddr)
|
||||
return (DID_ERROR << 16);
|
||||
kaddr_off = (unsigned char *)kaddr + sgpnt->offset;
|
||||
len = sgpnt->length;
|
||||
kaddr_off = (unsigned char *)kaddr + sg->offset;
|
||||
len = sg->length;
|
||||
if ((req_len + len) > arr_len) {
|
||||
active = 0;
|
||||
len = arr_len - req_len;
|
||||
@@ -637,7 +638,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
act_len += len;
|
||||
}
|
||||
req_len += sgpnt->length;
|
||||
req_len += sg->length;
|
||||
}
|
||||
if (scp->resid)
|
||||
scp->resid -= act_len;
|
||||
@@ -653,7 +654,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
|
||||
int k, req_len, len, fin;
|
||||
void * kaddr;
|
||||
void * kaddr_off;
|
||||
struct scatterlist * sgpnt;
|
||||
struct scatterlist * sg;
|
||||
|
||||
if (0 == scp->request_bufflen)
|
||||
return 0;
|
||||
@@ -668,13 +669,14 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
|
||||
memcpy(arr, scp->request_buffer, len);
|
||||
return len;
|
||||
}
|
||||
sgpnt = (struct scatterlist *)scp->request_buffer;
|
||||
for (k = 0, req_len = 0, fin = 0; k < scp->use_sg; ++k, ++sgpnt) {
|
||||
kaddr = (unsigned char *)kmap_atomic(sgpnt->page, KM_USER0);
|
||||
sg = scsi_sglist(scp);
|
||||
req_len = fin = 0;
|
||||
for (k = 0; k < scp->use_sg; ++k, sg = sg_next(sg)) {
|
||||
kaddr = (unsigned char *)kmap_atomic(sg->page, KM_USER0);
|
||||
if (NULL == kaddr)
|
||||
return -1;
|
||||
kaddr_off = (unsigned char *)kaddr + sgpnt->offset;
|
||||
len = sgpnt->length;
|
||||
kaddr_off = (unsigned char *)kaddr + sg->offset;
|
||||
len = sg->length;
|
||||
if ((req_len + len) > max_arr_len) {
|
||||
len = max_arr_len - req_len;
|
||||
fin = 1;
|
||||
@@ -683,7 +685,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
if (fin)
|
||||
return req_len + len;
|
||||
req_len += sgpnt->length;
|
||||
req_len += sg->length;
|
||||
}
|
||||
return req_len;
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/scatterlist.h>
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
@@ -33,35 +34,34 @@
|
||||
#define SG_MEMPOOL_NR ARRAY_SIZE(scsi_sg_pools)
|
||||
#define SG_MEMPOOL_SIZE 2
|
||||
|
||||
/*
|
||||
* The maximum number of SG segments that we will put inside a scatterlist
|
||||
* (unless chaining is used). Should ideally fit inside a single page, to
|
||||
* avoid a higher order allocation.
|
||||
*/
|
||||
#define SCSI_MAX_SG_SEGMENTS 128
|
||||
|
||||
struct scsi_host_sg_pool {
|
||||
size_t size;
|
||||
char *name;
|
||||
char *name;
|
||||
struct kmem_cache *slab;
|
||||
mempool_t *pool;
|
||||
};
|
||||
|
||||
#if (SCSI_MAX_PHYS_SEGMENTS < 32)
|
||||
#error SCSI_MAX_PHYS_SEGMENTS is too small
|
||||
#endif
|
||||
|
||||
#define SP(x) { x, "sgpool-" #x }
|
||||
#define SP(x) { x, "sgpool-" #x }
|
||||
static struct scsi_host_sg_pool scsi_sg_pools[] = {
|
||||
SP(8),
|
||||
SP(16),
|
||||
#if (SCSI_MAX_SG_SEGMENTS > 16)
|
||||
SP(32),
|
||||
#if (SCSI_MAX_PHYS_SEGMENTS > 32)
|
||||
#if (SCSI_MAX_SG_SEGMENTS > 32)
|
||||
SP(64),
|
||||
#if (SCSI_MAX_PHYS_SEGMENTS > 64)
|
||||
#if (SCSI_MAX_SG_SEGMENTS > 64)
|
||||
SP(128),
|
||||
#if (SCSI_MAX_PHYS_SEGMENTS > 128)
|
||||
SP(256),
|
||||
#if (SCSI_MAX_PHYS_SEGMENTS > 256)
|
||||
#error SCSI_MAX_PHYS_SEGMENTS is too large
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
};
|
||||
#undef SP
|
||||
|
||||
static void scsi_run_queue(struct request_queue *q);
|
||||
@@ -289,14 +289,16 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
|
||||
struct request_queue *q = rq->q;
|
||||
int nr_pages = (bufflen + sgl[0].offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
unsigned int data_len = bufflen, len, bytes, off;
|
||||
struct scatterlist *sg;
|
||||
struct page *page;
|
||||
struct bio *bio = NULL;
|
||||
int i, err, nr_vecs = 0;
|
||||
|
||||
for (i = 0; i < nsegs; i++) {
|
||||
page = sgl[i].page;
|
||||
off = sgl[i].offset;
|
||||
len = sgl[i].length;
|
||||
for_each_sg(sgl, sg, nsegs, i) {
|
||||
page = sg->page;
|
||||
off = sg->offset;
|
||||
len = sg->length;
|
||||
data_len += len;
|
||||
|
||||
while (len > 0 && data_len > 0) {
|
||||
/*
|
||||
@@ -695,56 +697,170 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
|
||||
/*
|
||||
* Like SCSI_MAX_SG_SEGMENTS, but for archs that have sg chaining. This limit
|
||||
* is totally arbitrary, a setting of 2048 will get you at least 8mb ios.
|
||||
*/
|
||||
#define SCSI_MAX_SG_CHAIN_SEGMENTS 2048
|
||||
|
||||
static inline unsigned int scsi_sgtable_index(unsigned short nents)
|
||||
{
|
||||
struct scsi_host_sg_pool *sgp;
|
||||
struct scatterlist *sgl;
|
||||
unsigned int index;
|
||||
|
||||
BUG_ON(!cmd->use_sg);
|
||||
|
||||
switch (cmd->use_sg) {
|
||||
switch (nents) {
|
||||
case 1 ... 8:
|
||||
cmd->sglist_len = 0;
|
||||
index = 0;
|
||||
break;
|
||||
case 9 ... 16:
|
||||
cmd->sglist_len = 1;
|
||||
index = 1;
|
||||
break;
|
||||
#if (SCSI_MAX_SG_SEGMENTS > 16)
|
||||
case 17 ... 32:
|
||||
cmd->sglist_len = 2;
|
||||
index = 2;
|
||||
break;
|
||||
#if (SCSI_MAX_PHYS_SEGMENTS > 32)
|
||||
#if (SCSI_MAX_SG_SEGMENTS > 32)
|
||||
case 33 ... 64:
|
||||
cmd->sglist_len = 3;
|
||||
index = 3;
|
||||
break;
|
||||
#if (SCSI_MAX_PHYS_SEGMENTS > 64)
|
||||
#if (SCSI_MAX_SG_SEGMENTS > 64)
|
||||
case 65 ... 128:
|
||||
cmd->sglist_len = 4;
|
||||
break;
|
||||
#if (SCSI_MAX_PHYS_SEGMENTS > 128)
|
||||
case 129 ... 256:
|
||||
cmd->sglist_len = 5;
|
||||
index = 4;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
return NULL;
|
||||
printk(KERN_ERR "scsi: bad segment count=%d\n", nents);
|
||||
BUG();
|
||||
}
|
||||
|
||||
sgp = scsi_sg_pools + cmd->sglist_len;
|
||||
sgl = mempool_alloc(sgp->pool, gfp_mask);
|
||||
return sgl;
|
||||
return index;
|
||||
}
|
||||
|
||||
struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
|
||||
{
|
||||
struct scsi_host_sg_pool *sgp;
|
||||
struct scatterlist *sgl, *prev, *ret;
|
||||
unsigned int index;
|
||||
int this, left;
|
||||
|
||||
BUG_ON(!cmd->use_sg);
|
||||
|
||||
left = cmd->use_sg;
|
||||
ret = prev = NULL;
|
||||
do {
|
||||
this = left;
|
||||
if (this > SCSI_MAX_SG_SEGMENTS) {
|
||||
this = SCSI_MAX_SG_SEGMENTS - 1;
|
||||
index = SG_MEMPOOL_NR - 1;
|
||||
} else
|
||||
index = scsi_sgtable_index(this);
|
||||
|
||||
left -= this;
|
||||
|
||||
sgp = scsi_sg_pools + index;
|
||||
|
||||
sgl = mempool_alloc(sgp->pool, gfp_mask);
|
||||
if (unlikely(!sgl))
|
||||
goto enomem;
|
||||
|
||||
memset(sgl, 0, sizeof(*sgl) * sgp->size);
|
||||
|
||||
/*
|
||||
* first loop through, set initial index and return value
|
||||
*/
|
||||
if (!ret)
|
||||
ret = sgl;
|
||||
|
||||
/*
|
||||
* chain previous sglist, if any. we know the previous
|
||||
* sglist must be the biggest one, or we would not have
|
||||
* ended up doing another loop.
|
||||
*/
|
||||
if (prev)
|
||||
sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
|
||||
|
||||
/*
|
||||
* don't allow subsequent mempool allocs to sleep, it would
|
||||
* violate the mempool principle.
|
||||
*/
|
||||
gfp_mask &= ~__GFP_WAIT;
|
||||
gfp_mask |= __GFP_HIGH;
|
||||
prev = sgl;
|
||||
} while (left);
|
||||
|
||||
/*
|
||||
* ->use_sg may get modified after dma mapping has potentially
|
||||
* shrunk the number of segments, so keep a copy of it for free.
|
||||
*/
|
||||
cmd->__use_sg = cmd->use_sg;
|
||||
return ret;
|
||||
enomem:
|
||||
if (ret) {
|
||||
/*
|
||||
* Free entries chained off ret. Since we were trying to
|
||||
* allocate another sglist, we know that all entries are of
|
||||
* the max size.
|
||||
*/
|
||||
sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1;
|
||||
prev = ret;
|
||||
ret = &ret[SCSI_MAX_SG_SEGMENTS - 1];
|
||||
|
||||
while ((sgl = sg_chain_ptr(ret)) != NULL) {
|
||||
ret = &sgl[SCSI_MAX_SG_SEGMENTS - 1];
|
||||
mempool_free(sgl, sgp->pool);
|
||||
}
|
||||
|
||||
mempool_free(prev, sgp->pool);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(scsi_alloc_sgtable);
|
||||
|
||||
void scsi_free_sgtable(struct scatterlist *sgl, int index)
|
||||
void scsi_free_sgtable(struct scsi_cmnd *cmd)
|
||||
{
|
||||
struct scatterlist *sgl = cmd->request_buffer;
|
||||
struct scsi_host_sg_pool *sgp;
|
||||
|
||||
BUG_ON(index >= SG_MEMPOOL_NR);
|
||||
/*
|
||||
* if this is the biggest size sglist, check if we have
|
||||
* chained parts we need to free
|
||||
*/
|
||||
if (cmd->__use_sg > SCSI_MAX_SG_SEGMENTS) {
|
||||
unsigned short this, left;
|
||||
struct scatterlist *next;
|
||||
unsigned int index;
|
||||
|
||||
left = cmd->__use_sg - (SCSI_MAX_SG_SEGMENTS - 1);
|
||||
next = sg_chain_ptr(&sgl[SCSI_MAX_SG_SEGMENTS - 1]);
|
||||
while (left && next) {
|
||||
sgl = next;
|
||||
this = left;
|
||||
if (this > SCSI_MAX_SG_SEGMENTS) {
|
||||
this = SCSI_MAX_SG_SEGMENTS - 1;
|
||||
index = SG_MEMPOOL_NR - 1;
|
||||
} else
|
||||
index = scsi_sgtable_index(this);
|
||||
|
||||
left -= this;
|
||||
|
||||
sgp = scsi_sg_pools + index;
|
||||
|
||||
if (left)
|
||||
next = sg_chain_ptr(&sgl[sgp->size - 1]);
|
||||
|
||||
mempool_free(sgl, sgp->pool);
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore original, will be freed below
|
||||
*/
|
||||
sgl = cmd->request_buffer;
|
||||
sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1;
|
||||
} else
|
||||
sgp = scsi_sg_pools + scsi_sgtable_index(cmd->__use_sg);
|
||||
|
||||
sgp = scsi_sg_pools + index;
|
||||
mempool_free(sgl, sgp->pool);
|
||||
}
|
||||
|
||||
@@ -770,7 +886,7 @@ EXPORT_SYMBOL(scsi_free_sgtable);
|
||||
static void scsi_release_buffers(struct scsi_cmnd *cmd)
|
||||
{
|
||||
if (cmd->use_sg)
|
||||
scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
|
||||
scsi_free_sgtable(cmd);
|
||||
|
||||
/*
|
||||
* Zero these out. They now point to freed memory, and it is
|
||||
@@ -984,7 +1100,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
|
||||
static int scsi_init_io(struct scsi_cmnd *cmd)
|
||||
{
|
||||
struct request *req = cmd->request;
|
||||
struct scatterlist *sgpnt;
|
||||
int count;
|
||||
|
||||
/*
|
||||
@@ -997,14 +1112,13 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
|
||||
/*
|
||||
* If sg table allocation fails, requeue request later.
|
||||
*/
|
||||
sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC);
|
||||
if (unlikely(!sgpnt)) {
|
||||
cmd->request_buffer = scsi_alloc_sgtable(cmd, GFP_ATOMIC);
|
||||
if (unlikely(!cmd->request_buffer)) {
|
||||
scsi_unprep_request(req);
|
||||
return BLKPREP_DEFER;
|
||||
}
|
||||
|
||||
req->buffer = NULL;
|
||||
cmd->request_buffer = (char *) sgpnt;
|
||||
if (blk_pc_request(req))
|
||||
cmd->request_bufflen = req->data_len;
|
||||
else
|
||||
@@ -1529,8 +1643,25 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
|
||||
if (!q)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* this limit is imposed by hardware restrictions
|
||||
*/
|
||||
blk_queue_max_hw_segments(q, shost->sg_tablesize);
|
||||
blk_queue_max_phys_segments(q, SCSI_MAX_PHYS_SEGMENTS);
|
||||
|
||||
/*
|
||||
* In the future, sg chaining support will be mandatory and this
|
||||
* ifdef can then go away. Right now we don't have all archs
|
||||
* converted, so better keep it safe.
|
||||
*/
|
||||
#ifdef ARCH_HAS_SG_CHAIN
|
||||
if (shost->use_sg_chaining)
|
||||
blk_queue_max_phys_segments(q, SCSI_MAX_SG_CHAIN_SEGMENTS);
|
||||
else
|
||||
blk_queue_max_phys_segments(q, SCSI_MAX_SG_SEGMENTS);
|
||||
#else
|
||||
blk_queue_max_phys_segments(q, SCSI_MAX_SG_SEGMENTS);
|
||||
#endif
|
||||
|
||||
blk_queue_max_sectors(q, shost->max_sectors);
|
||||
blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost));
|
||||
blk_queue_segment_boundary(q, shost->dma_boundary);
|
||||
@@ -2193,18 +2324,19 @@ EXPORT_SYMBOL_GPL(scsi_target_unblock);
|
||||
*
|
||||
* Returns virtual address of the start of the mapped page
|
||||
*/
|
||||
void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
|
||||
void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count,
|
||||
size_t *offset, size_t *len)
|
||||
{
|
||||
int i;
|
||||
size_t sg_len = 0, len_complete = 0;
|
||||
struct scatterlist *sg;
|
||||
struct page *page;
|
||||
|
||||
WARN_ON(!irqs_disabled());
|
||||
|
||||
for (i = 0; i < sg_count; i++) {
|
||||
for_each_sg(sgl, sg, sg_count, i) {
|
||||
len_complete = sg_len; /* Complete sg-entries */
|
||||
sg_len += sg[i].length;
|
||||
sg_len += sg->length;
|
||||
if (sg_len > *offset)
|
||||
break;
|
||||
}
|
||||
@@ -2218,10 +2350,10 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
|
||||
}
|
||||
|
||||
/* Offset starting from the beginning of first page in this sg-entry */
|
||||
*offset = *offset - len_complete + sg[i].offset;
|
||||
*offset = *offset - len_complete + sg->offset;
|
||||
|
||||
/* Assumption: contiguous pages can be accessed as "page + i" */
|
||||
page = nth_page(sg[i].page, (*offset >> PAGE_SHIFT));
|
||||
page = nth_page(sg->page, (*offset >> PAGE_SHIFT));
|
||||
*offset &= ~PAGE_MASK;
|
||||
|
||||
/* Bytes in this sg-entry from *offset to the end of the page */
|
||||
|
@@ -332,7 +332,7 @@ static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd)
|
||||
scsi_tgt_uspace_send_status(cmd, tcmd->itn_id, tcmd->tag);
|
||||
|
||||
if (cmd->request_buffer)
|
||||
scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
|
||||
scsi_free_sgtable(cmd);
|
||||
|
||||
queue_work(scsi_tgtd, &tcmd->work);
|
||||
}
|
||||
@@ -373,7 +373,7 @@ static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask)
|
||||
}
|
||||
|
||||
eprintk("cmd %p cnt %d\n", cmd, cmd->use_sg);
|
||||
scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
|
||||
scsi_free_sgtable(cmd);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@@ -826,27 +826,6 @@ static int sd_sync_cache(struct scsi_disk *sdkp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_issue_flush(struct request_queue *q, struct gendisk *disk,
|
||||
sector_t *error_sector)
|
||||
{
|
||||
int ret = 0;
|
||||
struct scsi_device *sdp = q->queuedata;
|
||||
struct scsi_disk *sdkp;
|
||||
|
||||
if (sdp->sdev_state != SDEV_RUNNING)
|
||||
return -ENXIO;
|
||||
|
||||
sdkp = scsi_disk_get_from_dev(&sdp->sdev_gendev);
|
||||
|
||||
if (!sdkp)
|
||||
return -ENODEV;
|
||||
|
||||
if (sdkp->WCE)
|
||||
ret = sd_sync_cache(sdkp);
|
||||
scsi_disk_put(sdkp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sd_prepare_flush(struct request_queue *q, struct request *rq)
|
||||
{
|
||||
memset(rq->cmd, 0, sizeof(rq->cmd));
|
||||
@@ -1697,7 +1676,6 @@ static int sd_probe(struct device *dev)
|
||||
sd_revalidate_disk(gd);
|
||||
|
||||
blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
|
||||
blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush);
|
||||
|
||||
gd->driverfs_dev = &sdp->sdev_gendev;
|
||||
gd->flags = GENHD_FL_DRIVERFS;
|
||||
|
@@ -1165,7 +1165,7 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
|
||||
sg = rsv_schp->buffer;
|
||||
sa = vma->vm_start;
|
||||
for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
|
||||
++k, ++sg) {
|
||||
++k, sg = sg_next(sg)) {
|
||||
len = vma->vm_end - sa;
|
||||
len = (len < sg->length) ? len : sg->length;
|
||||
if (offset < len) {
|
||||
@@ -1209,7 +1209,7 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
sa = vma->vm_start;
|
||||
sg = rsv_schp->buffer;
|
||||
for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
|
||||
++k, ++sg) {
|
||||
++k, sg = sg_next(sg)) {
|
||||
len = vma->vm_end - sa;
|
||||
len = (len < sg->length) ? len : sg->length;
|
||||
sa += len;
|
||||
@@ -1840,7 +1840,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
|
||||
}
|
||||
for (k = 0, sg = schp->buffer, rem_sz = blk_size;
|
||||
(rem_sz > 0) && (k < mx_sc_elems);
|
||||
++k, rem_sz -= ret_sz, ++sg) {
|
||||
++k, rem_sz -= ret_sz, sg = sg_next(sg)) {
|
||||
|
||||
num = (rem_sz > scatter_elem_sz_prev) ?
|
||||
scatter_elem_sz_prev : rem_sz;
|
||||
@@ -1913,7 +1913,7 @@ sg_write_xfer(Sg_request * srp)
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
for (; p; ++sg, ksglen = sg->length,
|
||||
for (; p; sg = sg_next(sg), ksglen = sg->length,
|
||||
p = page_address(sg->page)) {
|
||||
if (usglen <= 0)
|
||||
break;
|
||||
@@ -1992,7 +1992,7 @@ sg_remove_scat(Sg_scatter_hold * schp)
|
||||
int k;
|
||||
|
||||
for (k = 0; (k < schp->k_use_sg) && sg->page;
|
||||
++k, ++sg) {
|
||||
++k, sg = sg_next(sg)) {
|
||||
SCSI_LOG_TIMEOUT(5, printk(
|
||||
"sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
|
||||
k, sg->page, sg->length));
|
||||
@@ -2045,7 +2045,7 @@ sg_read_xfer(Sg_request * srp)
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
for (; p; ++sg, ksglen = sg->length,
|
||||
for (; p; sg = sg_next(sg), ksglen = sg->length,
|
||||
p = page_address(sg->page)) {
|
||||
if (usglen <= 0)
|
||||
break;
|
||||
@@ -2092,7 +2092,7 @@ sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
|
||||
if ((!outp) || (num_read_xfer <= 0))
|
||||
return 0;
|
||||
|
||||
for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, ++sg) {
|
||||
for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, sg = sg_next(sg)) {
|
||||
num = sg->length;
|
||||
if (num > num_read_xfer) {
|
||||
if (__copy_to_user(outp, page_address(sg->page),
|
||||
@@ -2142,7 +2142,7 @@ sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size)
|
||||
SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size));
|
||||
rem = size;
|
||||
|
||||
for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sg) {
|
||||
for (k = 0; k < rsv_schp->k_use_sg; ++k, sg = sg_next(sg)) {
|
||||
num = sg->length;
|
||||
if (rem <= num) {
|
||||
sfp->save_scat_len = num;
|
||||
|
@@ -1123,6 +1123,7 @@ static struct scsi_host_template driver_template = {
|
||||
.this_id = -1,
|
||||
.sg_tablesize = ST_MAX_SG,
|
||||
.cmd_per_lun = ST_CMD_PER_LUN,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
static int stex_set_dma_mask(struct pci_dev * pdev)
|
||||
|
@@ -854,5 +854,6 @@ static struct scsi_host_template driver_template = {
|
||||
.cmd_per_lun = 1,
|
||||
.unchecked_isa_dma = 1,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
#include "scsi_module.c"
|
||||
|
@@ -1808,6 +1808,7 @@ static struct scsi_host_template sym2_template = {
|
||||
.eh_host_reset_handler = sym53c8xx_eh_host_reset_handler,
|
||||
.this_id = 7,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
.max_sectors = 0xFFFF,
|
||||
#ifdef SYM_LINUX_PROC_INFO_SUPPORT
|
||||
.proc_info = sym53c8xx_proc_info,
|
||||
|
@@ -450,7 +450,8 @@ static struct scsi_host_template driver_template = {
|
||||
.slave_configure = u14_34f_slave_configure,
|
||||
.this_id = 7,
|
||||
.unchecked_isa_dma = 1,
|
||||
.use_clustering = ENABLE_CLUSTERING
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
|
@@ -1197,5 +1197,6 @@ static struct scsi_host_template driver_template = {
|
||||
.cmd_per_lun = ULTRASTOR_MAX_CMDS_PER_LUN,
|
||||
.unchecked_isa_dma = 1,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
#include "scsi_module.c"
|
||||
|
@@ -1671,6 +1671,7 @@ static struct scsi_host_template driver_template = {
|
||||
.cmd_per_lun = 1,
|
||||
.unchecked_isa_dma = 1,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.use_sg_chaining = ENABLE_SG_CHAINING,
|
||||
};
|
||||
|
||||
#include "scsi_module.c"
|
||||
|
Verwijs in nieuw issue
Block a user