[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MiNT] [PATCH] Add XHEject handling to USB mass storage driver



Alan please commit this patch for the USB mass storage driver.

Commit message:

Add XHEject handling to the USB mass storage driver
Index: usb/src.km/udd/storage/usb_storage.c
===================================================================
RCS file: /mint/freemint/sys/usb/src.km/udd/storage/usb_storage.c,v
retrieving revision 1.6
diff -u -8 -r1.6 usb_storage.c
--- usb/src.km/udd/storage/usb_storage.c	2 Jan 2014 11:55:42 -0000	1.6
+++ usb/src.km/udd/storage/usb_storage.c	4 Feb 2014 00:08:58 -0000
@@ -57,17 +57,17 @@
 
 #include "../../config.h"
 #include "../../usb.h"
 #include "../udd_defs.h"
 #include "../../usb_api.h"
 
 
 #define VER_MAJOR	0
-#define VER_MINOR	2
+#define VER_MINOR	3
 #define VER_STATUS	
 
 #define MSG_VERSION	str (VER_MAJOR) "." str (VER_MINOR) str (VER_STATUS) 
 #define MSG_BUILDDATE	__DATE__
 
 #define MSG_BOOT	\
 	"\033p USB mass storage class driver " MSG_VERSION " \033q\r\n"
 
@@ -326,16 +326,17 @@
 //#define le32_to_int(a) swap_32(*(unsigned long *)a)
 
 /* Functions prototypes */
 long _cdecl	init			(struct kentry *, struct usb_module_api *, long, long);
 long 		usb_stor_get_info	(struct usb_device *, struct us_data *, block_dev_desc_t *);
 long 		usb_stor_probe		(struct usb_device *, unsigned long, struct us_data *);
 unsigned long 	usb_stor_read		(long, unsigned long, unsigned long, void *);
 unsigned long 	usb_stor_write		(long, unsigned long, unsigned long, const void *);
+void		usb_stor_eject		(long);
 //struct usb_device * 	usb_get_dev_index	(long index);
 long 		usb_stor_info		(void);
 block_dev_desc_t *	usb_stor_get_dev	(long);
 void 		uhci_show_temp_int_td	(void);
 long 		usb_stor_BBB_comdat	(ccb *, struct us_data *);
 long 		usb_stor_CB_comdat	(ccb *, struct us_data *);
 long 		usb_stor_CBI_get_status	(ccb *, struct us_data *);
 long 		usb_stor_BBB_clear_endpt_stall	(struct us_data *, unsigned char);
@@ -1785,49 +1786,88 @@
 	DEBUG((" address %d", dev_desc->target));
 	DEBUG(("partype: %d", dev_desc->part_type));
 	init_part(dev_desc);
 	DEBUG(("partype: %d", dev_desc->part_type));
 	return 1;
 }
 
 
+void
+usb_stor_eject(long device)
+{
+	if (usb_stor[device].pusb_dev->devnum == usb_dev_desc[device].target)
+	{
+		memset(&usb_dev_desc[device], 0, sizeof(block_dev_desc_t));
+		usb_dev_desc[device].target = 0xff;
+		usb_dev_desc[device].if_type = IF_TYPE_USB;
+		usb_dev_desc[device].dev = device;
+		usb_dev_desc[device].part_type = PART_TYPE_UNKNOWN;
+		usb_dev_desc[device].block_read = usb_stor_read;
+		usb_dev_desc[device].block_write = usb_stor_write;
+		usb_max_devs--;
+	}
+	else
+	{
+		DEBUG(("USB mass storage device was already disconnected"));
+		return;
+	}
+
+	long idx;
+	for (idx = 1; idx <= bios_part[device].partnum; idx++)
+	{	
+		uninstall_usb_stor(bios_part[device].biosnum[idx - 1]);
+	}
+	bios_part[device].partnum = 0;
+
+	ALERT(("USB Storage Device disconnected: (%ld) %s", usb_stor[device].pusb_dev->devnum,
+							    usb_stor[device].pusb_dev->prod));
+}
+
+
 /*******************************************************************************
  * 
  * 
  */
 void
 usb_storage_disconnect(struct usb_device *dev)
 {
-	long i, idx;
-	long biosdev;
-
-	ALERT(("USB Storage Device disconnected: (%ld) %s", dev->devnum, dev->prod));
-
+	long i;
 	for (i = 0; i <= USB_MAX_STOR_DEV; i++)
 	{
 		if (dev->devnum == usb_dev_desc[i].target)
 		{
 			memset(&usb_dev_desc[i], 0, sizeof(block_dev_desc_t));
 			usb_dev_desc[i].target = 0xff;
 			usb_dev_desc[i].if_type = IF_TYPE_USB;
 			usb_dev_desc[i].dev = i;
 			usb_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
 			usb_dev_desc[i].block_read = usb_stor_read;
 			usb_dev_desc[i].block_write = usb_stor_write;
 			usb_max_devs--;
 			break;
 		}
 	}
+
+	if (i > USB_MAX_STOR_DEV) 
+	{
+		/* Probably the device has been already disconnected by software (XHEject) */
+		DEBUG(("USB mass storage device was already disconnected"));
+		return;
+	}
+
+	long idx;
 	for (idx = 1; idx <= bios_part[i].partnum; idx++)
 	{	
-		biosdev = uninstall_usb_stor(bios_part[i].biosnum[idx - 1]);
-		changedrv((unsigned short)biosdev);
+		uninstall_usb_stor(bios_part[i].biosnum[idx - 1]);
 	}
 	bios_part[i].partnum = 0;
+
+	ALERT(("USB Storage Device disconnected: (%ld) %s", dev->devnum, dev->prod));
+
 }
 
 
 /*******************************************************************************
  * 
  * 
  */
 long
@@ -1884,16 +1924,18 @@
 		/* install partition */
 		r = install_usb_stor(dev_num, part_type, part_offset, 
 				     part_size, stor_dev->vendor, 
 				     stor_dev->revision, stor_dev->product);
 		if (r == -1)
 			c_conws("unable to install storage device\r\n");
 		else
 		{
+			/* inform the kernel about media change */
+			changedrv(r);
 			bios_part[dev_num].biosnum[part_num - 1] = r;
 			bios_part[dev_num].partnum = part_num;
 		}	
 		part_num++;
 	}
 	return 0;
 }
 
Index: usb/src.km/udd/storage/xhdi.c
===================================================================
RCS file: /mint/freemint/sys/usb/src.km/udd/storage/xhdi.c,v
retrieving revision 1.1
diff -u -8 -r1.1 xhdi.c
--- usb/src.km/udd/storage/xhdi.c	18 Apr 2012 21:47:36 -0000	1.1
+++ usb/src.km/udd/storage/xhdi.c	4 Feb 2014 00:08:59 -0000
@@ -67,16 +67,17 @@
 extern long usb_1st_disk_drive;
 extern short max_logical_drive;
 #define MAX_LOGICAL_DRIVE	max_logical_drive
 
 /* --- External functions ---*/
 
 extern ulong usb_stor_read(long, ulong, ulong, void *);
 extern ulong usb_stor_write(long, ulong, ulong, const void *);
+extern void usb_stor_eject(long);
 
 /*--- Functions prototypes ---*/
 
 typedef long (*XHDI_HANDLER)(ushort opcode, ...);
 static XHDI_HANDLER next_handler; /* Next handler installed by XHNewCookie() */
 
 long install_xhdi_driver(void);
 long xhdi_handler(ushort stack);
@@ -273,17 +274,22 @@
 		long ret = next_handler(XHEJECT, major, minor, do_eject, key);
 		if (ret != ENOSYS && ret != ENODEV && ret != ENXIO)
 			return ret;
 	}
 
 	if (major < PUN_USB || major > PUN_USB + PUN_DEV)
 		return ENODEV;
 
-	return ENOSYS;
+	/* device number in the USB bus */
+	short dev = pun_ptr_usb->dev_num[major & PUN_DEV];
+
+	usb_stor_eject(dev);
+
+	return E_OK;
 }
 
 static long
 XHInqDriver(ushort dev, char *name, char *version, char *company,
 		ushort *ahdi_version, ushort *max_IPL)
 {
 	if (next_handler) {
 		long ret = next_handler(XHSTOP, dev, name, version, company,