mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-20 06:06:23 +00:00
Synchronize with Feral CVS repository:
- Make FC_SCRATCH_ACQUIRE a macro that returns true/false - Fixes from Stanislaw for 2.6.23 & 2.6.24. Many thanks. - A quick hack to isp_kthread to use waitqueues instead of semaphores to have less blockage. More rewrites later git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@314 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $Id: isp_cb_ops.c,v 1.87 2008/03/10 17:55:51 mjacob Exp $ */
|
||||
/* $Id: isp_cb_ops.c,v 1.88 2008/03/15 18:16:47 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2008 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -1251,7 +1251,12 @@ isp_exti_fcct_passthru(EXT_IOCTL *pext)
|
||||
* Acquire Scratch
|
||||
*/
|
||||
MEMZERO(qe, QENTRY_LEN);
|
||||
FC_SCRATCH_ACQUIRE(isp, 0);
|
||||
if (FC_SCRATCH_ACQUIRE(isp, 0)) {
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
isp_prt(isp, ISP_LOGWARN, "failed to get FC scratch area");
|
||||
pext->Status = EXT_STATUS_BUSY;
|
||||
goto out;
|
||||
}
|
||||
scp = fcp->isp_scratch;
|
||||
|
||||
MEMCPY(&scp[IGPOFF], localmem, pext->RequestLen);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: isp_linux.c,v 1.228 2008/03/10 17:55:51 mjacob Exp $ */
|
||||
/* $Id: isp_linux.c,v 1.229 2008/03/15 18:16:47 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2008 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -2593,7 +2593,10 @@ isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role)
|
||||
MEMZERO(qe, QENTRY_LEN);
|
||||
/* Acquire Scratch */
|
||||
|
||||
FC_SCRATCH_ACQUIRE(isp, chan);
|
||||
if (FC_SCRATCH_ACQUIRE(isp, chan)) {
|
||||
ISP_DATA(isp, chan)->blocked = 0;
|
||||
return (-EBUSY);
|
||||
}
|
||||
scp = fcp->isp_scratch;
|
||||
|
||||
/*
|
||||
@@ -3112,9 +3115,11 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
|
||||
}
|
||||
}
|
||||
if (lp->ini_map_idx) {
|
||||
unsigned long arg;
|
||||
tgt = lp->ini_map_idx - 1;
|
||||
isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "arrived at", tgt, lp->node_wwn, lp->port_wwn);
|
||||
ISP_THREAD_EVENT(isp, ISP_THREAD_SCSI_SCAN, 0, 0, __FUNCTION__, __LINE__);
|
||||
arg = tgt | (bus << 16);
|
||||
ISP_THREAD_EVENT(isp, ISP_THREAD_SCSI_SCAN, (void *)arg, 0, __FUNCTION__, __LINE__);
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "arrived", lp->node_wwn, lp->port_wwn);
|
||||
}
|
||||
@@ -3155,12 +3160,14 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
|
||||
va_end(ap);
|
||||
fcp = FCPARAM(isp, bus);
|
||||
if (lp->ini_map_idx) {
|
||||
unsigned long arg;
|
||||
tgt = lp->ini_map_idx - 1;
|
||||
fcp->isp_ini_map[tgt] = 0;
|
||||
lp->state = FC_PORTDB_STATE_NIL;
|
||||
lp->ini_map_idx = 0;
|
||||
isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "departed", tgt, lp->node_wwn, lp->port_wwn);
|
||||
ISP_THREAD_EVENT(isp, ISP_THREAD_SCSI_SCAN, 0, 0, __FUNCTION__, __LINE__);
|
||||
arg = tgt | (bus << 16) | (1 << 31);
|
||||
ISP_THREAD_EVENT(isp, ISP_THREAD_SCSI_SCAN, (void *)arg, 0, __FUNCTION__, __LINE__);
|
||||
} else if (lp->reserved == 0) {
|
||||
isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "departed", lp->node_wwn, lp->port_wwn);
|
||||
}
|
||||
@@ -4483,8 +4490,18 @@ isp_task_thread(void *arg)
|
||||
case ISP_THREAD_NIL:
|
||||
break;
|
||||
case ISP_THREAD_SCSI_SCAN:
|
||||
scsi_scan_host(isp->isp_osinfo.host);
|
||||
{
|
||||
/* this gets pegged in isplinux_queuecommand, even for async scanning */
|
||||
#if 0
|
||||
unsigned long arg = (unsigned long) tap->arg;
|
||||
int tgt, chan, rescan;
|
||||
tgt = arg & 0xffff;
|
||||
chan = (arg >> 16) & 0xff;
|
||||
rescan = (arg >> 31) & 1;
|
||||
scsi_scan_target(&isp->isp_osinfo.host->shost_gendev, chan, tgt, SCAN_WILD_CARD, rescan);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case ISP_THREAD_REINIT:
|
||||
ISP_LOCKU_SOFTC(isp);
|
||||
if (isp->isp_dead) {
|
||||
|
||||
+31
-29
@@ -1,4 +1,4 @@
|
||||
/* $Id: isp_linux.h,v 1.159 2008/03/03 01:42:01 mjacob Exp $ */
|
||||
/* $Id: isp_linux.h,v 1.160 2008/03/15 18:16:47 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2008 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -323,7 +323,7 @@ struct isposinfo {
|
||||
intsok : 1;
|
||||
u16 frame_size;
|
||||
u16 exec_throttle;
|
||||
struct semaphore trq;
|
||||
wait_queue_head_t trq;
|
||||
struct semaphore tcs;
|
||||
spinlock_t tlock;
|
||||
unsigned int nt_actions;
|
||||
@@ -376,16 +376,17 @@ struct isposinfo {
|
||||
kernel_thread(isp_task_thread, (x), 0); \
|
||||
down(&isp->isp_osinfo.tcs)
|
||||
|
||||
#define ISP_THREAD_IACK(x) \
|
||||
sema_init(&(x)->isp_osinfo.trq, 0); \
|
||||
(x)->isp_osinfo.task_active = 1; \
|
||||
#define ISP_THREAD_IACK(x) \
|
||||
init_waitqueue_head(&(x)->isp_osinfo.trq); \
|
||||
(x)->isp_osinfo.task_active = 1; \
|
||||
up(&(x)->isp_osinfo.tcs)
|
||||
|
||||
#define ISP_THREAD_WAIT(x) down_interruptible(&(x)->isp_osinfo.trq)
|
||||
|
||||
#define ISP_THREAD_WAIT(x) \
|
||||
wait_event_interruptible((x)->isp_osinfo.trq, (((x)->isp_osinfo.task_active == 0) || ((x)->isp_osinfo.nt_actions != 0)))
|
||||
|
||||
#define ISP_THREAD_EVENT isp_thread_event
|
||||
|
||||
#define ISP_THREAD_WAKE(x) up(&(x)->isp_osinfo.trq)
|
||||
#define ISP_THREAD_WAKE(x) wake_up_all(&(x)->isp_osinfo.trq)
|
||||
|
||||
#define ISP_THREAD_KILL(x) \
|
||||
{ \
|
||||
@@ -394,7 +395,7 @@ struct isposinfo {
|
||||
if ((x)->isp_osinfo.task_active) { \
|
||||
sema_init(&(x)->isp_osinfo.tcs, 0); \
|
||||
(x)->isp_osinfo.task_active = 0; \
|
||||
up(&(x)->isp_osinfo.trq); \
|
||||
wake_up_all(&(x)->isp_osinfo.trq); \
|
||||
spin_unlock_irqrestore(&(x)->isp_osinfo.tlock, _fl); \
|
||||
down(&(x)->isp_osinfo.tcs); \
|
||||
} else { \
|
||||
@@ -476,26 +477,9 @@ struct isposinfo {
|
||||
isp->mboxcmd_done = 1
|
||||
#define MBOX_RELEASE(isp) up(&isp->mbox_sem)
|
||||
|
||||
#define FC_SCRATCH_ACQUIRE(isp, chan) \
|
||||
/* \
|
||||
* Try and acquire semaphore the easy way first- \
|
||||
* with our lock already held. \
|
||||
*/ \
|
||||
if (ISP_ATOMIC()) { \
|
||||
while (down_trylock(&isp->fcs_sem)) { \
|
||||
ISP_DROP_LK_SOFTC(isp); \
|
||||
USEC_DELAY(5000); \
|
||||
ISP_IGET_LK_SOFTC(isp); \
|
||||
} \
|
||||
} else { \
|
||||
ISP_DROP_LK_SOFTC(isp); \
|
||||
down(&isp->fcs_sem); \
|
||||
ISP_IGET_LK_SOFTC(isp); \
|
||||
}
|
||||
|
||||
#define FC_SCRATCH_RELEASE(isp, chan) up(&isp->fcs_sem)
|
||||
|
||||
|
||||
#define FC_SCRATCH_ACQUIRE fc_scratch_acquire
|
||||
#define FC_SCRATCH_RELEASE(isp, chan) ISP_DATA(isp, chan)->scratch_busy = 0
|
||||
|
||||
#ifndef SCSI_GOOD
|
||||
#define SCSI_GOOD 0x0
|
||||
#endif
|
||||
@@ -628,6 +612,14 @@ void isp_prt(ispsoftc_t *, int level, const char *, ...) __attribute__((__format
|
||||
void isp_prt(ispsoftc_t *, int level, const char *, ...);
|
||||
#endif
|
||||
|
||||
#ifndef DECLARE_MUTEX_LOCKED
|
||||
#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
|
||||
#define sg_page(_sg) ((_sg)->page)
|
||||
#define sg_assign_page(_sg, _pg) ((_sg)->page = (_pg))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* isp_osinfo definitions, extensions and shorthand.
|
||||
@@ -644,6 +636,7 @@ typedef struct {
|
||||
: 10,
|
||||
fcrswdog : 1,
|
||||
: 1,
|
||||
scratch_busy : 1,
|
||||
blocked : 1,
|
||||
deadloop : 1,
|
||||
role : 2;
|
||||
@@ -918,6 +911,15 @@ mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
fc_scratch_acquire(ispsoftc_t *isp, int chan)
|
||||
{
|
||||
if (ISP_DATA(isp, chan)->scratch_busy) {
|
||||
return (-1);
|
||||
}
|
||||
ISP_DATA(isp, chan)->scratch_busy = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that these allocators aren't interrupt safe
|
||||
|
||||
+28
-19
@@ -1,4 +1,4 @@
|
||||
/* $Id: scsi_target.c,v 1.82 2008/02/27 21:01:12 mjacob Exp $ */
|
||||
/* $Id: scsi_target.c,v 1.83 2008/03/15 18:16:47 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2008 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -93,6 +93,15 @@
|
||||
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
|
||||
#endif
|
||||
|
||||
#ifndef DECLARE_MUTEX_LOCKED
|
||||
#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
|
||||
#define sg_page(_sg) ((_sg)->page)
|
||||
#define sg_assign_page(_sg, _pg) ((_sg)->page = (_pg))
|
||||
#endif
|
||||
|
||||
#include "isp_tpublic.h"
|
||||
#include "linux/smp_lock.h"
|
||||
|
||||
@@ -180,8 +189,8 @@
|
||||
#define SGS0 (roundup(sizeof (struct scatterlist), sizeof (void *)))
|
||||
#define SGS_PAYLOAD_SIZE (SGS_SIZE - SGS0)
|
||||
#define SGS_SGP(x) ((struct scatterlist *)&((u8 *)(x))[SGS_PAYLOAD_SIZE])
|
||||
#define COPYIN(u, k, n) copy_from_user((void*)(k), (const void*)(u), (n))
|
||||
#define COPYOUT(k, u, n) copy_to_user((void*)(u), (const void*)(k), (n))
|
||||
#define COPYIN(uarg, karg, amt) copy_from_user(karg, uarg, amt)
|
||||
#define COPYOUT(karg, uarg, amt) copy_to_user(uarg, karg, amt)
|
||||
|
||||
static __inline void * scsi_target_kalloc(size_t, int);
|
||||
static __inline void scsi_target_kfree(void *, size_t);
|
||||
@@ -226,10 +235,10 @@ init_sg_elem(struct scatterlist *sgp, struct page *p, int offset, void *addr, si
|
||||
{
|
||||
sgp->length = length;
|
||||
if (p) {
|
||||
sgp->page = p;
|
||||
sg_assign_page(sgp, p);
|
||||
sgp->offset = offset;
|
||||
} else {
|
||||
sgp->page = virt_to_page(addr);
|
||||
sg_assign_page(sgp, virt_to_page(addr));
|
||||
sgp->offset = offset_in_page(addr);
|
||||
}
|
||||
}
|
||||
@@ -1573,8 +1582,8 @@ scsi_target_rdwr(tmd_cmd_t *tmd, ini_t *ini, int from_intr)
|
||||
spin_lock_irqsave(&scsi_target_lock, flags);
|
||||
dp = sg_cache;
|
||||
if (dp) {
|
||||
sg_cache = (struct scatterlist *) dp->page;
|
||||
dp->page = NULL;
|
||||
sg_cache = (struct scatterlist *) sg_page(dp);
|
||||
sg_assign_page(dp, NULL);
|
||||
tmd->cd_flags |= CDF_PRIVATE_3;
|
||||
}
|
||||
spin_unlock_irqrestore(&scsi_target_lock, flags);
|
||||
@@ -1606,17 +1615,17 @@ scsi_target_rdwr(tmd_cmd_t *tmd, ini_t *ini, int from_intr)
|
||||
spin_lock_irqsave(&scsi_target_lock, flags);
|
||||
while (count < byte_count) {
|
||||
struct page *pp;
|
||||
dp[sgidx].page = (struct page *) lp->pagelists;
|
||||
if (dp[sgidx].page == NULL) {
|
||||
sg_assign_page(&dp[sgidx], (struct page *) lp->pagelists);
|
||||
if (sg_page(&dp[sgidx]) == NULL) {
|
||||
lp->outtagas = 1;
|
||||
scsi_cmd_sched_restart_locked(tmd, 0, "out of pages");
|
||||
while (--sgidx >= 0) {
|
||||
struct page *pp = dp[sgidx].page;
|
||||
struct page *pp = sg_page(&dp[sgidx]);
|
||||
NextPage(pp) = (NextPageType) lp->pagelists;
|
||||
lp->pagelists = (struct page ***) pp;
|
||||
}
|
||||
if (tmd->cd_flags & CDF_PRIVATE_3) {
|
||||
dp->page = (struct page *) sg_cache;
|
||||
sg_assign_page(dp, (struct page *) sg_cache);
|
||||
sg_cache = (struct scatterlist *) dp;
|
||||
spin_unlock_irqrestore(&scsi_target_lock, flags);
|
||||
tmd->cd_flags ^= CDF_PRIVATE_3;
|
||||
@@ -1628,7 +1637,7 @@ scsi_target_rdwr(tmd_cmd_t *tmd, ini_t *ini, int from_intr)
|
||||
}
|
||||
dp[sgidx].length = min(PAGE_SIZE, byte_count - count);
|
||||
count += dp[sgidx].length;
|
||||
pp = dp[sgidx].page;
|
||||
pp = sg_page(&dp[sgidx]);
|
||||
lp->pagelists = (struct page ***) NextPage(pp);
|
||||
lp->npglists -= 1;
|
||||
SDprintk2("scsi_target: [%llx] dp[%d]:off %u len %u\n", tmd->cd_tagval, sgidx, dp[sgidx].offset, dp[sgidx].length);
|
||||
@@ -1660,7 +1669,7 @@ scsi_target_rdwr(tmd_cmd_t *tmd, ini_t *ini, int from_intr)
|
||||
dp[sgidx].length = min(PAGE_SIZE, byte_count - count);
|
||||
}
|
||||
SDprintk2(" dp[%d]:off %u len %u %u:%u\n", sgidx, dp[sgidx].offset, dp[sgidx].length, list_idx, page_idx);
|
||||
dp[sgidx].page = pglist[page_idx++];
|
||||
sg_assign_page(&dp[sgidx], pglist[page_idx++]);
|
||||
count += dp[sgidx++].length;
|
||||
if (count != byte_count) {
|
||||
if (page_idx == PG_PER_LIST) {
|
||||
@@ -1741,7 +1750,7 @@ scsi_target_ldfree(bus_t *bp, tmd_xact_t *xact, int from_intr)
|
||||
}
|
||||
SDprintk("scsi_target: LDFREE[%llx] %p xact->td_data %p\n", tmd->cd_tagval, tmd, dp);
|
||||
if (dp) {
|
||||
scsi_target_kfree(page_address(dp->page) + dp->offset, SGS_SIZE);
|
||||
scsi_target_kfree(page_address(sg_page(dp)) + dp->offset, SGS_SIZE);
|
||||
} else {
|
||||
printk(KERN_ERR "scsi_target: LDFREE[%llx] null dp @ line %d\n", tmd->cd_tagval, __LINE__);
|
||||
return (0);
|
||||
@@ -1767,7 +1776,7 @@ scsi_target_ldfree(bus_t *bp, tmd_xact_t *xact, int from_intr)
|
||||
}
|
||||
if (lp->overcommit) {
|
||||
for (i = 0; i < tmd->cd_nsgelems; i++) {
|
||||
struct page *pp = dp[i].page;
|
||||
struct page *pp = sg_page(&dp[i]);
|
||||
if (pp == NULL) {
|
||||
printk(KERN_ERR "%s: LDFREE[%llx] whoa! nullpage at index %d of %d for command 0x%x\n", __FUNCTION__, tmd->cd_tagval, i, tmd->cd_nsgelems - 1, tmd->cd_cdb[0] & 0xff);
|
||||
continue;
|
||||
@@ -1782,7 +1791,7 @@ scsi_target_ldfree(bus_t *bp, tmd_xact_t *xact, int from_intr)
|
||||
}
|
||||
if (tmd->cd_flags & CDF_PRIVATE_3) {
|
||||
memset(dp, 0, tmd->cd_nsgelems * sizeof (struct scatterlist));
|
||||
dp->page = (struct page *) sg_cache;
|
||||
sg_assign_page(dp, (struct page *) sg_cache);
|
||||
sg_cache = dp;
|
||||
spin_unlock_irqrestore(&scsi_target_lock, flags);
|
||||
tmd->cd_flags &= ~CDF_PRIVATE_3;
|
||||
@@ -2280,7 +2289,7 @@ scsi_target_copydata(struct scatterlist *dp, void *ubuf, uint32_t len, int from_
|
||||
idx = count = 0;
|
||||
uva = ubuf;
|
||||
while (count < len) {
|
||||
pp = dp[idx].page;
|
||||
pp = sg_page(&dp[idx]);
|
||||
kva = kmap(pp);
|
||||
if (kva == NULL) {
|
||||
return (-EFAULT);
|
||||
@@ -2580,7 +2589,7 @@ int init_module(void)
|
||||
if (sg == NULL) {
|
||||
break;
|
||||
}
|
||||
sg->page = (struct page *) sg_cache;
|
||||
sg_assign_page(sg, (struct page *) sg_cache);
|
||||
sg_cache = sg;
|
||||
}
|
||||
printk(KERN_INFO "Allocated %d cached sg elements\n", i);
|
||||
@@ -2597,7 +2606,7 @@ void cleanup_module(void)
|
||||
down(&scsi_thread_entry_exit_semaphore);
|
||||
free_sdata_chain(sdp);
|
||||
while (sg_cache) {
|
||||
struct scatterlist *sg = (struct scatterlist *) sg_cache->page;
|
||||
struct scatterlist *sg = (struct scatterlist *) sg_page(sg_cache);
|
||||
scsi_target_kfree(sg_cache, SGELEM_CACHE_SIZE * sizeof (struct scatterlist));
|
||||
sg_cache = sg;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user