usb: storage: fix module reference for scsi host

While accessing a unusual usb storage (ums-alauda, ums-cypress, ...),
the module reference count is not incremented.  Because these drivers
allocate scsi hosts with usb_stor_host_template defined in usb-storage
module.  So these drivers always can be unloaded.

This fixes it by preparing scsi host template which is initialized
at module_init() for each ums-* driver.  In order to minimize the
difference in ums-* drivers, introduce module_usb_stor_driver() helper
macro which is same as module_usb_driver() except that it also
initializes scsi host template.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Cc: Vinayak Holikatti <vinholikatti@gmail.com>
Cc: Dolev Raviv <draviv@codeaurora.org>
Cc: Sujit Reddy Thumma <sthumma@codeaurora.org>
Cc: Subhash Jadavani <subhashj@codeaurora.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: "James E.J. Bottomley" <JBottomley@parallels.com>
Cc: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Hannes Reinecke <hare@suse.de>
Cc: linux-usb@vger.kernel.org
Cc: usb-storage@lists.one-eyed-alien.net
Cc: linux-scsi@vger.kernel.org
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Akinobu Mita
2015-05-06 18:24:21 +09:00
committed by Greg Kroah-Hartman
parent 1cb39e2564
commit aa519be34f
17 changed files with 150 additions and 47 deletions

View File

@@ -76,6 +76,8 @@
#include "uas-detect.h"
#endif
#define DRV_NAME "usb-storage"
/* Some informational data */
MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>");
MODULE_DESCRIPTION("USB Mass Storage driver for Linux");
@@ -924,7 +926,8 @@ static unsigned int usb_stor_sg_tablesize(struct usb_interface *intf)
int usb_stor_probe1(struct us_data **pus,
struct usb_interface *intf,
const struct usb_device_id *id,
struct us_unusual_dev *unusual_dev)
struct us_unusual_dev *unusual_dev,
struct scsi_host_template *sht)
{
struct Scsi_Host *host;
struct us_data *us;
@@ -936,7 +939,7 @@ int usb_stor_probe1(struct us_data **pus,
* Ask the SCSI layer to allocate a host structure, with extra
* space at the end for our private us_data structure.
*/
host = scsi_host_alloc(&usb_stor_host_template, sizeof(*us));
host = scsi_host_alloc(sht, sizeof(*us));
if (!host) {
dev_warn(&intf->dev, "Unable to allocate the scsi host\n");
return -ENOMEM;
@@ -1073,6 +1076,8 @@ void usb_stor_disconnect(struct usb_interface *intf)
}
EXPORT_SYMBOL_GPL(usb_stor_disconnect);
static struct scsi_host_template usb_stor_host_template;
/* The main probe routine for standard devices */
static int storage_probe(struct usb_interface *intf,
const struct usb_device_id *id)
@@ -1113,7 +1118,8 @@ static int storage_probe(struct usb_interface *intf,
id->idVendor, id->idProduct);
}
result = usb_stor_probe1(&us, intf, id, unusual_dev);
result = usb_stor_probe1(&us, intf, id, unusual_dev,
&usb_stor_host_template);
if (result)
return result;
@@ -1124,7 +1130,7 @@ static int storage_probe(struct usb_interface *intf,
}
static struct usb_driver usb_storage_driver = {
.name = "usb-storage",
.name = DRV_NAME,
.probe = storage_probe,
.disconnect = usb_stor_disconnect,
.suspend = usb_stor_suspend,
@@ -1137,4 +1143,4 @@ static struct usb_driver usb_storage_driver = {
.soft_unbind = 1,
};
module_usb_driver(usb_storage_driver);
module_usb_stor_driver(usb_storage_driver, usb_stor_host_template, DRV_NAME);