Skip to content

Commit

Permalink
[SCSI] sym2: Manage sym_lcb properly
Browse files Browse the repository at this point in the history
Allocate the lcb in slave_alloc and free it in slave_destroy.  This allows
us to remove all the code that checks to see if it's already been allocated.

From: Christoph Hellwig <hch@lst.de>
Signed-off-by: Matthew Wilcox <matthew@wil.cx>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
  • Loading branch information
Matthew Wilcox authored and James Bottomley committed Dec 14, 2005
1 parent 760c9de commit 84e203a
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 121 deletions.
59 changes: 31 additions & 28 deletions drivers/scsi/sym53c8xx_2/sym_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -563,10 +563,7 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s
/*
* activate this job.
*/
if (lp)
sym_start_next_ccbs(np, lp, 2);
else
sym_put_start_queue(np, cp);
sym_start_next_ccbs(np, lp, 2);
return 0;

out_abort:
Expand Down Expand Up @@ -981,15 +978,13 @@ static int device_queue_depth(struct sym_hcb *np, int target, int lun)

static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
{
struct sym_hcb *np;
struct sym_tcb *tp;
struct sym_hcb *np = sym_get_hcb(sdev->host);
struct sym_tcb *tp = &np->target[sdev->id];
struct sym_lcb *lp;

if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN)
return -ENXIO;

np = sym_get_hcb(sdev->host);
tp = &np->target[sdev->id];

/*
* Fail the device init if the device is flagged NOSCAN at BOOT in
* the NVRAM. This may speed up boot and maintain coherency with
Expand All @@ -1005,28 +1000,24 @@ static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
return -ENXIO;
}

lp = sym_alloc_lcb(np, sdev->id, sdev->lun);
if (!lp)
return -ENOMEM;

tp->starget = sdev->sdev_target;
return 0;
}

/*
* Linux entry point for device queue sizing.
*/
static int sym53c8xx_slave_configure(struct scsi_device *device)
static int sym53c8xx_slave_configure(struct scsi_device *sdev)
{
struct sym_hcb *np = sym_get_hcb(device->host);
struct sym_tcb *tp = &np->target[device->id];
struct sym_lcb *lp;
struct sym_hcb *np = sym_get_hcb(sdev->host);
struct sym_tcb *tp = &np->target[sdev->id];
struct sym_lcb *lp = sym_lp(tp, sdev->lun);
int reqtags, depth_to_use;

/*
* Allocate the LCB if not yet.
* If it fail, we may well be in the sh*t. :)
*/
lp = sym_alloc_lcb(np, device->id, device->lun);
if (!lp)
return -ENOMEM;

/*
* Get user flags.
*/
Expand All @@ -1038,10 +1029,10 @@ static int sym53c8xx_slave_configure(struct scsi_device *device)
* Use at least 2.
* Donnot use more than our maximum.
*/
reqtags = device_queue_depth(np, device->id, device->lun);
reqtags = device_queue_depth(np, sdev->id, sdev->lun);
if (reqtags > tp->usrtags)
reqtags = tp->usrtags;
if (!device->tagged_supported)
if (!sdev->tagged_supported)
reqtags = 0;
#if 1 /* Avoid to locally queue commands for no good reasons */
if (reqtags > SYM_CONF_MAX_TAG)
Expand All @@ -1050,19 +1041,30 @@ static int sym53c8xx_slave_configure(struct scsi_device *device)
#else
depth_to_use = (reqtags ? SYM_CONF_MAX_TAG : 2);
#endif
scsi_adjust_queue_depth(device,
(device->tagged_supported ?
scsi_adjust_queue_depth(sdev,
(sdev->tagged_supported ?
MSG_SIMPLE_TAG : 0),
depth_to_use);
lp->s.scdev_depth = depth_to_use;
sym_tune_dev_queuing(tp, device->lun, reqtags);
sym_tune_dev_queuing(tp, sdev->lun, reqtags);

if (!spi_initial_dv(device->sdev_target))
spi_dv_device(device);
if (!spi_initial_dv(sdev->sdev_target))
spi_dv_device(sdev);

return 0;
}

static void sym53c8xx_slave_destroy(struct scsi_device *sdev)
{
struct sym_hcb *np = sym_get_hcb(sdev->host);
struct sym_lcb *lp = sym_lp(&np->target[sdev->id], sdev->lun);

if (lp->itlq_tbl)
sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK * 4, "ITLQ_TBL");
kfree(lp->cb_tags);
sym_mfree_dma(lp, sizeof(*lp), "LCB");
}

/*
* Linux entry point for info() function
*/
Expand Down Expand Up @@ -1926,6 +1928,7 @@ static struct scsi_host_template sym2_template = {
.queuecommand = sym53c8xx_queue_command,
.slave_alloc = sym53c8xx_slave_alloc,
.slave_configure = sym53c8xx_slave_configure,
.slave_destroy = sym53c8xx_slave_destroy,
.eh_abort_handler = sym53c8xx_eh_abort_handler,
.eh_device_reset_handler = sym53c8xx_eh_device_reset_handler,
.eh_bus_reset_handler = sym53c8xx_eh_bus_reset_handler,
Expand Down
86 changes: 7 additions & 79 deletions drivers/scsi/sym53c8xx_2/sym_hipd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1523,7 +1523,7 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp
/*
* Insert a job into the start queue.
*/
void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp)
static void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp)
{
u_short qidx;

Expand Down Expand Up @@ -4664,30 +4664,7 @@ struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char t
goto out;
cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);

#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
/*
* If the LCB is not yet available and the LUN
* has been probed ok, try to allocate the LCB.
*/
if (!lp && sym_is_bit(tp->lun_map, ln)) {
lp = sym_alloc_lcb(np, tn, ln);
if (!lp)
goto out_free;
}
#endif

/*
* If the LCB is not available here, then the
* logical unit is not yet discovered. For those
* ones only accept 1 SCSI IO per logical unit,
* since we cannot allow disconnections.
*/
if (!lp) {
if (!sym_is_bit(tp->busy0_map, ln))
sym_set_bit(tp->busy0_map, ln);
else
goto out_free;
} else {
{
/*
* If we have been asked for a tagged command.
*/
Expand Down Expand Up @@ -4840,12 +4817,6 @@ void sym_free_ccb (struct sym_hcb *np, struct sym_ccb *cp)
lp->head.resel_sa =
cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
}
/*
* Otherwise, we only accept 1 IO per LUN.
* Clear the bit that keeps track of this IO.
*/
else
sym_clr_bit(tp->busy0_map, cp->lun);

/*
* We donnot queue more than 1 ccb per target
Expand Down Expand Up @@ -4997,20 +4968,7 @@ static void sym_init_tcb (struct sym_hcb *np, u_char tn)
struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
{
struct sym_tcb *tp = &np->target[tn];
struct sym_lcb *lp = sym_lp(tp, ln);

/*
* Already done, just return.
*/
if (lp)
return lp;

/*
* Donnot allow LUN control block
* allocation for not probed LUNs.
*/
if (!sym_is_bit(tp->lun_map, ln))
return NULL;
struct sym_lcb *lp = NULL;

/*
* Initialize the target control block if not yet.
Expand Down Expand Up @@ -5082,13 +5040,7 @@ struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
lp->started_max = SYM_CONF_MAX_TASK;
lp->started_limit = SYM_CONF_MAX_TASK;
#endif
/*
* If we are busy, count the IO.
*/
if (sym_is_bit(tp->busy0_map, ln)) {
lp->busy_itl = 1;
sym_clr_bit(tp->busy0_map, ln);
}

fail:
return lp;
}
Expand All @@ -5102,12 +5054,6 @@ static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln)
struct sym_lcb *lp = sym_lp(tp, ln);
int i;

/*
* If LCB not available, try to allocate it.
*/
if (!lp && !(lp = sym_alloc_lcb(np, tn, ln)))
goto fail;

/*
* Allocate the task table and and the tag allocation
* circular buffer. We want both or none.
Expand Down Expand Up @@ -5481,8 +5427,7 @@ if (resid)
/*
* Donnot start more than 1 command after an error.
*/
if (lp)
sym_start_next_ccbs(np, lp, 1);
sym_start_next_ccbs(np, lp, 1);
#endif
}

Expand Down Expand Up @@ -5520,12 +5465,6 @@ void sym_complete_ok (struct sym_hcb *np, struct sym_ccb *cp)
tp = &np->target[cp->target];
lp = sym_lp(tp, cp->lun);

/*
* Assume device discovered on first success.
*/
if (!lp)
sym_set_bit(tp->lun_map, cp->lun);

/*
* If all data have been transferred, given than no
* extended error did occur, there is no residual.
Expand Down Expand Up @@ -5578,7 +5517,7 @@ if (resid)
/*
* Requeue a couple of awaiting scsi commands.
*/
if (lp && !sym_que_empty(&lp->waiting_ccbq))
if (!sym_que_empty(&lp->waiting_ccbq))
sym_start_next_ccbs(np, lp, 2);
#endif
/*
Expand Down Expand Up @@ -5821,8 +5760,7 @@ void sym_hcb_free(struct sym_hcb *np)
SYM_QUEHEAD *qp;
struct sym_ccb *cp;
struct sym_tcb *tp;
struct sym_lcb *lp;
int target, lun;
int target;

if (np->scriptz0)
sym_mfree_dma(np->scriptz0, np->scriptz_sz, "SCRIPTZ0");
Expand All @@ -5848,16 +5786,6 @@ void sym_hcb_free(struct sym_hcb *np)

for (target = 0; target < SYM_CONF_MAX_TARGET ; target++) {
tp = &np->target[target];
for (lun = 0 ; lun < SYM_CONF_MAX_LUN ; lun++) {
lp = sym_lp(tp, lun);
if (!lp)
continue;
if (lp->itlq_tbl)
sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4,
"ITLQ_TBL");
kfree(lp->cb_tags);
sym_mfree_dma(lp, sizeof(*lp), "LCB");
}
#if SYM_CONF_MAX_LUN > 1
kfree(tp->lunmp);
#endif
Expand Down
14 changes: 0 additions & 14 deletions drivers/scsi/sym53c8xx_2/sym_hipd.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,19 +416,6 @@ struct sym_tcb {
struct sym_lcb **lunmp; /* Other LCBs [1..MAX_LUN] */
#endif

/*
* Bitmap that tells about LUNs that succeeded at least
* 1 IO and therefore assumed to be a real device.
* Avoid useless allocation of the LCB structure.
*/
u32 lun_map[(SYM_CONF_MAX_LUN+31)/32];

/*
* Bitmap that tells about LUNs that haven't yet an LCB
* allocated (not discovered or LCB allocation failed).
*/
u32 busy0_map[(SYM_CONF_MAX_LUN+31)/32];

#ifdef SYM_HAVE_STCB
/*
* O/S specific data structure.
Expand Down Expand Up @@ -1077,7 +1064,6 @@ char *sym_driver_name(void);
void sym_print_xerr(struct scsi_cmnd *cmd, int x_status);
int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int);
struct sym_chip *sym_lookup_chip_table(u_short device_id, u_char revision);
void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp);
#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn);
#endif
Expand Down

0 comments on commit 84e203a

Please sign in to comment.