Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
c23ee349
Commit
c23ee349
authored
Dec 05, 2002
by
Christoph Hellwig
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] move all sgtable handling in one place
We only need it in scsi_lib.c so the helper should be there aswell.
parent
d9841db4
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
116 additions
and
135 deletions
+116
-135
drivers/scsi/scsi.c
drivers/scsi/scsi.c
+3
-104
drivers/scsi/scsi.h
drivers/scsi/scsi.h
+2
-9
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_lib.c
+111
-22
No files found.
drivers/scsi/scsi.c
View file @
c23ee349
...
...
@@ -55,7 +55,6 @@
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/mempool.h>
#define __KERNEL_SYSCALLS__
...
...
@@ -74,24 +73,6 @@
#include <linux/kmod.h>
#endif
#define SG_MEMPOOL_NR 5
#define SG_MEMPOOL_SIZE 32
struct
scsi_host_sg_pool
{
int
size
;
char
*
name
;
kmem_cache_t
*
slab
;
mempool_t
*
pool
;
};
#define SP(x) { x, "sgpool-" #x }
struct
scsi_host_sg_pool
scsi_sg_pools
[
SG_MEMPOOL_NR
]
=
{
SP
(
8
),
SP
(
16
),
SP
(
32
),
SP
(
64
),
SP
(
MAX_PHYS_SEGMENTS
)
};
#undef SP
/*
static const char RCSid[] = "$Header: /vger/u4/cvs/linux/drivers/scsi/scsi.c,v 1.38 1997/01/19 23:07:18 davem Exp $";
*/
/*
* Definitions and constants.
...
...
@@ -668,10 +649,7 @@ int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason)
*/
void
scsi_release_command
(
Scsi_Cmnd
*
SCpnt
)
{
request_queue_t
*
q
;
Scsi_Device
*
SDpnt
;
SDpnt
=
SCpnt
->
device
;
request_queue_t
*
q
=
&
SCpnt
->
device
->
request_queue
;
__scsi_release_command
(
SCpnt
);
...
...
@@ -681,7 +659,6 @@ void scsi_release_command(Scsi_Cmnd * SCpnt)
* This won't block - if the device cannot take any more, life
* will go on.
*/
q
=
&
SDpnt
->
request_queue
;
scsi_queue_next_request
(
q
,
NULL
);
}
...
...
@@ -2084,81 +2061,12 @@ static int __init setup_scsi_default_dev_flags(char *str)
__setup
(
"scsi_default_dev_flags="
,
setup_scsi_default_dev_flags
);
#endif
static
void
*
scsi_pool_alloc
(
int
gfp_mask
,
void
*
data
)
{
return
kmem_cache_alloc
(
data
,
gfp_mask
);
}
static
void
scsi_pool_free
(
void
*
ptr
,
void
*
data
)
{
kmem_cache_free
(
data
,
ptr
);
}
struct
scatterlist
*
scsi_alloc_sgtable
(
Scsi_Cmnd
*
SCpnt
,
int
gfp_mask
)
{
struct
scsi_host_sg_pool
*
sgp
;
struct
scatterlist
*
sgl
;
int
pf_flags
;
BUG_ON
(
!
SCpnt
->
use_sg
);
switch
(
SCpnt
->
use_sg
)
{
case
1
...
8
:
SCpnt
->
sglist_len
=
0
;
break
;
case
9
...
16
:
SCpnt
->
sglist_len
=
1
;
break
;
case
17
...
32
:
SCpnt
->
sglist_len
=
2
;
break
;
case
33
...
64
:
SCpnt
->
sglist_len
=
3
;
break
;
case
65
...
MAX_PHYS_SEGMENTS
:
SCpnt
->
sglist_len
=
4
;
break
;
default:
return
NULL
;
}
sgp
=
scsi_sg_pools
+
SCpnt
->
sglist_len
;
pf_flags
=
current
->
flags
;
current
->
flags
|=
PF_NOWARN
;
sgl
=
mempool_alloc
(
sgp
->
pool
,
gfp_mask
);
current
->
flags
=
pf_flags
;
if
(
sgl
)
{
memset
(
sgl
,
0
,
sgp
->
size
);
return
sgl
;
}
return
sgl
;
}
void
scsi_free_sgtable
(
struct
scatterlist
*
sgl
,
int
index
)
{
struct
scsi_host_sg_pool
*
sgp
=
scsi_sg_pools
+
index
;
if
(
unlikely
(
index
>
SG_MEMPOOL_NR
))
{
printk
(
"scsi_free_sgtable: mempool %d
\n
"
,
index
);
BUG
();
}
mempool_free
(
sgl
,
sgp
->
pool
);
}
static
int
__init
init_scsi
(
void
)
{
int
i
;
printk
(
KERN_INFO
"SCSI subsystem driver "
REVISION
"
\n
"
);
/*
* setup sg memory pools
*/
for
(
i
=
0
;
i
<
SG_MEMPOOL_NR
;
i
++
)
{
struct
scsi_host_sg_pool
*
sgp
=
scsi_sg_pools
+
i
;
int
size
=
sgp
->
size
*
sizeof
(
struct
scatterlist
);
sgp
->
slab
=
kmem_cache_create
(
sgp
->
name
,
size
,
0
,
SLAB_HWCACHE_ALIGN
,
NULL
,
NULL
);
if
(
!
sgp
->
slab
)
printk
(
KERN_ERR
"SCSI: can't init sg slab %s
\n
"
,
sgp
->
name
);
sgp
->
pool
=
mempool_create
(
SG_MEMPOOL_SIZE
,
scsi_pool_alloc
,
scsi_pool_free
,
sgp
->
slab
);
if
(
!
sgp
->
pool
)
printk
(
KERN_ERR
"SCSI: can't init sg mempool %s
\n
"
,
sgp
->
name
);
}
scsi_init_queue
();
scsi_init_procfs
();
scsi_devfs_handle
=
devfs_mk_dir
(
NULL
,
"scsi"
,
NULL
);
scsi_host_init
();
...
...
@@ -2170,20 +2078,11 @@ static int __init init_scsi(void)
static
void
__exit
exit_scsi
(
void
)
{
int
i
;
scsi_sysfs_unregister
();
scsi_dev_info_list_delete
();
devfs_unregister
(
scsi_devfs_handle
);
scsi_exit_procfs
();
for
(
i
=
0
;
i
<
SG_MEMPOOL_NR
;
i
++
)
{
struct
scsi_host_sg_pool
*
sgp
=
scsi_sg_pools
+
i
;
mempool_destroy
(
sgp
->
pool
);
kmem_cache_destroy
(
sgp
->
slab
);
sgp
->
pool
=
NULL
;
sgp
->
slab
=
NULL
;
}
scsi_exit_queue
();
}
subsys_initcall
(
init_scsi
);
...
...
drivers/scsi/scsi.h
View file @
c23ee349
...
...
@@ -420,12 +420,6 @@ extern int scsi_partsize(unsigned char *buf, unsigned long capacity,
unsigned
int
*
cyls
,
unsigned
int
*
hds
,
unsigned
int
*
secs
);
/*
* sg list allocations
*/
struct
scatterlist
*
scsi_alloc_sgtable
(
Scsi_Cmnd
*
SCpnt
,
int
gfp_mask
);
void
scsi_free_sgtable
(
struct
scatterlist
*
sgl
,
int
index
);
/*
* Prototypes for functions in scsi_lib.c
*/
...
...
@@ -437,13 +431,13 @@ extern void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
extern
void
scsi_queue_next_request
(
request_queue_t
*
q
,
Scsi_Cmnd
*
SCpnt
);
extern
int
scsi_prep_fn
(
struct
request_queue
*
q
,
struct
request
*
req
);
extern
void
scsi_request_fn
(
request_queue_t
*
q
);
extern
int
scsi_starvation_completion
(
Scsi_Device
*
SDpnt
);
extern
int
scsi_init_queue
(
void
);
extern
void
scsi_exit_queue
(
void
);
/*
* Prototypes for functions in scsi.c
*/
extern
int
scsi_dispatch_cmd
(
Scsi_Cmnd
*
SCpnt
);
extern
void
scsi_bottom_half_handler
(
void
);
extern
void
scsi_release_commandblocks
(
Scsi_Device
*
SDpnt
);
extern
void
scsi_build_commandblocks
(
Scsi_Device
*
SDpnt
);
extern
void
scsi_adjust_queue_depth
(
Scsi_Device
*
,
int
,
int
);
...
...
@@ -462,7 +456,6 @@ extern void scsi_do_cmd(Scsi_Cmnd *, const void *cmnd,
void
*
buffer
,
unsigned
bufflen
,
void
(
*
done
)
(
struct
scsi_cmnd
*
),
int
timeout
,
int
retries
);
extern
int
scsi_dev_init
(
void
);
extern
int
scsi_mlqueue_insert
(
struct
scsi_cmnd
*
,
int
);
extern
int
scsi_attach_device
(
struct
scsi_device
*
);
extern
void
scsi_detach_device
(
struct
scsi_device
*
);
...
...
drivers/scsi/scsi_lib.c
View file @
c23ee349
...
...
@@ -11,12 +11,29 @@
#include <linux/blk.h>
#include <linux/completion.h>
#include <linux/kernel.h>
#include <linux/mempool.h>
#include <linux/slab.h>
#include "scsi.h"
#include "hosts.h"
#define SG_MEMPOOL_NR 5
#define SG_MEMPOOL_SIZE 32
struct
scsi_host_sg_pool
{
size_t
size
;
char
*
name
;
kmem_cache_t
*
slab
;
mempool_t
*
pool
;
};
#define SP(x) { x, "sgpool-" #x }
struct
scsi_host_sg_pool
scsi_sg_pools
[
SG_MEMPOOL_NR
]
=
{
SP
(
8
),
SP
(
16
),
SP
(
32
),
SP
(
64
),
SP
(
MAX_PHYS_SEGMENTS
)
};
#undef SP
/*
* Function: scsi_insert_special_cmd()
*
...
...
@@ -348,6 +365,51 @@ static Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt,
return
NULL
;
}
static
struct
scatterlist
*
scsi_alloc_sgtable
(
Scsi_Cmnd
*
SCpnt
,
int
gfp_mask
)
{
struct
scsi_host_sg_pool
*
sgp
;
struct
scatterlist
*
sgl
;
BUG_ON
(
!
SCpnt
->
use_sg
);
switch
(
SCpnt
->
use_sg
)
{
case
1
...
8
:
SCpnt
->
sglist_len
=
0
;
break
;
case
9
...
16
:
SCpnt
->
sglist_len
=
1
;
break
;
case
17
...
32
:
SCpnt
->
sglist_len
=
2
;
break
;
case
33
...
64
:
SCpnt
->
sglist_len
=
3
;
break
;
case
65
...
MAX_PHYS_SEGMENTS
:
SCpnt
->
sglist_len
=
4
;
break
;
default:
return
NULL
;
}
sgp
=
scsi_sg_pools
+
SCpnt
->
sglist_len
;
sgl
=
mempool_alloc
(
sgp
->
pool
,
gfp_mask
);
if
(
sgl
)
memset
(
sgl
,
0
,
sgp
->
size
);
return
sgl
;
}
static
void
scsi_free_sgtable
(
struct
scatterlist
*
sgl
,
int
index
)
{
struct
scsi_host_sg_pool
*
sgp
;
BUG_ON
(
index
>
SG_MEMPOOL_NR
);
sgp
=
scsi_sg_pools
+
index
;
mempool_free
(
sgl
,
sgp
->
pool
);
}
/*
* Function: scsi_release_buffers()
*
...
...
@@ -374,15 +436,10 @@ static void scsi_release_buffers(Scsi_Cmnd * SCpnt)
/*
* Free up any indirection buffers we allocated for DMA purposes.
*/
if
(
SCpnt
->
use_sg
)
{
struct
scatterlist
*
sgpnt
;
sgpnt
=
(
struct
scatterlist
*
)
SCpnt
->
request_buffer
;
if
(
SCpnt
->
use_sg
)
scsi_free_sgtable
(
SCpnt
->
request_buffer
,
SCpnt
->
sglist_len
);
}
else
{
if
(
SCpnt
->
request_buffer
!=
req
->
buffer
)
kfree
(
SCpnt
->
request_buffer
);
}
else
if
(
SCpnt
->
request_buffer
!=
req
->
buffer
)
kfree
(
SCpnt
->
request_buffer
);
/*
* Zero these out. They now point to freed memory, and it is
...
...
@@ -462,22 +519,16 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
* For the case of a READ, we need to copy the data out of the
* bounce buffer and into the real buffer.
*/
if
(
SCpnt
->
use_sg
)
{
struct
scatterlist
*
sgpnt
;
sgpnt
=
(
struct
scatterlist
*
)
SCpnt
->
buffer
;
if
(
SCpnt
->
use_sg
)
scsi_free_sgtable
(
SCpnt
->
buffer
,
SCpnt
->
sglist_len
);
}
else
{
if
(
SCpnt
->
buffer
!=
req
->
buffer
)
{
if
(
rq_data_dir
(
req
)
==
READ
)
{
unsigned
long
flags
;
char
*
to
=
bio_kmap_irq
(
req
->
bio
,
&
flags
);
memcpy
(
to
,
SCpnt
->
buffer
,
SCpnt
->
bufflen
);
bio_kunmap_irq
(
to
,
&
flags
);
}
kfree
(
SCpnt
->
buffer
);
else
if
(
SCpnt
->
buffer
!=
req
->
buffer
)
{
if
(
rq_data_dir
(
req
)
==
READ
)
{
unsigned
long
flags
;
char
*
to
=
bio_kmap_irq
(
req
->
bio
,
&
flags
);
memcpy
(
to
,
SCpnt
->
buffer
,
SCpnt
->
bufflen
);
bio_kunmap_irq
(
to
,
&
flags
);
}
kfree
(
SCpnt
->
buffer
);
}
if
(
blk_pc_request
(
req
))
{
...
...
@@ -1093,3 +1144,41 @@ void scsi_register_blocked_host(struct Scsi_Host * SHpnt)
void
scsi_deregister_blocked_host
(
struct
Scsi_Host
*
SHpnt
)
{
}
int
__init
scsi_init_queue
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
SG_MEMPOOL_NR
;
i
++
)
{
struct
scsi_host_sg_pool
*
sgp
=
scsi_sg_pools
+
i
;
int
size
=
sgp
->
size
*
sizeof
(
struct
scatterlist
);
sgp
->
slab
=
kmem_cache_create
(
sgp
->
name
,
size
,
0
,
SLAB_HWCACHE_ALIGN
,
NULL
,
NULL
);
if
(
!
sgp
->
slab
)
{
printk
(
KERN_ERR
"SCSI: can't init sg slab %s
\n
"
,
sgp
->
name
);
}
sgp
->
pool
=
mempool_create
(
SG_MEMPOOL_SIZE
,
mempool_alloc_slab
,
mempool_free_slab
,
sgp
->
slab
);
if
(
!
sgp
->
pool
)
{
printk
(
KERN_ERR
"SCSI: can't init sg mempool %s
\n
"
,
sgp
->
name
);
}
}
return
0
;
}
void
__exit
scsi_exit_lib
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
SG_MEMPOOL_NR
;
i
++
)
{
struct
scsi_host_sg_pool
*
sgp
=
scsi_sg_pools
+
i
;
mempool_destroy
(
sgp
->
pool
);
kmem_cache_destroy
(
sgp
->
slab
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment