[SCSI] sym2: Manage sym_lcb properly

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>
This commit is contained in:
Matthew Wilcox 2005-11-29 23:08:31 -05:00 committed by James Bottomley
parent 760c9de589
commit 84e203a279
3 changed files with 38 additions and 121 deletions

View file

@ -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:
@ -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
@ -1005,6 +1000,10 @@ 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;
}
@ -1012,21 +1011,13 @@ static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
/*
* 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.
*/
@ -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)
@ -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
*/
@ -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,

View file

@ -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;
@ -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.
*/
@ -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
@ -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.
@ -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;
}
@ -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.
@ -5481,8 +5427,7 @@ finish:
/*
* 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
}
@ -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.
@ -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
/*
@ -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");
@ -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

View file

@ -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.
@ -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